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:
-rw-r--r--.arcconfig2
-rw-r--r--.gitmodules4
-rw-r--r--CMakeLists.txt64
-rw-r--r--GNUmakefile2
-rwxr-xr-xbuild_files/build_environment/install_deps.sh14
-rw-r--r--build_files/cmake/Modules/FindGLEW.cmake12
-rw-r--r--build_files/cmake/macros.cmake2
-rw-r--r--build_files/cmake/platform/platform_apple.cmake2
-rw-r--r--doc/python_api/examples/gpu.offscreen.1.py2
-rw-r--r--doc/python_api/sphinx_doc_gen.py2
-rw-r--r--extern/glew-es/CMakeLists.txt5
-rw-r--r--extern/glew/CMakeLists.txt5
-rw-r--r--extern/glew/include/GL/eglew.h2261
-rw-r--r--extern/glew/include/GL/glew.h476
-rw-r--r--extern/glew/include/GL/glxew.h61
-rw-r--r--extern/glew/include/GL/wglew.h36
-rw-r--r--extern/glew/src/glew.c9333
-rw-r--r--intern/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/addon/__init__.py18
-rw-r--r--intern/cycles/blender/addon/engine.py13
-rw-r--r--intern/cycles/blender/addon/properties.py6
-rw-r--r--intern/cycles/blender/addon/ui.py35
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2
-rw-r--r--intern/cycles/blender/blender_object.cpp127
-rw-r--r--intern/cycles/blender/blender_python.cpp16
-rw-r--r--intern/cycles/blender/blender_session.cpp8
-rw-r--r--intern/cycles/blender/blender_session.h3
-rw-r--r--intern/cycles/blender/blender_sync.cpp39
-rw-r--r--intern/cycles/blender/blender_sync.h4
-rw-r--r--intern/cycles/device/device.cpp321
-rw-r--r--intern/cycles/device/device.h22
-rw-r--r--intern/cycles/device/device_cuda.cpp57
-rw-r--r--intern/cycles/device/device_multi.cpp9
-rw-r--r--intern/cycles/render/buffers.cpp6
-rw-r--r--intern/cycles/util/util_opengl.h8
-rw-r--r--intern/cycles/util/util_view.cpp2
-rw-r--r--intern/elbeem/intern/solver_control.cpp152
-rw-r--r--intern/elbeem/intern/solver_util.cpp217
-rw-r--r--intern/gawain/CMakeLists.txt33
-rw-r--r--intern/gawain/gawain/attrib_binding.h19
-rw-r--r--intern/gawain/gawain/attrib_binding_private.h20
-rw-r--r--intern/gawain/gawain/batch.h129
-rw-r--r--intern/gawain/gawain/buffer_id.h34
-rw-r--r--intern/gawain/gawain/common.h27
-rw-r--r--intern/gawain/gawain/element.h75
-rw-r--r--intern/gawain/gawain/imm_util.h18
-rw-r--r--intern/gawain/gawain/immediate.h119
-rw-r--r--intern/gawain/gawain/primitive.h40
-rw-r--r--intern/gawain/gawain/primitive_private.h14
-rw-r--r--intern/gawain/gawain/shader_interface.h53
-rw-r--r--intern/gawain/gawain/vertex_buffer.h78
-rw-r--r--intern/gawain/gawain/vertex_format.h78
-rw-r--r--intern/gawain/gawain/vertex_format_private.h16
-rw-r--r--intern/gawain/src/attrib_binding.c70
-rw-r--r--intern/gawain/src/batch.c442
-rw-r--r--intern/gawain/src/buffer_id.cpp115
-rw-r--r--intern/gawain/src/element.c295
-rw-r--r--intern/gawain/src/imm_util.c46
-rw-r--r--intern/gawain/src/immediate.c919
-rw-r--r--intern/gawain/src/primitive.c63
-rw-r--r--intern/gawain/src/shader_interface.c303
-rw-r--r--intern/gawain/src/vertex_buffer.c183
-rw-r--r--intern/gawain/src/vertex_format.c296
-rw-r--r--intern/ghost/intern/GHOST_Context.cpp6
-rw-r--r--intern/ghost/intern/GHOST_Context.h11
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h13
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.mm36
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.cpp33
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.h20
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp44
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.h19
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.cpp2
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.cpp50
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.h27
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm69
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp117
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp122
-rw-r--r--intern/ghost/test/CMakeLists.txt3
-rw-r--r--intern/glew-mx/glew-mx.h31
-rw-r--r--intern/glew-mx/intern/gl-deprecated.h6
-rw-r--r--intern/glew-mx/intern/glew-mx.c58
-rw-r--r--intern/opencolorio/CMakeLists.txt2
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl10
-rw-r--r--intern/opencolorio/gpu_shader_display_transform_vertex.glsl12
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc98
-rw-r--r--intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl15
-rw-r--r--intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl7
-rw-r--r--intern/opensubdiv/opensubdiv_capi.cc13
-rw-r--r--intern/opensubdiv/opensubdiv_capi.h4
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc83
-rw-r--r--intern/opensubdiv/opensubdiv_utils_capi.cc14
-rw-r--r--make.bat2
-rw-r--r--release/darwin/blender.app/Contents/Info.plist4
-rw-r--r--release/datafiles/preview.blendbin575216 -> 795192 bytes
-rw-r--r--release/datafiles/preview_cycles.blendbin1263660 -> 1363956 bytes
-rw-r--r--release/scripts/modules/bpy_extras/__init__.py1
-rw-r--r--release/scripts/modules/bpy_extras/node_utils.py47
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py75
-rw-r--r--release/scripts/presets/keyconfig/3dsmax.py3
-rw-r--r--release/scripts/presets/keyconfig/maya.py3
-rw-r--r--release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py1
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py4
-rw-r--r--release/scripts/startup/bl_operators/clip.py4
-rw-r--r--release/scripts/startup/bl_operators/freestyle.py2
-rw-r--r--release/scripts/startup/bl_operators/mesh.py2
-rw-r--r--release/scripts/startup/bl_operators/object.py22
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py2
-rw-r--r--release/scripts/startup/bl_operators/rigidbody.py8
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_follow_active.py6
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py15
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py4
-rw-r--r--release/scripts/startup/bl_ui/__init__.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_collection.py167
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py50
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lamp.py17
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lattice.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py78
-rw-r--r--release/scripts/startup/bl_ui/properties_data_metaball.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py15
-rw-r--r--release/scripts/startup/bl_ui/properties_data_speaker.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py128
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py40
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_smoke.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py89
-rw-r--r--release/scripts/startup/bl_ui/properties_render_layer.py186
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py16
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_world.py33
-rw-r--r--release/scripts/startup/bl_ui/space_image.py2
-rw-r--r--release/scripts/startup/bl_ui/space_info.py6
-rw-r--r--release/scripts/startup/bl_ui/space_node.py3
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py13
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py74
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py14
-rw-r--r--release/scripts/startup/nodeitems_builtins.py2
-rw-r--r--release/scripts/templates_py/batch_export.py6
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py2
-rw-r--r--source/CMakeLists.txt4
-rw-r--r--source/blender/CMakeLists.txt3
-rw-r--r--source/blender/alembic/CMakeLists.txt1
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc85
-rw-r--r--source/blender/alembic/intern/abc_exporter.h9
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc7
-rw-r--r--source/blender/alembic/intern/abc_object.cc1
-rw-r--r--source/blender/alembic/intern/abc_util.cc36
-rw-r--r--source/blender/alembic/intern/abc_util.h4
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc48
-rw-r--r--source/blender/blenfont/BLF_api.h34
-rw-r--r--source/blender/blenfont/intern/blf.c230
-rw-r--r--source/blender/blenfont/intern/blf_font.c44
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c146
-rw-r--r--source/blender/blenfont/intern/blf_internal.h5
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h8
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h31
-rw-r--r--source/blender/blenkernel/BKE_armature.h1
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h4
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h2
-rw-r--r--source/blender/blenkernel/BKE_camera.h3
-rw-r--r--source/blender/blenkernel/BKE_collection.h100
-rw-r--r--source/blender/blenkernel/BKE_collision.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h10
-rw-r--r--source/blender/blenkernel/BKE_curve.h8
-rw-r--r--source/blender/blenkernel/BKE_customdata.h11
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h48
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h6
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h1
-rw-r--r--source/blender/blenkernel/BKE_editmesh_tangent.h40
-rw-r--r--source/blender/blenkernel/BKE_group.h5
-rw-r--r--source/blender/blenkernel/BKE_lattice.h8
-rw-r--r--source/blender/blenkernel/BKE_layer.h253
-rw-r--r--source/blender/blenkernel/BKE_material.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh.h19
-rw-r--r--source/blender/blenkernel/BKE_mesh_tangent.h59
-rw-r--r--source/blender/blenkernel/BKE_modifier.h10
-rw-r--r--source/blender/blenkernel/BKE_node.h10
-rw-r--r--source/blender/blenkernel/BKE_object.h20
-rw-r--r--source/blender/blenkernel/BKE_object_facemap.h53
-rw-r--r--source/blender/blenkernel/BKE_outliner_treehash.h3
-rw-r--r--source/blender/blenkernel/BKE_paint.h7
-rw-r--r--source/blender/blenkernel/BKE_particle.h7
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h5
-rw-r--r--source/blender/blenkernel/BKE_scene.h31
-rw-r--r--source/blender/blenkernel/BKE_screen.h14
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/BKE_smoke.h2
-rw-r--r--source/blender/blenkernel/BKE_softbody.h3
-rw-r--r--source/blender/blenkernel/CMakeLists.txt16
-rw-r--r--source/blender/blenkernel/depsgraph_private.h169
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c2
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c568
-rw-r--r--source/blender/blenkernel/intern/action.c10
-rw-r--r--source/blender/blenkernel/intern/anim.c49
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c7
-rw-r--r--source/blender/blenkernel/intern/armature.c18
-rw-r--r--source/blender/blenkernel/intern/armature_update.c25
-rw-r--r--source/blender/blenkernel/intern/blender.c8
-rw-r--r--source/blender/blenkernel/intern/blender_copybuffer.c9
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c5
-rw-r--r--source/blender/blenkernel/intern/cachefile.c6
-rw-r--r--source/blender/blenkernel/intern/camera.c6
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c318
-rw-r--r--source/blender/blenkernel/intern/cloth.c1
-rw-r--r--source/blender/blenkernel/intern/collection.c640
-rw-r--r--source/blender/blenkernel/intern/collision.c10
-rw-r--r--source/blender/blenkernel/intern/context.c78
-rw-r--r--source/blender/blenkernel/intern/curve.c25
-rw-r--r--source/blender/blenkernel/intern/customdata.c112
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c4
-rw-r--r--source/blender/blenkernel/intern/deform.c3
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c3539
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c35
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c644
-rw-r--r--source/blender/blenkernel/intern/editmesh.c20
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.c420
-rw-r--r--source/blender/blenkernel/intern/effect.c18
-rw-r--r--source/blender/blenkernel/intern/group.c21
-rw-r--r--source/blender/blenkernel/intern/icons.c2
-rw-r--r--source/blender/blenkernel/intern/idprop.c20
-rw-r--r--source/blender/blenkernel/intern/lattice.c21
-rw-r--r--source/blender/blenkernel/intern/layer.c1837
-rw-r--r--source/blender/blenkernel/intern/library.c77
-rw-r--r--source/blender/blenkernel/intern/library_query.c52
-rw-r--r--source/blender/blenkernel/intern/library_remap.c72
-rw-r--r--source/blender/blenkernel/intern/material.c534
-rw-r--r--source/blender/blenkernel/intern/mball.c39
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c7
-rw-r--r--source/blender/blenkernel/intern/mesh.c106
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c204
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.c684
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c84
-rw-r--r--source/blender/blenkernel/intern/node.c19
-rw-r--r--source/blender/blenkernel/intern/object.c106
-rw-r--r--source/blender/blenkernel/intern/object_deform.c3
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c4
-rw-r--r--source/blender/blenkernel/intern/object_facemap.c259
-rw-r--r--source/blender/blenkernel/intern/object_update.c23
-rw-r--r--source/blender/blenkernel/intern/outliner_treehash.c39
-rw-r--r--source/blender/blenkernel/intern/paint.c35
-rw-r--r--source/blender/blenkernel/intern/particle.c34
-rw-r--r--source/blender/blenkernel/intern/particle_system.c13
-rw-r--r--source/blender/blenkernel/intern/pbvh.c109
-rw-r--r--source/blender/blenkernel/intern/pointcache.c4
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c9
-rw-r--r--source/blender/blenkernel/intern/scene.c974
-rw-r--r--source/blender/blenkernel/intern/screen.c17
-rw-r--r--source/blender/blenkernel/intern/sequencer.c12
-rw-r--r--source/blender/blenkernel/intern/smoke.c20
-rw-r--r--source/blender/blenkernel/intern/softbody.c55
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c264
-rw-r--r--source/blender/blenkernel/intern/text.c1
-rw-r--r--source/blender/blenlib/BLI_callbacks.h2
-rw-r--r--source/blender/blenlib/BLI_ghash.h1
-rw-r--r--source/blender/blenlib/BLI_iterator.h55
-rw-r--r--source/blender/blenlib/BLI_listbase.h1
-rw-r--r--source/blender/blenlib/BLI_math_color.h4
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h192
-rw-r--r--source/blender/blenlib/BLI_math_vector.h5
-rw-r--r--source/blender/blenlib/BLI_utildefines.h3
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/intern/listbase.c28
-rw-r--r--source/blender/blenlib/intern/math_color.c6
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c8
-rw-r--r--source/blender/blenlib/intern/math_matrix.c311
-rw-r--r--source/blender/blenlib/intern/math_vector.c14
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c16
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c14
-rw-r--r--source/blender/blenloader/BLO_readfile.h5
-rw-r--r--source/blender/blenloader/CMakeLists.txt2
-rw-r--r--source/blender/blenloader/intern/readfile.c401
-rw-r--r--source/blender/blenloader/intern/readfile.h4
-rw-r--r--source/blender/blenloader/intern/versioning_250.c4
-rw-r--r--source/blender/blenloader/intern/versioning_270.c21
-rw-r--r--source/blender/blenloader/intern/versioning_280.c288
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c3
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c81
-rw-r--r--source/blender/blenloader/intern/writefile.c70
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c45
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h2
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c64
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c21
-rw-r--r--source/blender/collada/AnimationExporter.cpp2
-rw-r--r--source/blender/collada/ArmatureImporter.cpp7
-rw-r--r--source/blender/collada/CMakeLists.txt1
-rw-r--r--source/blender/collada/DocumentImporter.cpp17
-rw-r--r--source/blender/collada/EffectExporter.cpp67
-rw-r--r--source/blender/collada/ExportSettings.h1
-rw-r--r--source/blender/collada/ImageExporter.cpp56
-rw-r--r--source/blender/collada/ImageExporter.h1
-rw-r--r--source/blender/collada/MeshImporter.cpp39
-rw-r--r--source/blender/collada/MeshImporter.h10
-rw-r--r--source/blender/collada/collada.cpp5
-rw-r--r--source/blender/collada/collada.h3
-rw-r--r--source/blender/collada/collada_utils.cpp9
-rw-r--r--source/blender/depsgraph/CMakeLists.txt6
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h36
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h15
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h27
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc114
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.h1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc45
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h17
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc117
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc15
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h19
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc127
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc12
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc34
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc5
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h8
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc49
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc107
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc86
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type_defines.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_types.h7
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc51
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.h3
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc1
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc6
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.h3
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.cc14
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.h7
-rw-r--r--source/blender/depsgraph/util/deg_util_foreach.h10
-rw-r--r--source/blender/depsgraph/util/deg_util_function.h61
-rw-r--r--source/blender/draw/CMakeLists.txt178
-rw-r--r--source/blender/draw/DRW_engine.h93
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c257
-rw-r--r--source/blender/draw/engines/basic/basic_engine.h32
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c907
-rw-r--r--source/blender/draw/engines/clay/clay_engine.h36
-rw-r--r--source/blender/draw/engines/clay/shaders/clay_frag.glsl198
-rw-r--r--source/blender/draw/engines/clay/shaders/clay_particle_strand_frag.glsl144
-rw-r--r--source/blender/draw/engines/clay/shaders/clay_particle_vert.glsl34
-rw-r--r--source/blender/draw/engines/clay/shaders/clay_vert.glsl17
-rw-r--r--source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl75
-rw-r--r--source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl122
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c658
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c715
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.h31
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c668
-rw-r--r--source/blender/draw/engines/eevee/eevee_lut.h3347
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h343
-rw-r--r--source/blender/draw/engines/eevee/eevee_probes.c310
-rw-r--r--source/blender/draw/engines/eevee/shaders/background_vert.glsl17
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl274
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl180
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl46
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl54
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl15
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_world_frag.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl207
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl261
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_geom.glsl55
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl99
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl63
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl228
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl34
-rw-r--r--source/blender/draw/engines/eevee/shaders/ltc_lib.glsl232
-rw-r--r--source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl86
-rw-r--r--source/blender/draw/engines/eevee/shaders/probe_geom.glsl28
-rw-r--r--source/blender/draw/engines/eevee/shaders/probe_sh_frag.glsl107
-rw-r--r--source/blender/draw/engines/eevee/shaders/probe_vert.glsl10
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_frag.glsl15
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_geom.glsl27
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl64
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl13
-rw-r--r--source/blender/draw/engines/external/external_engine.c232
-rw-r--r--source/blender/draw/engines/external/external_engine.h31
-rw-r--r--source/blender/draw/intern/DRW_render.h394
-rw-r--r--source/blender/draw/intern/draw_armature.c1442
-rw-r--r--source/blender/draw/intern/draw_cache.c2415
-rw-r--r--source/blender/draw/intern/draw_cache.h147
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h100
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c1047
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c168
-rw-r--r--source/blender/draw/intern/draw_cache_impl_lattice.c510
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c3235
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c348
-rw-r--r--source/blender/draw/intern/draw_common.c449
-rw-r--r--source/blender/draw/intern/draw_common.h131
-rw-r--r--source/blender/draw/intern/draw_manager.c3309
-rw-r--r--source/blender/draw/intern/draw_manager_text.c199
-rw-r--r--source/blender/draw/intern/draw_manager_text.h54
-rw-r--r--source/blender/draw/intern/draw_view.c732
-rw-r--r--source/blender/draw/intern/draw_view.h35
-rw-r--r--source/blender/draw/modes/draw_mode_engines.h44
-rw-r--r--source/blender/draw/modes/edit_armature_mode.c149
-rw-r--r--source/blender/draw/modes/edit_curve_mode.c329
-rw-r--r--source/blender/draw/modes/edit_lattice_mode.c290
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c584
-rw-r--r--source/blender/draw/modes/edit_metaball_mode.c268
-rw-r--r--source/blender/draw/modes/edit_surface_mode.c268
-rw-r--r--source/blender/draw/modes/edit_text_mode.c311
-rw-r--r--source/blender/draw/modes/object_mode.c1736
-rw-r--r--source/blender/draw/modes/paint_texture_mode.c420
-rw-r--r--source/blender/draw/modes/paint_vertex_mode.c206
-rw-r--r--source/blender/draw/modes/paint_weight_mode.c250
-rw-r--r--source/blender/draw/modes/particle_mode.c263
-rw-r--r--source/blender/draw/modes/pose_mode.c195
-rw-r--r--source/blender/draw/modes/sculpt_mode.c299
-rw-r--r--source/blender/draw/modes/shaders/common_globals_lib.glsl58
-rw-r--r--source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl22
-rw-r--r--source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl39
-rw-r--r--source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl22
-rw-r--r--source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl39
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl12
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl14
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_frag.glsl29
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl29
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl187
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl143
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl277
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_loosevert_vert.glsl59
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl24
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl23
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_geom.glsl15
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_vert.glsl30
-rw-r--r--source/blender/draw/modes/shaders/object_empty_image_frag.glsl21
-rw-r--r--source/blender/draw/modes/shaders/object_empty_image_vert.glsl38
-rw-r--r--source/blender/draw/modes/shaders/object_grid_frag.glsl189
-rw-r--r--source/blender/draw/modes/shaders/object_grid_vert.glsl63
-rw-r--r--source/blender/draw/modes/shaders/object_outline_detect_frag.glsl61
-rw-r--r--source/blender/draw/modes/shaders/object_outline_expand_frag.glsl45
-rw-r--r--source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl11
-rw-r--r--source/blender/draw/modes/shaders/object_particle_dot_frag.glsl52
-rw-r--r--source/blender/draw/modes/shaders/object_particle_dot_vert.glsl28
-rw-r--r--source/blender/draw/modes/shaders/object_particle_prim_frag.glsl9
-rw-r--r--source/blender/draw/modes/shaders/object_particle_prim_vert.glsl64
-rw-r--r--source/blender/draw/modes/shaders/paint_texture_frag.glsl11
-rw-r--r--source/blender/draw/modes/shaders/paint_texture_vert.glsl15
-rw-r--r--source/blender/draw/modes/shaders/paint_vert_frag.glsl26
-rw-r--r--source/blender/draw/modes/shaders/paint_wire_frag.glsl24
-rw-r--r--source/blender/draw/modes/shaders/paint_wire_vert.glsl14
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c127
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c15
-rw-r--r--source/blender/editors/animation/anim_draw.c76
-rw-r--r--source/blender/editors/animation/anim_filter.c45
-rw-r--r--source/blender/editors/animation/anim_markers.c77
-rw-r--r--source/blender/editors/animation/keyframes_draw.c234
-rw-r--r--source/blender/editors/animation/keyframes_edit.c2
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_relations.c22
-rw-r--r--source/blender/editors/armature/armature_select.c2
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c190
-rw-r--r--source/blender/editors/armature/pose_select.c4
-rw-r--r--source/blender/editors/armature/reeb.c234
-rw-r--r--source/blender/editors/curve/editcurve.c8
-rw-r--r--source/blender/editors/curve/editcurve_paint.c106
-rw-r--r--source/blender/editors/curve/editfont.c7
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c1163
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c32
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c62
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c9
-rw-r--r--source/blender/editors/include/BIF_gl.h53
-rw-r--r--source/blender/editors/include/BIF_glutil.h159
-rw-r--r--source/blender/editors/include/ED_anim_api.h1
-rw-r--r--source/blender/editors/include/ED_armature.h12
-rw-r--r--source/blender/editors/include/ED_image.h3
-rw-r--r--source/blender/editors/include/ED_info.h4
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h6
-rw-r--r--source/blender/editors/include/ED_mesh.h5
-rw-r--r--source/blender/editors/include/ED_node.h2
-rw-r--r--source/blender/editors/include/ED_object.h26
-rw-r--r--source/blender/editors/include/ED_particle.h21
-rw-r--r--source/blender/editors/include/ED_screen.h11
-rw-r--r--source/blender/editors/include/ED_sculpt.h3
-rw-r--r--source/blender/editors/include/ED_transform.h17
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h5
-rw-r--r--source/blender/editors/include/ED_uvedit.h7
-rw-r--r--source/blender/editors/include/ED_view3d.h31
-rw-r--r--source/blender/editors/include/UI_interface.h55
-rw-r--r--source/blender/editors/include/UI_interface_icons.h1
-rw-r--r--source/blender/editors/include/UI_resources.h23
-rw-r--r--source/blender/editors/interface/interface.c51
-rw-r--r--source/blender/editors/interface/interface_align.c6
-rw-r--r--source/blender/editors/interface/interface_draw.c1528
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c11
-rw-r--r--source/blender/editors/interface/interface_handlers.c63
-rw-r--r--source/blender/editors/interface/interface_icons.c186
-rw-r--r--source/blender/editors/interface/interface_intern.h29
-rw-r--r--source/blender/editors/interface/interface_layout.c102
-rw-r--r--source/blender/editors/interface/interface_ops.c125
-rw-r--r--source/blender/editors/interface/interface_panel.c336
-rw-r--r--source/blender/editors/interface/interface_regions.c25
-rw-r--r--source/blender/editors/interface/interface_style.c27
-rw-r--r--source/blender/editors/interface/interface_templates.c464
-rw-r--r--source/blender/editors/interface/interface_utils.c83
-rw-r--r--source/blender/editors/interface/interface_widgets.c656
-rw-r--r--source/blender/editors/interface/resources.c176
-rw-r--r--source/blender/editors/interface/view2d.c330
-rw-r--r--source/blender/editors/io/io_collada.c10
-rw-r--r--source/blender/editors/mask/mask_draw.c470
-rw-r--r--source/blender/editors/mesh/editface.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c166
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c41
-rw-r--r--source/blender/editors/mesh/editmesh_select.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c32
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c15
-rw-r--r--source/blender/editors/mesh/mesh_data.c54
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c7
-rw-r--r--source/blender/editors/mesh/meshtools.c2
-rw-r--r--source/blender/editors/object/CMakeLists.txt2
-rw-r--r--source/blender/editors/object/object_add.c190
-rw-r--r--source/blender/editors/object/object_bake.c66
-rw-r--r--source/blender/editors/object/object_bake_api.c16
-rw-r--r--source/blender/editors/object/object_constraint.c11
-rw-r--r--source/blender/editors/object/object_data_transfer.c10
-rw-r--r--source/blender/editors/object/object_edit.c249
-rw-r--r--source/blender/editors/object/object_facemap_ops.c493
-rw-r--r--source/blender/editors/object/object_group.c33
-rw-r--r--source/blender/editors/object/object_hook.c23
-rw-r--r--source/blender/editors/object/object_intern.h14
-rw-r--r--source/blender/editors/object/object_modifier.c18
-rw-r--r--source/blender/editors/object/object_ops.c33
-rw-r--r--source/blender/editors/object/object_relations.c336
-rw-r--r--source/blender/editors/object/object_select.c315
-rw-r--r--source/blender/editors/object/object_vgroup.c24
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c5
-rw-r--r--source/blender/editors/physics/particle_edit.c223
-rw-r--r--source/blender/editors/physics/particle_object.c43
-rw-r--r--source/blender/editors/physics/physics_fluid.c12
-rw-r--r--source/blender/editors/physics/physics_ops.c17
-rw-r--r--source/blender/editors/physics/physics_pointcache.c14
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c14
-rw-r--r--source/blender/editors/physics/rigidbody_object.c4
-rw-r--r--source/blender/editors/render/CMakeLists.txt1
-rw-r--r--source/blender/editors/render/render_internal.c31
-rw-r--r--source/blender/editors/render/render_opengl.c33
-rw-r--r--source/blender/editors/render/render_preview.c126
-rw-r--r--source/blender/editors/render/render_shading.c14
-rw-r--r--source/blender/editors/render/render_update.c12
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/area.c461
-rw-r--r--source/blender/editors/screen/glutil.c646
-rw-r--r--source/blender/editors/screen/screen_context.c157
-rw-r--r--source/blender/editors/screen/screen_draw.c495
-rw-r--r--source/blender/editors/screen/screen_edit.c339
-rw-r--r--source/blender/editors/screen/screen_intern.h8
-rw-r--r--source/blender/editors/screen/screen_ops.c11
-rw-r--r--source/blender/editors/screen/screendump.c31
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c392
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c29
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h1
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c59
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c20
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c19
-rw-r--r--source/blender/editors/sound/sound_ops.c4
-rw-r--r--source/blender/editors/space_action/action_draw.c108
-rw-r--r--source/blender/editors/space_action/space_action.c19
-rw-r--r--source/blender/editors/space_api/spacetypes.c12
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c60
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c5
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c261
-rw-r--r--source/blender/editors/space_clip/clip_draw.c873
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c150
-rw-r--r--source/blender/editors/space_clip/clip_intern.h4
-rw-r--r--source/blender/editors/space_clip/clip_utils.c71
-rw-r--r--source/blender/editors/space_clip/space_clip.c40
-rw-r--r--source/blender/editors/space_clip/tracking_ops_orient.c19
-rw-r--r--source/blender/editors/space_console/console_draw.c22
-rw-r--r--source/blender/editors/space_console/space_console.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c125
-rw-r--r--source/blender/editors/space_file/filesel.c2
-rw-r--r--source/blender/editors/space_file/space_file.c14
-rw-r--r--source/blender/editors/space_graph/graph_draw.c747
-rw-r--r--source/blender/editors/space_graph/space_graph.c81
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_image/image_draw.c478
-rw-r--r--source/blender/editors/space_image/image_edit.c10
-rw-r--r--source/blender/editors/space_image/image_ops.c4
-rw-r--r--source/blender/editors/space_image/space_image.c47
-rw-r--r--source/blender/editors/space_info/info_stats.c54
-rw-r--r--source/blender/editors/space_info/space_info.c8
-rw-r--r--source/blender/editors/space_info/textview.c46
-rw-r--r--source/blender/editors/space_logic/logic_window.c25
-rw-r--r--source/blender/editors/space_logic/space_logic.c4
-rw-r--r--source/blender/editors/space_nla/nla_channels.c15
-rw-r--r--source/blender/editors/space_nla/nla_draw.c454
-rw-r--r--source/blender/editors/space_nla/space_nla.c14
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_node/drawnode.c497
-rw-r--r--source/blender/editors/space_node/node_draw.c434
-rw-r--r--source/blender/editors/space_node/node_edit.c8
-rw-r--r--source/blender/editors/space_node/node_intern.h7
-rw-r--r--source/blender/editors/space_node/node_widgets.c114
-rw-r--r--source/blender/editors/space_node/space_node.c54
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c462
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c1136
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c326
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h124
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c302
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c447
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c209
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c389
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c234
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c21
-rw-r--r--source/blender/editors/space_script/space_script.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c738
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c23
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h2
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c15
-rw-r--r--source/blender/editors/space_text/space_text.c2
-rw-r--r--source/blender/editors/space_text/text_draw.c268
-rw-r--r--source/blender/editors/space_time/space_time.c267
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c8
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c132
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c1427
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c1034
-rw-r--r--source/blender/editors/space_view3d/drawobject.c4590
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c111
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c3
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c250
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c4635
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c2161
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c186
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c49
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h82
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c27
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c29
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c239
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c168
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c391
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c37
-rw-r--r--source/blender/editors/transform/CMakeLists.txt4
-rw-r--r--source/blender/editors/transform/transform.c343
-rw-r--r--source/blender/editors/transform/transform.h12
-rw-r--r--source/blender/editors/transform/transform_constraints.c53
-rw-r--r--source/blender/editors/transform/transform_conversions.c156
-rw-r--r--source/blender/editors/transform/transform_generics.c70
-rw-r--r--source/blender/editors/transform/transform_manipulator.c1835
-rw-r--r--source/blender/editors/transform/transform_orientations.c14
-rw-r--r--source/blender/editors/transform/transform_snap.c92
-rw-r--r--source/blender/editors/transform/transform_snap_object.c18
-rw-r--r--source/blender/editors/util/ed_util.c37
-rw-r--r--source/blender/editors/util/undo.c13
-rw-r--r--source/blender/editors/uvedit/CMakeLists.txt1
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c10
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c640
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h2
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c308
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c135
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c19
-rw-r--r--source/blender/freestyle/CMakeLists.txt1
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp2
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp38
-rw-r--r--source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp9
-rw-r--r--source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h15
-rw-r--r--source/blender/gpu/CMakeLists.txt106
-rw-r--r--source/blender/gpu/GPU_basic_shader.h9
-rw-r--r--source/blender/gpu/GPU_batch.h51
-rw-r--r--source/blender/gpu/GPU_buffers.h8
-rw-r--r--source/blender/gpu/GPU_debug.h18
-rw-r--r--source/blender/gpu/GPU_draw.h39
-rw-r--r--source/blender/gpu/GPU_extensions.h9
-rw-r--r--source/blender/gpu/GPU_framebuffer.h11
-rw-r--r--source/blender/gpu/GPU_glew.h4
-rw-r--r--source/blender/gpu/GPU_immediate.h58
-rw-r--r--source/blender/gpu/GPU_immediate_util.h59
-rw-r--r--source/blender/gpu/GPU_lamp.h77
-rw-r--r--source/blender/gpu/GPU_legacy_stubs.h457
-rw-r--r--source/blender/gpu/GPU_material.h30
-rw-r--r--source/blender/gpu/GPU_matrix.h180
-rw-r--r--source/blender/gpu/GPU_shader.h110
-rw-r--r--source/blender/gpu/GPU_texture.h128
-rw-r--r--source/blender/gpu/GPU_uniformbuffer.h49
-rw-r--r--source/blender/gpu/GPU_viewport.h118
-rw-r--r--source/blender/gpu/intern/gpu_basic_shader.c413
-rw-r--r--source/blender/gpu/intern/gpu_batch.c171
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c776
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c288
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h6
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c340
-rw-r--r--source/blender/gpu/intern/gpu_debug.c695
-rw-r--r--source/blender/gpu/intern/gpu_draw.c628
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c122
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c414
-rw-r--r--source/blender/gpu/intern/gpu_immediate.c88
-rw-r--r--source/blender/gpu/intern/gpu_immediate_util.c344
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c11
-rw-r--r--source/blender/gpu/intern/gpu_lamp.c486
-rw-r--r--source/blender/gpu/intern/gpu_lamp_private.h86
-rw-r--r--source/blender/gpu/intern/gpu_material.c489
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c624
-rw-r--r--source/blender/gpu/intern/gpu_select.c7
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c10
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c6
-rw-r--r--source/blender/gpu/intern/gpu_shader.c636
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.h45
-rw-r--r--source/blender/gpu/intern/gpu_texture.c877
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c105
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c584
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl42
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl46
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl21
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl24
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl27
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_vert.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl26
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_line_dashed_legacy_vert.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_line_dashed_vert.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl22
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl21
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl24
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_vert.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_basic_frag.glsl37
-rw-r--r--source/blender/gpu/shaders/gpu_shader_basic_geom.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_basic_vert.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_checker_frag.glsl20
-rw-r--r--source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl20
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl54
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl60
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl68
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl44
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl20
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl67
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl52
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fire_frag.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl5
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl111
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl68
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl39
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl34
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl45
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_lib.glsl7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl23
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_vert.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_geometry.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl34
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl30
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl122
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl103
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl50
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl25
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl57
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl64
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl29
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl32
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl29
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl22
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl31
-rw-r--r--source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl34
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl417
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl24
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl17
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl36
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl31
-rw-r--r--source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl19
-rw-r--r--source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl17
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl19
-rw-r--r--source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_text_frag.glsl15
-rw-r--r--source/blender/gpu/shaders/gpu_shader_text_vert.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl15
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex_world.glsl5
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl7
-rw-r--r--source/blender/makesdna/DNA_ID.h11
-rw-r--r--source/blender/makesdna/DNA_action_types.h18
-rw-r--r--source/blender/makesdna/DNA_camera_types.h7
-rw-r--r--source/blender/makesdna/DNA_curve_types.h1
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h8
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h5
-rw-r--r--source/blender/makesdna/DNA_gpu_types.h2
-rw-r--r--source/blender/makesdna/DNA_lattice_types.h1
-rw-r--r--source/blender/makesdna/DNA_layer_types.h148
-rw-r--r--source/blender/makesdna/DNA_manipulator_types.h43
-rw-r--r--source/blender/makesdna/DNA_material_types.h18
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h76
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_force.h6
-rw-r--r--source/blender/makesdna/DNA_object_types.h31
-rw-r--r--source/blender/makesdna/DNA_outliner_types.h21
-rw-r--r--source/blender/makesdna/DNA_particle_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h81
-rw-r--r--source/blender/makesdna/DNA_screen_types.h7
-rw-r--r--source/blender/makesdna/DNA_space_types.h39
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h6
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h27
-rw-r--r--source/blender/makesdna/DNA_world_types.h1
-rw-r--r--source/blender/makesdna/intern/makesdna.c4
-rw-r--r--source/blender/makesrna/RNA_access.h11
-rw-r--r--source/blender/makesrna/RNA_define.h8
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/RNA_types.h1
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt5
-rw-r--r--source/blender/makesrna/intern/rna_ID.c2
-rw-r--r--source/blender/makesrna/intern/rna_access.c7
-rw-r--r--source/blender/makesrna/intern/rna_brush.c36
-rw-r--r--source/blender/makesrna/intern/rna_cachefile.c2
-rw-r--r--source/blender/makesrna/intern/rna_context.c46
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c38
-rw-r--r--source/blender/makesrna/intern/rna_group.c12
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c5
-rw-r--r--source/blender/makesrna/intern/rna_internal.h4
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c1
-rw-r--r--source/blender/makesrna/intern/rna_material.c18
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c380
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c3
-rw-r--r--source/blender/makesrna/intern/rna_mesh_utils.h11
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c21
-rw-r--r--source/blender/makesrna/intern/rna_object.c294
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c94
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c9
-rw-r--r--source/blender/makesrna/intern/rna_particle.c4
-rw-r--r--source/blender/makesrna/intern/rna_render.c71
-rw-r--r--source/blender/makesrna/intern/rna_scene.c1917
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c20
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c80
-rw-r--r--source/blender/makesrna/intern/rna_space.c41
-rw-r--r--source/blender/makesrna/intern/rna_texture.c19
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c35
-rw-r--r--source/blender/makesrna/intern/rna_world.c1
-rw-r--r--source/blender/modifiers/CMakeLists.txt7
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c19
-rw-r--r--source/blender/modifiers/intern/MOD_array.c37
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c1
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c19
-rw-r--r--source/blender/modifiers/intern/MOD_build.c1
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c20
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c25
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c1
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c1
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c21
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c19
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c1
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c27
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c39
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c1
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c1
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim.c36
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c20
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c1
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c1
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c19
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c20
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c1
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c20
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c19
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c17
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c1
-rw-r--r--source/blender/modifiers/intern/MOD_none.c1
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c17
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c20
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c1
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c1
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c20
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c1
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c20
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c16
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c1
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c31
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c1
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c26
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c1
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c13
-rw-r--r--source/blender/modifiers/intern/MOD_surface.c1
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c18
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c1
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c49
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c38
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c24
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c26
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c22
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c22
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c28
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c1
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_shader.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c3
-rw-r--r--source/blender/nodes/shader/node_shader_util.h1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_background.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_material.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_metallic.c90
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_specular.c89
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.c23
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c4
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c3
-rw-r--r--source/blender/python/bmesh/CMakeLists.txt1
-rw-r--r--source/blender/python/bmesh/bmesh_py_api.c5
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c8
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c15
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c91
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.h4
-rw-r--r--source/blender/python/generic/bgl.c1215
-rw-r--r--source/blender/python/generic/blf_py_api.c4
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c2
-rw-r--r--source/blender/python/intern/gpu_offscreen.c12
-rw-r--r--source/blender/render/CMakeLists.txt1
-rw-r--r--source/blender/render/extern/include/RE_engine.h23
-rw-r--r--source/blender/render/extern/include/RE_multires_bake.h6
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h2
-rw-r--r--source/blender/render/intern/source/bake.c7
-rw-r--r--source/blender/render/intern/source/convertblender.c34
-rw-r--r--source/blender/render/intern/source/envmap.c16
-rw-r--r--source/blender/render/intern/source/external_engine.c130
-rw-r--r--source/blender/render/intern/source/initrender.c7
-rw-r--r--source/blender/render/intern/source/multires_bake.c57
-rw-r--r--source/blender/render/intern/source/pipeline.c37
-rw-r--r--source/blender/render/intern/source/shadeinput.c45
-rw-r--r--source/blender/render/intern/source/shadeoutput.c17
-rw-r--r--source/blender/windowmanager/CMakeLists.txt21
-rw-r--r--source/blender/windowmanager/WM_api.h16
-rw-r--r--source/blender/windowmanager/WM_types.h4
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c18
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c184
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c128
-rw-r--r--source/blender/windowmanager/intern/wm_files.c13
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c38
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c262
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c13
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c225
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c85
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c183
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c29
-rw-r--r--source/blender/windowmanager/intern/wm_window.c106
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_api.h113
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_library.h128
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_types.h152
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c231
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c548
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c592
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c375
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c141
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c75
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c813
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h51
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h100
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_utils.c171
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c250
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c485
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h227
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c590
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c769
-rw-r--r--source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h90
-rw-r--r--source/blender/windowmanager/wm.h2
-rw-r--r--source/blender/windowmanager/wm_draw.h4
-rw-r--r--source/blender/windowmanager/wm_event_system.h5
-rw-r--r--source/blender/windowmanager/wm_event_types.h2
-rw-r--r--source/blender/windowmanager/wm_window.h9
-rw-r--r--source/blenderplayer/CMakeLists.txt1
-rw-r--r--source/blenderplayer/bad_level_call_stubs/CMakeLists.txt3
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c60
-rw-r--r--source/creator/creator.c7
-rw-r--r--source/creator/creator_args.c40
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp2
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp3
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp31
-rw-r--r--source/gameengine/GamePlayer/ghost/CMakeLists.txt1
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp7
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp1
-rw-r--r--source/gameengine/Ketsji/BL_Material.h1
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp23
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h1
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp49
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_Light.h4
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp8
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp4
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp1
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp40
-rw-r--r--tests/python/CMakeLists.txt2
-rw-r--r--tests/python/bl_alembic_import_test.py4
-rw-r--r--tests/python/bl_mesh_modifiers.py2
-rw-r--r--tests/python/render_layer/CMakeLists.txt172
-rw-r--r--tests/python/render_layer/render_layer_common.py785
-rw-r--r--tests/python/render_layer/test_active_collection.py75
-rw-r--r--tests/python/render_layer/test_collection_rename.py81
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_a.py38
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_b.py39
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_c.py38
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_d.py38
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_e.py39
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_f.py40
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_g.py40
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_h.py40
-rw-r--r--tests/python/render_layer/test_evaluation_render_settings_i.py40
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_a.py57
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_b.py59
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_c.py57
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_d.py60
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_e.py59
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_f.py48
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_a.py57
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_b.py57
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_c.py57
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_d.py54
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_e.py57
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_f.py58
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_g.py35
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_h.py35
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_i.py35
-rw-r--r--tests/python/render_layer/test_layer_linking.py114
-rw-r--r--tests/python/render_layer/test_layer_syncing.py118
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_a.py53
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_b.py53
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_c.py53
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_d.py53
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_e.py45
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_f.py105
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_g.py86
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_h.py71
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_i.py78
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_j.py68
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_k.py45
-rw-r--r--tests/python/render_layer/test_move_above_below_layer_collection_l.py65
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_a.py85
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_b.py74
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_c.py56
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_d.py65
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_e.py65
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_f.py56
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_g.py49
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_h.py89
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_i.py65
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_a.py85
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_b.py74
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_c.py56
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_d.py65
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_e.py65
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_f.py56
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_g.py49
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_h.py89
-rw-r--r--tests/python/render_layer/test_move_above_below_scene_collection_sync_i.py65
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_a.py74
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_b.py45
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_c.py45
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_d.py45
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_e.py45
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_f.py91
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_g.py82
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_h.py81
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_i.py45
-rw-r--r--tests/python/render_layer/test_move_into_layer_collection_j.py46
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_a.py58
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_b.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_c.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_d.py42
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_e.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_f.py56
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_g.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_h.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_i.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_j.py48
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_k.py41
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_l.py41
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_a.py42
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_b.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_c.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_d.py42
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_e.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_f.py56
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_g.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_h.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_i.py57
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_j.py48
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_k.py41
-rw-r--r--tests/python/render_layer/test_move_into_scene_collection_sync_l.py41
-rw-r--r--tests/python/render_layer/test_object_add_cylinder.py39
-rw-r--r--tests/python/render_layer/test_object_add_empty.py39
-rw-r--r--tests/python/render_layer/test_object_add_no_collection_cylinder.py37
-rw-r--r--tests/python/render_layer/test_object_add_no_collection_empty.py36
-rw-r--r--tests/python/render_layer/test_object_add_no_collection_torus.py36
-rw-r--r--tests/python/render_layer/test_object_add_torus.py39
-rw-r--r--tests/python/render_layer/test_object_copy.py98
-rw-r--r--tests/python/render_layer/test_object_delete_a.py36
-rw-r--r--tests/python/render_layer/test_object_delete_b.py36
-rw-r--r--tests/python/render_layer/test_object_link_a.py37
-rw-r--r--tests/python/render_layer/test_object_link_b.py38
-rw-r--r--tests/python/render_layer/test_object_link_c.py40
-rw-r--r--tests/python/render_layer/test_operator_context.py133
-rw-r--r--tests/python/render_layer/test_scene_copy_a.py42
-rw-r--r--tests/python/render_layer/test_scene_copy_b.py43
-rw-r--r--tests/python/render_layer/test_scene_copy_c.py42
-rw-r--r--tests/python/render_layer/test_scene_copy_d.py42
-rw-r--r--tests/python/render_layer/test_scene_write_read.py149
1147 files changed, 104680 insertions, 40056 deletions
diff --git a/.arcconfig b/.arcconfig
index 8fc370a94ac..086fdc038bb 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,6 +1,6 @@
{
"project_id" : "Blender",
"conduit_uri" : "https://developer.blender.org/",
- "git.default-relative-commit" : "origin/master",
+ "git.default-relative-commit" : "origin/blender2.8",
"arc.land.update.default" : "rebase"
}
diff --git a/.gitmodules b/.gitmodules
index 2f52bfce372..11ce247b455 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,20 +1,24 @@
[submodule "release/scripts/addons"]
path = release/scripts/addons
url = ../blender-addons.git
+ branch = blender2.8
ignore = all
branch = master
[submodule "release/scripts/addons_contrib"]
path = release/scripts/addons_contrib
url = ../blender-addons-contrib.git
+ branch = master
ignore = all
branch = master
[submodule "release/datafiles/locale"]
path = release/datafiles/locale
url = ../blender-translations.git
+ branch = master
ignore = all
branch = master
[submodule "source/tools"]
path = source/tools
url = ../blender-dev-tools.git
+ branch = master
ignore = all
branch = master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66ee215864d..22d46391dab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -242,6 +242,8 @@ endif()
option(WITH_PLAYER "Build Player" OFF)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
+option(WITH_CLAY_ENGINE "Enable New Clay engine (Breaks Mac and Mesa compatibility)" ON)
+
# Compositor
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
@@ -462,28 +464,16 @@ endif()
# OpenGL
-option(WITH_GLEW_MX "Support multiple GLEW contexts (experimental)" OFF )
option(WITH_GLEW_ES "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF)
option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL, glX, or WGL)" OFF)
-option(WITH_GL_PROFILE_COMPAT "Support using the OpenGL 'compatibility' profile. (deprecated)" ON )
-option(WITH_GL_PROFILE_CORE "Support using the OpenGL 3.2+ 'core' profile." OFF)
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (thru either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
mark_as_advanced(
- WITH_GLEW_MX
WITH_GLEW_ES
WITH_GL_EGL
- WITH_GL_PROFILE_COMPAT
- WITH_GL_PROFILE_CORE
WITH_GL_PROFILE_ES20
)
-if(WITH_GL_PROFILE_COMPAT)
- set(WITH_GLU ON)
-else()
- set(WITH_GLU OFF)
-endif()
-
if(WIN32)
option(WITH_GL_ANGLE "Link with the ANGLE library, an OpenGL ES 2.0 implementation based on Direct3D, instead of the system OpenGL library." OFF)
mark_as_advanced(WITH_GL_ANGLE)
@@ -504,11 +494,10 @@ endif()
# We default options to whatever default standard in the current compiler.
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11))
set(_c11_init ON)
- set(_cxx11_init ON)
else()
set(_c11_init OFF)
- set(_cxx11_init OFF)
endif()
+set(_cxx11_init ON)
option(WITH_C11 "Build with C11 standard enabled, for development use only!" ${_c11_init})
mark_as_advanced(WITH_C11)
@@ -961,19 +950,11 @@ endif()
find_package(OpenGL)
blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
-if(WITH_GLU)
- list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_glu_LIBRARY}")
- list(APPEND GL_DEFINITIONS -DWITH_GLU)
-endif()
-
if(WITH_SYSTEM_GLES)
find_package_wrapper(OpenGLES)
endif()
-if(WITH_GL_PROFILE_COMPAT OR WITH_GL_PROFILE_CORE)
- list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_gl_LIBRARY}")
-
-elseif(WITH_GL_PROFILE_ES20)
+if(WITH_GL_PROFILE_ES20)
if(WITH_SYSTEM_GLES)
if(NOT OPENGLES_LIBRARY)
message(FATAL_ERROR
@@ -1033,6 +1014,9 @@ elseif(WITH_GL_PROFILE_ES20)
endif()
+else()
+ list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_gl_LIBRARY}")
+
endif()
if(WITH_GL_EGL)
@@ -1080,16 +1064,10 @@ if(WITH_GL_EGL)
endif()
-if(WITH_GL_PROFILE_COMPAT)
- list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_COMPAT)
-endif()
-
-if(WITH_GL_PROFILE_CORE)
- list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_CORE)
-endif()
-
if(WITH_GL_PROFILE_ES20)
list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_ES20)
+else()
+ list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_CORE)
endif()
if(WITH_GL_EGL)
@@ -1126,10 +1104,6 @@ endif()
#-----------------------------------------------------------------------------
# Configure GLEW
-if(WITH_GLEW_MX)
- list(APPEND GL_DEFINITIONS -DWITH_GLEW_MX)
-endif()
-
if(WITH_SYSTEM_GLEW)
find_package(GLEW)
@@ -1139,11 +1113,7 @@ if(WITH_SYSTEM_GLEW)
message(FATAL_ERROR "GLEW is required to build Blender. Install it or disable WITH_SYSTEM_GLEW.")
endif()
- if(WITH_GLEW_MX)
- set(BLENDER_GLEW_LIBRARIES ${GLEW_MX_LIBRARY})
- else()
- set(BLENDER_GLEW_LIBRARIES ${GLEW_LIBRARY})
- endif()
+ set(BLENDER_GLEW_LIBRARIES ${GLEW_LIBRARY})
else()
if(WITH_GLEW_ES)
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew-es/include")
@@ -1151,12 +1121,11 @@ else()
list(APPEND GL_DEFINITIONS -DGLEW_STATIC -DWITH_GLEW_ES)
# These definitions remove APIs from glew.h, making GLEW smaller, and catching unguarded API usage
- if(NOT WITH_GL_PROFILE_ES20)
+ if(WITH_GL_PROFILE_ES20)
+ list(APPEND GL_DEFINITIONS -DGLEW_ES_ONLY)
+ else()
# No ES functions are needed
list(APPEND GL_DEFINITIONS -DGLEW_NO_ES)
- elseif(NOT (WITH_GL_PROFILE_CORE OR WITH_GL_PROFILE_COMPAT))
- # ES is enabled, but the other functions are all disabled
- list(APPEND GL_DEFINITIONS -DGLEW_ES_ONLY)
endif()
if(WITH_GL_PROFILE_ES20)
@@ -1193,9 +1162,7 @@ else()
endif()
-if(NOT WITH_GLU)
- list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
-endif()
+list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
#-----------------------------------------------------------------------------
# Configure Bullet
@@ -1740,10 +1707,7 @@ if(FIRST_RUN)
info_cfg_text("OpenGL:")
info_cfg_option(WITH_GLEW_ES)
- info_cfg_option(WITH_GLU)
info_cfg_option(WITH_GL_EGL)
- info_cfg_option(WITH_GL_PROFILE_COMPAT)
- info_cfg_option(WITH_GL_PROFILE_CORE)
info_cfg_option(WITH_GL_PROFILE_ES20)
if(WIN32)
info_cfg_option(WITH_GL_ANGLE)
diff --git a/GNUmakefile b/GNUmakefile
index 86964e68873..7ee011911f8 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -402,7 +402,7 @@ update: .FORCE
svn update ../lib/* ; \
fi
git pull --rebase
- git submodule foreach git pull --rebase origin master
+ git submodule update --remote
# -----------------------------------------------------------------------------
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index b996c234c67..95cb82ee6ec 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -25,7 +25,7 @@
ARGS=$( \
getopt \
-o s:i:t:h \
---long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,use-cxx11,\
+--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,\
with-all,with-opencollada,\
ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,\
force-all,force-python,force-numpy,force-boost,\
@@ -104,11 +104,6 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--no-confirm
Disable any interaction with user (suitable for automated run).
- --use-cxx11
- Build all libraries in cpp11 'mode' (will be mandatory soon in blender2.8 branch).
- NOTE: If your compiler is gcc-6.0 or above, you probably *want* to enable this option (since it's default
- standard starting from this version).
-
--with-all
By default, a number of optional and not-so-often needed libraries are not installed.
This option will try to install them, at the cost of potential conflicts (depending on
@@ -287,7 +282,7 @@ SUDO="sudo"
NO_BUILD=false
NO_CONFIRM=false
-USE_CXX11=false
+USE_CXX11=true # Mandatory in blender2.8
PYTHON_VERSION="3.5.3"
PYTHON_VERSION_MIN="3.5"
@@ -498,9 +493,6 @@ while true; do
--no-confirm)
NO_CONFIRM=true; shift; continue
;;
- --use-cxx11)
- USE_CXX11=true; shift; continue
- ;;
--with-all)
WITH_ALL=true; shift; continue
;;
@@ -795,7 +787,7 @@ FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" )
CXXFLAGS_BACK=$CXXFLAGS
if [ "$USE_CXX11" = true ]; then
- WARNING "You are trying to use c++11, this *should* go smoothely with any very recent distribution
+ WARNING "C++11 is now mandatory for blender2.8, this *should* go smoothly with any very recent distribution.
However, if you are experiencing linking errors (also when building Blender itself), please try the following:
* Re-run this script with '--build-all --force-all' options.
* Ensure your gcc version is at the very least 4.8, if possible you should really rather use gcc-5.1 or above.
diff --git a/build_files/cmake/Modules/FindGLEW.cmake b/build_files/cmake/Modules/FindGLEW.cmake
index 2f098d5d9a4..3057237f3c6 100644
--- a/build_files/cmake/Modules/FindGLEW.cmake
+++ b/build_files/cmake/Modules/FindGLEW.cmake
@@ -9,7 +9,6 @@
#
# also defined,
# GLEW_LIBRARY, where to find the Glew library.
-# GLEW_MX_LIBRARY, where to find the GlewMX library.
#=============================================================================
# Copyright 2014 Blender Foundation.
@@ -50,16 +49,6 @@ FIND_LIBRARY(GLEW_LIBRARY
lib64 lib
)
-
-FIND_LIBRARY(GLEW_MX_LIBRARY
- NAMES
- GLEWmx
- HINTS
- ${_glew_SEARCH_DIRS}
- PATH_SUFFIXES
- lib64 lib
- )
-
# handle the QUIETLY and REQUIRED arguments and set GLEW_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
@@ -73,7 +62,6 @@ ENDIF(GLEW_FOUND)
MARK_AS_ADVANCED(
GLEW_INCLUDE_DIR
GLEW_LIBRARY
- GLEW_MX_LIBRARY
)
UNSET(_glew_SEARCH_DIRS)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 6303119773d..bb356f51ab9 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -604,6 +604,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
bf_alembic
bf_bmesh
bf_gpu
+ bf_draw
bf_blenloader
bf_blenkernel
bf_physics
@@ -660,6 +661,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
cycles_util
cycles_subd
bf_intern_opencolorio
+ bf_intern_gawain
bf_intern_eigen
extern_rangetree
extern_wcwidth
diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake
index 6105f2e04de..5336024b75c 100644
--- a/build_files/cmake/platform/platform_apple.cmake
+++ b/build_files/cmake/platform/platform_apple.cmake
@@ -23,6 +23,8 @@
# Libraries configuration for Apple.
+set(MACOSX_DEPLOYMENT_TARGET "10.9")
+
macro(find_package_wrapper)
# do nothing, just satisfy the macro
endmacro()
diff --git a/doc/python_api/examples/gpu.offscreen.1.py b/doc/python_api/examples/gpu.offscreen.1.py
index 75ddf804e70..ff1a7ad7cce 100644
--- a/doc/python_api/examples/gpu.offscreen.1.py
+++ b/doc/python_api/examples/gpu.offscreen.1.py
@@ -52,6 +52,7 @@ class OffScreenDraw(bpy.types.Operator):
@staticmethod
def _update_offscreen(context, offscreen):
scene = context.scene
+ render_layer = context.render_layer
render = scene.render
camera = scene.camera
@@ -65,6 +66,7 @@ class OffScreenDraw(bpy.types.Operator):
offscreen.draw_view3d(
scene,
+ render_layer,
context.space_data,
context.region,
projection_matrix,
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 47bb323e574..0316b6cd23e 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1024,6 +1024,7 @@ context_type_map = {
"brush": ("Brush", False),
"camera": ("Camera", False),
"cloth": ("ClothModifier", False),
+ "collection": ("LayerCollection", False),
"collision": ("CollisionModifier", False),
"curve": ("Curve", False),
"dynamic_paint": ("DynamicPaintModifier", False),
@@ -1055,6 +1056,7 @@ context_type_map = {
"particle_system": ("ParticleSystem", False),
"particle_system_editable": ("ParticleSystem", False),
"pose_bone": ("PoseBone", False),
+ "render_layer": ("SceneLayer", False),
"scene": ("Scene", False),
"sculpt_object": ("Object", False),
"selectable_bases": ("ObjectBase", True),
diff --git a/extern/glew-es/CMakeLists.txt b/extern/glew-es/CMakeLists.txt
index ba80d3f6120..ea25425df81 100644
--- a/extern/glew-es/CMakeLists.txt
+++ b/extern/glew-es/CMakeLists.txt
@@ -49,9 +49,4 @@ set(SRC
add_definitions(${GL_DEFINITIONS})
-if(WITH_GLEW_MX)
- add_definitions(-DGLEW_MX)
-endif()
-
-
blender_add_lib(extern_glew_es "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/glew/CMakeLists.txt b/extern/glew/CMakeLists.txt
index f264b3905be..c9323fa12b2 100644
--- a/extern/glew/CMakeLists.txt
+++ b/extern/glew/CMakeLists.txt
@@ -40,6 +40,7 @@ endif()
set(SRC
src/glew.c
+ include/GL/eglew.h
include/GL/glew.h
include/GL/glxew.h
include/GL/wglew.h
@@ -47,8 +48,4 @@ set(SRC
add_definitions(${GL_DEFINITIONS})
-if(WITH_GLEW_MX)
- add_definitions(-DGLEW_MX)
-endif()
-
blender_add_lib(extern_glew "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/glew/include/GL/eglew.h b/extern/glew/include/GL/eglew.h
new file mode 100644
index 00000000000..aef65c87950
--- /dev/null
+++ b/extern/glew/include/GL/eglew.h
@@ -0,0 +1,2261 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2008-2015, Nigel Stewart <nigels[]users sourceforge net>
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.0
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __eglew_h__
+#define __eglew_h__
+#define __EGLEW_H__
+
+#ifdef __eglext_h_
+#error eglext.h included before eglew.h
+#endif
+
+#if defined(__egl_h_)
+#error egl.h included before eglew.h
+#endif
+
+#define __eglext_h_
+
+#define __egl_h_
+
+#ifndef EGLAPIENTRY
+#define EGLAPIENTRY
+#endif
+#ifndef EGLAPI
+#define EGLAPI extern
+#endif
+
+/* EGL Types */
+#include <sys/types.h>
+
+#include <KHR/khrplatform.h>
+#include <EGL/eglplatform.h>
+
+#include <GL/glew.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int32_t EGLint;
+
+typedef unsigned int EGLBoolean;
+typedef void *EGLDisplay;
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+typedef void *EGLImage;
+
+typedef void *EGLSyncKHR;
+typedef intptr_t EGLAttribKHR;
+typedef void *EGLLabelKHR;
+typedef void *EGLObjectKHR;
+typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+typedef void *EGLImageKHR;
+typedef void *EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+typedef int EGLNativeFileDescriptorKHR;
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+typedef void *EGLDeviceEXT;
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+typedef void *EGLSyncNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
+typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
+
+struct EGLClientPixmapHI;
+
+#define EGL_DONT_CARE ((EGLint)-1)
+
+#define EGL_NO_CONTEXT ((EGLContext)0)
+#define EGL_NO_DISPLAY ((EGLDisplay)0)
+#define EGL_NO_IMAGE ((EGLImage)0)
+#define EGL_NO_SURFACE ((EGLSurface)0)
+#define EGL_NO_SYNC ((EGLSync)0)
+
+#define EGL_UNKNOWN ((EGLint)-1)
+
+#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
+
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+/* ---------------------------- EGL_VERSION_1_0 ---------------------------- */
+
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
+
+#define EGL_FALSE 0
+#define EGL_PBUFFER_BIT 0x0001
+#define EGL_TRUE 1
+#define EGL_PIXMAP_BIT 0x0002
+#define EGL_WINDOW_BIT 0x0004
+#define EGL_SUCCESS 0x3000
+#define EGL_NOT_INITIALIZED 0x3001
+#define EGL_BAD_ACCESS 0x3002
+#define EGL_BAD_ALLOC 0x3003
+#define EGL_BAD_ATTRIBUTE 0x3004
+#define EGL_BAD_CONFIG 0x3005
+#define EGL_BAD_CONTEXT 0x3006
+#define EGL_BAD_CURRENT_SURFACE 0x3007
+#define EGL_BAD_DISPLAY 0x3008
+#define EGL_BAD_MATCH 0x3009
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
+#define EGL_BAD_NATIVE_WINDOW 0x300B
+#define EGL_BAD_PARAMETER 0x300C
+#define EGL_BAD_SURFACE 0x300D
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_RED_SIZE 0x3024
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_STENCIL_SIZE 0x3026
+#define EGL_CONFIG_CAVEAT 0x3027
+#define EGL_CONFIG_ID 0x3028
+#define EGL_LEVEL 0x3029
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
+#define EGL_NATIVE_RENDERABLE 0x302D
+#define EGL_NATIVE_VISUAL_ID 0x302E
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_TRANSPARENT_TYPE 0x3034
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
+#define EGL_NONE 0x3038
+#define EGL_SLOW_CONFIG 0x3050
+#define EGL_NON_CONFORMANT_CONFIG 0x3051
+#define EGL_TRANSPARENT_RGB 0x3052
+#define EGL_VENDOR 0x3053
+#define EGL_VERSION 0x3054
+#define EGL_EXTENSIONS 0x3055
+#define EGL_HEIGHT 0x3056
+#define EGL_WIDTH 0x3057
+#define EGL_LARGEST_PBUFFER 0x3058
+#define EGL_DRAW 0x3059
+#define EGL_READ 0x305A
+#define EGL_CORE_NATIVE_ENGINE 0x305B
+
+typedef EGLBoolean ( * PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config);
+typedef EGLBoolean ( * PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+typedef EGLContext ( * PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list);
+typedef EGLSurface ( * PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list);
+typedef EGLSurface ( * PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list);
+typedef EGLSurface ( * PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx);
+typedef EGLBoolean ( * PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean ( * PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value);
+typedef EGLBoolean ( * PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config);
+typedef EGLDisplay ( * PFNEGLGETCURRENTDISPLAYPROC) ( void );
+typedef EGLSurface ( * PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw);
+typedef EGLDisplay ( * PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id);
+typedef EGLint ( * PFNEGLGETERRORPROC) ( void );
+typedef EGLBoolean ( * PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint * major, EGLint * minor);
+typedef EGLBoolean ( * PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+typedef EGLBoolean ( * PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value);
+typedef const char * ( * PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name);
+typedef EGLBoolean ( * PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value);
+typedef EGLBoolean ( * PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean ( * PFNEGLTERMINATEPROC) (EGLDisplay dpy);
+typedef EGLBoolean ( * PFNEGLWAITGLPROC) ( void );
+typedef EGLBoolean ( * PFNEGLWAITNATIVEPROC) (EGLint engine);
+
+#define eglChooseConfig EGLEW_GET_FUN(__eglewChooseConfig)
+#define eglCopyBuffers EGLEW_GET_FUN(__eglewCopyBuffers)
+#define eglCreateContext EGLEW_GET_FUN(__eglewCreateContext)
+#define eglCreatePbufferSurface EGLEW_GET_FUN(__eglewCreatePbufferSurface)
+#define eglCreatePixmapSurface EGLEW_GET_FUN(__eglewCreatePixmapSurface)
+#define eglCreateWindowSurface EGLEW_GET_FUN(__eglewCreateWindowSurface)
+#define eglDestroyContext EGLEW_GET_FUN(__eglewDestroyContext)
+#define eglDestroySurface EGLEW_GET_FUN(__eglewDestroySurface)
+#define eglGetConfigAttrib EGLEW_GET_FUN(__eglewGetConfigAttrib)
+#define eglGetConfigs EGLEW_GET_FUN(__eglewGetConfigs)
+#define eglGetCurrentDisplay EGLEW_GET_FUN(__eglewGetCurrentDisplay)
+#define eglGetCurrentSurface EGLEW_GET_FUN(__eglewGetCurrentSurface)
+#define eglGetDisplay EGLEW_GET_FUN(__eglewGetDisplay)
+#define eglGetError EGLEW_GET_FUN(__eglewGetError)
+#define eglInitialize EGLEW_GET_FUN(__eglewInitialize)
+#define eglMakeCurrent EGLEW_GET_FUN(__eglewMakeCurrent)
+#define eglQueryContext EGLEW_GET_FUN(__eglewQueryContext)
+#define eglQueryString EGLEW_GET_FUN(__eglewQueryString)
+#define eglQuerySurface EGLEW_GET_FUN(__eglewQuerySurface)
+#define eglSwapBuffers EGLEW_GET_FUN(__eglewSwapBuffers)
+#define eglTerminate EGLEW_GET_FUN(__eglewTerminate)
+#define eglWaitGL EGLEW_GET_FUN(__eglewWaitGL)
+#define eglWaitNative EGLEW_GET_FUN(__eglewWaitNative)
+
+#define EGLEW_VERSION_1_0 EGLEW_GET_VAR(__EGLEW_VERSION_1_0)
+
+#endif /* EGL_VERSION_1_0 */
+
+/* ---------------------------- EGL_VERSION_1_1 ---------------------------- */
+
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+
+#define EGL_CONTEXT_LOST 0x300E
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define EGL_MIN_SWAP_INTERVAL 0x303B
+#define EGL_MAX_SWAP_INTERVAL 0x303C
+#define EGL_NO_TEXTURE 0x305C
+#define EGL_TEXTURE_RGB 0x305D
+#define EGL_TEXTURE_RGBA 0x305E
+#define EGL_TEXTURE_2D 0x305F
+#define EGL_TEXTURE_FORMAT 0x3080
+#define EGL_TEXTURE_TARGET 0x3081
+#define EGL_MIPMAP_TEXTURE 0x3082
+#define EGL_MIPMAP_LEVEL 0x3083
+#define EGL_BACK_BUFFER 0x3084
+
+typedef EGLBoolean ( * PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean ( * PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean ( * PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+typedef EGLBoolean ( * PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval);
+
+#define eglBindTexImage EGLEW_GET_FUN(__eglewBindTexImage)
+#define eglReleaseTexImage EGLEW_GET_FUN(__eglewReleaseTexImage)
+#define eglSurfaceAttrib EGLEW_GET_FUN(__eglewSurfaceAttrib)
+#define eglSwapInterval EGLEW_GET_FUN(__eglewSwapInterval)
+
+#define EGLEW_VERSION_1_1 EGLEW_GET_VAR(__EGLEW_VERSION_1_1)
+
+#endif /* EGL_VERSION_1_1 */
+
+/* ---------------------------- EGL_VERSION_1_2 ---------------------------- */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+
+#define EGL_OPENGL_ES_BIT 0x0001
+#define EGL_OPENVG_BIT 0x0002
+#define EGL_LUMINANCE_SIZE 0x303D
+#define EGL_ALPHA_MASK_SIZE 0x303E
+#define EGL_COLOR_BUFFER_TYPE 0x303F
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_SINGLE_BUFFER 0x3085
+#define EGL_RENDER_BUFFER 0x3086
+#define EGL_COLORSPACE 0x3087
+#define EGL_ALPHA_FORMAT 0x3088
+#define EGL_COLORSPACE_LINEAR 0x308A
+#define EGL_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_ALPHA_FORMAT_PRE 0x308C
+#define EGL_CLIENT_APIS 0x308D
+#define EGL_RGB_BUFFER 0x308E
+#define EGL_LUMINANCE_BUFFER 0x308F
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
+#define EGL_VERTICAL_RESOLUTION 0x3091
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
+#define EGL_SWAP_BEHAVIOR 0x3093
+#define EGL_BUFFER_PRESERVED 0x3094
+#define EGL_BUFFER_DESTROYED 0x3095
+#define EGL_OPENVG_IMAGE 0x3096
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
+#define EGL_OPENGL_ES_API 0x30A0
+#define EGL_OPENVG_API 0x30A1
+#define EGL_DISPLAY_SCALING 10000
+
+typedef EGLBoolean ( * PFNEGLBINDAPIPROC) (EGLenum api);
+typedef EGLSurface ( * PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list);
+typedef EGLenum ( * PFNEGLQUERYAPIPROC) ( void );
+typedef EGLBoolean ( * PFNEGLRELEASETHREADPROC) ( void );
+typedef EGLBoolean ( * PFNEGLWAITCLIENTPROC) ( void );
+
+#define eglBindAPI EGLEW_GET_FUN(__eglewBindAPI)
+#define eglCreatePbufferFromClientBuffer EGLEW_GET_FUN(__eglewCreatePbufferFromClientBuffer)
+#define eglQueryAPI EGLEW_GET_FUN(__eglewQueryAPI)
+#define eglReleaseThread EGLEW_GET_FUN(__eglewReleaseThread)
+#define eglWaitClient EGLEW_GET_FUN(__eglewWaitClient)
+
+#define EGLEW_VERSION_1_2 EGLEW_GET_VAR(__EGLEW_VERSION_1_2)
+
+#endif /* EGL_VERSION_1_2 */
+
+/* ---------------------------- EGL_VERSION_1_3 ---------------------------- */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+
+#define EGL_OPENGL_ES2_BIT 0x0004
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041
+#define EGL_CONFORMANT 0x3042
+#define EGL_VG_COLORSPACE 0x3087
+#define EGL_VG_ALPHA_FORMAT 0x3088
+#define EGL_VG_COLORSPACE_LINEAR 0x308A
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+
+#define EGLEW_VERSION_1_3 EGLEW_GET_VAR(__EGLEW_VERSION_1_3)
+
+#endif /* EGL_VERSION_1_3 */
+
+/* ---------------------------- EGL_VERSION_1_4 ---------------------------- */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+
+#define EGL_OPENGL_BIT 0x0008
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
+#define EGL_OPENGL_API 0x30A2
+
+typedef EGLContext ( * PFNEGLGETCURRENTCONTEXTPROC) ( void );
+
+#define eglGetCurrentContext EGLEW_GET_FUN(__eglewGetCurrentContext)
+
+#define EGLEW_VERSION_1_4 EGLEW_GET_VAR(__EGLEW_VERSION_1_4)
+
+#endif /* EGL_VERSION_1_4 */
+
+/* ---------------------------- EGL_VERSION_1_5 ---------------------------- */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_GL_COLORSPACE_SRGB 0x3089
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CL_EVENT_HANDLE 0x309C
+#define EGL_GL_COLORSPACE 0x309D
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_GL_TEXTURE_3D 0x30B2
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_GL_RENDERBUFFER 0x30B9
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
+#define EGL_IMAGE_PRESERVED 0x30D2
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define EGL_SYNC_STATUS 0x30F1
+#define EGL_SIGNALED 0x30F2
+#define EGL_UNSIGNALED 0x30F3
+#define EGL_TIMEOUT_EXPIRED 0x30F5
+#define EGL_CONDITION_SATISFIED 0x30F6
+#define EGL_SYNC_TYPE 0x30F7
+#define EGL_SYNC_CONDITION 0x30F8
+#define EGL_SYNC_FENCE 0x30F9
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_SYNC_CL_EVENT 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFF
+
+typedef EGLint ( * PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+typedef EGLImage ( * PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list);
+typedef EGLSurface ( * PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list);
+typedef EGLSurface ( * PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list);
+typedef EGLSync ( * PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list);
+typedef EGLBoolean ( * PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image);
+typedef EGLBoolean ( * PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync);
+typedef EGLDisplay ( * PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void * native_display, const EGLAttrib * attrib_list);
+typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value);
+typedef EGLBoolean ( * PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags);
+
+#define eglClientWaitSync EGLEW_GET_FUN(__eglewClientWaitSync)
+#define eglCreateImage EGLEW_GET_FUN(__eglewCreateImage)
+#define eglCreatePlatformPixmapSurface EGLEW_GET_FUN(__eglewCreatePlatformPixmapSurface)
+#define eglCreatePlatformWindowSurface EGLEW_GET_FUN(__eglewCreatePlatformWindowSurface)
+#define eglCreateSync EGLEW_GET_FUN(__eglewCreateSync)
+#define eglDestroyImage EGLEW_GET_FUN(__eglewDestroyImage)
+#define eglDestroySync EGLEW_GET_FUN(__eglewDestroySync)
+#define eglGetPlatformDisplay EGLEW_GET_FUN(__eglewGetPlatformDisplay)
+#define eglGetSyncAttrib EGLEW_GET_FUN(__eglewGetSyncAttrib)
+#define eglWaitSync EGLEW_GET_FUN(__eglewWaitSync)
+
+#define EGLEW_VERSION_1_5 EGLEW_GET_VAR(__EGLEW_VERSION_1_5)
+
+#endif /* EGL_VERSION_1_5 */
+
+/* ------------------------- EGL_ANDROID_blob_cache ------------------------ */
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+
+typedef void ( * PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+
+#define eglSetBlobCacheFuncsANDROID EGLEW_GET_FUN(__eglewSetBlobCacheFuncsANDROID)
+
+#define EGLEW_ANDROID_blob_cache EGLEW_GET_VAR(__EGLEW_ANDROID_blob_cache)
+
+#endif /* EGL_ANDROID_blob_cache */
+
+/* ---------------- EGL_ANDROID_create_native_client_buffer ---------------- */
+
+#ifndef EGL_ANDROID_create_native_client_buffer
+#define EGL_ANDROID_create_native_client_buffer 1
+
+#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001
+#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002
+#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004
+#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143
+
+typedef EGLClientBuffer ( * PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint * attrib_list);
+
+#define eglCreateNativeClientBufferANDROID EGLEW_GET_FUN(__eglewCreateNativeClientBufferANDROID)
+
+#define EGLEW_ANDROID_create_native_client_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_create_native_client_buffer)
+
+#endif /* EGL_ANDROID_create_native_client_buffer */
+
+/* --------------------- EGL_ANDROID_framebuffer_target -------------------- */
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+
+#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+
+#define EGLEW_ANDROID_framebuffer_target EGLEW_GET_VAR(__EGLEW_ANDROID_framebuffer_target)
+
+#endif /* EGL_ANDROID_framebuffer_target */
+
+/* ----------------- EGL_ANDROID_front_buffer_auto_refresh ----------------- */
+
+#ifndef EGL_ANDROID_front_buffer_auto_refresh
+#define EGL_ANDROID_front_buffer_auto_refresh 1
+
+#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
+
+#define EGLEW_ANDROID_front_buffer_auto_refresh EGLEW_GET_VAR(__EGLEW_ANDROID_front_buffer_auto_refresh)
+
+#endif /* EGL_ANDROID_front_buffer_auto_refresh */
+
+/* -------------------- EGL_ANDROID_image_native_buffer -------------------- */
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+
+#define EGLEW_ANDROID_image_native_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_image_native_buffer)
+
+#endif /* EGL_ANDROID_image_native_buffer */
+
+/* --------------------- EGL_ANDROID_native_fence_sync --------------------- */
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+
+typedef EGLint ( * PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+
+#define eglDupNativeFenceFDANDROID EGLEW_GET_FUN(__eglewDupNativeFenceFDANDROID)
+
+#define EGLEW_ANDROID_native_fence_sync EGLEW_GET_VAR(__EGLEW_ANDROID_native_fence_sync)
+
+#endif /* EGL_ANDROID_native_fence_sync */
+
+/* --------------------- EGL_ANDROID_presentation_time --------------------- */
+
+#ifndef EGL_ANDROID_presentation_time
+#define EGL_ANDROID_presentation_time 1
+
+typedef EGLBoolean ( * PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+
+#define eglPresentationTimeANDROID EGLEW_GET_FUN(__eglewPresentationTimeANDROID)
+
+#define EGLEW_ANDROID_presentation_time EGLEW_GET_VAR(__EGLEW_ANDROID_presentation_time)
+
+#endif /* EGL_ANDROID_presentation_time */
+
+/* ------------------------- EGL_ANDROID_recordable ------------------------ */
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+
+#define EGL_RECORDABLE_ANDROID 0x3142
+
+#define EGLEW_ANDROID_recordable EGLEW_GET_VAR(__EGLEW_ANDROID_recordable)
+
+#endif /* EGL_ANDROID_recordable */
+
+/* ---------------- EGL_ANGLE_d3d_share_handle_client_buffer --------------- */
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+
+#define EGLEW_ANGLE_d3d_share_handle_client_buffer EGLEW_GET_VAR(__EGLEW_ANGLE_d3d_share_handle_client_buffer)
+
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+
+/* -------------------------- EGL_ANGLE_device_d3d ------------------------- */
+
+#ifndef EGL_ANGLE_device_d3d
+#define EGL_ANGLE_device_d3d 1
+
+#define EGL_D3D9_DEVICE_ANGLE 0x33A0
+#define EGL_D3D11_DEVICE_ANGLE 0x33A1
+
+#define EGLEW_ANGLE_device_d3d EGLEW_GET_VAR(__EGLEW_ANGLE_device_d3d)
+
+#endif /* EGL_ANGLE_device_d3d */
+
+/* -------------------- EGL_ANGLE_query_surface_pointer -------------------- */
+
+#ifndef EGL_ANGLE_query_surface_pointer
+#define EGL_ANGLE_query_surface_pointer 1
+
+typedef EGLBoolean ( * PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void ** value);
+
+#define eglQuerySurfacePointerANGLE EGLEW_GET_FUN(__eglewQuerySurfacePointerANGLE)
+
+#define EGLEW_ANGLE_query_surface_pointer EGLEW_GET_VAR(__EGLEW_ANGLE_query_surface_pointer)
+
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+/* ------------- EGL_ANGLE_surface_d3d_texture_2d_share_handle ------------- */
+
+#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+
+#define EGLEW_ANGLE_surface_d3d_texture_2d_share_handle EGLEW_GET_VAR(__EGLEW_ANGLE_surface_d3d_texture_2d_share_handle)
+
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+
+/* ---------------------- EGL_ANGLE_window_fixed_size ---------------------- */
+
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+
+#define EGL_FIXED_SIZE_ANGLE 0x3201
+
+#define EGLEW_ANGLE_window_fixed_size EGLEW_GET_VAR(__EGLEW_ANGLE_window_fixed_size)
+
+#endif /* EGL_ANGLE_window_fixed_size */
+
+/* ------------------- EGL_ARM_pixmap_multisample_discard ------------------ */
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+
+#define EGL_DISCARD_SAMPLES_ARM 0x3286
+
+#define EGLEW_ARM_pixmap_multisample_discard EGLEW_GET_VAR(__EGLEW_ARM_pixmap_multisample_discard)
+
+#endif /* EGL_ARM_pixmap_multisample_discard */
+
+/* --------------------------- EGL_EXT_buffer_age -------------------------- */
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+
+#define EGL_BUFFER_AGE_EXT 0x313D
+
+#define EGLEW_EXT_buffer_age EGLEW_GET_VAR(__EGLEW_EXT_buffer_age)
+
+#endif /* EGL_EXT_buffer_age */
+
+/* ----------------------- EGL_EXT_client_extensions ----------------------- */
+
+#ifndef EGL_EXT_client_extensions
+#define EGL_EXT_client_extensions 1
+
+#define EGLEW_EXT_client_extensions EGLEW_GET_VAR(__EGLEW_EXT_client_extensions)
+
+#endif /* EGL_EXT_client_extensions */
+
+/* ------------------- EGL_EXT_create_context_robustness ------------------- */
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+
+#define EGLEW_EXT_create_context_robustness EGLEW_GET_VAR(__EGLEW_EXT_create_context_robustness)
+
+#endif /* EGL_EXT_create_context_robustness */
+
+/* -------------------------- EGL_EXT_device_base -------------------------- */
+
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+
+#define EGL_BAD_DEVICE_EXT 0x322B
+#define EGL_DEVICE_EXT 0x322C
+
+#define EGLEW_EXT_device_base EGLEW_GET_VAR(__EGLEW_EXT_device_base)
+
+#endif /* EGL_EXT_device_base */
+
+/* --------------------------- EGL_EXT_device_drm -------------------------- */
+
+#ifndef EGL_EXT_device_drm
+#define EGL_EXT_device_drm 1
+
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+
+#define EGLEW_EXT_device_drm EGLEW_GET_VAR(__EGLEW_EXT_device_drm)
+
+#endif /* EGL_EXT_device_drm */
+
+/* ----------------------- EGL_EXT_device_enumeration ---------------------- */
+
+#ifndef EGL_EXT_device_enumeration
+#define EGL_EXT_device_enumeration 1
+
+typedef EGLBoolean ( * PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT * devices, EGLint * num_devices);
+
+#define eglQueryDevicesEXT EGLEW_GET_FUN(__eglewQueryDevicesEXT)
+
+#define EGLEW_EXT_device_enumeration EGLEW_GET_VAR(__EGLEW_EXT_device_enumeration)
+
+#endif /* EGL_EXT_device_enumeration */
+
+/* ------------------------- EGL_EXT_device_openwf ------------------------- */
+
+#ifndef EGL_EXT_device_openwf
+#define EGL_EXT_device_openwf 1
+
+#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
+
+#define EGLEW_EXT_device_openwf EGLEW_GET_VAR(__EGLEW_EXT_device_openwf)
+
+#endif /* EGL_EXT_device_openwf */
+
+/* -------------------------- EGL_EXT_device_query ------------------------- */
+
+#ifndef EGL_EXT_device_query
+#define EGL_EXT_device_query 1
+
+#define EGL_BAD_DEVICE_EXT 0x322B
+#define EGL_DEVICE_EXT 0x322C
+
+typedef EGLBoolean ( * PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib * value);
+typedef const char * ( * PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib * value);
+
+#define eglQueryDeviceAttribEXT EGLEW_GET_FUN(__eglewQueryDeviceAttribEXT)
+#define eglQueryDeviceStringEXT EGLEW_GET_FUN(__eglewQueryDeviceStringEXT)
+#define eglQueryDisplayAttribEXT EGLEW_GET_FUN(__eglewQueryDisplayAttribEXT)
+
+#define EGLEW_EXT_device_query EGLEW_GET_VAR(__EGLEW_EXT_device_query)
+
+#endif /* EGL_EXT_device_query */
+
+/* ---------------------- EGL_EXT_image_dma_buf_import --------------------- */
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT 0x327F
+#define EGL_ITU_REC709_EXT 0x3280
+#define EGL_ITU_REC2020_EXT 0x3281
+#define EGL_YUV_FULL_RANGE_EXT 0x3282
+#define EGL_YUV_NARROW_RANGE_EXT 0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+
+#define EGLEW_EXT_image_dma_buf_import EGLEW_GET_VAR(__EGLEW_EXT_image_dma_buf_import)
+
+#endif /* EGL_EXT_image_dma_buf_import */
+
+/* ------------------------ EGL_EXT_multiview_window ----------------------- */
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+
+#define EGLEW_EXT_multiview_window EGLEW_GET_VAR(__EGLEW_EXT_multiview_window)
+
+#endif /* EGL_EXT_multiview_window */
+
+/* -------------------------- EGL_EXT_output_base -------------------------- */
+
+#ifndef EGL_EXT_output_base
+#define EGL_EXT_output_base 1
+
+#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D
+#define EGL_BAD_OUTPUT_PORT_EXT 0x322E
+#define EGL_SWAP_INTERVAL_EXT 0x322F
+
+typedef EGLBoolean ( * PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib * attrib_list, EGLOutputLayerEXT * layers, EGLint max_layers, EGLint * num_layers);
+typedef EGLBoolean ( * PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib * attrib_list, EGLOutputPortEXT * ports, EGLint max_ports, EGLint * num_ports);
+typedef EGLBoolean ( * PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean ( * PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean ( * PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib * value);
+typedef const char * ( * PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean ( * PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib * value);
+typedef const char * ( * PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+
+#define eglGetOutputLayersEXT EGLEW_GET_FUN(__eglewGetOutputLayersEXT)
+#define eglGetOutputPortsEXT EGLEW_GET_FUN(__eglewGetOutputPortsEXT)
+#define eglOutputLayerAttribEXT EGLEW_GET_FUN(__eglewOutputLayerAttribEXT)
+#define eglOutputPortAttribEXT EGLEW_GET_FUN(__eglewOutputPortAttribEXT)
+#define eglQueryOutputLayerAttribEXT EGLEW_GET_FUN(__eglewQueryOutputLayerAttribEXT)
+#define eglQueryOutputLayerStringEXT EGLEW_GET_FUN(__eglewQueryOutputLayerStringEXT)
+#define eglQueryOutputPortAttribEXT EGLEW_GET_FUN(__eglewQueryOutputPortAttribEXT)
+#define eglQueryOutputPortStringEXT EGLEW_GET_FUN(__eglewQueryOutputPortStringEXT)
+
+#define EGLEW_EXT_output_base EGLEW_GET_VAR(__EGLEW_EXT_output_base)
+
+#endif /* EGL_EXT_output_base */
+
+/* --------------------------- EGL_EXT_output_drm -------------------------- */
+
+#ifndef EGL_EXT_output_drm
+#define EGL_EXT_output_drm 1
+
+#define EGL_DRM_CRTC_EXT 0x3234
+#define EGL_DRM_PLANE_EXT 0x3235
+#define EGL_DRM_CONNECTOR_EXT 0x3236
+
+#define EGLEW_EXT_output_drm EGLEW_GET_VAR(__EGLEW_EXT_output_drm)
+
+#endif /* EGL_EXT_output_drm */
+
+/* ------------------------- EGL_EXT_output_openwf ------------------------- */
+
+#ifndef EGL_EXT_output_openwf
+#define EGL_EXT_output_openwf 1
+
+#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238
+#define EGL_OPENWF_PORT_ID_EXT 0x3239
+
+#define EGLEW_EXT_output_openwf EGLEW_GET_VAR(__EGLEW_EXT_output_openwf)
+
+#endif /* EGL_EXT_output_openwf */
+
+/* ------------------------- EGL_EXT_platform_base ------------------------- */
+
+#ifndef EGL_EXT_platform_base
+#define EGL_EXT_platform_base 1
+
+typedef EGLSurface ( * PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLint * attrib_list);
+typedef EGLSurface ( * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void * native_window, const EGLint * attrib_list);
+typedef EGLDisplay ( * PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void * native_display, const EGLint * attrib_list);
+
+#define eglCreatePlatformPixmapSurfaceEXT EGLEW_GET_FUN(__eglewCreatePlatformPixmapSurfaceEXT)
+#define eglCreatePlatformWindowSurfaceEXT EGLEW_GET_FUN(__eglewCreatePlatformWindowSurfaceEXT)
+#define eglGetPlatformDisplayEXT EGLEW_GET_FUN(__eglewGetPlatformDisplayEXT)
+
+#define EGLEW_EXT_platform_base EGLEW_GET_VAR(__EGLEW_EXT_platform_base)
+
+#endif /* EGL_EXT_platform_base */
+
+/* ------------------------ EGL_EXT_platform_device ------------------------ */
+
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+
+#define EGLEW_EXT_platform_device EGLEW_GET_VAR(__EGLEW_EXT_platform_device)
+
+#endif /* EGL_EXT_platform_device */
+
+/* ------------------------ EGL_EXT_platform_wayland ----------------------- */
+
+#ifndef EGL_EXT_platform_wayland
+#define EGL_EXT_platform_wayland 1
+
+#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
+
+#define EGLEW_EXT_platform_wayland EGLEW_GET_VAR(__EGLEW_EXT_platform_wayland)
+
+#endif /* EGL_EXT_platform_wayland */
+
+/* -------------------------- EGL_EXT_platform_x11 ------------------------- */
+
+#ifndef EGL_EXT_platform_x11
+#define EGL_EXT_platform_x11 1
+
+#define EGL_PLATFORM_X11_EXT 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
+
+#define EGLEW_EXT_platform_x11 EGLEW_GET_VAR(__EGLEW_EXT_platform_x11)
+
+#endif /* EGL_EXT_platform_x11 */
+
+/* ----------------------- EGL_EXT_protected_content ----------------------- */
+
+#ifndef EGL_EXT_protected_content
+#define EGL_EXT_protected_content 1
+
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+
+#define EGLEW_EXT_protected_content EGLEW_GET_VAR(__EGLEW_EXT_protected_content)
+
+#endif /* EGL_EXT_protected_content */
+
+/* ----------------------- EGL_EXT_protected_surface ----------------------- */
+
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+
+#define EGLEW_EXT_protected_surface EGLEW_GET_VAR(__EGLEW_EXT_protected_surface)
+
+#endif /* EGL_EXT_protected_surface */
+
+/* ------------------- EGL_EXT_stream_consumer_egloutput ------------------- */
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+#define EGL_EXT_stream_consumer_egloutput 1
+
+typedef EGLBoolean ( * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+
+#define eglStreamConsumerOutputEXT EGLEW_GET_FUN(__eglewStreamConsumerOutputEXT)
+
+#define EGLEW_EXT_stream_consumer_egloutput EGLEW_GET_VAR(__EGLEW_EXT_stream_consumer_egloutput)
+
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
+/* -------------------- EGL_EXT_swap_buffers_with_damage ------------------- */
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+
+typedef EGLBoolean ( * PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects);
+
+#define eglSwapBuffersWithDamageEXT EGLEW_GET_FUN(__eglewSwapBuffersWithDamageEXT)
+
+#define EGLEW_EXT_swap_buffers_with_damage EGLEW_GET_VAR(__EGLEW_EXT_swap_buffers_with_damage)
+
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+/* -------------------------- EGL_EXT_yuv_surface -------------------------- */
+
+#ifndef EGL_EXT_yuv_surface
+#define EGL_EXT_yuv_surface 1
+
+#define EGL_YUV_BUFFER_EXT 0x3300
+#define EGL_YUV_ORDER_EXT 0x3301
+#define EGL_YUV_ORDER_YUV_EXT 0x3302
+#define EGL_YUV_ORDER_YVU_EXT 0x3303
+#define EGL_YUV_ORDER_YUYV_EXT 0x3304
+#define EGL_YUV_ORDER_UYVY_EXT 0x3305
+#define EGL_YUV_ORDER_YVYU_EXT 0x3306
+#define EGL_YUV_ORDER_VYUY_EXT 0x3307
+#define EGL_YUV_ORDER_AYUV_EXT 0x3308
+#define EGL_YUV_CSC_STANDARD_EXT 0x330A
+#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B
+#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C
+#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D
+#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311
+#define EGL_YUV_SUBSAMPLE_EXT 0x3312
+#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313
+#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314
+#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315
+#define EGL_YUV_DEPTH_RANGE_EXT 0x3317
+#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318
+#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319
+#define EGL_YUV_PLANE_BPP_EXT 0x331A
+#define EGL_YUV_PLANE_BPP_0_EXT 0x331B
+#define EGL_YUV_PLANE_BPP_8_EXT 0x331C
+#define EGL_YUV_PLANE_BPP_10_EXT 0x331D
+
+#define EGLEW_EXT_yuv_surface EGLEW_GET_VAR(__EGLEW_EXT_yuv_surface)
+
+#endif /* EGL_EXT_yuv_surface */
+
+/* -------------------------- EGL_HI_clientpixmap -------------------------- */
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+
+#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+
+typedef EGLSurface ( * PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI * pixmap);
+
+#define eglCreatePixmapSurfaceHI EGLEW_GET_FUN(__eglewCreatePixmapSurfaceHI)
+
+#define EGLEW_HI_clientpixmap EGLEW_GET_VAR(__EGLEW_HI_clientpixmap)
+
+#endif /* EGL_HI_clientpixmap */
+
+/* -------------------------- EGL_HI_colorformats -------------------------- */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+
+#define EGL_COLOR_FORMAT_HI 0x8F70
+#define EGL_COLOR_RGB_HI 0x8F71
+#define EGL_COLOR_RGBA_HI 0x8F72
+#define EGL_COLOR_ARGB_HI 0x8F73
+
+#define EGLEW_HI_colorformats EGLEW_GET_VAR(__EGLEW_HI_colorformats)
+
+#endif /* EGL_HI_colorformats */
+
+/* ------------------------ EGL_IMG_context_priority ----------------------- */
+
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+
+#define EGLEW_IMG_context_priority EGLEW_GET_VAR(__EGLEW_IMG_context_priority)
+
+#endif /* EGL_IMG_context_priority */
+
+/* ---------------------- EGL_IMG_image_plane_attribs ---------------------- */
+
+#ifndef EGL_IMG_image_plane_attribs
+#define EGL_IMG_image_plane_attribs 1
+
+#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105
+#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106
+
+#define EGLEW_IMG_image_plane_attribs EGLEW_GET_VAR(__EGLEW_IMG_image_plane_attribs)
+
+#endif /* EGL_IMG_image_plane_attribs */
+
+/* ---------------------------- EGL_KHR_cl_event --------------------------- */
+
+#ifndef EGL_KHR_cl_event
+#define EGL_KHR_cl_event 1
+
+#define EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+
+#define EGLEW_KHR_cl_event EGLEW_GET_VAR(__EGLEW_KHR_cl_event)
+
+#endif /* EGL_KHR_cl_event */
+
+/* --------------------------- EGL_KHR_cl_event2 --------------------------- */
+
+#ifndef EGL_KHR_cl_event2
+#define EGL_KHR_cl_event2 1
+
+#define EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+
+typedef EGLSyncKHR ( * PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR * attrib_list);
+
+#define eglCreateSync64KHR EGLEW_GET_FUN(__eglewCreateSync64KHR)
+
+#define EGLEW_KHR_cl_event2 EGLEW_GET_VAR(__EGLEW_KHR_cl_event2)
+
+#endif /* EGL_KHR_cl_event2 */
+
+/* ----------------- EGL_KHR_client_get_all_proc_addresses ----------------- */
+
+#ifndef EGL_KHR_client_get_all_proc_addresses
+#define EGL_KHR_client_get_all_proc_addresses 1
+
+#define EGLEW_KHR_client_get_all_proc_addresses EGLEW_GET_VAR(__EGLEW_KHR_client_get_all_proc_addresses)
+
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+
+/* ------------------------- EGL_KHR_config_attribs ------------------------ */
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
+#define EGL_CONFORMANT_KHR 0x3042
+
+#define EGLEW_KHR_config_attribs EGLEW_GET_VAR(__EGLEW_KHR_config_attribs)
+
+#endif /* EGL_KHR_config_attribs */
+
+/* ------------------------- EGL_KHR_create_context ------------------------ */
+
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+
+#define EGLEW_KHR_create_context EGLEW_GET_VAR(__EGLEW_KHR_create_context)
+
+#endif /* EGL_KHR_create_context */
+
+/* -------------------- EGL_KHR_create_context_no_error -------------------- */
+
+#ifndef EGL_KHR_create_context_no_error
+#define EGL_KHR_create_context_no_error 1
+
+#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3
+
+#define EGLEW_KHR_create_context_no_error EGLEW_GET_VAR(__EGLEW_KHR_create_context_no_error)
+
+#endif /* EGL_KHR_create_context_no_error */
+
+/* ----------------------------- EGL_KHR_debug ----------------------------- */
+
+#ifndef EGL_KHR_debug
+#define EGL_KHR_debug 1
+
+#define EGL_OBJECT_THREAD_KHR 0x33B0
+#define EGL_OBJECT_DISPLAY_KHR 0x33B1
+#define EGL_OBJECT_CONTEXT_KHR 0x33B2
+#define EGL_OBJECT_SURFACE_KHR 0x33B3
+#define EGL_OBJECT_IMAGE_KHR 0x33B4
+#define EGL_OBJECT_SYNC_KHR 0x33B5
+#define EGL_OBJECT_STREAM_KHR 0x33B6
+#define EGL_DEBUG_CALLBACK_KHR 0x33B8
+#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9
+#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA
+#define EGL_DEBUG_MSG_WARN_KHR 0x33BB
+#define EGL_DEBUG_MSG_INFO_KHR 0x33BC
+
+typedef EGLint ( * PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib * attrib_list);
+typedef EGLint ( * PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+typedef EGLBoolean ( * PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib * value);
+
+#define eglDebugMessageControlKHR EGLEW_GET_FUN(__eglewDebugMessageControlKHR)
+#define eglLabelObjectKHR EGLEW_GET_FUN(__eglewLabelObjectKHR)
+#define eglQueryDebugKHR EGLEW_GET_FUN(__eglewQueryDebugKHR)
+
+#define EGLEW_KHR_debug EGLEW_GET_VAR(__EGLEW_KHR_debug)
+
+#endif /* EGL_KHR_debug */
+
+/* --------------------------- EGL_KHR_fence_sync -------------------------- */
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+
+#define EGLEW_KHR_fence_sync EGLEW_GET_VAR(__EGLEW_KHR_fence_sync)
+
+#endif /* EGL_KHR_fence_sync */
+
+/* --------------------- EGL_KHR_get_all_proc_addresses -------------------- */
+
+#ifndef EGL_KHR_get_all_proc_addresses
+#define EGL_KHR_get_all_proc_addresses 1
+
+#define EGLEW_KHR_get_all_proc_addresses EGLEW_GET_VAR(__EGLEW_KHR_get_all_proc_addresses)
+
+#endif /* EGL_KHR_get_all_proc_addresses */
+
+/* ------------------------- EGL_KHR_gl_colorspace ------------------------- */
+
+#ifndef EGL_KHR_gl_colorspace
+#define EGL_KHR_gl_colorspace 1
+
+#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
+#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
+#define EGL_GL_COLORSPACE_KHR 0x309D
+
+#define EGLEW_KHR_gl_colorspace EGLEW_GET_VAR(__EGLEW_KHR_gl_colorspace)
+
+#endif /* EGL_KHR_gl_colorspace */
+
+/* --------------------- EGL_KHR_gl_renderbuffer_image --------------------- */
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9
+
+#define EGLEW_KHR_gl_renderbuffer_image EGLEW_GET_VAR(__EGLEW_KHR_gl_renderbuffer_image)
+
+#endif /* EGL_KHR_gl_renderbuffer_image */
+
+/* ---------------------- EGL_KHR_gl_texture_2D_image ---------------------- */
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+
+#define EGLEW_KHR_gl_texture_2D_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_2D_image)
+
+#endif /* EGL_KHR_gl_texture_2D_image */
+
+/* ---------------------- EGL_KHR_gl_texture_3D_image ---------------------- */
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
+
+#define EGLEW_KHR_gl_texture_3D_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_3D_image)
+
+#endif /* EGL_KHR_gl_texture_3D_image */
+
+/* -------------------- EGL_KHR_gl_texture_cubemap_image ------------------- */
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+
+#define EGLEW_KHR_gl_texture_cubemap_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_cubemap_image)
+
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+
+/* ----------------------------- EGL_KHR_image ----------------------------- */
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+
+typedef EGLImageKHR ( * PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+
+#define eglCreateImageKHR EGLEW_GET_FUN(__eglewCreateImageKHR)
+#define eglDestroyImageKHR EGLEW_GET_FUN(__eglewDestroyImageKHR)
+
+#define EGLEW_KHR_image EGLEW_GET_VAR(__EGLEW_KHR_image)
+
+#endif /* EGL_KHR_image */
+
+/* --------------------------- EGL_KHR_image_base -------------------------- */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+
+#define EGLEW_KHR_image_base EGLEW_GET_VAR(__EGLEW_KHR_image_base)
+
+#endif /* EGL_KHR_image_base */
+
+/* -------------------------- EGL_KHR_image_pixmap ------------------------- */
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+
+#define EGLEW_KHR_image_pixmap EGLEW_GET_VAR(__EGLEW_KHR_image_pixmap)
+
+#endif /* EGL_KHR_image_pixmap */
+
+/* -------------------------- EGL_KHR_lock_surface ------------------------- */
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define EGL_MATCH_FORMAT_KHR 0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define EGL_FORMAT_RGB_565_KHR 0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR 0x30CE
+#define EGL_UPPER_LEFT_KHR 0x30CF
+
+typedef EGLBoolean ( * PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
+
+#define eglLockSurfaceKHR EGLEW_GET_FUN(__eglewLockSurfaceKHR)
+#define eglUnlockSurfaceKHR EGLEW_GET_FUN(__eglewUnlockSurfaceKHR)
+
+#define EGLEW_KHR_lock_surface EGLEW_GET_VAR(__EGLEW_KHR_lock_surface)
+
+#endif /* EGL_KHR_lock_surface */
+
+/* ------------------------- EGL_KHR_lock_surface2 ------------------------- */
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+
+#define EGLEW_KHR_lock_surface2 EGLEW_GET_VAR(__EGLEW_KHR_lock_surface2)
+
+#endif /* EGL_KHR_lock_surface2 */
+
+/* ------------------------- EGL_KHR_lock_surface3 ------------------------- */
+
+#ifndef EGL_KHR_lock_surface3
+#define EGL_KHR_lock_surface3 1
+
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define EGL_MATCH_FORMAT_KHR 0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define EGL_FORMAT_RGB_565_KHR 0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR 0x30CE
+#define EGL_UPPER_LEFT_KHR 0x30CF
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+
+typedef EGLBoolean ( * PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR * value);
+
+#define eglQuerySurface64KHR EGLEW_GET_FUN(__eglewQuerySurface64KHR)
+
+#define EGLEW_KHR_lock_surface3 EGLEW_GET_VAR(__EGLEW_KHR_lock_surface3)
+
+#endif /* EGL_KHR_lock_surface3 */
+
+/* --------------------- EGL_KHR_mutable_render_buffer --------------------- */
+
+#ifndef EGL_KHR_mutable_render_buffer
+#define EGL_KHR_mutable_render_buffer 1
+
+#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000
+
+#define EGLEW_KHR_mutable_render_buffer EGLEW_GET_VAR(__EGLEW_KHR_mutable_render_buffer)
+
+#endif /* EGL_KHR_mutable_render_buffer */
+
+/* ------------------------- EGL_KHR_partial_update ------------------------ */
+
+#ifndef EGL_KHR_partial_update
+#define EGL_KHR_partial_update 1
+
+#define EGL_BUFFER_AGE_KHR 0x313D
+
+typedef EGLBoolean ( * PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects);
+
+#define eglSetDamageRegionKHR EGLEW_GET_FUN(__eglewSetDamageRegionKHR)
+
+#define EGLEW_KHR_partial_update EGLEW_GET_VAR(__EGLEW_KHR_partial_update)
+
+#endif /* EGL_KHR_partial_update */
+
+/* ------------------------ EGL_KHR_platform_android ----------------------- */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+
+#define EGL_PLATFORM_ANDROID_KHR 0x3141
+
+#define EGLEW_KHR_platform_android EGLEW_GET_VAR(__EGLEW_KHR_platform_android)
+
+#endif /* EGL_KHR_platform_android */
+
+/* -------------------------- EGL_KHR_platform_gbm ------------------------- */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+
+#define EGL_PLATFORM_GBM_KHR 0x31D7
+
+#define EGLEW_KHR_platform_gbm EGLEW_GET_VAR(__EGLEW_KHR_platform_gbm)
+
+#endif /* EGL_KHR_platform_gbm */
+
+/* ------------------------ EGL_KHR_platform_wayland ----------------------- */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
+
+#define EGLEW_KHR_platform_wayland EGLEW_GET_VAR(__EGLEW_KHR_platform_wayland)
+
+#endif /* EGL_KHR_platform_wayland */
+
+/* -------------------------- EGL_KHR_platform_x11 ------------------------- */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
+
+#define EGLEW_KHR_platform_x11 EGLEW_GET_VAR(__EGLEW_KHR_platform_x11)
+
+#endif /* EGL_KHR_platform_x11 */
+
+/* ------------------------- EGL_KHR_reusable_sync ------------------------- */
+
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
+#define EGL_SYNC_STATUS_KHR 0x30F1
+#define EGL_SIGNALED_KHR 0x30F2
+#define EGL_UNSIGNALED_KHR 0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_REUSABLE_KHR 0x30FA
+#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFF
+
+typedef EGLint ( * PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLSyncKHR ( * PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint * value);
+typedef EGLBoolean ( * PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+
+#define eglClientWaitSyncKHR EGLEW_GET_FUN(__eglewClientWaitSyncKHR)
+#define eglCreateSyncKHR EGLEW_GET_FUN(__eglewCreateSyncKHR)
+#define eglDestroySyncKHR EGLEW_GET_FUN(__eglewDestroySyncKHR)
+#define eglGetSyncAttribKHR EGLEW_GET_FUN(__eglewGetSyncAttribKHR)
+#define eglSignalSyncKHR EGLEW_GET_FUN(__eglewSignalSyncKHR)
+
+#define EGLEW_KHR_reusable_sync EGLEW_GET_VAR(__EGLEW_KHR_reusable_sync)
+
+#endif /* EGL_KHR_reusable_sync */
+
+/* ----------------------------- EGL_KHR_stream ---------------------------- */
+
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+
+typedef EGLStreamKHR ( * PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean ( * PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint * value);
+typedef EGLBoolean ( * PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR * value);
+typedef EGLBoolean ( * PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+
+#define eglCreateStreamKHR EGLEW_GET_FUN(__eglewCreateStreamKHR)
+#define eglDestroyStreamKHR EGLEW_GET_FUN(__eglewDestroyStreamKHR)
+#define eglQueryStreamKHR EGLEW_GET_FUN(__eglewQueryStreamKHR)
+#define eglQueryStreamu64KHR EGLEW_GET_FUN(__eglewQueryStreamu64KHR)
+#define eglStreamAttribKHR EGLEW_GET_FUN(__eglewStreamAttribKHR)
+
+#define EGLEW_KHR_stream EGLEW_GET_VAR(__EGLEW_KHR_stream)
+
+#endif /* EGL_KHR_stream */
+
+/* ------------------- EGL_KHR_stream_consumer_gltexture ------------------- */
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+
+typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+
+#define eglStreamConsumerAcquireKHR EGLEW_GET_FUN(__eglewStreamConsumerAcquireKHR)
+#define eglStreamConsumerGLTextureExternalKHR EGLEW_GET_FUN(__eglewStreamConsumerGLTextureExternalKHR)
+#define eglStreamConsumerReleaseKHR EGLEW_GET_FUN(__eglewStreamConsumerReleaseKHR)
+
+#define EGLEW_KHR_stream_consumer_gltexture EGLEW_GET_VAR(__EGLEW_KHR_stream_consumer_gltexture)
+
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+/* -------------------- EGL_KHR_stream_cross_process_fd -------------------- */
+
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+
+typedef EGLStreamKHR ( * PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+typedef EGLNativeFileDescriptorKHR ( * PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+
+#define eglCreateStreamFromFileDescriptorKHR EGLEW_GET_FUN(__eglewCreateStreamFromFileDescriptorKHR)
+#define eglGetStreamFileDescriptorKHR EGLEW_GET_FUN(__eglewGetStreamFileDescriptorKHR)
+
+#define EGLEW_KHR_stream_cross_process_fd EGLEW_GET_VAR(__EGLEW_KHR_stream_cross_process_fd)
+
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+/* -------------------------- EGL_KHR_stream_fifo -------------------------- */
+
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+
+typedef EGLBoolean ( * PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR * value);
+
+#define eglQueryStreamTimeKHR EGLEW_GET_FUN(__eglewQueryStreamTimeKHR)
+
+#define EGLEW_KHR_stream_fifo EGLEW_GET_VAR(__EGLEW_KHR_stream_fifo)
+
+#endif /* EGL_KHR_stream_fifo */
+
+/* ----------------- EGL_KHR_stream_producer_aldatalocator ----------------- */
+
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+
+#define EGLEW_KHR_stream_producer_aldatalocator EGLEW_GET_VAR(__EGLEW_KHR_stream_producer_aldatalocator)
+
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+
+/* ------------------- EGL_KHR_stream_producer_eglsurface ------------------ */
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+
+#define EGL_STREAM_BIT_KHR 0x0800
+
+typedef EGLSurface ( * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint * attrib_list);
+
+#define eglCreateStreamProducerSurfaceKHR EGLEW_GET_FUN(__eglewCreateStreamProducerSurfaceKHR)
+
+#define EGLEW_KHR_stream_producer_eglsurface EGLEW_GET_VAR(__EGLEW_KHR_stream_producer_eglsurface)
+
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+/* ---------------------- EGL_KHR_surfaceless_context ---------------------- */
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+
+#define EGLEW_KHR_surfaceless_context EGLEW_GET_VAR(__EGLEW_KHR_surfaceless_context)
+
+#endif /* EGL_KHR_surfaceless_context */
+
+/* -------------------- EGL_KHR_swap_buffers_with_damage ------------------- */
+
+#ifndef EGL_KHR_swap_buffers_with_damage
+#define EGL_KHR_swap_buffers_with_damage 1
+
+typedef EGLBoolean ( * PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects);
+
+#define eglSwapBuffersWithDamageKHR EGLEW_GET_FUN(__eglewSwapBuffersWithDamageKHR)
+
+#define EGLEW_KHR_swap_buffers_with_damage EGLEW_GET_VAR(__EGLEW_KHR_swap_buffers_with_damage)
+
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
+/* ------------------------ EGL_KHR_vg_parent_image ------------------------ */
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
+
+#define EGLEW_KHR_vg_parent_image EGLEW_GET_VAR(__EGLEW_KHR_vg_parent_image)
+
+#endif /* EGL_KHR_vg_parent_image */
+
+/* --------------------------- EGL_KHR_wait_sync --------------------------- */
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+
+typedef EGLint ( * PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+
+#define eglWaitSyncKHR EGLEW_GET_FUN(__eglewWaitSyncKHR)
+
+#define EGLEW_KHR_wait_sync EGLEW_GET_VAR(__EGLEW_KHR_wait_sync)
+
+#endif /* EGL_KHR_wait_sync */
+
+/* --------------------------- EGL_MESA_drm_image -------------------------- */
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
+#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
+#define EGL_DRM_BUFFER_USE_MESA 0x31D1
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define EGL_DRM_BUFFER_MESA 0x31D3
+#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
+
+typedef EGLImageKHR ( * PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint * name, EGLint * handle, EGLint * stride);
+
+#define eglCreateDRMImageMESA EGLEW_GET_FUN(__eglewCreateDRMImageMESA)
+#define eglExportDRMImageMESA EGLEW_GET_FUN(__eglewExportDRMImageMESA)
+
+#define EGLEW_MESA_drm_image EGLEW_GET_VAR(__EGLEW_MESA_drm_image)
+
+#endif /* EGL_MESA_drm_image */
+
+/* --------------------- EGL_MESA_image_dma_buf_export --------------------- */
+
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+
+typedef EGLBoolean ( * PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int * fds, EGLint * strides, EGLint * offsets);
+typedef EGLBoolean ( * PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int * fourcc, int * num_planes, EGLuint64KHR * modifiers);
+
+#define eglExportDMABUFImageMESA EGLEW_GET_FUN(__eglewExportDMABUFImageMESA)
+#define eglExportDMABUFImageQueryMESA EGLEW_GET_FUN(__eglewExportDMABUFImageQueryMESA)
+
+#define EGLEW_MESA_image_dma_buf_export EGLEW_GET_VAR(__EGLEW_MESA_image_dma_buf_export)
+
+#endif /* EGL_MESA_image_dma_buf_export */
+
+/* ------------------------- EGL_MESA_platform_gbm ------------------------- */
+
+#ifndef EGL_MESA_platform_gbm
+#define EGL_MESA_platform_gbm 1
+
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+
+#define EGLEW_MESA_platform_gbm EGLEW_GET_VAR(__EGLEW_MESA_platform_gbm)
+
+#endif /* EGL_MESA_platform_gbm */
+
+/* -------------------------- EGL_NOK_swap_region -------------------------- */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+
+typedef EGLBoolean ( * PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint * rects);
+
+#define eglSwapBuffersRegionNOK EGLEW_GET_FUN(__eglewSwapBuffersRegionNOK)
+
+#define EGLEW_NOK_swap_region EGLEW_GET_VAR(__EGLEW_NOK_swap_region)
+
+#endif /* EGL_NOK_swap_region */
+
+/* -------------------------- EGL_NOK_swap_region2 ------------------------- */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+
+typedef EGLBoolean ( * PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint * rects);
+
+#define eglSwapBuffersRegion2NOK EGLEW_GET_FUN(__eglewSwapBuffersRegion2NOK)
+
+#define EGLEW_NOK_swap_region2 EGLEW_GET_VAR(__EGLEW_NOK_swap_region2)
+
+#endif /* EGL_NOK_swap_region2 */
+
+/* ---------------------- EGL_NOK_texture_from_pixmap ---------------------- */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+
+#define EGL_Y_INVERTED_NOK 0x307F
+
+#define EGLEW_NOK_texture_from_pixmap EGLEW_GET_VAR(__EGLEW_NOK_texture_from_pixmap)
+
+#endif /* EGL_NOK_texture_from_pixmap */
+
+/* ------------------------ EGL_NV_3dvision_surface ------------------------ */
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+
+#define EGL_AUTO_STEREO_NV 0x3136
+
+#define EGLEW_NV_3dvision_surface EGLEW_GET_VAR(__EGLEW_NV_3dvision_surface)
+
+#endif /* EGL_NV_3dvision_surface */
+
+/* ------------------------- EGL_NV_coverage_sample ------------------------ */
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+
+#define EGLEW_NV_coverage_sample EGLEW_GET_VAR(__EGLEW_NV_coverage_sample)
+
+#endif /* EGL_NV_coverage_sample */
+
+/* --------------------- EGL_NV_coverage_sample_resolve -------------------- */
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+
+#define EGLEW_NV_coverage_sample_resolve EGLEW_GET_VAR(__EGLEW_NV_coverage_sample_resolve)
+
+#endif /* EGL_NV_coverage_sample_resolve */
+
+/* --------------------------- EGL_NV_cuda_event --------------------------- */
+
+#ifndef EGL_NV_cuda_event
+#define EGL_NV_cuda_event 1
+
+#define EGL_CUDA_EVENT_HANDLE_NV 0x323B
+#define EGL_SYNC_CUDA_EVENT_NV 0x323C
+#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D
+
+#define EGLEW_NV_cuda_event EGLEW_GET_VAR(__EGLEW_NV_cuda_event)
+
+#endif /* EGL_NV_cuda_event */
+
+/* ------------------------- EGL_NV_depth_nonlinear ------------------------ */
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+
+#define EGLEW_NV_depth_nonlinear EGLEW_GET_VAR(__EGLEW_NV_depth_nonlinear)
+
+#endif /* EGL_NV_depth_nonlinear */
+
+/* --------------------------- EGL_NV_device_cuda -------------------------- */
+
+#ifndef EGL_NV_device_cuda
+#define EGL_NV_device_cuda 1
+
+#define EGL_CUDA_DEVICE_NV 0x323A
+
+#define EGLEW_NV_device_cuda EGLEW_GET_VAR(__EGLEW_NV_device_cuda)
+
+#endif /* EGL_NV_device_cuda */
+
+/* -------------------------- EGL_NV_native_query -------------------------- */
+
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+
+typedef EGLBoolean ( * PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType * display_id);
+typedef EGLBoolean ( * PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType * pixmap);
+typedef EGLBoolean ( * PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType * window);
+
+#define eglQueryNativeDisplayNV EGLEW_GET_FUN(__eglewQueryNativeDisplayNV)
+#define eglQueryNativePixmapNV EGLEW_GET_FUN(__eglewQueryNativePixmapNV)
+#define eglQueryNativeWindowNV EGLEW_GET_FUN(__eglewQueryNativeWindowNV)
+
+#define EGLEW_NV_native_query EGLEW_GET_VAR(__EGLEW_NV_native_query)
+
+#endif /* EGL_NV_native_query */
+
+/* ---------------------- EGL_NV_post_convert_rounding --------------------- */
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+
+#define EGLEW_NV_post_convert_rounding EGLEW_GET_VAR(__EGLEW_NV_post_convert_rounding)
+
+#endif /* EGL_NV_post_convert_rounding */
+
+/* ------------------------- EGL_NV_post_sub_buffer ------------------------ */
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
+
+typedef EGLBoolean ( * PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+
+#define eglPostSubBufferNV EGLEW_GET_FUN(__eglewPostSubBufferNV)
+
+#define EGLEW_NV_post_sub_buffer EGLEW_GET_VAR(__EGLEW_NV_post_sub_buffer)
+
+#endif /* EGL_NV_post_sub_buffer */
+
+/* ------------------ EGL_NV_robustness_video_memory_purge ----------------- */
+
+#ifndef EGL_NV_robustness_video_memory_purge
+#define EGL_NV_robustness_video_memory_purge 1
+
+#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+
+#define EGLEW_NV_robustness_video_memory_purge EGLEW_GET_VAR(__EGLEW_NV_robustness_video_memory_purge)
+
+#endif /* EGL_NV_robustness_video_memory_purge */
+
+/* ------------------ EGL_NV_stream_consumer_gltexture_yuv ----------------- */
+
+#ifndef EGL_NV_stream_consumer_gltexture_yuv
+#define EGL_NV_stream_consumer_gltexture_yuv 1
+
+#define EGL_YUV_BUFFER_EXT 0x3300
+#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311
+#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C
+#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D
+#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E
+
+typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
+
+#define eglStreamConsumerGLTextureExternalAttribsNV EGLEW_GET_FUN(__eglewStreamConsumerGLTextureExternalAttribsNV)
+
+#define EGLEW_NV_stream_consumer_gltexture_yuv EGLEW_GET_VAR(__EGLEW_NV_stream_consumer_gltexture_yuv)
+
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+/* ------------------------- EGL_NV_stream_metadata ------------------------ */
+
+#ifndef EGL_NV_stream_metadata
+#define EGL_NV_stream_metadata 1
+
+#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250
+#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251
+#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252
+#define EGL_PRODUCER_METADATA_NV 0x3253
+#define EGL_CONSUMER_METADATA_NV 0x3254
+#define EGL_METADATA0_SIZE_NV 0x3255
+#define EGL_METADATA1_SIZE_NV 0x3256
+#define EGL_METADATA2_SIZE_NV 0x3257
+#define EGL_METADATA3_SIZE_NV 0x3258
+#define EGL_METADATA0_TYPE_NV 0x3259
+#define EGL_METADATA1_TYPE_NV 0x325A
+#define EGL_METADATA2_TYPE_NV 0x325B
+#define EGL_METADATA3_TYPE_NV 0x325C
+#define EGL_PENDING_METADATA_NV 0x3328
+
+typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib * value);
+typedef EGLBoolean ( * PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void * data);
+typedef EGLBoolean ( * PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void * data);
+
+#define eglQueryDisplayAttribNV EGLEW_GET_FUN(__eglewQueryDisplayAttribNV)
+#define eglQueryStreamMetadataNV EGLEW_GET_FUN(__eglewQueryStreamMetadataNV)
+#define eglSetStreamMetadataNV EGLEW_GET_FUN(__eglewSetStreamMetadataNV)
+
+#define EGLEW_NV_stream_metadata EGLEW_GET_VAR(__EGLEW_NV_stream_metadata)
+
+#endif /* EGL_NV_stream_metadata */
+
+/* --------------------------- EGL_NV_stream_sync -------------------------- */
+
+#ifndef EGL_NV_stream_sync
+#define EGL_NV_stream_sync 1
+
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_NEW_FRAME_NV 0x321F
+
+typedef EGLSyncKHR ( * PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint * attrib_list);
+
+#define eglCreateStreamSyncNV EGLEW_GET_FUN(__eglewCreateStreamSyncNV)
+
+#define EGLEW_NV_stream_sync EGLEW_GET_VAR(__EGLEW_NV_stream_sync)
+
+#endif /* EGL_NV_stream_sync */
+
+/* ------------------------------ EGL_NV_sync ------------------------------ */
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV 0x30E7
+#define EGL_SIGNALED_NV 0x30E8
+#define EGL_UNSIGNALED_NV 0x30E9
+#define EGL_ALREADY_SIGNALED_NV 0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define EGL_CONDITION_SATISFIED_NV 0x30EC
+#define EGL_SYNC_TYPE_NV 0x30ED
+#define EGL_SYNC_CONDITION_NV 0x30EE
+#define EGL_SYNC_FENCE_NV 0x30EF
+#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFF
+
+typedef EGLint ( * PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLSyncNV ( * PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint * attrib_list);
+typedef EGLBoolean ( * PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean ( * PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint * value);
+typedef EGLBoolean ( * PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+
+#define eglClientWaitSyncNV EGLEW_GET_FUN(__eglewClientWaitSyncNV)
+#define eglCreateFenceSyncNV EGLEW_GET_FUN(__eglewCreateFenceSyncNV)
+#define eglDestroySyncNV EGLEW_GET_FUN(__eglewDestroySyncNV)
+#define eglFenceNV EGLEW_GET_FUN(__eglewFenceNV)
+#define eglGetSyncAttribNV EGLEW_GET_FUN(__eglewGetSyncAttribNV)
+#define eglSignalSyncNV EGLEW_GET_FUN(__eglewSignalSyncNV)
+
+#define EGLEW_NV_sync EGLEW_GET_VAR(__EGLEW_NV_sync)
+
+#endif /* EGL_NV_sync */
+
+/* --------------------------- EGL_NV_system_time -------------------------- */
+
+#ifndef EGL_NV_system_time
+#define EGL_NV_system_time 1
+
+typedef EGLuint64NV ( * PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) ( void );
+typedef EGLuint64NV ( * PFNEGLGETSYSTEMTIMENVPROC) ( void );
+
+#define eglGetSystemTimeFrequencyNV EGLEW_GET_FUN(__eglewGetSystemTimeFrequencyNV)
+#define eglGetSystemTimeNV EGLEW_GET_FUN(__eglewGetSystemTimeNV)
+
+#define EGLEW_NV_system_time EGLEW_GET_VAR(__EGLEW_NV_system_time)
+
+#endif /* EGL_NV_system_time */
+
+/* --------------------- EGL_TIZEN_image_native_buffer --------------------- */
+
+#ifndef EGL_TIZEN_image_native_buffer
+#define EGL_TIZEN_image_native_buffer 1
+
+#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
+
+#define EGLEW_TIZEN_image_native_buffer EGLEW_GET_VAR(__EGLEW_TIZEN_image_native_buffer)
+
+#endif /* EGL_TIZEN_image_native_buffer */
+
+/* --------------------- EGL_TIZEN_image_native_surface -------------------- */
+
+#ifndef EGL_TIZEN_image_native_surface
+#define EGL_TIZEN_image_native_surface 1
+
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+
+#define EGLEW_TIZEN_image_native_surface EGLEW_GET_VAR(__EGLEW_TIZEN_image_native_surface)
+
+#endif /* EGL_TIZEN_image_native_surface */
+
+/* ------------------------------------------------------------------------- */
+
+#define EGLEW_FUN_EXPORT GLEW_FUN_EXPORT
+#define EGLEW_VAR_EXPORT GLEW_VAR_EXPORT
+
+EGLEW_FUN_EXPORT PFNEGLCHOOSECONFIGPROC __eglewChooseConfig;
+EGLEW_FUN_EXPORT PFNEGLCOPYBUFFERSPROC __eglewCopyBuffers;
+EGLEW_FUN_EXPORT PFNEGLCREATECONTEXTPROC __eglewCreateContext;
+EGLEW_FUN_EXPORT PFNEGLCREATEPBUFFERSURFACEPROC __eglewCreatePbufferSurface;
+EGLEW_FUN_EXPORT PFNEGLCREATEPIXMAPSURFACEPROC __eglewCreatePixmapSurface;
+EGLEW_FUN_EXPORT PFNEGLCREATEWINDOWSURFACEPROC __eglewCreateWindowSurface;
+EGLEW_FUN_EXPORT PFNEGLDESTROYCONTEXTPROC __eglewDestroyContext;
+EGLEW_FUN_EXPORT PFNEGLDESTROYSURFACEPROC __eglewDestroySurface;
+EGLEW_FUN_EXPORT PFNEGLGETCONFIGATTRIBPROC __eglewGetConfigAttrib;
+EGLEW_FUN_EXPORT PFNEGLGETCONFIGSPROC __eglewGetConfigs;
+EGLEW_FUN_EXPORT PFNEGLGETCURRENTDISPLAYPROC __eglewGetCurrentDisplay;
+EGLEW_FUN_EXPORT PFNEGLGETCURRENTSURFACEPROC __eglewGetCurrentSurface;
+EGLEW_FUN_EXPORT PFNEGLGETDISPLAYPROC __eglewGetDisplay;
+EGLEW_FUN_EXPORT PFNEGLGETERRORPROC __eglewGetError;
+EGLEW_FUN_EXPORT PFNEGLINITIALIZEPROC __eglewInitialize;
+EGLEW_FUN_EXPORT PFNEGLMAKECURRENTPROC __eglewMakeCurrent;
+EGLEW_FUN_EXPORT PFNEGLQUERYCONTEXTPROC __eglewQueryContext;
+EGLEW_FUN_EXPORT PFNEGLQUERYSTRINGPROC __eglewQueryString;
+EGLEW_FUN_EXPORT PFNEGLQUERYSURFACEPROC __eglewQuerySurface;
+EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSPROC __eglewSwapBuffers;
+EGLEW_FUN_EXPORT PFNEGLTERMINATEPROC __eglewTerminate;
+EGLEW_FUN_EXPORT PFNEGLWAITGLPROC __eglewWaitGL;
+EGLEW_FUN_EXPORT PFNEGLWAITNATIVEPROC __eglewWaitNative;
+
+EGLEW_FUN_EXPORT PFNEGLBINDTEXIMAGEPROC __eglewBindTexImage;
+EGLEW_FUN_EXPORT PFNEGLRELEASETEXIMAGEPROC __eglewReleaseTexImage;
+EGLEW_FUN_EXPORT PFNEGLSURFACEATTRIBPROC __eglewSurfaceAttrib;
+EGLEW_FUN_EXPORT PFNEGLSWAPINTERVALPROC __eglewSwapInterval;
+
+EGLEW_FUN_EXPORT PFNEGLBINDAPIPROC __eglewBindAPI;
+EGLEW_FUN_EXPORT PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC __eglewCreatePbufferFromClientBuffer;
+EGLEW_FUN_EXPORT PFNEGLQUERYAPIPROC __eglewQueryAPI;
+EGLEW_FUN_EXPORT PFNEGLRELEASETHREADPROC __eglewReleaseThread;
+EGLEW_FUN_EXPORT PFNEGLWAITCLIENTPROC __eglewWaitClient;
+
+EGLEW_FUN_EXPORT PFNEGLGETCURRENTCONTEXTPROC __eglewGetCurrentContext;
+
+EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCPROC __eglewClientWaitSync;
+EGLEW_FUN_EXPORT PFNEGLCREATEIMAGEPROC __eglewCreateImage;
+EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC __eglewCreatePlatformPixmapSurface;
+EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMWINDOWSURFACEPROC __eglewCreatePlatformWindowSurface;
+EGLEW_FUN_EXPORT PFNEGLCREATESYNCPROC __eglewCreateSync;
+EGLEW_FUN_EXPORT PFNEGLDESTROYIMAGEPROC __eglewDestroyImage;
+EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCPROC __eglewDestroySync;
+EGLEW_FUN_EXPORT PFNEGLGETPLATFORMDISPLAYPROC __eglewGetPlatformDisplay;
+EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBPROC __eglewGetSyncAttrib;
+EGLEW_FUN_EXPORT PFNEGLWAITSYNCPROC __eglewWaitSync;
+
+EGLEW_FUN_EXPORT PFNEGLSETBLOBCACHEFUNCSANDROIDPROC __eglewSetBlobCacheFuncsANDROID;
+
+EGLEW_FUN_EXPORT PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC __eglewCreateNativeClientBufferANDROID;
+
+EGLEW_FUN_EXPORT PFNEGLDUPNATIVEFENCEFDANDROIDPROC __eglewDupNativeFenceFDANDROID;
+
+EGLEW_FUN_EXPORT PFNEGLPRESENTATIONTIMEANDROIDPROC __eglewPresentationTimeANDROID;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYSURFACEPOINTERANGLEPROC __eglewQuerySurfacePointerANGLE;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYDEVICESEXTPROC __eglewQueryDevicesEXT;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYDEVICEATTRIBEXTPROC __eglewQueryDeviceAttribEXT;
+EGLEW_FUN_EXPORT PFNEGLQUERYDEVICESTRINGEXTPROC __eglewQueryDeviceStringEXT;
+EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBEXTPROC __eglewQueryDisplayAttribEXT;
+
+EGLEW_FUN_EXPORT PFNEGLGETOUTPUTLAYERSEXTPROC __eglewGetOutputLayersEXT;
+EGLEW_FUN_EXPORT PFNEGLGETOUTPUTPORTSEXTPROC __eglewGetOutputPortsEXT;
+EGLEW_FUN_EXPORT PFNEGLOUTPUTLAYERATTRIBEXTPROC __eglewOutputLayerAttribEXT;
+EGLEW_FUN_EXPORT PFNEGLOUTPUTPORTATTRIBEXTPROC __eglewOutputPortAttribEXT;
+EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC __eglewQueryOutputLayerAttribEXT;
+EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC __eglewQueryOutputLayerStringEXT;
+EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC __eglewQueryOutputPortAttribEXT;
+EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC __eglewQueryOutputPortStringEXT;
+
+EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC __eglewCreatePlatformPixmapSurfaceEXT;
+EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC __eglewCreatePlatformWindowSurfaceEXT;
+EGLEW_FUN_EXPORT PFNEGLGETPLATFORMDISPLAYEXTPROC __eglewGetPlatformDisplayEXT;
+
+EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMEROUTPUTEXTPROC __eglewStreamConsumerOutputEXT;
+
+EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC __eglewSwapBuffersWithDamageEXT;
+
+EGLEW_FUN_EXPORT PFNEGLCREATEPIXMAPSURFACEHIPROC __eglewCreatePixmapSurfaceHI;
+
+EGLEW_FUN_EXPORT PFNEGLCREATESYNC64KHRPROC __eglewCreateSync64KHR;
+
+EGLEW_FUN_EXPORT PFNEGLDEBUGMESSAGECONTROLKHRPROC __eglewDebugMessageControlKHR;
+EGLEW_FUN_EXPORT PFNEGLLABELOBJECTKHRPROC __eglewLabelObjectKHR;
+EGLEW_FUN_EXPORT PFNEGLQUERYDEBUGKHRPROC __eglewQueryDebugKHR;
+
+EGLEW_FUN_EXPORT PFNEGLCREATEIMAGEKHRPROC __eglewCreateImageKHR;
+EGLEW_FUN_EXPORT PFNEGLDESTROYIMAGEKHRPROC __eglewDestroyImageKHR;
+
+EGLEW_FUN_EXPORT PFNEGLLOCKSURFACEKHRPROC __eglewLockSurfaceKHR;
+EGLEW_FUN_EXPORT PFNEGLUNLOCKSURFACEKHRPROC __eglewUnlockSurfaceKHR;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYSURFACE64KHRPROC __eglewQuerySurface64KHR;
+
+EGLEW_FUN_EXPORT PFNEGLSETDAMAGEREGIONKHRPROC __eglewSetDamageRegionKHR;
+
+EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCKHRPROC __eglewClientWaitSyncKHR;
+EGLEW_FUN_EXPORT PFNEGLCREATESYNCKHRPROC __eglewCreateSyncKHR;
+EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCKHRPROC __eglewDestroySyncKHR;
+EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBKHRPROC __eglewGetSyncAttribKHR;
+EGLEW_FUN_EXPORT PFNEGLSIGNALSYNCKHRPROC __eglewSignalSyncKHR;
+
+EGLEW_FUN_EXPORT PFNEGLCREATESTREAMKHRPROC __eglewCreateStreamKHR;
+EGLEW_FUN_EXPORT PFNEGLDESTROYSTREAMKHRPROC __eglewDestroyStreamKHR;
+EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMKHRPROC __eglewQueryStreamKHR;
+EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMU64KHRPROC __eglewQueryStreamu64KHR;
+EGLEW_FUN_EXPORT PFNEGLSTREAMATTRIBKHRPROC __eglewStreamAttribKHR;
+
+EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERACQUIREKHRPROC __eglewStreamConsumerAcquireKHR;
+EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC __eglewStreamConsumerGLTextureExternalKHR;
+EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERRELEASEKHRPROC __eglewStreamConsumerReleaseKHR;
+
+EGLEW_FUN_EXPORT PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC __eglewCreateStreamFromFileDescriptorKHR;
+EGLEW_FUN_EXPORT PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC __eglewGetStreamFileDescriptorKHR;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMTIMEKHRPROC __eglewQueryStreamTimeKHR;
+
+EGLEW_FUN_EXPORT PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC __eglewCreateStreamProducerSurfaceKHR;
+
+EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC __eglewSwapBuffersWithDamageKHR;
+
+EGLEW_FUN_EXPORT PFNEGLWAITSYNCKHRPROC __eglewWaitSyncKHR;
+
+EGLEW_FUN_EXPORT PFNEGLCREATEDRMIMAGEMESAPROC __eglewCreateDRMImageMESA;
+EGLEW_FUN_EXPORT PFNEGLEXPORTDRMIMAGEMESAPROC __eglewExportDRMImageMESA;
+
+EGLEW_FUN_EXPORT PFNEGLEXPORTDMABUFIMAGEMESAPROC __eglewExportDMABUFImageMESA;
+EGLEW_FUN_EXPORT PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC __eglewExportDMABUFImageQueryMESA;
+
+EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSREGIONNOKPROC __eglewSwapBuffersRegionNOK;
+
+EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSREGION2NOKPROC __eglewSwapBuffersRegion2NOK;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEDISPLAYNVPROC __eglewQueryNativeDisplayNV;
+EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEPIXMAPNVPROC __eglewQueryNativePixmapNV;
+EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEWINDOWNVPROC __eglewQueryNativeWindowNV;
+
+EGLEW_FUN_EXPORT PFNEGLPOSTSUBBUFFERNVPROC __eglewPostSubBufferNV;
+
+EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC __eglewStreamConsumerGLTextureExternalAttribsNV;
+
+EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBNVPROC __eglewQueryDisplayAttribNV;
+EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMMETADATANVPROC __eglewQueryStreamMetadataNV;
+EGLEW_FUN_EXPORT PFNEGLSETSTREAMMETADATANVPROC __eglewSetStreamMetadataNV;
+
+EGLEW_FUN_EXPORT PFNEGLCREATESTREAMSYNCNVPROC __eglewCreateStreamSyncNV;
+
+EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCNVPROC __eglewClientWaitSyncNV;
+EGLEW_FUN_EXPORT PFNEGLCREATEFENCESYNCNVPROC __eglewCreateFenceSyncNV;
+EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCNVPROC __eglewDestroySyncNV;
+EGLEW_FUN_EXPORT PFNEGLFENCENVPROC __eglewFenceNV;
+EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBNVPROC __eglewGetSyncAttribNV;
+EGLEW_FUN_EXPORT PFNEGLSIGNALSYNCNVPROC __eglewSignalSyncNV;
+
+EGLEW_FUN_EXPORT PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC __eglewGetSystemTimeFrequencyNV;
+EGLEW_FUN_EXPORT PFNEGLGETSYSTEMTIMENVPROC __eglewGetSystemTimeNV;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_0;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_1;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_2;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_3;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_4;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_5;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_blob_cache;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_create_native_client_buffer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_framebuffer_target;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_front_buffer_auto_refresh;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_image_native_buffer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_native_fence_sync;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_presentation_time;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_recordable;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_d3d_share_handle_client_buffer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_device_d3d;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_query_surface_pointer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_surface_d3d_texture_2d_share_handle;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_window_fixed_size;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_ARM_pixmap_multisample_discard;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_buffer_age;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_client_extensions;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_create_context_robustness;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_base;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_drm;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_enumeration;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_openwf;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_query;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_dma_buf_import;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_multiview_window;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_base;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_drm;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_openwf;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_base;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_device;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_wayland;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_x11;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_protected_content;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_protected_surface;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_stream_consumer_egloutput;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_swap_buffers_with_damage;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_yuv_surface;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_HI_clientpixmap;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_HI_colorformats;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_IMG_context_priority;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_IMG_image_plane_attribs;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_cl_event;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_cl_event2;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_client_get_all_proc_addresses;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_config_attribs;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_create_context;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_create_context_no_error;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_debug;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_fence_sync;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_get_all_proc_addresses;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_colorspace;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_renderbuffer_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_2D_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_3D_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_cubemap_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image_base;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image_pixmap;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface2;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface3;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_mutable_render_buffer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_partial_update;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_android;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_gbm;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_wayland;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_x11;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_reusable_sync;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_consumer_gltexture;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_cross_process_fd;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_fifo;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_producer_aldatalocator;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_producer_eglsurface;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_surfaceless_context;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_swap_buffers_with_damage;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_vg_parent_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_wait_sync;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_drm_image;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_image_dma_buf_export;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_platform_gbm;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_swap_region;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_swap_region2;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_texture_from_pixmap;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_3dvision_surface;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_coverage_sample;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_coverage_sample_resolve;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_cuda_event;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_depth_nonlinear;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_device_cuda;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_native_query;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_post_convert_rounding;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_post_sub_buffer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_robustness_video_memory_purge;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_consumer_gltexture_yuv;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_metadata;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_sync;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_sync;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_system_time;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_TIZEN_image_native_buffer;
+EGLEW_VAR_EXPORT GLboolean __EGLEW_TIZEN_image_native_surface;
+/* ------------------------------------------------------------------------ */
+
+GLEWAPI GLenum GLEWAPIENTRY eglewInit (EGLDisplay display);
+GLEWAPI GLboolean GLEWAPIENTRY eglewIsSupported (const char *name);
+
+#define EGLEW_GET_VAR(x) (*(const GLboolean*)&x)
+#define EGLEW_GET_FUN(x) x
+
+GLEWAPI GLboolean GLEWAPIENTRY eglewGetExtension (const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __eglew_h__ */
diff --git a/extern/glew/include/GL/glew.h b/extern/glew/include/GL/glew.h
index 702265c38b4..fae0c216a96 100644
--- a/extern/glew/include/GL/glew.h
+++ b/extern/glew/include/GL/glew.h
@@ -263,6 +263,9 @@ typedef _W64 int ptrdiff_t;
#define GLEWAPIENTRY
#endif
+#define GLEW_VAR_EXPORT GLEWAPI
+#define GLEW_FUN_EXPORT GLEWAPI
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -2819,6 +2822,15 @@ typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint i
#endif /* GL_AMD_shader_atomic_counter_ops */
+/* ---------------- GL_AMD_shader_explicit_vertex_parameter ---------------- */
+
+#ifndef GL_AMD_shader_explicit_vertex_parameter
+#define GL_AMD_shader_explicit_vertex_parameter 1
+
+#define GLEW_AMD_shader_explicit_vertex_parameter GLEW_GET_VAR(__GLEW_AMD_shader_explicit_vertex_parameter)
+
+#endif /* GL_AMD_shader_explicit_vertex_parameter */
+
/* ---------------------- GL_AMD_shader_stencil_export --------------------- */
#ifndef GL_AMD_shader_stencil_export
@@ -4023,8 +4035,8 @@ typedef void (GLAPIENTRY * PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffe
typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target);
typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
-typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLfloat depth, GLint stencil);
-typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat* value);
typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value);
typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value);
typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
@@ -4663,6 +4675,22 @@ typedef void (GLAPIENTRY * PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint l
#endif /* GL_ARB_get_texture_sub_image */
+/* ---------------------------- GL_ARB_gl_spirv ---------------------------- */
+
+#ifndef GL_ARB_gl_spirv
+#define GL_ARB_gl_spirv 1
+
+#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551
+#define GL_SPIR_V_BINARY_ARB 0x9552
+
+typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue);
+
+#define glSpecializeShaderARB GLEW_GET_FUN(__glewSpecializeShaderARB)
+
+#define GLEW_ARB_gl_spirv GLEW_GET_VAR(__GLEW_ARB_gl_spirv)
+
+#endif /* GL_ARB_gl_spirv */
+
/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */
#ifndef GL_ARB_gpu_shader5
@@ -6600,7 +6628,7 @@ typedef void (GLAPIENTRY * PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, G
#define GL_TIMEOUT_EXPIRED 0x911B
#define GL_CONDITION_SATISFIED 0x911C
#define GL_WAIT_FAILED 0x911D
-#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync);
@@ -7363,7 +7391,7 @@ typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]);
#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
-#define GL_INVALID_INDEX 0xFFFFFFFF
+#define GL_INVALID_INDEX 0xFFFFFFFFu
typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
@@ -8620,6 +8648,18 @@ typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GL
#endif /* GL_ATI_vertex_streams */
+/* ---------------- GL_EGL_NV_robustness_video_memory_purge ---------------- */
+
+#ifndef GL_EGL_NV_robustness_video_memory_purge
+#define GL_EGL_NV_robustness_video_memory_purge 1
+
+#define GL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
+
+#define GLEW_EGL_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_EGL_NV_robustness_video_memory_purge)
+
+#endif /* GL_EGL_NV_robustness_video_memory_purge */
+
/* --------------------------- GL_EXT_422_pixels --------------------------- */
#ifndef GL_EXT_422_pixels
@@ -11597,6 +11637,26 @@ typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight);
#endif /* GL_EXT_vertex_weighting */
+/* ------------------------ GL_EXT_window_rectangles ----------------------- */
+
+#ifndef GL_EXT_window_rectangles
+#define GL_EXT_window_rectangles 1
+
+#define GL_INCLUSIVE_EXT 0x8F10
+#define GL_EXCLUSIVE_EXT 0x8F11
+#define GL_WINDOW_RECTANGLE_EXT 0x8F12
+#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13
+#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14
+#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15
+
+typedef void (GLAPIENTRY * PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint box[]);
+
+#define glWindowRectanglesEXT GLEW_GET_FUN(__glewWindowRectanglesEXT)
+
+#define GLEW_EXT_window_rectangles GLEW_GET_VAR(__GLEW_EXT_window_rectangles)
+
+#endif /* GL_EXT_window_rectangles */
+
/* ------------------------- GL_EXT_x11_sync_object ------------------------ */
#ifndef GL_EXT_x11_sync_object
@@ -11821,6 +11881,17 @@ typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum ty
#endif /* GL_INGR_interlace_read */
+/* ------------------ GL_INTEL_conservative_rasterization ------------------ */
+
+#ifndef GL_INTEL_conservative_rasterization
+#define GL_INTEL_conservative_rasterization 1
+
+#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
+
+#define GLEW_INTEL_conservative_rasterization GLEW_GET_VAR(__GLEW_INTEL_conservative_rasterization)
+
+#endif /* GL_INTEL_conservative_rasterization */
+
/* ------------------- GL_INTEL_fragment_shader_ordering ------------------- */
#ifndef GL_INTEL_fragment_shader_ordering
@@ -12202,6 +12273,15 @@ typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei widt
#endif /* GL_KHR_texture_compression_astc_ldr */
+/* --------------- GL_KHR_texture_compression_astc_sliced_3d --------------- */
+
+#ifndef GL_KHR_texture_compression_astc_sliced_3d
+#define GL_KHR_texture_compression_astc_sliced_3d 1
+
+#define GLEW_KHR_texture_compression_astc_sliced_3d GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_sliced_3d)
+
+#endif /* GL_KHR_texture_compression_astc_sliced_3d */
+
/* -------------------------- GL_KTX_buffer_region ------------------------- */
#ifndef GL_KTX_buffer_region
@@ -12268,6 +12348,15 @@ typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void);
#endif /* GL_MESA_resize_buffers */
+/* -------------------- GL_MESA_shader_integer_functions ------------------- */
+
+#ifndef GL_MESA_shader_integer_functions
+#define GL_MESA_shader_integer_functions 1
+
+#define GLEW_MESA_shader_integer_functions GLEW_GET_VAR(__GLEW_MESA_shader_integer_functions)
+
+#endif /* GL_MESA_shader_integer_functions */
+
/* --------------------------- GL_MESA_window_pos -------------------------- */
#ifndef GL_MESA_window_pos
@@ -12340,6 +12429,15 @@ typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p);
#endif /* GL_MESA_ycbcr_texture */
+/* ----------- GL_NVX_blend_equation_advanced_multi_draw_buffers ----------- */
+
+#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers
+#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1
+
+#define GLEW_NVX_blend_equation_advanced_multi_draw_buffers GLEW_GET_VAR(__GLEW_NVX_blend_equation_advanced_multi_draw_buffers)
+
+#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */
+
/* ----------------------- GL_NVX_conditional_render ----------------------- */
#ifndef GL_NVX_conditional_render
@@ -12370,6 +12468,26 @@ typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVXPROC) (void);
#endif /* GL_NVX_gpu_memory_info */
+/* ---------------------- GL_NVX_linked_gpu_multicast ---------------------- */
+
+#ifndef GL_NVX_linked_gpu_multicast
+#define GL_NVX_linked_gpu_multicast 1
+
+#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800
+#define GL_MAX_LGPU_GPUS_NVX 0x92BA
+
+typedef void (GLAPIENTRY * PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAPIENTRY * PFNGLLGPUINTERLOCKNVXPROC) (void);
+typedef void (GLAPIENTRY * PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
+
+#define glLGPUCopyImageSubDataNVX GLEW_GET_FUN(__glewLGPUCopyImageSubDataNVX)
+#define glLGPUInterlockNVX GLEW_GET_FUN(__glewLGPUInterlockNVX)
+#define glLGPUNamedBufferSubDataNVX GLEW_GET_FUN(__glewLGPUNamedBufferSubDataNVX)
+
+#define GLEW_NVX_linked_gpu_multicast GLEW_GET_VAR(__GLEW_NVX_linked_gpu_multicast)
+
+#endif /* GL_NVX_linked_gpu_multicast */
+
/* ------------------- GL_NV_bindless_multi_draw_indirect ------------------ */
#ifndef GL_NV_bindless_multi_draw_indirect
@@ -12521,6 +12639,88 @@ typedef void (GLAPIENTRY * PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint valu
#endif /* GL_NV_blend_square */
+/* ----------------------- GL_NV_clip_space_w_scaling ---------------------- */
+
+#ifndef GL_NV_clip_space_w_scaling
+#define GL_NV_clip_space_w_scaling 1
+
+#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C
+#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D
+#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E
+
+typedef void (GLAPIENTRY * PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff);
+
+#define glViewportPositionWScaleNV GLEW_GET_FUN(__glewViewportPositionWScaleNV)
+
+#define GLEW_NV_clip_space_w_scaling GLEW_GET_VAR(__GLEW_NV_clip_space_w_scaling)
+
+#endif /* GL_NV_clip_space_w_scaling */
+
+/* --------------------------- GL_NV_command_list -------------------------- */
+
+#ifndef GL_NV_command_list
+#define GL_NV_command_list 1
+
+#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000
+#define GL_NOP_COMMAND_NV 0x0001
+#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002
+#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003
+#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004
+#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005
+#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006
+#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007
+#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008
+#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009
+#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000a
+#define GL_BLEND_COLOR_COMMAND_NV 0x000b
+#define GL_STENCIL_REF_COMMAND_NV 0x000c
+#define GL_LINE_WIDTH_COMMAND_NV 0x000d
+#define GL_POLYGON_OFFSET_COMMAND_NV 0x000e
+#define GL_ALPHA_REF_COMMAND_NV 0x000f
+#define GL_VIEWPORT_COMMAND_NV 0x0010
+#define GL_SCISSOR_COMMAND_NV 0x0011
+#define GL_FRONT_FACE_COMMAND_NV 0x0012
+
+typedef void (GLAPIENTRY * PFNGLCALLCOMMANDLISTNVPROC) (GLuint list);
+typedef void (GLAPIENTRY * PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments);
+typedef void (GLAPIENTRY * PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list);
+typedef void (GLAPIENTRY * PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint* lists);
+typedef void (GLAPIENTRY * PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint* states);
+typedef void (GLAPIENTRY * PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint* lists);
+typedef void (GLAPIENTRY * PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint* states);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64* indirects, const GLsizei* sizes, GLuint count);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, GLuint count);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count);
+typedef GLuint (GLAPIENTRY * PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size);
+typedef GLushort (GLAPIENTRY * PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype);
+typedef GLboolean (GLAPIENTRY * PFNGLISCOMMANDLISTNVPROC) (GLuint list);
+typedef GLboolean (GLAPIENTRY * PFNGLISSTATENVPROC) (GLuint state);
+typedef void (GLAPIENTRY * PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void** indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count);
+typedef void (GLAPIENTRY * PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode);
+
+#define glCallCommandListNV GLEW_GET_FUN(__glewCallCommandListNV)
+#define glCommandListSegmentsNV GLEW_GET_FUN(__glewCommandListSegmentsNV)
+#define glCompileCommandListNV GLEW_GET_FUN(__glewCompileCommandListNV)
+#define glCreateCommandListsNV GLEW_GET_FUN(__glewCreateCommandListsNV)
+#define glCreateStatesNV GLEW_GET_FUN(__glewCreateStatesNV)
+#define glDeleteCommandListsNV GLEW_GET_FUN(__glewDeleteCommandListsNV)
+#define glDeleteStatesNV GLEW_GET_FUN(__glewDeleteStatesNV)
+#define glDrawCommandsAddressNV GLEW_GET_FUN(__glewDrawCommandsAddressNV)
+#define glDrawCommandsNV GLEW_GET_FUN(__glewDrawCommandsNV)
+#define glDrawCommandsStatesAddressNV GLEW_GET_FUN(__glewDrawCommandsStatesAddressNV)
+#define glDrawCommandsStatesNV GLEW_GET_FUN(__glewDrawCommandsStatesNV)
+#define glGetCommandHeaderNV GLEW_GET_FUN(__glewGetCommandHeaderNV)
+#define glGetStageIndexNV GLEW_GET_FUN(__glewGetStageIndexNV)
+#define glIsCommandListNV GLEW_GET_FUN(__glewIsCommandListNV)
+#define glIsStateNV GLEW_GET_FUN(__glewIsStateNV)
+#define glListDrawCommandsStatesClientNV GLEW_GET_FUN(__glewListDrawCommandsStatesClientNV)
+#define glStateCaptureNV GLEW_GET_FUN(__glewStateCaptureNV)
+
+#define GLEW_NV_command_list GLEW_GET_VAR(__GLEW_NV_command_list)
+
+#endif /* GL_NV_command_list */
+
/* ------------------------- GL_NV_compute_program5 ------------------------ */
#ifndef GL_NV_compute_program5
@@ -12588,6 +12788,23 @@ typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pnam
#endif /* GL_NV_conservative_raster_dilate */
+/* -------------- GL_NV_conservative_raster_pre_snap_triangles ------------- */
+
+#ifndef GL_NV_conservative_raster_pre_snap_triangles
+#define GL_NV_conservative_raster_pre_snap_triangles 1
+
+#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D
+#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F
+
+typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param);
+
+#define glConservativeRasterParameteriNV GLEW_GET_FUN(__glewConservativeRasterParameteriNV)
+
+#define GLEW_NV_conservative_raster_pre_snap_triangles GLEW_GET_VAR(__GLEW_NV_conservative_raster_pre_snap_triangles)
+
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+
/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */
#ifndef GL_NV_copy_depth_to_color
@@ -12686,6 +12903,29 @@ typedef void (GLAPIENTRY * PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampl
#endif /* GL_NV_draw_texture */
+/* ------------------------ GL_NV_draw_vulkan_image ------------------------ */
+
+#ifndef GL_NV_draw_vulkan_image
+#define GL_NV_draw_vulkan_image 1
+
+typedef void (APIENTRY *GLVULKANPROCNV)(void);
+
+typedef void (GLAPIENTRY * PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+typedef GLVULKANPROCNV (GLAPIENTRY * PFNGLGETVKPROCADDRNVPROC) (const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence);
+typedef void (GLAPIENTRY * PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+typedef void (GLAPIENTRY * PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+
+#define glDrawVkImageNV GLEW_GET_FUN(__glewDrawVkImageNV)
+#define glGetVkProcAddrNV GLEW_GET_FUN(__glewGetVkProcAddrNV)
+#define glSignalVkFenceNV GLEW_GET_FUN(__glewSignalVkFenceNV)
+#define glSignalVkSemaphoreNV GLEW_GET_FUN(__glewSignalVkSemaphoreNV)
+#define glWaitVkSemaphoreNV GLEW_GET_FUN(__glewWaitVkSemaphoreNV)
+
+#define GLEW_NV_draw_vulkan_image GLEW_GET_VAR(__GLEW_NV_draw_vulkan_image)
+
+#endif /* GL_NV_draw_vulkan_image */
+
/* ---------------------------- GL_NV_evaluators --------------------------- */
#ifndef GL_NV_evaluators
@@ -13011,6 +13251,47 @@ typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint
#endif /* GL_NV_geometry_shader_passthrough */
+/* -------------------------- GL_NV_gpu_multicast -------------------------- */
+
+#ifndef GL_NV_gpu_multicast
+#define GL_NV_gpu_multicast 1
+
+#define GL_PER_GPU_STORAGE_BIT_NV 0x0800
+#define GL_MULTICAST_GPUS_NV 0x92BA
+#define GL_PER_GPU_STORAGE_NV 0x9548
+#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549
+#define GL_RENDER_GPU_MASK_NV 0x9558
+
+typedef void (GLAPIENTRY * PFNGLMULTICASTBARRIERNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GLAPIENTRY * PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+typedef void (GLAPIENTRY * PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask);
+typedef void (GLAPIENTRY * PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask);
+
+#define glMulticastBarrierNV GLEW_GET_FUN(__glewMulticastBarrierNV)
+#define glMulticastBlitFramebufferNV GLEW_GET_FUN(__glewMulticastBlitFramebufferNV)
+#define glMulticastBufferSubDataNV GLEW_GET_FUN(__glewMulticastBufferSubDataNV)
+#define glMulticastCopyBufferSubDataNV GLEW_GET_FUN(__glewMulticastCopyBufferSubDataNV)
+#define glMulticastCopyImageSubDataNV GLEW_GET_FUN(__glewMulticastCopyImageSubDataNV)
+#define glMulticastFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewMulticastFramebufferSampleLocationsfvNV)
+#define glMulticastGetQueryObjecti64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjecti64vNV)
+#define glMulticastGetQueryObjectivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectivNV)
+#define glMulticastGetQueryObjectui64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjectui64vNV)
+#define glMulticastGetQueryObjectuivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectuivNV)
+#define glMulticastWaitSyncNV GLEW_GET_FUN(__glewMulticastWaitSyncNV)
+#define glRenderGpuMaskNV GLEW_GET_FUN(__glewRenderGpuMaskNV)
+
+#define GLEW_NV_gpu_multicast GLEW_GET_VAR(__GLEW_NV_gpu_multicast)
+
+#endif /* GL_NV_gpu_multicast */
+
/* --------------------------- GL_NV_gpu_program4 -------------------------- */
#ifndef GL_NV_gpu_program4
@@ -13925,6 +14206,18 @@ typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage
#endif /* GL_NV_register_combiners2 */
+/* ------------------ GL_NV_robustness_video_memory_purge ------------------ */
+
+#ifndef GL_NV_robustness_video_memory_purge
+#define GL_NV_robustness_video_memory_purge 1
+
+#define GL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
+
+#define GLEW_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_NV_robustness_video_memory_purge)
+
+#endif /* GL_NV_robustness_video_memory_purge */
+
/* ------------------------- GL_NV_sample_locations ------------------------ */
#ifndef GL_NV_sample_locations
@@ -13976,6 +14269,15 @@ typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint
#endif /* GL_NV_shader_atomic_float */
+/* ---------------------- GL_NV_shader_atomic_float64 ---------------------- */
+
+#ifndef GL_NV_shader_atomic_float64
+#define GL_NV_shader_atomic_float64 1
+
+#define GLEW_NV_shader_atomic_float64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_float64)
+
+#endif /* GL_NV_shader_atomic_float64 */
+
/* -------------------- GL_NV_shader_atomic_fp16_vector -------------------- */
#ifndef GL_NV_shader_atomic_fp16_vector
@@ -14066,6 +14368,15 @@ typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei cou
#endif /* GL_NV_shader_thread_shuffle */
+/* ---------------------- GL_NV_stereo_view_rendering ---------------------- */
+
+#ifndef GL_NV_stereo_view_rendering
+#define GL_NV_stereo_view_rendering 1
+
+#define GLEW_NV_stereo_view_rendering GLEW_GET_VAR(__GLEW_NV_stereo_view_rendering)
+
+#endif /* GL_NV_stereo_view_rendering */
+
/* ---------------------- GL_NV_tessellation_program5 ---------------------- */
#ifndef GL_NV_tessellation_program5
@@ -14976,6 +15287,32 @@ typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint vid
#endif /* GL_NV_viewport_array2 */
+/* ------------------------- GL_NV_viewport_swizzle ------------------------ */
+
+#ifndef GL_NV_viewport_swizzle
+#define GL_NV_viewport_swizzle 1
+
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357
+#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358
+#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359
+#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A
+#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B
+
+typedef void (GLAPIENTRY * PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);
+
+#define glViewportSwizzleNV GLEW_GET_FUN(__glewViewportSwizzleNV)
+
+#define GLEW_NV_viewport_swizzle GLEW_GET_VAR(__GLEW_NV_viewport_swizzle)
+
+#endif /* GL_NV_viewport_swizzle */
+
/* ------------------------ GL_OES_byte_coordinates ------------------------ */
#ifndef GL_OES_byte_coordinates
@@ -15733,10 +16070,6 @@ typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void);
#ifndef GL_SGIX_fog_texture
#define GL_SGIX_fog_texture 1
-#define GL_FOG_PATCHY_FACTOR_SGIX 0
-#define GL_FRAGMENT_FOG_SGIX 0
-#define GL_TEXTURE_FOG_SGIX 0
-
typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname);
#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX)
@@ -16406,22 +16739,7 @@ typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsiz
/* ------------------------------------------------------------------------- */
-#if defined(GLEW_MX) && defined(_WIN32)
-#define GLEW_FUN_EXPORT
-#else
-#define GLEW_FUN_EXPORT GLEWAPI
-#endif /* GLEW_MX */
-
-#if defined(GLEW_MX)
-#define GLEW_VAR_EXPORT
-#else
-#define GLEW_VAR_EXPORT GLEWAPI
-#endif /* GLEW_MX */
-#if defined(GLEW_MX) && defined(_WIN32)
-struct GLEWContextStruct
-{
-#endif /* GLEW_MX */
GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D;
GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements;
@@ -17047,6 +17365,8 @@ GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri;
GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage;
GLEW_FUN_EXPORT PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage;
+GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB;
+
GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv;
GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d;
GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv;
@@ -18323,6 +18643,8 @@ GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT;
GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT;
GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT;
+GLEW_FUN_EXPORT PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT;
+
GLEW_FUN_EXPORT PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT;
GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY;
@@ -18425,6 +18747,10 @@ GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA;
GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX;
GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX;
+GLEW_FUN_EXPORT PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX;
+GLEW_FUN_EXPORT PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX;
+GLEW_FUN_EXPORT PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX;
+
GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV;
GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV;
@@ -18448,6 +18774,26 @@ GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV;
GLEW_FUN_EXPORT PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV;
GLEW_FUN_EXPORT PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV;
+GLEW_FUN_EXPORT PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV;
+
+GLEW_FUN_EXPORT PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV;
+GLEW_FUN_EXPORT PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV;
+GLEW_FUN_EXPORT PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV;
+GLEW_FUN_EXPORT PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV;
+GLEW_FUN_EXPORT PFNGLCREATESTATESNVPROC __glewCreateStatesNV;
+GLEW_FUN_EXPORT PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV;
+GLEW_FUN_EXPORT PFNGLDELETESTATESNVPROC __glewDeleteStatesNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV;
+GLEW_FUN_EXPORT PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV;
+GLEW_FUN_EXPORT PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV;
+GLEW_FUN_EXPORT PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV;
+GLEW_FUN_EXPORT PFNGLISSTATENVPROC __glewIsStateNV;
+GLEW_FUN_EXPORT PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV;
+GLEW_FUN_EXPORT PFNGLSTATECAPTURENVPROC __glewStateCaptureNV;
+
GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV;
GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV;
@@ -18455,6 +18801,8 @@ GLEW_FUN_EXPORT PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV;
GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV;
+GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV;
+
GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV;
GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV;
@@ -18463,6 +18811,12 @@ GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV;
GLEW_FUN_EXPORT PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV;
+GLEW_FUN_EXPORT PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV;
+GLEW_FUN_EXPORT PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV;
+GLEW_FUN_EXPORT PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV;
+GLEW_FUN_EXPORT PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV;
+GLEW_FUN_EXPORT PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV;
+
GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV;
GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV;
GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV;
@@ -18498,6 +18852,19 @@ GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbu
GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV;
+GLEW_FUN_EXPORT PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV;
+
GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV;
GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV;
GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV;
@@ -18876,6 +19243,8 @@ GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStrea
GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV;
GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV;
+GLEW_FUN_EXPORT PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV;
+
GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES;
GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES;
GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES;
@@ -19071,12 +19440,6 @@ GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN;
GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN;
GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN;
-
-#if defined(GLEW_MX) && !defined(_WIN32)
-struct GLEWContextStruct
-{
-#endif /* GLEW_MX */
-
GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1;
GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2;
GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2_1;
@@ -19115,6 +19478,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_AMD_query_buffer_object;
GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions;
GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture;
GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_atomic_counter_ops;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_explicit_vertex_parameter;
GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export;
GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_value_export;
GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_trinary_minmax;
@@ -19204,6 +19568,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB;
GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4;
GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_program_binary;
GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_texture_sub_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gl_spirv;
GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5;
GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64;
GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_int64;
@@ -19344,6 +19709,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once;
GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object;
GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object;
GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams;
+GLEW_VAR_EXPORT GLboolean __GLEW_EGL_NV_robustness_video_memory_purge;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr;
@@ -19451,6 +19817,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_window_rectangles;
GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object;
GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator;
GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker;
@@ -19466,6 +19833,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat;
GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists;
GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp;
GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_conservative_rasterization;
GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_fragment_shader_ordering;
GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_framebuffer_CMAA;
GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_map_texture;
@@ -19481,24 +19849,31 @@ GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robust_buffer_access_behavior;
GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robustness;
GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_hdr;
GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_ldr;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d;
GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region;
GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack;
GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert;
GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_shader_integer_functions;
GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos;
GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers;
GLEW_VAR_EXPORT GLboolean __GLEW_NVX_conditional_render;
GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_linked_gpu_multicast;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect_count;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_texture;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced_coherent;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_clip_space_w_scaling;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_command_list;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_program5;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_dilate;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_deep_texture3D;
@@ -19506,6 +19881,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_vulkan_image;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence;
@@ -19523,6 +19899,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader_passthrough;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_multicast;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5_mem_extended;
@@ -19545,16 +19922,19 @@ GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_robustness_video_memory_purge;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_locations;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_mask_override_coverage;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_counters;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float64;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_fp16_vector;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_int64;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_storage_buffer_object;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_group;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_shuffle;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_stereo_view_rendering;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection;
@@ -19583,6 +19963,7 @@ GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_video_capture;
GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_swizzle;
GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates;
GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture;
GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format;
@@ -19663,11 +20044,6 @@ GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex;
GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading;
GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog;
GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint;
-
-#ifdef GLEW_MX
-}; /* GLEWContextStruct */
-#endif /* GLEW_MX */
-
/* ------------------------------------------------------------------------- */
/* error codes */
@@ -19688,40 +20064,24 @@ GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint;
/* GLEW version info */
/*
-VERSION 1.13.0
-VERSION_MAJOR 1
-VERSION_MINOR 13
+VERSION 2.0.0
+VERSION_MAJOR 2
+VERSION_MINOR 0
VERSION_MICRO 0
*/
/* API */
-#ifdef GLEW_MX
-
-typedef struct GLEWContextStruct GLEWContext;
-GLEWAPI GLenum GLEWAPIENTRY glewContextInit (GLEWContext *ctx);
-GLEWAPI GLboolean GLEWAPIENTRY glewContextIsSupported (const GLEWContext *ctx, const char *name);
-
-#define glewInit() glewContextInit(glewGetContext())
-#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x)
-#define glewIsExtensionSupported(x) glewIsSupported(x)
-
-#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x))
-#ifdef _WIN32
-# define GLEW_GET_FUN(x) glewGetContext()->x
-#else
-# define GLEW_GET_FUN(x) x
-#endif
-
-#else /* GLEW_MX */
-
GLEWAPI GLenum GLEWAPIENTRY glewInit (void);
GLEWAPI GLboolean GLEWAPIENTRY glewIsSupported (const char *name);
#define glewIsExtensionSupported(x) glewIsSupported(x)
+#ifndef GLEW_GET_VAR
#define GLEW_GET_VAR(x) (*(const GLboolean*)&x)
-#define GLEW_GET_FUN(x) x
+#endif
-#endif /* GLEW_MX */
+#ifndef GLEW_GET_FUN
+#define GLEW_GET_FUN(x) x
+#endif
GLEWAPI GLboolean glewExperimental;
GLEWAPI GLboolean GLEWAPIENTRY glewGetExtension (const char *name);
diff --git a/extern/glew/include/GL/glxew.h b/extern/glew/include/GL/glxew.h
index d803d260b37..1e2596d6627 100644
--- a/extern/glew/include/GL/glxew.h
+++ b/extern/glew/include/GL/glxew.h
@@ -670,6 +670,17 @@ typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context
#endif /* GLX_EXT_import_context */
+/* ---------------------------- GLX_EXT_libglvnd --------------------------- */
+
+#ifndef GLX_EXT_libglvnd
+#define GLX_EXT_libglvnd 1
+
+#define GLX_VENDOR_NAMES_EXT 0x20F6
+
+#define GLXEW_EXT_libglvnd GLXEW_GET_VAR(__GLXEW_EXT_libglvnd)
+
+#endif /* GLX_EXT_libglvnd */
+
/* -------------------------- GLX_EXT_scene_marker ------------------------- */
#ifndef GLX_EXT_scene_marker
@@ -1015,6 +1026,17 @@ typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int
#endif /* GLX_NV_present_video */
+/* ------------------ GLX_NV_robustness_video_memory_purge ----------------- */
+
+#ifndef GLX_NV_robustness_video_memory_purge
+#define GLX_NV_robustness_video_memory_purge 1
+
+#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
+
+#define GLXEW_NV_robustness_video_memory_purge GLXEW_GET_VAR(__GLXEW_NV_robustness_video_memory_purge)
+
+#endif /* GLX_NV_robustness_video_memory_purge */
+
/* --------------------------- GLX_NV_swap_group --------------------------- */
#ifndef GLX_NV_swap_group
@@ -1500,13 +1522,8 @@ typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window,
/* ------------------------------------------------------------------------- */
-#ifdef GLEW_MX
-#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT
-#define GLXEW_VAR_EXPORT
-#else
#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT
#define GLXEW_VAR_EXPORT GLEW_VAR_EXPORT
-#endif /* GLEW_MX */
GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay;
@@ -1658,12 +1675,6 @@ GLXEW_FUN_EXPORT PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN;
GLXEW_FUN_EXPORT PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN;
GLXEW_FUN_EXPORT PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN;
-
-#if defined(GLEW_MX)
-struct GLXEWContextStruct
-{
-#endif /* GLEW_MX */
-
GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0;
GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1;
GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;
@@ -1690,6 +1701,7 @@ GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es_profile;
GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float;
GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB;
GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_import_context;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_libglvnd;
GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_scene_marker;
GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_stereo_tree;
GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control;
@@ -1711,6 +1723,7 @@ GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_delay_before_swap;
GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_float_buffer;
GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multisample_coverage;
GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_present_video;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_robustness_video_memory_purge;
GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_swap_group;
GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_vertex_array_range;
GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_capture;
@@ -1734,34 +1747,18 @@ GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_swap_control;
GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_video_sync;
GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_get_transparent_index;
GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_video_resize;
-
-#ifdef GLEW_MX
-}; /* GLXEWContextStruct */
-#endif /* GLEW_MX */
-
/* ------------------------------------------------------------------------ */
-#ifdef GLEW_MX
-
-typedef struct GLXEWContextStruct GLXEWContext;
-GLEWAPI GLenum GLEWAPIENTRY glxewContextInit (GLXEWContext *ctx);
-GLEWAPI GLboolean GLEWAPIENTRY glxewContextIsSupported (const GLXEWContext *ctx, const char *name);
-
-#define glxewInit() glxewContextInit(glxewGetContext())
-#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x)
-
-#define GLXEW_GET_VAR(x) (*(const GLboolean*)&(glxewGetContext()->x))
-#define GLXEW_GET_FUN(x) x
-
-#else /* GLEW_MX */
-
GLEWAPI GLenum GLEWAPIENTRY glxewInit ();
GLEWAPI GLboolean GLEWAPIENTRY glxewIsSupported (const char *name);
+#ifndef GLXEW_GET_VAR
#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x)
-#define GLXEW_GET_FUN(x) x
+#endif
-#endif /* GLEW_MX */
+#ifndef GLXEW_GET_FUN
+#define GLXEW_GET_FUN(x) x
+#endif
GLEWAPI GLboolean GLEWAPIENTRY glxewGetExtension (const char *name);
diff --git a/extern/glew/include/GL/wglew.h b/extern/glew/include/GL/wglew.h
index 23e4d3fbaba..71ee0f30132 100644
--- a/extern/glew/include/GL/wglew.h
+++ b/extern/glew/include/GL/wglew.h
@@ -1197,18 +1197,8 @@ typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT6
/* ------------------------------------------------------------------------- */
-#ifdef GLEW_MX
-#define WGLEW_FUN_EXPORT
-#define WGLEW_VAR_EXPORT
-#else
#define WGLEW_FUN_EXPORT GLEW_FUN_EXPORT
#define WGLEW_VAR_EXPORT GLEW_VAR_EXPORT
-#endif /* GLEW_MX */
-
-#ifdef GLEW_MX
-struct WGLEWContextStruct
-{
-#endif /* GLEW_MX */
WGLEW_FUN_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL;
@@ -1413,34 +1403,18 @@ WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_vertex_array_range;
WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_capture;
WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_output;
WGLEW_VAR_EXPORT GLboolean __WGLEW_OML_sync_control;
-
-#ifdef GLEW_MX
-}; /* WGLEWContextStruct */
-#endif /* GLEW_MX */
-
/* ------------------------------------------------------------------------- */
-#ifdef GLEW_MX
-
-typedef struct WGLEWContextStruct WGLEWContext;
-GLEWAPI GLenum GLEWAPIENTRY wglewContextInit (WGLEWContext *ctx);
-GLEWAPI GLboolean GLEWAPIENTRY wglewContextIsSupported (const WGLEWContext *ctx, const char *name);
-
-#define wglewInit() wglewContextInit(wglewGetContext())
-#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x)
-
-#define WGLEW_GET_VAR(x) (*(const GLboolean*)&(wglewGetContext()->x))
-#define WGLEW_GET_FUN(x) wglewGetContext()->x
-
-#else /* GLEW_MX */
-
GLEWAPI GLenum GLEWAPIENTRY wglewInit ();
GLEWAPI GLboolean GLEWAPIENTRY wglewIsSupported (const char *name);
+#ifndef WGLEW_GET_VAR
#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x)
-#define WGLEW_GET_FUN(x) x
+#endif
-#endif /* GLEW_MX */
+#ifndef WGLEW_GET_FUN
+#define WGLEW_GET_FUN(x) x
+#endif
GLEWAPI GLboolean GLEWAPIENTRY wglewGetExtension (const char *name);
diff --git a/extern/glew/src/glew.c b/extern/glew/src/glew.c
index 0ed5520dae2..6c93c07e46f 100644
--- a/extern/glew/src/glew.c
+++ b/extern/glew/src/glew.c
@@ -32,7 +32,12 @@
#include <GL/glew.h>
-#if defined(_WIN32)
+#if defined(GLEW_OSMESA)
+# define GLAPI extern
+# include <GL/osmesa.h>
+#elif defined(GLEW_EGL)
+# include <GL/eglew.h>
+#elif defined(_WIN32)
# include <GL/wglew.h>
#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
# include <GL/glxew.h>
@@ -40,36 +45,8 @@
#include <stddef.h> /* For size_t */
-/*
- * Define glewGetContext and related helper macros.
- */
-#ifdef GLEW_MX
-# define glewGetContext() ctx
-# ifdef _WIN32
-# define GLEW_CONTEXT_ARG_DEF_INIT GLEWContext* ctx
-# define GLEW_CONTEXT_ARG_VAR_INIT ctx
-# define wglewGetContext() ctx
-# define WGLEW_CONTEXT_ARG_DEF_INIT WGLEWContext* ctx
-# define WGLEW_CONTEXT_ARG_DEF_LIST WGLEWContext* ctx
-# else /* _WIN32 */
-# define GLEW_CONTEXT_ARG_DEF_INIT void
-# define GLEW_CONTEXT_ARG_VAR_INIT
-# define glxewGetContext() ctx
-# define GLXEW_CONTEXT_ARG_DEF_INIT void
-# define GLXEW_CONTEXT_ARG_DEF_LIST GLXEWContext* ctx
-# endif /* _WIN32 */
-# define GLEW_CONTEXT_ARG_DEF_LIST GLEWContext* ctx
-#else /* GLEW_MX */
-# define GLEW_CONTEXT_ARG_DEF_INIT void
-# define GLEW_CONTEXT_ARG_VAR_INIT
-# define GLEW_CONTEXT_ARG_DEF_LIST void
-# define WGLEW_CONTEXT_ARG_DEF_INIT void
-# define WGLEW_CONTEXT_ARG_DEF_LIST void
-# define GLXEW_CONTEXT_ARG_DEF_INIT void
-# define GLXEW_CONTEXT_ARG_DEF_LIST void
-#endif /* GLEW_MX */
-
-#if defined(GLEW_REGAL)
+#if defined(GLEW_EGL)
+#elif defined(GLEW_REGAL)
/* In GLEW_REGAL mode we call direcly into the linked
libRegal.so glGetProcAddressREGAL for looking up
@@ -121,7 +98,7 @@ void* NSGLGetProcAddress (const GLubyte *name)
{
static void* image = NULL;
void* addr;
- if (NULL == image)
+ if (NULL == image)
{
image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
}
@@ -170,7 +147,11 @@ void* NSGLGetProcAddress (const GLubyte *name)
* Define glewGetProcAddress.
*/
#if defined(GLEW_REGAL)
-# define glewGetProcAddress(name) regalGetProcAddress((const GLchar *) name)
+# define glewGetProcAddress(name) regalGetProcAddress((const GLchar *)name)
+#elif defined(GLEW_OSMESA)
+# define glewGetProcAddress(name) OSMesaGetProcAddress((const char *)name)
+#elif defined(GLEW_EGL)
+# define glewGetProcAddress(name) eglGetProcAddress((const char *)name)
#elif defined(_WIN32)
# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name)
#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX)
@@ -190,34 +171,28 @@ void* NSGLGetProcAddress (const GLubyte *name)
*/
#undef GLEW_GET_VAR
-#ifdef GLEW_MX
-# define GLEW_GET_VAR(x) (glewGetContext()->x)
-#else /* GLEW_MX */
# define GLEW_GET_VAR(x) (x)
-#endif /* GLEW_MX */
#ifdef WGLEW_GET_VAR
# undef WGLEW_GET_VAR
-# ifdef GLEW_MX
-# define WGLEW_GET_VAR(x) (wglewGetContext()->x)
-# else /* GLEW_MX */
-# define WGLEW_GET_VAR(x) (x)
-# endif /* GLEW_MX */
+# define WGLEW_GET_VAR(x) (x)
#endif /* WGLEW_GET_VAR */
#ifdef GLXEW_GET_VAR
# undef GLXEW_GET_VAR
-# ifdef GLEW_MX
-# define GLXEW_GET_VAR(x) (glxewGetContext()->x)
-# else /* GLEW_MX */
-# define GLXEW_GET_VAR(x) (x)
-# endif /* GLEW_MX */
+# define GLXEW_GET_VAR(x) (x)
#endif /* GLXEW_GET_VAR */
+#ifdef EGLEW_GET_VAR
+# undef EGLEW_GET_VAR
+# define EGLEW_GET_VAR(x) (x)
+#endif /* EGLEW_GET_VAR */
+
/*
* GLEW, just like OpenGL or GLU, does not rely on the standard C library.
* These functions implement the functionality required in this file.
*/
+
static GLuint _glewStrLen (const GLubyte* s)
{
GLuint i=0;
@@ -231,9 +206,20 @@ static GLuint _glewStrCLen (const GLubyte* s, GLubyte c)
GLuint i=0;
if (s == NULL) return 0;
while (s[i] != '\0' && s[i] != c) i++;
- return (s[i] == '\0' || s[i] == c) ? i : 0;
+ return i;
+}
+
+static GLuint _glewStrCopy(char *d, const char *s, char c)
+{
+ GLuint i=0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0' && s[i] != c) { d[i] = s[i]; i++; }
+ d[i] = '\0';
+ return i;
}
+#if !defined(GLEW_OSMESA)
+#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n)
{
GLuint i=0;
@@ -242,6 +228,8 @@ static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n)
while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++;
return i == n ? GL_TRUE : GL_FALSE;
}
+#endif
+#endif
static GLboolean _glewStrSame1 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
{
@@ -302,6 +290,8 @@ static GLboolean _glewStrSame3 (const GLubyte** a, GLuint* na, const GLubyte* b,
* other extension names. Could use strtok() but the constant
* string returned by glGetString might be in read-only memory.
*/
+#if !defined(GLEW_OSMESA)
+#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end)
{
const GLubyte* p;
@@ -315,8 +305,8 @@ static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, c
}
return GL_FALSE;
}
-
-#if !defined(_WIN32) || !defined(GLEW_MX)
+#endif
+#endif
PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL;
PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL;
@@ -942,6 +932,8 @@ PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri = NULL;
PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage = NULL;
PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage = NULL;
+PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB = NULL;
+
PFNGLGETUNIFORMDVPROC __glewGetUniformdv = NULL;
PFNGLUNIFORM1DPROC __glewUniform1d = NULL;
PFNGLUNIFORM1DVPROC __glewUniform1dv = NULL;
@@ -2218,6 +2210,8 @@ PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL;
PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL;
PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL;
+PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT = NULL;
+
PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT = NULL;
PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL;
@@ -2320,6 +2314,10 @@ PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL;
PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX = NULL;
PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX = NULL;
+PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX = NULL;
+PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX = NULL;
+PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX = NULL;
+
PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV = NULL;
PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV = NULL;
@@ -2343,6 +2341,26 @@ PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV = NULL;
PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV = NULL;
PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV = NULL;
+PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV = NULL;
+
+PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV = NULL;
+PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV = NULL;
+PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV = NULL;
+PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV = NULL;
+PFNGLCREATESTATESNVPROC __glewCreateStatesNV = NULL;
+PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV = NULL;
+PFNGLDELETESTATESNVPROC __glewDeleteStatesNV = NULL;
+PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV = NULL;
+PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV = NULL;
+PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV = NULL;
+PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV = NULL;
+PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV = NULL;
+PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV = NULL;
+PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV = NULL;
+PFNGLISSTATENVPROC __glewIsStateNV = NULL;
+PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV = NULL;
+PFNGLSTATECAPTURENVPROC __glewStateCaptureNV = NULL;
+
PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL;
PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL;
@@ -2350,6 +2368,8 @@ PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV = NULL;
PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV = NULL;
+PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV = NULL;
+
PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV = NULL;
PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL;
@@ -2358,6 +2378,12 @@ PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL;
PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV = NULL;
+PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV = NULL;
+PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV = NULL;
+PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV = NULL;
+PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV = NULL;
+PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV = NULL;
+
PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL;
PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL;
PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL;
@@ -2393,6 +2419,19 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMulti
PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL;
+PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV = NULL;
+PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV = NULL;
+PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV = NULL;
+PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV = NULL;
+PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV = NULL;
+PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV = NULL;
+PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV = NULL;
+PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV = NULL;
+
PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL;
PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL;
PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL;
@@ -2771,6 +2810,8 @@ PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV =
PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV = NULL;
PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV = NULL;
+PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV = NULL;
+
PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES = NULL;
PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES = NULL;
PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES = NULL;
@@ -2967,10 +3008,6 @@ PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL;
PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL;
-#endif /* !WIN32 || !GLEW_MX */
-
-#if !defined(GLEW_MX)
-
GLboolean __GLEW_VERSION_1_1 = GL_FALSE;
GLboolean __GLEW_VERSION_1_2 = GL_FALSE;
GLboolean __GLEW_VERSION_1_2_1 = GL_FALSE;
@@ -3009,6 +3046,7 @@ GLboolean __GLEW_AMD_query_buffer_object = GL_FALSE;
GLboolean __GLEW_AMD_sample_positions = GL_FALSE;
GLboolean __GLEW_AMD_seamless_cubemap_per_texture = GL_FALSE;
GLboolean __GLEW_AMD_shader_atomic_counter_ops = GL_FALSE;
+GLboolean __GLEW_AMD_shader_explicit_vertex_parameter = GL_FALSE;
GLboolean __GLEW_AMD_shader_stencil_export = GL_FALSE;
GLboolean __GLEW_AMD_shader_stencil_value_export = GL_FALSE;
GLboolean __GLEW_AMD_shader_trinary_minmax = GL_FALSE;
@@ -3098,6 +3136,7 @@ GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE;
GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE;
GLboolean __GLEW_ARB_get_program_binary = GL_FALSE;
GLboolean __GLEW_ARB_get_texture_sub_image = GL_FALSE;
+GLboolean __GLEW_ARB_gl_spirv = GL_FALSE;
GLboolean __GLEW_ARB_gpu_shader5 = GL_FALSE;
GLboolean __GLEW_ARB_gpu_shader_fp64 = GL_FALSE;
GLboolean __GLEW_ARB_gpu_shader_int64 = GL_FALSE;
@@ -3238,6 +3277,7 @@ GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE;
GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE;
GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE;
GLboolean __GLEW_ATI_vertex_streams = GL_FALSE;
+GLboolean __GLEW_EGL_NV_robustness_video_memory_purge = GL_FALSE;
GLboolean __GLEW_EXT_422_pixels = GL_FALSE;
GLboolean __GLEW_EXT_Cg_shader = GL_FALSE;
GLboolean __GLEW_EXT_abgr = GL_FALSE;
@@ -3345,6 +3385,7 @@ GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE;
GLboolean __GLEW_EXT_vertex_attrib_64bit = GL_FALSE;
GLboolean __GLEW_EXT_vertex_shader = GL_FALSE;
GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE;
+GLboolean __GLEW_EXT_window_rectangles = GL_FALSE;
GLboolean __GLEW_EXT_x11_sync_object = GL_FALSE;
GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE;
GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE;
@@ -3360,6 +3401,7 @@ GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE;
GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE;
GLboolean __GLEW_INGR_color_clamp = GL_FALSE;
GLboolean __GLEW_INGR_interlace_read = GL_FALSE;
+GLboolean __GLEW_INTEL_conservative_rasterization = GL_FALSE;
GLboolean __GLEW_INTEL_fragment_shader_ordering = GL_FALSE;
GLboolean __GLEW_INTEL_framebuffer_CMAA = GL_FALSE;
GLboolean __GLEW_INTEL_map_texture = GL_FALSE;
@@ -3375,24 +3417,31 @@ GLboolean __GLEW_KHR_robust_buffer_access_behavior = GL_FALSE;
GLboolean __GLEW_KHR_robustness = GL_FALSE;
GLboolean __GLEW_KHR_texture_compression_astc_hdr = GL_FALSE;
GLboolean __GLEW_KHR_texture_compression_astc_ldr = GL_FALSE;
+GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d = GL_FALSE;
GLboolean __GLEW_KTX_buffer_region = GL_FALSE;
GLboolean __GLEW_MESAX_texture_stack = GL_FALSE;
GLboolean __GLEW_MESA_pack_invert = GL_FALSE;
GLboolean __GLEW_MESA_resize_buffers = GL_FALSE;
+GLboolean __GLEW_MESA_shader_integer_functions = GL_FALSE;
GLboolean __GLEW_MESA_window_pos = GL_FALSE;
GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE;
+GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers = GL_FALSE;
GLboolean __GLEW_NVX_conditional_render = GL_FALSE;
GLboolean __GLEW_NVX_gpu_memory_info = GL_FALSE;
+GLboolean __GLEW_NVX_linked_gpu_multicast = GL_FALSE;
GLboolean __GLEW_NV_bindless_multi_draw_indirect = GL_FALSE;
GLboolean __GLEW_NV_bindless_multi_draw_indirect_count = GL_FALSE;
GLboolean __GLEW_NV_bindless_texture = GL_FALSE;
GLboolean __GLEW_NV_blend_equation_advanced = GL_FALSE;
GLboolean __GLEW_NV_blend_equation_advanced_coherent = GL_FALSE;
GLboolean __GLEW_NV_blend_square = GL_FALSE;
+GLboolean __GLEW_NV_clip_space_w_scaling = GL_FALSE;
+GLboolean __GLEW_NV_command_list = GL_FALSE;
GLboolean __GLEW_NV_compute_program5 = GL_FALSE;
GLboolean __GLEW_NV_conditional_render = GL_FALSE;
GLboolean __GLEW_NV_conservative_raster = GL_FALSE;
GLboolean __GLEW_NV_conservative_raster_dilate = GL_FALSE;
+GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles = GL_FALSE;
GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE;
GLboolean __GLEW_NV_copy_image = GL_FALSE;
GLboolean __GLEW_NV_deep_texture3D = GL_FALSE;
@@ -3400,6 +3449,7 @@ GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE;
GLboolean __GLEW_NV_depth_clamp = GL_FALSE;
GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE;
GLboolean __GLEW_NV_draw_texture = GL_FALSE;
+GLboolean __GLEW_NV_draw_vulkan_image = GL_FALSE;
GLboolean __GLEW_NV_evaluators = GL_FALSE;
GLboolean __GLEW_NV_explicit_multisample = GL_FALSE;
GLboolean __GLEW_NV_fence = GL_FALSE;
@@ -3417,6 +3467,7 @@ GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE;
GLboolean __GLEW_NV_geometry_program4 = GL_FALSE;
GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE;
GLboolean __GLEW_NV_geometry_shader_passthrough = GL_FALSE;
+GLboolean __GLEW_NV_gpu_multicast = GL_FALSE;
GLboolean __GLEW_NV_gpu_program4 = GL_FALSE;
GLboolean __GLEW_NV_gpu_program5 = GL_FALSE;
GLboolean __GLEW_NV_gpu_program5_mem_extended = GL_FALSE;
@@ -3439,16 +3490,19 @@ GLboolean __GLEW_NV_present_video = GL_FALSE;
GLboolean __GLEW_NV_primitive_restart = GL_FALSE;
GLboolean __GLEW_NV_register_combiners = GL_FALSE;
GLboolean __GLEW_NV_register_combiners2 = GL_FALSE;
+GLboolean __GLEW_NV_robustness_video_memory_purge = GL_FALSE;
GLboolean __GLEW_NV_sample_locations = GL_FALSE;
GLboolean __GLEW_NV_sample_mask_override_coverage = GL_FALSE;
GLboolean __GLEW_NV_shader_atomic_counters = GL_FALSE;
GLboolean __GLEW_NV_shader_atomic_float = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_float64 = GL_FALSE;
GLboolean __GLEW_NV_shader_atomic_fp16_vector = GL_FALSE;
GLboolean __GLEW_NV_shader_atomic_int64 = GL_FALSE;
GLboolean __GLEW_NV_shader_buffer_load = GL_FALSE;
GLboolean __GLEW_NV_shader_storage_buffer_object = GL_FALSE;
GLboolean __GLEW_NV_shader_thread_group = GL_FALSE;
GLboolean __GLEW_NV_shader_thread_shuffle = GL_FALSE;
+GLboolean __GLEW_NV_stereo_view_rendering = GL_FALSE;
GLboolean __GLEW_NV_tessellation_program5 = GL_FALSE;
GLboolean __GLEW_NV_texgen_emboss = GL_FALSE;
GLboolean __GLEW_NV_texgen_reflection = GL_FALSE;
@@ -3477,6 +3531,7 @@ GLboolean __GLEW_NV_vertex_program3 = GL_FALSE;
GLboolean __GLEW_NV_vertex_program4 = GL_FALSE;
GLboolean __GLEW_NV_video_capture = GL_FALSE;
GLboolean __GLEW_NV_viewport_array2 = GL_FALSE;
+GLboolean __GLEW_NV_viewport_swizzle = GL_FALSE;
GLboolean __GLEW_OES_byte_coordinates = GL_FALSE;
GLboolean __GLEW_OES_compressed_paletted_texture = GL_FALSE;
GLboolean __GLEW_OES_read_format = GL_FALSE;
@@ -3558,11 +3613,3925 @@ GLboolean __GLEW_WIN_phong_shading = GL_FALSE;
GLboolean __GLEW_WIN_specular_fog = GL_FALSE;
GLboolean __GLEW_WIN_swap_hint = GL_FALSE;
-#endif /* !GLEW_MX */
+static const char * _glewExtensionLookup[] = {
+#ifdef GL_VERSION_1_2
+ "GL_VERSION_1_2",
+#endif
+#ifdef GL_VERSION_1_2_1
+ "GL_VERSION_1_2_1",
+#endif
+#ifdef GL_VERSION_1_3
+ "GL_VERSION_1_3",
+#endif
+#ifdef GL_VERSION_1_4
+ "GL_VERSION_1_4",
+#endif
+#ifdef GL_VERSION_1_5
+ "GL_VERSION_1_5",
+#endif
+#ifdef GL_VERSION_2_0
+ "GL_VERSION_2_0",
+#endif
+#ifdef GL_VERSION_2_1
+ "GL_VERSION_2_1",
+#endif
+#ifdef GL_VERSION_3_0
+ "GL_VERSION_3_0",
+#endif
+#ifdef GL_VERSION_3_1
+ "GL_VERSION_3_1",
+#endif
+#ifdef GL_VERSION_3_2
+ "GL_VERSION_3_2",
+#endif
+#ifdef GL_VERSION_3_3
+ "GL_VERSION_3_3",
+#endif
+#ifdef GL_VERSION_4_0
+ "GL_VERSION_4_0",
+#endif
+#ifdef GL_VERSION_4_1
+ "GL_VERSION_4_1",
+#endif
+#ifdef GL_VERSION_4_2
+ "GL_VERSION_4_2",
+#endif
+#ifdef GL_VERSION_4_3
+ "GL_VERSION_4_3",
+#endif
+#ifdef GL_VERSION_4_4
+ "GL_VERSION_4_4",
+#endif
+#ifdef GL_VERSION_4_5
+ "GL_VERSION_4_5",
+#endif
+#ifdef GL_3DFX_multisample
+ "GL_3DFX_multisample",
+#endif
+#ifdef GL_3DFX_tbuffer
+ "GL_3DFX_tbuffer",
+#endif
+#ifdef GL_3DFX_texture_compression_FXT1
+ "GL_3DFX_texture_compression_FXT1",
+#endif
+#ifdef GL_AMD_blend_minmax_factor
+ "GL_AMD_blend_minmax_factor",
+#endif
+#ifdef GL_AMD_conservative_depth
+ "GL_AMD_conservative_depth",
+#endif
+#ifdef GL_AMD_debug_output
+ "GL_AMD_debug_output",
+#endif
+#ifdef GL_AMD_depth_clamp_separate
+ "GL_AMD_depth_clamp_separate",
+#endif
+#ifdef GL_AMD_draw_buffers_blend
+ "GL_AMD_draw_buffers_blend",
+#endif
+#ifdef GL_AMD_gcn_shader
+ "GL_AMD_gcn_shader",
+#endif
+#ifdef GL_AMD_gpu_shader_int64
+ "GL_AMD_gpu_shader_int64",
+#endif
+#ifdef GL_AMD_interleaved_elements
+ "GL_AMD_interleaved_elements",
+#endif
+#ifdef GL_AMD_multi_draw_indirect
+ "GL_AMD_multi_draw_indirect",
+#endif
+#ifdef GL_AMD_name_gen_delete
+ "GL_AMD_name_gen_delete",
+#endif
+#ifdef GL_AMD_occlusion_query_event
+ "GL_AMD_occlusion_query_event",
+#endif
+#ifdef GL_AMD_performance_monitor
+ "GL_AMD_performance_monitor",
+#endif
+#ifdef GL_AMD_pinned_memory
+ "GL_AMD_pinned_memory",
+#endif
+#ifdef GL_AMD_query_buffer_object
+ "GL_AMD_query_buffer_object",
+#endif
+#ifdef GL_AMD_sample_positions
+ "GL_AMD_sample_positions",
+#endif
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ "GL_AMD_seamless_cubemap_per_texture",
+#endif
+#ifdef GL_AMD_shader_atomic_counter_ops
+ "GL_AMD_shader_atomic_counter_ops",
+#endif
+#ifdef GL_AMD_shader_explicit_vertex_parameter
+ "GL_AMD_shader_explicit_vertex_parameter",
+#endif
+#ifdef GL_AMD_shader_stencil_export
+ "GL_AMD_shader_stencil_export",
+#endif
+#ifdef GL_AMD_shader_stencil_value_export
+ "GL_AMD_shader_stencil_value_export",
+#endif
+#ifdef GL_AMD_shader_trinary_minmax
+ "GL_AMD_shader_trinary_minmax",
+#endif
+#ifdef GL_AMD_sparse_texture
+ "GL_AMD_sparse_texture",
+#endif
+#ifdef GL_AMD_stencil_operation_extended
+ "GL_AMD_stencil_operation_extended",
+#endif
+#ifdef GL_AMD_texture_texture4
+ "GL_AMD_texture_texture4",
+#endif
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ "GL_AMD_transform_feedback3_lines_triangles",
+#endif
+#ifdef GL_AMD_transform_feedback4
+ "GL_AMD_transform_feedback4",
+#endif
+#ifdef GL_AMD_vertex_shader_layer
+ "GL_AMD_vertex_shader_layer",
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+ "GL_AMD_vertex_shader_tessellator",
+#endif
+#ifdef GL_AMD_vertex_shader_viewport_index
+ "GL_AMD_vertex_shader_viewport_index",
+#endif
+#ifdef GL_ANGLE_depth_texture
+ "GL_ANGLE_depth_texture",
+#endif
+#ifdef GL_ANGLE_framebuffer_blit
+ "GL_ANGLE_framebuffer_blit",
+#endif
+#ifdef GL_ANGLE_framebuffer_multisample
+ "GL_ANGLE_framebuffer_multisample",
+#endif
+#ifdef GL_ANGLE_instanced_arrays
+ "GL_ANGLE_instanced_arrays",
+#endif
+#ifdef GL_ANGLE_pack_reverse_row_order
+ "GL_ANGLE_pack_reverse_row_order",
+#endif
+#ifdef GL_ANGLE_program_binary
+ "GL_ANGLE_program_binary",
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt1
+ "GL_ANGLE_texture_compression_dxt1",
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt3
+ "GL_ANGLE_texture_compression_dxt3",
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt5
+ "GL_ANGLE_texture_compression_dxt5",
+#endif
+#ifdef GL_ANGLE_texture_usage
+ "GL_ANGLE_texture_usage",
+#endif
+#ifdef GL_ANGLE_timer_query
+ "GL_ANGLE_timer_query",
+#endif
+#ifdef GL_ANGLE_translated_shader_source
+ "GL_ANGLE_translated_shader_source",
+#endif
+#ifdef GL_APPLE_aux_depth_stencil
+ "GL_APPLE_aux_depth_stencil",
+#endif
+#ifdef GL_APPLE_client_storage
+ "GL_APPLE_client_storage",
+#endif
+#ifdef GL_APPLE_element_array
+ "GL_APPLE_element_array",
+#endif
+#ifdef GL_APPLE_fence
+ "GL_APPLE_fence",
+#endif
+#ifdef GL_APPLE_float_pixels
+ "GL_APPLE_float_pixels",
+#endif
+#ifdef GL_APPLE_flush_buffer_range
+ "GL_APPLE_flush_buffer_range",
+#endif
+#ifdef GL_APPLE_object_purgeable
+ "GL_APPLE_object_purgeable",
+#endif
+#ifdef GL_APPLE_pixel_buffer
+ "GL_APPLE_pixel_buffer",
+#endif
+#ifdef GL_APPLE_rgb_422
+ "GL_APPLE_rgb_422",
+#endif
+#ifdef GL_APPLE_row_bytes
+ "GL_APPLE_row_bytes",
+#endif
+#ifdef GL_APPLE_specular_vector
+ "GL_APPLE_specular_vector",
+#endif
+#ifdef GL_APPLE_texture_range
+ "GL_APPLE_texture_range",
+#endif
+#ifdef GL_APPLE_transform_hint
+ "GL_APPLE_transform_hint",
+#endif
+#ifdef GL_APPLE_vertex_array_object
+ "GL_APPLE_vertex_array_object",
+#endif
+#ifdef GL_APPLE_vertex_array_range
+ "GL_APPLE_vertex_array_range",
+#endif
+#ifdef GL_APPLE_vertex_program_evaluators
+ "GL_APPLE_vertex_program_evaluators",
+#endif
+#ifdef GL_APPLE_ycbcr_422
+ "GL_APPLE_ycbcr_422",
+#endif
+#ifdef GL_ARB_ES2_compatibility
+ "GL_ARB_ES2_compatibility",
+#endif
+#ifdef GL_ARB_ES3_1_compatibility
+ "GL_ARB_ES3_1_compatibility",
+#endif
+#ifdef GL_ARB_ES3_2_compatibility
+ "GL_ARB_ES3_2_compatibility",
+#endif
+#ifdef GL_ARB_ES3_compatibility
+ "GL_ARB_ES3_compatibility",
+#endif
+#ifdef GL_ARB_arrays_of_arrays
+ "GL_ARB_arrays_of_arrays",
+#endif
+#ifdef GL_ARB_base_instance
+ "GL_ARB_base_instance",
+#endif
+#ifdef GL_ARB_bindless_texture
+ "GL_ARB_bindless_texture",
+#endif
+#ifdef GL_ARB_blend_func_extended
+ "GL_ARB_blend_func_extended",
+#endif
+#ifdef GL_ARB_buffer_storage
+ "GL_ARB_buffer_storage",
+#endif
+#ifdef GL_ARB_cl_event
+ "GL_ARB_cl_event",
+#endif
+#ifdef GL_ARB_clear_buffer_object
+ "GL_ARB_clear_buffer_object",
+#endif
+#ifdef GL_ARB_clear_texture
+ "GL_ARB_clear_texture",
+#endif
+#ifdef GL_ARB_clip_control
+ "GL_ARB_clip_control",
+#endif
+#ifdef GL_ARB_color_buffer_float
+ "GL_ARB_color_buffer_float",
+#endif
+#ifdef GL_ARB_compatibility
+ "GL_ARB_compatibility",
+#endif
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ "GL_ARB_compressed_texture_pixel_storage",
+#endif
+#ifdef GL_ARB_compute_shader
+ "GL_ARB_compute_shader",
+#endif
+#ifdef GL_ARB_compute_variable_group_size
+ "GL_ARB_compute_variable_group_size",
+#endif
+#ifdef GL_ARB_conditional_render_inverted
+ "GL_ARB_conditional_render_inverted",
+#endif
+#ifdef GL_ARB_conservative_depth
+ "GL_ARB_conservative_depth",
+#endif
+#ifdef GL_ARB_copy_buffer
+ "GL_ARB_copy_buffer",
+#endif
+#ifdef GL_ARB_copy_image
+ "GL_ARB_copy_image",
+#endif
+#ifdef GL_ARB_cull_distance
+ "GL_ARB_cull_distance",
+#endif
+#ifdef GL_ARB_debug_output
+ "GL_ARB_debug_output",
+#endif
+#ifdef GL_ARB_depth_buffer_float
+ "GL_ARB_depth_buffer_float",
+#endif
+#ifdef GL_ARB_depth_clamp
+ "GL_ARB_depth_clamp",
+#endif
+#ifdef GL_ARB_depth_texture
+ "GL_ARB_depth_texture",
+#endif
+#ifdef GL_ARB_derivative_control
+ "GL_ARB_derivative_control",
+#endif
+#ifdef GL_ARB_direct_state_access
+ "GL_ARB_direct_state_access",
+#endif
+#ifdef GL_ARB_draw_buffers
+ "GL_ARB_draw_buffers",
+#endif
+#ifdef GL_ARB_draw_buffers_blend
+ "GL_ARB_draw_buffers_blend",
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+ "GL_ARB_draw_elements_base_vertex",
+#endif
+#ifdef GL_ARB_draw_indirect
+ "GL_ARB_draw_indirect",
+#endif
+#ifdef GL_ARB_draw_instanced
+ "GL_ARB_draw_instanced",
+#endif
+#ifdef GL_ARB_enhanced_layouts
+ "GL_ARB_enhanced_layouts",
+#endif
+#ifdef GL_ARB_explicit_attrib_location
+ "GL_ARB_explicit_attrib_location",
+#endif
+#ifdef GL_ARB_explicit_uniform_location
+ "GL_ARB_explicit_uniform_location",
+#endif
+#ifdef GL_ARB_fragment_coord_conventions
+ "GL_ARB_fragment_coord_conventions",
+#endif
+#ifdef GL_ARB_fragment_layer_viewport
+ "GL_ARB_fragment_layer_viewport",
+#endif
+#ifdef GL_ARB_fragment_program
+ "GL_ARB_fragment_program",
+#endif
+#ifdef GL_ARB_fragment_program_shadow
+ "GL_ARB_fragment_program_shadow",
+#endif
+#ifdef GL_ARB_fragment_shader
+ "GL_ARB_fragment_shader",
+#endif
+#ifdef GL_ARB_fragment_shader_interlock
+ "GL_ARB_fragment_shader_interlock",
+#endif
+#ifdef GL_ARB_framebuffer_no_attachments
+ "GL_ARB_framebuffer_no_attachments",
+#endif
+#ifdef GL_ARB_framebuffer_object
+ "GL_ARB_framebuffer_object",
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ "GL_ARB_framebuffer_sRGB",
+#endif
+#ifdef GL_ARB_geometry_shader4
+ "GL_ARB_geometry_shader4",
+#endif
+#ifdef GL_ARB_get_program_binary
+ "GL_ARB_get_program_binary",
+#endif
+#ifdef GL_ARB_get_texture_sub_image
+ "GL_ARB_get_texture_sub_image",
+#endif
+#ifdef GL_ARB_gl_spirv
+ "GL_ARB_gl_spirv",
+#endif
+#ifdef GL_ARB_gpu_shader5
+ "GL_ARB_gpu_shader5",
+#endif
+#ifdef GL_ARB_gpu_shader_fp64
+ "GL_ARB_gpu_shader_fp64",
+#endif
+#ifdef GL_ARB_gpu_shader_int64
+ "GL_ARB_gpu_shader_int64",
+#endif
+#ifdef GL_ARB_half_float_pixel
+ "GL_ARB_half_float_pixel",
+#endif
+#ifdef GL_ARB_half_float_vertex
+ "GL_ARB_half_float_vertex",
+#endif
+#ifdef GL_ARB_imaging
+ "GL_ARB_imaging",
+#endif
+#ifdef GL_ARB_indirect_parameters
+ "GL_ARB_indirect_parameters",
+#endif
+#ifdef GL_ARB_instanced_arrays
+ "GL_ARB_instanced_arrays",
+#endif
+#ifdef GL_ARB_internalformat_query
+ "GL_ARB_internalformat_query",
+#endif
+#ifdef GL_ARB_internalformat_query2
+ "GL_ARB_internalformat_query2",
+#endif
+#ifdef GL_ARB_invalidate_subdata
+ "GL_ARB_invalidate_subdata",
+#endif
+#ifdef GL_ARB_map_buffer_alignment
+ "GL_ARB_map_buffer_alignment",
+#endif
+#ifdef GL_ARB_map_buffer_range
+ "GL_ARB_map_buffer_range",
+#endif
+#ifdef GL_ARB_matrix_palette
+ "GL_ARB_matrix_palette",
+#endif
+#ifdef GL_ARB_multi_bind
+ "GL_ARB_multi_bind",
+#endif
+#ifdef GL_ARB_multi_draw_indirect
+ "GL_ARB_multi_draw_indirect",
+#endif
+#ifdef GL_ARB_multisample
+ "GL_ARB_multisample",
+#endif
+#ifdef GL_ARB_multitexture
+ "GL_ARB_multitexture",
+#endif
+#ifdef GL_ARB_occlusion_query
+ "GL_ARB_occlusion_query",
+#endif
+#ifdef GL_ARB_occlusion_query2
+ "GL_ARB_occlusion_query2",
+#endif
+#ifdef GL_ARB_parallel_shader_compile
+ "GL_ARB_parallel_shader_compile",
+#endif
+#ifdef GL_ARB_pipeline_statistics_query
+ "GL_ARB_pipeline_statistics_query",
+#endif
+#ifdef GL_ARB_pixel_buffer_object
+ "GL_ARB_pixel_buffer_object",
+#endif
+#ifdef GL_ARB_point_parameters
+ "GL_ARB_point_parameters",
+#endif
+#ifdef GL_ARB_point_sprite
+ "GL_ARB_point_sprite",
+#endif
+#ifdef GL_ARB_post_depth_coverage
+ "GL_ARB_post_depth_coverage",
+#endif
+#ifdef GL_ARB_program_interface_query
+ "GL_ARB_program_interface_query",
+#endif
+#ifdef GL_ARB_provoking_vertex
+ "GL_ARB_provoking_vertex",
+#endif
+#ifdef GL_ARB_query_buffer_object
+ "GL_ARB_query_buffer_object",
+#endif
+#ifdef GL_ARB_robust_buffer_access_behavior
+ "GL_ARB_robust_buffer_access_behavior",
+#endif
+#ifdef GL_ARB_robustness
+ "GL_ARB_robustness",
+#endif
+#ifdef GL_ARB_robustness_application_isolation
+ "GL_ARB_robustness_application_isolation",
+#endif
+#ifdef GL_ARB_robustness_share_group_isolation
+ "GL_ARB_robustness_share_group_isolation",
+#endif
+#ifdef GL_ARB_sample_locations
+ "GL_ARB_sample_locations",
+#endif
+#ifdef GL_ARB_sample_shading
+ "GL_ARB_sample_shading",
+#endif
+#ifdef GL_ARB_sampler_objects
+ "GL_ARB_sampler_objects",
+#endif
+#ifdef GL_ARB_seamless_cube_map
+ "GL_ARB_seamless_cube_map",
+#endif
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ "GL_ARB_seamless_cubemap_per_texture",
+#endif
+#ifdef GL_ARB_separate_shader_objects
+ "GL_ARB_separate_shader_objects",
+#endif
+#ifdef GL_ARB_shader_atomic_counter_ops
+ "GL_ARB_shader_atomic_counter_ops",
+#endif
+#ifdef GL_ARB_shader_atomic_counters
+ "GL_ARB_shader_atomic_counters",
+#endif
+#ifdef GL_ARB_shader_ballot
+ "GL_ARB_shader_ballot",
+#endif
+#ifdef GL_ARB_shader_bit_encoding
+ "GL_ARB_shader_bit_encoding",
+#endif
+#ifdef GL_ARB_shader_clock
+ "GL_ARB_shader_clock",
+#endif
+#ifdef GL_ARB_shader_draw_parameters
+ "GL_ARB_shader_draw_parameters",
+#endif
+#ifdef GL_ARB_shader_group_vote
+ "GL_ARB_shader_group_vote",
+#endif
+#ifdef GL_ARB_shader_image_load_store
+ "GL_ARB_shader_image_load_store",
+#endif
+#ifdef GL_ARB_shader_image_size
+ "GL_ARB_shader_image_size",
+#endif
+#ifdef GL_ARB_shader_objects
+ "GL_ARB_shader_objects",
+#endif
+#ifdef GL_ARB_shader_precision
+ "GL_ARB_shader_precision",
+#endif
+#ifdef GL_ARB_shader_stencil_export
+ "GL_ARB_shader_stencil_export",
+#endif
+#ifdef GL_ARB_shader_storage_buffer_object
+ "GL_ARB_shader_storage_buffer_object",
+#endif
+#ifdef GL_ARB_shader_subroutine
+ "GL_ARB_shader_subroutine",
+#endif
+#ifdef GL_ARB_shader_texture_image_samples
+ "GL_ARB_shader_texture_image_samples",
+#endif
+#ifdef GL_ARB_shader_texture_lod
+ "GL_ARB_shader_texture_lod",
+#endif
+#ifdef GL_ARB_shader_viewport_layer_array
+ "GL_ARB_shader_viewport_layer_array",
+#endif
+#ifdef GL_ARB_shading_language_100
+ "GL_ARB_shading_language_100",
+#endif
+#ifdef GL_ARB_shading_language_420pack
+ "GL_ARB_shading_language_420pack",
+#endif
+#ifdef GL_ARB_shading_language_include
+ "GL_ARB_shading_language_include",
+#endif
+#ifdef GL_ARB_shading_language_packing
+ "GL_ARB_shading_language_packing",
+#endif
+#ifdef GL_ARB_shadow
+ "GL_ARB_shadow",
+#endif
+#ifdef GL_ARB_shadow_ambient
+ "GL_ARB_shadow_ambient",
+#endif
+#ifdef GL_ARB_sparse_buffer
+ "GL_ARB_sparse_buffer",
+#endif
+#ifdef GL_ARB_sparse_texture
+ "GL_ARB_sparse_texture",
+#endif
+#ifdef GL_ARB_sparse_texture2
+ "GL_ARB_sparse_texture2",
+#endif
+#ifdef GL_ARB_sparse_texture_clamp
+ "GL_ARB_sparse_texture_clamp",
+#endif
+#ifdef GL_ARB_stencil_texturing
+ "GL_ARB_stencil_texturing",
+#endif
+#ifdef GL_ARB_sync
+ "GL_ARB_sync",
+#endif
+#ifdef GL_ARB_tessellation_shader
+ "GL_ARB_tessellation_shader",
+#endif
+#ifdef GL_ARB_texture_barrier
+ "GL_ARB_texture_barrier",
+#endif
+#ifdef GL_ARB_texture_border_clamp
+ "GL_ARB_texture_border_clamp",
+#endif
+#ifdef GL_ARB_texture_buffer_object
+ "GL_ARB_texture_buffer_object",
+#endif
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ "GL_ARB_texture_buffer_object_rgb32",
+#endif
+#ifdef GL_ARB_texture_buffer_range
+ "GL_ARB_texture_buffer_range",
+#endif
+#ifdef GL_ARB_texture_compression
+ "GL_ARB_texture_compression",
+#endif
+#ifdef GL_ARB_texture_compression_bptc
+ "GL_ARB_texture_compression_bptc",
+#endif
+#ifdef GL_ARB_texture_compression_rgtc
+ "GL_ARB_texture_compression_rgtc",
+#endif
+#ifdef GL_ARB_texture_cube_map
+ "GL_ARB_texture_cube_map",
+#endif
+#ifdef GL_ARB_texture_cube_map_array
+ "GL_ARB_texture_cube_map_array",
+#endif
+#ifdef GL_ARB_texture_env_add
+ "GL_ARB_texture_env_add",
+#endif
+#ifdef GL_ARB_texture_env_combine
+ "GL_ARB_texture_env_combine",
+#endif
+#ifdef GL_ARB_texture_env_crossbar
+ "GL_ARB_texture_env_crossbar",
+#endif
+#ifdef GL_ARB_texture_env_dot3
+ "GL_ARB_texture_env_dot3",
+#endif
+#ifdef GL_ARB_texture_filter_minmax
+ "GL_ARB_texture_filter_minmax",
+#endif
+#ifdef GL_ARB_texture_float
+ "GL_ARB_texture_float",
+#endif
+#ifdef GL_ARB_texture_gather
+ "GL_ARB_texture_gather",
+#endif
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ "GL_ARB_texture_mirror_clamp_to_edge",
+#endif
+#ifdef GL_ARB_texture_mirrored_repeat
+ "GL_ARB_texture_mirrored_repeat",
+#endif
+#ifdef GL_ARB_texture_multisample
+ "GL_ARB_texture_multisample",
+#endif
+#ifdef GL_ARB_texture_non_power_of_two
+ "GL_ARB_texture_non_power_of_two",
+#endif
+#ifdef GL_ARB_texture_query_levels
+ "GL_ARB_texture_query_levels",
+#endif
+#ifdef GL_ARB_texture_query_lod
+ "GL_ARB_texture_query_lod",
+#endif
+#ifdef GL_ARB_texture_rectangle
+ "GL_ARB_texture_rectangle",
+#endif
+#ifdef GL_ARB_texture_rg
+ "GL_ARB_texture_rg",
+#endif
+#ifdef GL_ARB_texture_rgb10_a2ui
+ "GL_ARB_texture_rgb10_a2ui",
+#endif
+#ifdef GL_ARB_texture_stencil8
+ "GL_ARB_texture_stencil8",
+#endif
+#ifdef GL_ARB_texture_storage
+ "GL_ARB_texture_storage",
+#endif
+#ifdef GL_ARB_texture_storage_multisample
+ "GL_ARB_texture_storage_multisample",
+#endif
+#ifdef GL_ARB_texture_swizzle
+ "GL_ARB_texture_swizzle",
+#endif
+#ifdef GL_ARB_texture_view
+ "GL_ARB_texture_view",
+#endif
+#ifdef GL_ARB_timer_query
+ "GL_ARB_timer_query",
+#endif
+#ifdef GL_ARB_transform_feedback2
+ "GL_ARB_transform_feedback2",
+#endif
+#ifdef GL_ARB_transform_feedback3
+ "GL_ARB_transform_feedback3",
+#endif
+#ifdef GL_ARB_transform_feedback_instanced
+ "GL_ARB_transform_feedback_instanced",
+#endif
+#ifdef GL_ARB_transform_feedback_overflow_query
+ "GL_ARB_transform_feedback_overflow_query",
+#endif
+#ifdef GL_ARB_transpose_matrix
+ "GL_ARB_transpose_matrix",
+#endif
+#ifdef GL_ARB_uniform_buffer_object
+ "GL_ARB_uniform_buffer_object",
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+ "GL_ARB_vertex_array_bgra",
+#endif
+#ifdef GL_ARB_vertex_array_object
+ "GL_ARB_vertex_array_object",
+#endif
+#ifdef GL_ARB_vertex_attrib_64bit
+ "GL_ARB_vertex_attrib_64bit",
+#endif
+#ifdef GL_ARB_vertex_attrib_binding
+ "GL_ARB_vertex_attrib_binding",
+#endif
+#ifdef GL_ARB_vertex_blend
+ "GL_ARB_vertex_blend",
+#endif
+#ifdef GL_ARB_vertex_buffer_object
+ "GL_ARB_vertex_buffer_object",
+#endif
+#ifdef GL_ARB_vertex_program
+ "GL_ARB_vertex_program",
+#endif
+#ifdef GL_ARB_vertex_shader
+ "GL_ARB_vertex_shader",
+#endif
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ "GL_ARB_vertex_type_10f_11f_11f_rev",
+#endif
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ "GL_ARB_vertex_type_2_10_10_10_rev",
+#endif
+#ifdef GL_ARB_viewport_array
+ "GL_ARB_viewport_array",
+#endif
+#ifdef GL_ARB_window_pos
+ "GL_ARB_window_pos",
+#endif
+#ifdef GL_ATIX_point_sprites
+ "GL_ATIX_point_sprites",
+#endif
+#ifdef GL_ATIX_texture_env_combine3
+ "GL_ATIX_texture_env_combine3",
+#endif
+#ifdef GL_ATIX_texture_env_route
+ "GL_ATIX_texture_env_route",
+#endif
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ "GL_ATIX_vertex_shader_output_point_size",
+#endif
+#ifdef GL_ATI_draw_buffers
+ "GL_ATI_draw_buffers",
+#endif
+#ifdef GL_ATI_element_array
+ "GL_ATI_element_array",
+#endif
+#ifdef GL_ATI_envmap_bumpmap
+ "GL_ATI_envmap_bumpmap",
+#endif
+#ifdef GL_ATI_fragment_shader
+ "GL_ATI_fragment_shader",
+#endif
+#ifdef GL_ATI_map_object_buffer
+ "GL_ATI_map_object_buffer",
+#endif
+#ifdef GL_ATI_meminfo
+ "GL_ATI_meminfo",
+#endif
+#ifdef GL_ATI_pn_triangles
+ "GL_ATI_pn_triangles",
+#endif
+#ifdef GL_ATI_separate_stencil
+ "GL_ATI_separate_stencil",
+#endif
+#ifdef GL_ATI_shader_texture_lod
+ "GL_ATI_shader_texture_lod",
+#endif
+#ifdef GL_ATI_text_fragment_shader
+ "GL_ATI_text_fragment_shader",
+#endif
+#ifdef GL_ATI_texture_compression_3dc
+ "GL_ATI_texture_compression_3dc",
+#endif
+#ifdef GL_ATI_texture_env_combine3
+ "GL_ATI_texture_env_combine3",
+#endif
+#ifdef GL_ATI_texture_float
+ "GL_ATI_texture_float",
+#endif
+#ifdef GL_ATI_texture_mirror_once
+ "GL_ATI_texture_mirror_once",
+#endif
+#ifdef GL_ATI_vertex_array_object
+ "GL_ATI_vertex_array_object",
+#endif
+#ifdef GL_ATI_vertex_attrib_array_object
+ "GL_ATI_vertex_attrib_array_object",
+#endif
+#ifdef GL_ATI_vertex_streams
+ "GL_ATI_vertex_streams",
+#endif
+#ifdef GL_EGL_NV_robustness_video_memory_purge
+ "GL_EGL_NV_robustness_video_memory_purge",
+#endif
+#ifdef GL_EXT_422_pixels
+ "GL_EXT_422_pixels",
+#endif
+#ifdef GL_EXT_Cg_shader
+ "GL_EXT_Cg_shader",
+#endif
+#ifdef GL_EXT_abgr
+ "GL_EXT_abgr",
+#endif
+#ifdef GL_EXT_bgra
+ "GL_EXT_bgra",
+#endif
+#ifdef GL_EXT_bindable_uniform
+ "GL_EXT_bindable_uniform",
+#endif
+#ifdef GL_EXT_blend_color
+ "GL_EXT_blend_color",
+#endif
+#ifdef GL_EXT_blend_equation_separate
+ "GL_EXT_blend_equation_separate",
+#endif
+#ifdef GL_EXT_blend_func_separate
+ "GL_EXT_blend_func_separate",
+#endif
+#ifdef GL_EXT_blend_logic_op
+ "GL_EXT_blend_logic_op",
+#endif
+#ifdef GL_EXT_blend_minmax
+ "GL_EXT_blend_minmax",
+#endif
+#ifdef GL_EXT_blend_subtract
+ "GL_EXT_blend_subtract",
+#endif
+#ifdef GL_EXT_clip_volume_hint
+ "GL_EXT_clip_volume_hint",
+#endif
+#ifdef GL_EXT_cmyka
+ "GL_EXT_cmyka",
+#endif
+#ifdef GL_EXT_color_subtable
+ "GL_EXT_color_subtable",
+#endif
+#ifdef GL_EXT_compiled_vertex_array
+ "GL_EXT_compiled_vertex_array",
+#endif
+#ifdef GL_EXT_convolution
+ "GL_EXT_convolution",
+#endif
+#ifdef GL_EXT_coordinate_frame
+ "GL_EXT_coordinate_frame",
+#endif
+#ifdef GL_EXT_copy_texture
+ "GL_EXT_copy_texture",
+#endif
+#ifdef GL_EXT_cull_vertex
+ "GL_EXT_cull_vertex",
+#endif
+#ifdef GL_EXT_debug_label
+ "GL_EXT_debug_label",
+#endif
+#ifdef GL_EXT_debug_marker
+ "GL_EXT_debug_marker",
+#endif
+#ifdef GL_EXT_depth_bounds_test
+ "GL_EXT_depth_bounds_test",
+#endif
+#ifdef GL_EXT_direct_state_access
+ "GL_EXT_direct_state_access",
+#endif
+#ifdef GL_EXT_draw_buffers2
+ "GL_EXT_draw_buffers2",
+#endif
+#ifdef GL_EXT_draw_instanced
+ "GL_EXT_draw_instanced",
+#endif
+#ifdef GL_EXT_draw_range_elements
+ "GL_EXT_draw_range_elements",
+#endif
+#ifdef GL_EXT_fog_coord
+ "GL_EXT_fog_coord",
+#endif
+#ifdef GL_EXT_fragment_lighting
+ "GL_EXT_fragment_lighting",
+#endif
+#ifdef GL_EXT_framebuffer_blit
+ "GL_EXT_framebuffer_blit",
+#endif
+#ifdef GL_EXT_framebuffer_multisample
+ "GL_EXT_framebuffer_multisample",
+#endif
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ "GL_EXT_framebuffer_multisample_blit_scaled",
+#endif
+#ifdef GL_EXT_framebuffer_object
+ "GL_EXT_framebuffer_object",
+#endif
+#ifdef GL_EXT_framebuffer_sRGB
+ "GL_EXT_framebuffer_sRGB",
+#endif
+#ifdef GL_EXT_geometry_shader4
+ "GL_EXT_geometry_shader4",
+#endif
+#ifdef GL_EXT_gpu_program_parameters
+ "GL_EXT_gpu_program_parameters",
+#endif
+#ifdef GL_EXT_gpu_shader4
+ "GL_EXT_gpu_shader4",
+#endif
+#ifdef GL_EXT_histogram
+ "GL_EXT_histogram",
+#endif
+#ifdef GL_EXT_index_array_formats
+ "GL_EXT_index_array_formats",
+#endif
+#ifdef GL_EXT_index_func
+ "GL_EXT_index_func",
+#endif
+#ifdef GL_EXT_index_material
+ "GL_EXT_index_material",
+#endif
+#ifdef GL_EXT_index_texture
+ "GL_EXT_index_texture",
+#endif
+#ifdef GL_EXT_light_texture
+ "GL_EXT_light_texture",
+#endif
+#ifdef GL_EXT_misc_attribute
+ "GL_EXT_misc_attribute",
+#endif
+#ifdef GL_EXT_multi_draw_arrays
+ "GL_EXT_multi_draw_arrays",
+#endif
+#ifdef GL_EXT_multisample
+ "GL_EXT_multisample",
+#endif
+#ifdef GL_EXT_packed_depth_stencil
+ "GL_EXT_packed_depth_stencil",
+#endif
+#ifdef GL_EXT_packed_float
+ "GL_EXT_packed_float",
+#endif
+#ifdef GL_EXT_packed_pixels
+ "GL_EXT_packed_pixels",
+#endif
+#ifdef GL_EXT_paletted_texture
+ "GL_EXT_paletted_texture",
+#endif
+#ifdef GL_EXT_pixel_buffer_object
+ "GL_EXT_pixel_buffer_object",
+#endif
+#ifdef GL_EXT_pixel_transform
+ "GL_EXT_pixel_transform",
+#endif
+#ifdef GL_EXT_pixel_transform_color_table
+ "GL_EXT_pixel_transform_color_table",
+#endif
+#ifdef GL_EXT_point_parameters
+ "GL_EXT_point_parameters",
+#endif
+#ifdef GL_EXT_polygon_offset
+ "GL_EXT_polygon_offset",
+#endif
+#ifdef GL_EXT_polygon_offset_clamp
+ "GL_EXT_polygon_offset_clamp",
+#endif
+#ifdef GL_EXT_post_depth_coverage
+ "GL_EXT_post_depth_coverage",
+#endif
+#ifdef GL_EXT_provoking_vertex
+ "GL_EXT_provoking_vertex",
+#endif
+#ifdef GL_EXT_raster_multisample
+ "GL_EXT_raster_multisample",
+#endif
+#ifdef GL_EXT_rescale_normal
+ "GL_EXT_rescale_normal",
+#endif
+#ifdef GL_EXT_scene_marker
+ "GL_EXT_scene_marker",
+#endif
+#ifdef GL_EXT_secondary_color
+ "GL_EXT_secondary_color",
+#endif
+#ifdef GL_EXT_separate_shader_objects
+ "GL_EXT_separate_shader_objects",
+#endif
+#ifdef GL_EXT_separate_specular_color
+ "GL_EXT_separate_specular_color",
+#endif
+#ifdef GL_EXT_shader_image_load_formatted
+ "GL_EXT_shader_image_load_formatted",
+#endif
+#ifdef GL_EXT_shader_image_load_store
+ "GL_EXT_shader_image_load_store",
+#endif
+#ifdef GL_EXT_shader_integer_mix
+ "GL_EXT_shader_integer_mix",
+#endif
+#ifdef GL_EXT_shadow_funcs
+ "GL_EXT_shadow_funcs",
+#endif
+#ifdef GL_EXT_shared_texture_palette
+ "GL_EXT_shared_texture_palette",
+#endif
+#ifdef GL_EXT_sparse_texture2
+ "GL_EXT_sparse_texture2",
+#endif
+#ifdef GL_EXT_stencil_clear_tag
+ "GL_EXT_stencil_clear_tag",
+#endif
+#ifdef GL_EXT_stencil_two_side
+ "GL_EXT_stencil_two_side",
+#endif
+#ifdef GL_EXT_stencil_wrap
+ "GL_EXT_stencil_wrap",
+#endif
+#ifdef GL_EXT_subtexture
+ "GL_EXT_subtexture",
+#endif
+#ifdef GL_EXT_texture
+ "GL_EXT_texture",
+#endif
+#ifdef GL_EXT_texture3D
+ "GL_EXT_texture3D",
+#endif
+#ifdef GL_EXT_texture_array
+ "GL_EXT_texture_array",
+#endif
+#ifdef GL_EXT_texture_buffer_object
+ "GL_EXT_texture_buffer_object",
+#endif
+#ifdef GL_EXT_texture_compression_dxt1
+ "GL_EXT_texture_compression_dxt1",
+#endif
+#ifdef GL_EXT_texture_compression_latc
+ "GL_EXT_texture_compression_latc",
+#endif
+#ifdef GL_EXT_texture_compression_rgtc
+ "GL_EXT_texture_compression_rgtc",
+#endif
+#ifdef GL_EXT_texture_compression_s3tc
+ "GL_EXT_texture_compression_s3tc",
+#endif
+#ifdef GL_EXT_texture_cube_map
+ "GL_EXT_texture_cube_map",
+#endif
+#ifdef GL_EXT_texture_edge_clamp
+ "GL_EXT_texture_edge_clamp",
+#endif
+#ifdef GL_EXT_texture_env
+ "GL_EXT_texture_env",
+#endif
+#ifdef GL_EXT_texture_env_add
+ "GL_EXT_texture_env_add",
+#endif
+#ifdef GL_EXT_texture_env_combine
+ "GL_EXT_texture_env_combine",
+#endif
+#ifdef GL_EXT_texture_env_dot3
+ "GL_EXT_texture_env_dot3",
+#endif
+#ifdef GL_EXT_texture_filter_anisotropic
+ "GL_EXT_texture_filter_anisotropic",
+#endif
+#ifdef GL_EXT_texture_filter_minmax
+ "GL_EXT_texture_filter_minmax",
+#endif
+#ifdef GL_EXT_texture_integer
+ "GL_EXT_texture_integer",
+#endif
+#ifdef GL_EXT_texture_lod_bias
+ "GL_EXT_texture_lod_bias",
+#endif
+#ifdef GL_EXT_texture_mirror_clamp
+ "GL_EXT_texture_mirror_clamp",
+#endif
+#ifdef GL_EXT_texture_object
+ "GL_EXT_texture_object",
+#endif
+#ifdef GL_EXT_texture_perturb_normal
+ "GL_EXT_texture_perturb_normal",
+#endif
+#ifdef GL_EXT_texture_rectangle
+ "GL_EXT_texture_rectangle",
+#endif
+#ifdef GL_EXT_texture_sRGB
+ "GL_EXT_texture_sRGB",
+#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ "GL_EXT_texture_sRGB_decode",
+#endif
+#ifdef GL_EXT_texture_shared_exponent
+ "GL_EXT_texture_shared_exponent",
+#endif
+#ifdef GL_EXT_texture_snorm
+ "GL_EXT_texture_snorm",
+#endif
+#ifdef GL_EXT_texture_swizzle
+ "GL_EXT_texture_swizzle",
+#endif
+#ifdef GL_EXT_timer_query
+ "GL_EXT_timer_query",
+#endif
+#ifdef GL_EXT_transform_feedback
+ "GL_EXT_transform_feedback",
+#endif
+#ifdef GL_EXT_vertex_array
+ "GL_EXT_vertex_array",
+#endif
+#ifdef GL_EXT_vertex_array_bgra
+ "GL_EXT_vertex_array_bgra",
+#endif
+#ifdef GL_EXT_vertex_attrib_64bit
+ "GL_EXT_vertex_attrib_64bit",
+#endif
+#ifdef GL_EXT_vertex_shader
+ "GL_EXT_vertex_shader",
+#endif
+#ifdef GL_EXT_vertex_weighting
+ "GL_EXT_vertex_weighting",
+#endif
+#ifdef GL_EXT_window_rectangles
+ "GL_EXT_window_rectangles",
+#endif
+#ifdef GL_EXT_x11_sync_object
+ "GL_EXT_x11_sync_object",
+#endif
+#ifdef GL_GREMEDY_frame_terminator
+ "GL_GREMEDY_frame_terminator",
+#endif
+#ifdef GL_GREMEDY_string_marker
+ "GL_GREMEDY_string_marker",
+#endif
+#ifdef GL_HP_convolution_border_modes
+ "GL_HP_convolution_border_modes",
+#endif
+#ifdef GL_HP_image_transform
+ "GL_HP_image_transform",
+#endif
+#ifdef GL_HP_occlusion_test
+ "GL_HP_occlusion_test",
+#endif
+#ifdef GL_HP_texture_lighting
+ "GL_HP_texture_lighting",
+#endif
+#ifdef GL_IBM_cull_vertex
+ "GL_IBM_cull_vertex",
+#endif
+#ifdef GL_IBM_multimode_draw_arrays
+ "GL_IBM_multimode_draw_arrays",
+#endif
+#ifdef GL_IBM_rasterpos_clip
+ "GL_IBM_rasterpos_clip",
+#endif
+#ifdef GL_IBM_static_data
+ "GL_IBM_static_data",
+#endif
+#ifdef GL_IBM_texture_mirrored_repeat
+ "GL_IBM_texture_mirrored_repeat",
+#endif
+#ifdef GL_IBM_vertex_array_lists
+ "GL_IBM_vertex_array_lists",
+#endif
+#ifdef GL_INGR_color_clamp
+ "GL_INGR_color_clamp",
+#endif
+#ifdef GL_INGR_interlace_read
+ "GL_INGR_interlace_read",
+#endif
+#ifdef GL_INTEL_conservative_rasterization
+ "GL_INTEL_conservative_rasterization",
+#endif
+#ifdef GL_INTEL_fragment_shader_ordering
+ "GL_INTEL_fragment_shader_ordering",
+#endif
+#ifdef GL_INTEL_framebuffer_CMAA
+ "GL_INTEL_framebuffer_CMAA",
+#endif
+#ifdef GL_INTEL_map_texture
+ "GL_INTEL_map_texture",
+#endif
+#ifdef GL_INTEL_parallel_arrays
+ "GL_INTEL_parallel_arrays",
+#endif
+#ifdef GL_INTEL_performance_query
+ "GL_INTEL_performance_query",
+#endif
+#ifdef GL_INTEL_texture_scissor
+ "GL_INTEL_texture_scissor",
+#endif
+#ifdef GL_KHR_blend_equation_advanced
+ "GL_KHR_blend_equation_advanced",
+#endif
+#ifdef GL_KHR_blend_equation_advanced_coherent
+ "GL_KHR_blend_equation_advanced_coherent",
+#endif
+#ifdef GL_KHR_context_flush_control
+ "GL_KHR_context_flush_control",
+#endif
+#ifdef GL_KHR_debug
+ "GL_KHR_debug",
+#endif
+#ifdef GL_KHR_no_error
+ "GL_KHR_no_error",
+#endif
+#ifdef GL_KHR_robust_buffer_access_behavior
+ "GL_KHR_robust_buffer_access_behavior",
+#endif
+#ifdef GL_KHR_robustness
+ "GL_KHR_robustness",
+#endif
+#ifdef GL_KHR_texture_compression_astc_hdr
+ "GL_KHR_texture_compression_astc_hdr",
+#endif
+#ifdef GL_KHR_texture_compression_astc_ldr
+ "GL_KHR_texture_compression_astc_ldr",
+#endif
+#ifdef GL_KHR_texture_compression_astc_sliced_3d
+ "GL_KHR_texture_compression_astc_sliced_3d",
+#endif
+#ifdef GL_KTX_buffer_region
+ "GL_KTX_buffer_region",
+#endif
+#ifdef GL_MESAX_texture_stack
+ "GL_MESAX_texture_stack",
+#endif
+#ifdef GL_MESA_pack_invert
+ "GL_MESA_pack_invert",
+#endif
+#ifdef GL_MESA_resize_buffers
+ "GL_MESA_resize_buffers",
+#endif
+#ifdef GL_MESA_shader_integer_functions
+ "GL_MESA_shader_integer_functions",
+#endif
+#ifdef GL_MESA_window_pos
+ "GL_MESA_window_pos",
+#endif
+#ifdef GL_MESA_ycbcr_texture
+ "GL_MESA_ycbcr_texture",
+#endif
+#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers
+ "GL_NVX_blend_equation_advanced_multi_draw_buffers",
+#endif
+#ifdef GL_NVX_conditional_render
+ "GL_NVX_conditional_render",
+#endif
+#ifdef GL_NVX_gpu_memory_info
+ "GL_NVX_gpu_memory_info",
+#endif
+#ifdef GL_NVX_linked_gpu_multicast
+ "GL_NVX_linked_gpu_multicast",
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect
+ "GL_NV_bindless_multi_draw_indirect",
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+ "GL_NV_bindless_multi_draw_indirect_count",
+#endif
+#ifdef GL_NV_bindless_texture
+ "GL_NV_bindless_texture",
+#endif
+#ifdef GL_NV_blend_equation_advanced
+ "GL_NV_blend_equation_advanced",
+#endif
+#ifdef GL_NV_blend_equation_advanced_coherent
+ "GL_NV_blend_equation_advanced_coherent",
+#endif
+#ifdef GL_NV_blend_square
+ "GL_NV_blend_square",
+#endif
+#ifdef GL_NV_clip_space_w_scaling
+ "GL_NV_clip_space_w_scaling",
+#endif
+#ifdef GL_NV_command_list
+ "GL_NV_command_list",
+#endif
+#ifdef GL_NV_compute_program5
+ "GL_NV_compute_program5",
+#endif
+#ifdef GL_NV_conditional_render
+ "GL_NV_conditional_render",
+#endif
+#ifdef GL_NV_conservative_raster
+ "GL_NV_conservative_raster",
+#endif
+#ifdef GL_NV_conservative_raster_dilate
+ "GL_NV_conservative_raster_dilate",
+#endif
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ "GL_NV_conservative_raster_pre_snap_triangles",
+#endif
+#ifdef GL_NV_copy_depth_to_color
+ "GL_NV_copy_depth_to_color",
+#endif
+#ifdef GL_NV_copy_image
+ "GL_NV_copy_image",
+#endif
+#ifdef GL_NV_deep_texture3D
+ "GL_NV_deep_texture3D",
+#endif
+#ifdef GL_NV_depth_buffer_float
+ "GL_NV_depth_buffer_float",
+#endif
+#ifdef GL_NV_depth_clamp
+ "GL_NV_depth_clamp",
+#endif
+#ifdef GL_NV_depth_range_unclamped
+ "GL_NV_depth_range_unclamped",
+#endif
+#ifdef GL_NV_draw_texture
+ "GL_NV_draw_texture",
+#endif
+#ifdef GL_NV_draw_vulkan_image
+ "GL_NV_draw_vulkan_image",
+#endif
+#ifdef GL_NV_evaluators
+ "GL_NV_evaluators",
+#endif
+#ifdef GL_NV_explicit_multisample
+ "GL_NV_explicit_multisample",
+#endif
+#ifdef GL_NV_fence
+ "GL_NV_fence",
+#endif
+#ifdef GL_NV_fill_rectangle
+ "GL_NV_fill_rectangle",
+#endif
+#ifdef GL_NV_float_buffer
+ "GL_NV_float_buffer",
+#endif
+#ifdef GL_NV_fog_distance
+ "GL_NV_fog_distance",
+#endif
+#ifdef GL_NV_fragment_coverage_to_color
+ "GL_NV_fragment_coverage_to_color",
+#endif
+#ifdef GL_NV_fragment_program
+ "GL_NV_fragment_program",
+#endif
+#ifdef GL_NV_fragment_program2
+ "GL_NV_fragment_program2",
+#endif
+#ifdef GL_NV_fragment_program4
+ "GL_NV_fragment_program4",
+#endif
+#ifdef GL_NV_fragment_program_option
+ "GL_NV_fragment_program_option",
+#endif
+#ifdef GL_NV_fragment_shader_interlock
+ "GL_NV_fragment_shader_interlock",
+#endif
+#ifdef GL_NV_framebuffer_mixed_samples
+ "GL_NV_framebuffer_mixed_samples",
+#endif
+#ifdef GL_NV_framebuffer_multisample_coverage
+ "GL_NV_framebuffer_multisample_coverage",
+#endif
+#ifdef GL_NV_geometry_program4
+ "GL_NV_geometry_program4",
+#endif
+#ifdef GL_NV_geometry_shader4
+ "GL_NV_geometry_shader4",
+#endif
+#ifdef GL_NV_geometry_shader_passthrough
+ "GL_NV_geometry_shader_passthrough",
+#endif
+#ifdef GL_NV_gpu_multicast
+ "GL_NV_gpu_multicast",
+#endif
+#ifdef GL_NV_gpu_program4
+ "GL_NV_gpu_program4",
+#endif
+#ifdef GL_NV_gpu_program5
+ "GL_NV_gpu_program5",
+#endif
+#ifdef GL_NV_gpu_program5_mem_extended
+ "GL_NV_gpu_program5_mem_extended",
+#endif
+#ifdef GL_NV_gpu_program_fp64
+ "GL_NV_gpu_program_fp64",
+#endif
+#ifdef GL_NV_gpu_shader5
+ "GL_NV_gpu_shader5",
+#endif
+#ifdef GL_NV_half_float
+ "GL_NV_half_float",
+#endif
+#ifdef GL_NV_internalformat_sample_query
+ "GL_NV_internalformat_sample_query",
+#endif
+#ifdef GL_NV_light_max_exponent
+ "GL_NV_light_max_exponent",
+#endif
+#ifdef GL_NV_multisample_coverage
+ "GL_NV_multisample_coverage",
+#endif
+#ifdef GL_NV_multisample_filter_hint
+ "GL_NV_multisample_filter_hint",
+#endif
+#ifdef GL_NV_occlusion_query
+ "GL_NV_occlusion_query",
+#endif
+#ifdef GL_NV_packed_depth_stencil
+ "GL_NV_packed_depth_stencil",
+#endif
+#ifdef GL_NV_parameter_buffer_object
+ "GL_NV_parameter_buffer_object",
+#endif
+#ifdef GL_NV_parameter_buffer_object2
+ "GL_NV_parameter_buffer_object2",
+#endif
+#ifdef GL_NV_path_rendering
+ "GL_NV_path_rendering",
+#endif
+#ifdef GL_NV_path_rendering_shared_edge
+ "GL_NV_path_rendering_shared_edge",
+#endif
+#ifdef GL_NV_pixel_data_range
+ "GL_NV_pixel_data_range",
+#endif
+#ifdef GL_NV_point_sprite
+ "GL_NV_point_sprite",
+#endif
+#ifdef GL_NV_present_video
+ "GL_NV_present_video",
+#endif
+#ifdef GL_NV_primitive_restart
+ "GL_NV_primitive_restart",
+#endif
+#ifdef GL_NV_register_combiners
+ "GL_NV_register_combiners",
+#endif
+#ifdef GL_NV_register_combiners2
+ "GL_NV_register_combiners2",
+#endif
+#ifdef GL_NV_robustness_video_memory_purge
+ "GL_NV_robustness_video_memory_purge",
+#endif
+#ifdef GL_NV_sample_locations
+ "GL_NV_sample_locations",
+#endif
+#ifdef GL_NV_sample_mask_override_coverage
+ "GL_NV_sample_mask_override_coverage",
+#endif
+#ifdef GL_NV_shader_atomic_counters
+ "GL_NV_shader_atomic_counters",
+#endif
+#ifdef GL_NV_shader_atomic_float
+ "GL_NV_shader_atomic_float",
+#endif
+#ifdef GL_NV_shader_atomic_float64
+ "GL_NV_shader_atomic_float64",
+#endif
+#ifdef GL_NV_shader_atomic_fp16_vector
+ "GL_NV_shader_atomic_fp16_vector",
+#endif
+#ifdef GL_NV_shader_atomic_int64
+ "GL_NV_shader_atomic_int64",
+#endif
+#ifdef GL_NV_shader_buffer_load
+ "GL_NV_shader_buffer_load",
+#endif
+#ifdef GL_NV_shader_storage_buffer_object
+ "GL_NV_shader_storage_buffer_object",
+#endif
+#ifdef GL_NV_shader_thread_group
+ "GL_NV_shader_thread_group",
+#endif
+#ifdef GL_NV_shader_thread_shuffle
+ "GL_NV_shader_thread_shuffle",
+#endif
+#ifdef GL_NV_stereo_view_rendering
+ "GL_NV_stereo_view_rendering",
+#endif
+#ifdef GL_NV_tessellation_program5
+ "GL_NV_tessellation_program5",
+#endif
+#ifdef GL_NV_texgen_emboss
+ "GL_NV_texgen_emboss",
+#endif
+#ifdef GL_NV_texgen_reflection
+ "GL_NV_texgen_reflection",
+#endif
+#ifdef GL_NV_texture_barrier
+ "GL_NV_texture_barrier",
+#endif
+#ifdef GL_NV_texture_compression_vtc
+ "GL_NV_texture_compression_vtc",
+#endif
+#ifdef GL_NV_texture_env_combine4
+ "GL_NV_texture_env_combine4",
+#endif
+#ifdef GL_NV_texture_expand_normal
+ "GL_NV_texture_expand_normal",
+#endif
+#ifdef GL_NV_texture_multisample
+ "GL_NV_texture_multisample",
+#endif
+#ifdef GL_NV_texture_rectangle
+ "GL_NV_texture_rectangle",
+#endif
+#ifdef GL_NV_texture_shader
+ "GL_NV_texture_shader",
+#endif
+#ifdef GL_NV_texture_shader2
+ "GL_NV_texture_shader2",
+#endif
+#ifdef GL_NV_texture_shader3
+ "GL_NV_texture_shader3",
+#endif
+#ifdef GL_NV_transform_feedback
+ "GL_NV_transform_feedback",
+#endif
+#ifdef GL_NV_transform_feedback2
+ "GL_NV_transform_feedback2",
+#endif
+#ifdef GL_NV_uniform_buffer_unified_memory
+ "GL_NV_uniform_buffer_unified_memory",
+#endif
+#ifdef GL_NV_vdpau_interop
+ "GL_NV_vdpau_interop",
+#endif
+#ifdef GL_NV_vertex_array_range
+ "GL_NV_vertex_array_range",
+#endif
+#ifdef GL_NV_vertex_array_range2
+ "GL_NV_vertex_array_range2",
+#endif
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ "GL_NV_vertex_attrib_integer_64bit",
+#endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+ "GL_NV_vertex_buffer_unified_memory",
+#endif
+#ifdef GL_NV_vertex_program
+ "GL_NV_vertex_program",
+#endif
+#ifdef GL_NV_vertex_program1_1
+ "GL_NV_vertex_program1_1",
+#endif
+#ifdef GL_NV_vertex_program2
+ "GL_NV_vertex_program2",
+#endif
+#ifdef GL_NV_vertex_program2_option
+ "GL_NV_vertex_program2_option",
+#endif
+#ifdef GL_NV_vertex_program3
+ "GL_NV_vertex_program3",
+#endif
+#ifdef GL_NV_vertex_program4
+ "GL_NV_vertex_program4",
+#endif
+#ifdef GL_NV_video_capture
+ "GL_NV_video_capture",
+#endif
+#ifdef GL_NV_viewport_array2
+ "GL_NV_viewport_array2",
+#endif
+#ifdef GL_NV_viewport_swizzle
+ "GL_NV_viewport_swizzle",
+#endif
+#ifdef GL_OES_byte_coordinates
+ "GL_OES_byte_coordinates",
+#endif
+#ifdef GL_OES_compressed_paletted_texture
+ "GL_OES_compressed_paletted_texture",
+#endif
+#ifdef GL_OES_read_format
+ "GL_OES_read_format",
+#endif
+#ifdef GL_OES_single_precision
+ "GL_OES_single_precision",
+#endif
+#ifdef GL_OML_interlace
+ "GL_OML_interlace",
+#endif
+#ifdef GL_OML_resample
+ "GL_OML_resample",
+#endif
+#ifdef GL_OML_subsample
+ "GL_OML_subsample",
+#endif
+#ifdef GL_OVR_multiview
+ "GL_OVR_multiview",
+#endif
+#ifdef GL_OVR_multiview2
+ "GL_OVR_multiview2",
+#endif
+#ifdef GL_PGI_misc_hints
+ "GL_PGI_misc_hints",
+#endif
+#ifdef GL_PGI_vertex_hints
+ "GL_PGI_vertex_hints",
+#endif
+#ifdef GL_REGAL_ES1_0_compatibility
+ "GL_REGAL_ES1_0_compatibility",
+#endif
+#ifdef GL_REGAL_ES1_1_compatibility
+ "GL_REGAL_ES1_1_compatibility",
+#endif
+#ifdef GL_REGAL_enable
+ "GL_REGAL_enable",
+#endif
+#ifdef GL_REGAL_error_string
+ "GL_REGAL_error_string",
+#endif
+#ifdef GL_REGAL_extension_query
+ "GL_REGAL_extension_query",
+#endif
+#ifdef GL_REGAL_log
+ "GL_REGAL_log",
+#endif
+#ifdef GL_REGAL_proc_address
+ "GL_REGAL_proc_address",
+#endif
+#ifdef GL_REND_screen_coordinates
+ "GL_REND_screen_coordinates",
+#endif
+#ifdef GL_S3_s3tc
+ "GL_S3_s3tc",
+#endif
+#ifdef GL_SGIS_color_range
+ "GL_SGIS_color_range",
+#endif
+#ifdef GL_SGIS_detail_texture
+ "GL_SGIS_detail_texture",
+#endif
+#ifdef GL_SGIS_fog_function
+ "GL_SGIS_fog_function",
+#endif
+#ifdef GL_SGIS_generate_mipmap
+ "GL_SGIS_generate_mipmap",
+#endif
+#ifdef GL_SGIS_multisample
+ "GL_SGIS_multisample",
+#endif
+#ifdef GL_SGIS_pixel_texture
+ "GL_SGIS_pixel_texture",
+#endif
+#ifdef GL_SGIS_point_line_texgen
+ "GL_SGIS_point_line_texgen",
+#endif
+#ifdef GL_SGIS_sharpen_texture
+ "GL_SGIS_sharpen_texture",
+#endif
+#ifdef GL_SGIS_texture4D
+ "GL_SGIS_texture4D",
+#endif
+#ifdef GL_SGIS_texture_border_clamp
+ "GL_SGIS_texture_border_clamp",
+#endif
+#ifdef GL_SGIS_texture_edge_clamp
+ "GL_SGIS_texture_edge_clamp",
+#endif
+#ifdef GL_SGIS_texture_filter4
+ "GL_SGIS_texture_filter4",
+#endif
+#ifdef GL_SGIS_texture_lod
+ "GL_SGIS_texture_lod",
+#endif
+#ifdef GL_SGIS_texture_select
+ "GL_SGIS_texture_select",
+#endif
+#ifdef GL_SGIX_async
+ "GL_SGIX_async",
+#endif
+#ifdef GL_SGIX_async_histogram
+ "GL_SGIX_async_histogram",
+#endif
+#ifdef GL_SGIX_async_pixel
+ "GL_SGIX_async_pixel",
+#endif
+#ifdef GL_SGIX_blend_alpha_minmax
+ "GL_SGIX_blend_alpha_minmax",
+#endif
+#ifdef GL_SGIX_clipmap
+ "GL_SGIX_clipmap",
+#endif
+#ifdef GL_SGIX_convolution_accuracy
+ "GL_SGIX_convolution_accuracy",
+#endif
+#ifdef GL_SGIX_depth_texture
+ "GL_SGIX_depth_texture",
+#endif
+#ifdef GL_SGIX_flush_raster
+ "GL_SGIX_flush_raster",
+#endif
+#ifdef GL_SGIX_fog_offset
+ "GL_SGIX_fog_offset",
+#endif
+#ifdef GL_SGIX_fog_texture
+ "GL_SGIX_fog_texture",
+#endif
+#ifdef GL_SGIX_fragment_specular_lighting
+ "GL_SGIX_fragment_specular_lighting",
+#endif
+#ifdef GL_SGIX_framezoom
+ "GL_SGIX_framezoom",
+#endif
+#ifdef GL_SGIX_interlace
+ "GL_SGIX_interlace",
+#endif
+#ifdef GL_SGIX_ir_instrument1
+ "GL_SGIX_ir_instrument1",
+#endif
+#ifdef GL_SGIX_list_priority
+ "GL_SGIX_list_priority",
+#endif
+#ifdef GL_SGIX_pixel_texture
+ "GL_SGIX_pixel_texture",
+#endif
+#ifdef GL_SGIX_pixel_texture_bits
+ "GL_SGIX_pixel_texture_bits",
+#endif
+#ifdef GL_SGIX_reference_plane
+ "GL_SGIX_reference_plane",
+#endif
+#ifdef GL_SGIX_resample
+ "GL_SGIX_resample",
+#endif
+#ifdef GL_SGIX_shadow
+ "GL_SGIX_shadow",
+#endif
+#ifdef GL_SGIX_shadow_ambient
+ "GL_SGIX_shadow_ambient",
+#endif
+#ifdef GL_SGIX_sprite
+ "GL_SGIX_sprite",
+#endif
+#ifdef GL_SGIX_tag_sample_buffer
+ "GL_SGIX_tag_sample_buffer",
+#endif
+#ifdef GL_SGIX_texture_add_env
+ "GL_SGIX_texture_add_env",
+#endif
+#ifdef GL_SGIX_texture_coordinate_clamp
+ "GL_SGIX_texture_coordinate_clamp",
+#endif
+#ifdef GL_SGIX_texture_lod_bias
+ "GL_SGIX_texture_lod_bias",
+#endif
+#ifdef GL_SGIX_texture_multi_buffer
+ "GL_SGIX_texture_multi_buffer",
+#endif
+#ifdef GL_SGIX_texture_range
+ "GL_SGIX_texture_range",
+#endif
+#ifdef GL_SGIX_texture_scale_bias
+ "GL_SGIX_texture_scale_bias",
+#endif
+#ifdef GL_SGIX_vertex_preclip
+ "GL_SGIX_vertex_preclip",
+#endif
+#ifdef GL_SGIX_vertex_preclip_hint
+ "GL_SGIX_vertex_preclip_hint",
+#endif
+#ifdef GL_SGIX_ycrcb
+ "GL_SGIX_ycrcb",
+#endif
+#ifdef GL_SGI_color_matrix
+ "GL_SGI_color_matrix",
+#endif
+#ifdef GL_SGI_color_table
+ "GL_SGI_color_table",
+#endif
+#ifdef GL_SGI_texture_color_table
+ "GL_SGI_texture_color_table",
+#endif
+#ifdef GL_SUNX_constant_data
+ "GL_SUNX_constant_data",
+#endif
+#ifdef GL_SUN_convolution_border_modes
+ "GL_SUN_convolution_border_modes",
+#endif
+#ifdef GL_SUN_global_alpha
+ "GL_SUN_global_alpha",
+#endif
+#ifdef GL_SUN_mesh_array
+ "GL_SUN_mesh_array",
+#endif
+#ifdef GL_SUN_read_video_pixels
+ "GL_SUN_read_video_pixels",
+#endif
+#ifdef GL_SUN_slice_accum
+ "GL_SUN_slice_accum",
+#endif
+#ifdef GL_SUN_triangle_list
+ "GL_SUN_triangle_list",
+#endif
+#ifdef GL_SUN_vertex
+ "GL_SUN_vertex",
+#endif
+#ifdef GL_WIN_phong_shading
+ "GL_WIN_phong_shading",
+#endif
+#ifdef GL_WIN_specular_fog
+ "GL_WIN_specular_fog",
+#endif
+#ifdef GL_WIN_swap_hint
+ "GL_WIN_swap_hint",
+#endif
+ NULL
+};
+
+/* Detected in the extension string or strings */
+static GLboolean _glewExtensionString[603];
+/* Detected via extension string or experimental mode */
+static GLboolean* _glewExtensionEnabled[] = {
+#ifdef GL_VERSION_1_2
+ &__GLEW_VERSION_1_2,
+#endif
+#ifdef GL_VERSION_1_2_1
+ &__GLEW_VERSION_1_2_1,
+#endif
+#ifdef GL_VERSION_1_3
+ &__GLEW_VERSION_1_3,
+#endif
+#ifdef GL_VERSION_1_4
+ &__GLEW_VERSION_1_4,
+#endif
+#ifdef GL_VERSION_1_5
+ &__GLEW_VERSION_1_5,
+#endif
+#ifdef GL_VERSION_2_0
+ &__GLEW_VERSION_2_0,
+#endif
+#ifdef GL_VERSION_2_1
+ &__GLEW_VERSION_2_1,
+#endif
+#ifdef GL_VERSION_3_0
+ &__GLEW_VERSION_3_0,
+#endif
+#ifdef GL_VERSION_3_1
+ &__GLEW_VERSION_3_1,
+#endif
+#ifdef GL_VERSION_3_2
+ &__GLEW_VERSION_3_2,
+#endif
+#ifdef GL_VERSION_3_3
+ &__GLEW_VERSION_3_3,
+#endif
+#ifdef GL_VERSION_4_0
+ &__GLEW_VERSION_4_0,
+#endif
+#ifdef GL_VERSION_4_1
+ &__GLEW_VERSION_4_1,
+#endif
+#ifdef GL_VERSION_4_2
+ &__GLEW_VERSION_4_2,
+#endif
+#ifdef GL_VERSION_4_3
+ &__GLEW_VERSION_4_3,
+#endif
+#ifdef GL_VERSION_4_4
+ &__GLEW_VERSION_4_4,
+#endif
+#ifdef GL_VERSION_4_5
+ &__GLEW_VERSION_4_5,
+#endif
+#ifdef GL_3DFX_multisample
+ &__GLEW_3DFX_multisample,
+#endif
+#ifdef GL_3DFX_tbuffer
+ &__GLEW_3DFX_tbuffer,
+#endif
+#ifdef GL_3DFX_texture_compression_FXT1
+ &__GLEW_3DFX_texture_compression_FXT1,
+#endif
+#ifdef GL_AMD_blend_minmax_factor
+ &__GLEW_AMD_blend_minmax_factor,
+#endif
+#ifdef GL_AMD_conservative_depth
+ &__GLEW_AMD_conservative_depth,
+#endif
+#ifdef GL_AMD_debug_output
+ &__GLEW_AMD_debug_output,
+#endif
+#ifdef GL_AMD_depth_clamp_separate
+ &__GLEW_AMD_depth_clamp_separate,
+#endif
+#ifdef GL_AMD_draw_buffers_blend
+ &__GLEW_AMD_draw_buffers_blend,
+#endif
+#ifdef GL_AMD_gcn_shader
+ &__GLEW_AMD_gcn_shader,
+#endif
+#ifdef GL_AMD_gpu_shader_int64
+ &__GLEW_AMD_gpu_shader_int64,
+#endif
+#ifdef GL_AMD_interleaved_elements
+ &__GLEW_AMD_interleaved_elements,
+#endif
+#ifdef GL_AMD_multi_draw_indirect
+ &__GLEW_AMD_multi_draw_indirect,
+#endif
+#ifdef GL_AMD_name_gen_delete
+ &__GLEW_AMD_name_gen_delete,
+#endif
+#ifdef GL_AMD_occlusion_query_event
+ &__GLEW_AMD_occlusion_query_event,
+#endif
+#ifdef GL_AMD_performance_monitor
+ &__GLEW_AMD_performance_monitor,
+#endif
+#ifdef GL_AMD_pinned_memory
+ &__GLEW_AMD_pinned_memory,
+#endif
+#ifdef GL_AMD_query_buffer_object
+ &__GLEW_AMD_query_buffer_object,
+#endif
+#ifdef GL_AMD_sample_positions
+ &__GLEW_AMD_sample_positions,
+#endif
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ &__GLEW_AMD_seamless_cubemap_per_texture,
+#endif
+#ifdef GL_AMD_shader_atomic_counter_ops
+ &__GLEW_AMD_shader_atomic_counter_ops,
+#endif
+#ifdef GL_AMD_shader_explicit_vertex_parameter
+ &__GLEW_AMD_shader_explicit_vertex_parameter,
+#endif
+#ifdef GL_AMD_shader_stencil_export
+ &__GLEW_AMD_shader_stencil_export,
+#endif
+#ifdef GL_AMD_shader_stencil_value_export
+ &__GLEW_AMD_shader_stencil_value_export,
+#endif
+#ifdef GL_AMD_shader_trinary_minmax
+ &__GLEW_AMD_shader_trinary_minmax,
+#endif
+#ifdef GL_AMD_sparse_texture
+ &__GLEW_AMD_sparse_texture,
+#endif
+#ifdef GL_AMD_stencil_operation_extended
+ &__GLEW_AMD_stencil_operation_extended,
+#endif
+#ifdef GL_AMD_texture_texture4
+ &__GLEW_AMD_texture_texture4,
+#endif
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ &__GLEW_AMD_transform_feedback3_lines_triangles,
+#endif
+#ifdef GL_AMD_transform_feedback4
+ &__GLEW_AMD_transform_feedback4,
+#endif
+#ifdef GL_AMD_vertex_shader_layer
+ &__GLEW_AMD_vertex_shader_layer,
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+ &__GLEW_AMD_vertex_shader_tessellator,
+#endif
+#ifdef GL_AMD_vertex_shader_viewport_index
+ &__GLEW_AMD_vertex_shader_viewport_index,
+#endif
+#ifdef GL_ANGLE_depth_texture
+ &__GLEW_ANGLE_depth_texture,
+#endif
+#ifdef GL_ANGLE_framebuffer_blit
+ &__GLEW_ANGLE_framebuffer_blit,
+#endif
+#ifdef GL_ANGLE_framebuffer_multisample
+ &__GLEW_ANGLE_framebuffer_multisample,
+#endif
+#ifdef GL_ANGLE_instanced_arrays
+ &__GLEW_ANGLE_instanced_arrays,
+#endif
+#ifdef GL_ANGLE_pack_reverse_row_order
+ &__GLEW_ANGLE_pack_reverse_row_order,
+#endif
+#ifdef GL_ANGLE_program_binary
+ &__GLEW_ANGLE_program_binary,
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt1
+ &__GLEW_ANGLE_texture_compression_dxt1,
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt3
+ &__GLEW_ANGLE_texture_compression_dxt3,
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt5
+ &__GLEW_ANGLE_texture_compression_dxt5,
+#endif
+#ifdef GL_ANGLE_texture_usage
+ &__GLEW_ANGLE_texture_usage,
+#endif
+#ifdef GL_ANGLE_timer_query
+ &__GLEW_ANGLE_timer_query,
+#endif
+#ifdef GL_ANGLE_translated_shader_source
+ &__GLEW_ANGLE_translated_shader_source,
+#endif
+#ifdef GL_APPLE_aux_depth_stencil
+ &__GLEW_APPLE_aux_depth_stencil,
+#endif
+#ifdef GL_APPLE_client_storage
+ &__GLEW_APPLE_client_storage,
+#endif
+#ifdef GL_APPLE_element_array
+ &__GLEW_APPLE_element_array,
+#endif
+#ifdef GL_APPLE_fence
+ &__GLEW_APPLE_fence,
+#endif
+#ifdef GL_APPLE_float_pixels
+ &__GLEW_APPLE_float_pixels,
+#endif
+#ifdef GL_APPLE_flush_buffer_range
+ &__GLEW_APPLE_flush_buffer_range,
+#endif
+#ifdef GL_APPLE_object_purgeable
+ &__GLEW_APPLE_object_purgeable,
+#endif
+#ifdef GL_APPLE_pixel_buffer
+ &__GLEW_APPLE_pixel_buffer,
+#endif
+#ifdef GL_APPLE_rgb_422
+ &__GLEW_APPLE_rgb_422,
+#endif
+#ifdef GL_APPLE_row_bytes
+ &__GLEW_APPLE_row_bytes,
+#endif
+#ifdef GL_APPLE_specular_vector
+ &__GLEW_APPLE_specular_vector,
+#endif
+#ifdef GL_APPLE_texture_range
+ &__GLEW_APPLE_texture_range,
+#endif
+#ifdef GL_APPLE_transform_hint
+ &__GLEW_APPLE_transform_hint,
+#endif
+#ifdef GL_APPLE_vertex_array_object
+ &__GLEW_APPLE_vertex_array_object,
+#endif
+#ifdef GL_APPLE_vertex_array_range
+ &__GLEW_APPLE_vertex_array_range,
+#endif
+#ifdef GL_APPLE_vertex_program_evaluators
+ &__GLEW_APPLE_vertex_program_evaluators,
+#endif
+#ifdef GL_APPLE_ycbcr_422
+ &__GLEW_APPLE_ycbcr_422,
+#endif
+#ifdef GL_ARB_ES2_compatibility
+ &__GLEW_ARB_ES2_compatibility,
+#endif
+#ifdef GL_ARB_ES3_1_compatibility
+ &__GLEW_ARB_ES3_1_compatibility,
+#endif
+#ifdef GL_ARB_ES3_2_compatibility
+ &__GLEW_ARB_ES3_2_compatibility,
+#endif
+#ifdef GL_ARB_ES3_compatibility
+ &__GLEW_ARB_ES3_compatibility,
+#endif
+#ifdef GL_ARB_arrays_of_arrays
+ &__GLEW_ARB_arrays_of_arrays,
+#endif
+#ifdef GL_ARB_base_instance
+ &__GLEW_ARB_base_instance,
+#endif
+#ifdef GL_ARB_bindless_texture
+ &__GLEW_ARB_bindless_texture,
+#endif
+#ifdef GL_ARB_blend_func_extended
+ &__GLEW_ARB_blend_func_extended,
+#endif
+#ifdef GL_ARB_buffer_storage
+ &__GLEW_ARB_buffer_storage,
+#endif
+#ifdef GL_ARB_cl_event
+ &__GLEW_ARB_cl_event,
+#endif
+#ifdef GL_ARB_clear_buffer_object
+ &__GLEW_ARB_clear_buffer_object,
+#endif
+#ifdef GL_ARB_clear_texture
+ &__GLEW_ARB_clear_texture,
+#endif
+#ifdef GL_ARB_clip_control
+ &__GLEW_ARB_clip_control,
+#endif
+#ifdef GL_ARB_color_buffer_float
+ &__GLEW_ARB_color_buffer_float,
+#endif
+#ifdef GL_ARB_compatibility
+ &__GLEW_ARB_compatibility,
+#endif
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ &__GLEW_ARB_compressed_texture_pixel_storage,
+#endif
+#ifdef GL_ARB_compute_shader
+ &__GLEW_ARB_compute_shader,
+#endif
+#ifdef GL_ARB_compute_variable_group_size
+ &__GLEW_ARB_compute_variable_group_size,
+#endif
+#ifdef GL_ARB_conditional_render_inverted
+ &__GLEW_ARB_conditional_render_inverted,
+#endif
+#ifdef GL_ARB_conservative_depth
+ &__GLEW_ARB_conservative_depth,
+#endif
+#ifdef GL_ARB_copy_buffer
+ &__GLEW_ARB_copy_buffer,
+#endif
+#ifdef GL_ARB_copy_image
+ &__GLEW_ARB_copy_image,
+#endif
+#ifdef GL_ARB_cull_distance
+ &__GLEW_ARB_cull_distance,
+#endif
+#ifdef GL_ARB_debug_output
+ &__GLEW_ARB_debug_output,
+#endif
+#ifdef GL_ARB_depth_buffer_float
+ &__GLEW_ARB_depth_buffer_float,
+#endif
+#ifdef GL_ARB_depth_clamp
+ &__GLEW_ARB_depth_clamp,
+#endif
+#ifdef GL_ARB_depth_texture
+ &__GLEW_ARB_depth_texture,
+#endif
+#ifdef GL_ARB_derivative_control
+ &__GLEW_ARB_derivative_control,
+#endif
+#ifdef GL_ARB_direct_state_access
+ &__GLEW_ARB_direct_state_access,
+#endif
+#ifdef GL_ARB_draw_buffers
+ &__GLEW_ARB_draw_buffers,
+#endif
+#ifdef GL_ARB_draw_buffers_blend
+ &__GLEW_ARB_draw_buffers_blend,
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+ &__GLEW_ARB_draw_elements_base_vertex,
+#endif
+#ifdef GL_ARB_draw_indirect
+ &__GLEW_ARB_draw_indirect,
+#endif
+#ifdef GL_ARB_draw_instanced
+ &__GLEW_ARB_draw_instanced,
+#endif
+#ifdef GL_ARB_enhanced_layouts
+ &__GLEW_ARB_enhanced_layouts,
+#endif
+#ifdef GL_ARB_explicit_attrib_location
+ &__GLEW_ARB_explicit_attrib_location,
+#endif
+#ifdef GL_ARB_explicit_uniform_location
+ &__GLEW_ARB_explicit_uniform_location,
+#endif
+#ifdef GL_ARB_fragment_coord_conventions
+ &__GLEW_ARB_fragment_coord_conventions,
+#endif
+#ifdef GL_ARB_fragment_layer_viewport
+ &__GLEW_ARB_fragment_layer_viewport,
+#endif
+#ifdef GL_ARB_fragment_program
+ &__GLEW_ARB_fragment_program,
+#endif
+#ifdef GL_ARB_fragment_program_shadow
+ &__GLEW_ARB_fragment_program_shadow,
+#endif
+#ifdef GL_ARB_fragment_shader
+ &__GLEW_ARB_fragment_shader,
+#endif
+#ifdef GL_ARB_fragment_shader_interlock
+ &__GLEW_ARB_fragment_shader_interlock,
+#endif
+#ifdef GL_ARB_framebuffer_no_attachments
+ &__GLEW_ARB_framebuffer_no_attachments,
+#endif
+#ifdef GL_ARB_framebuffer_object
+ &__GLEW_ARB_framebuffer_object,
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ &__GLEW_ARB_framebuffer_sRGB,
+#endif
+#ifdef GL_ARB_geometry_shader4
+ &__GLEW_ARB_geometry_shader4,
+#endif
+#ifdef GL_ARB_get_program_binary
+ &__GLEW_ARB_get_program_binary,
+#endif
+#ifdef GL_ARB_get_texture_sub_image
+ &__GLEW_ARB_get_texture_sub_image,
+#endif
+#ifdef GL_ARB_gl_spirv
+ &__GLEW_ARB_gl_spirv,
+#endif
+#ifdef GL_ARB_gpu_shader5
+ &__GLEW_ARB_gpu_shader5,
+#endif
+#ifdef GL_ARB_gpu_shader_fp64
+ &__GLEW_ARB_gpu_shader_fp64,
+#endif
+#ifdef GL_ARB_gpu_shader_int64
+ &__GLEW_ARB_gpu_shader_int64,
+#endif
+#ifdef GL_ARB_half_float_pixel
+ &__GLEW_ARB_half_float_pixel,
+#endif
+#ifdef GL_ARB_half_float_vertex
+ &__GLEW_ARB_half_float_vertex,
+#endif
+#ifdef GL_ARB_imaging
+ &__GLEW_ARB_imaging,
+#endif
+#ifdef GL_ARB_indirect_parameters
+ &__GLEW_ARB_indirect_parameters,
+#endif
+#ifdef GL_ARB_instanced_arrays
+ &__GLEW_ARB_instanced_arrays,
+#endif
+#ifdef GL_ARB_internalformat_query
+ &__GLEW_ARB_internalformat_query,
+#endif
+#ifdef GL_ARB_internalformat_query2
+ &__GLEW_ARB_internalformat_query2,
+#endif
+#ifdef GL_ARB_invalidate_subdata
+ &__GLEW_ARB_invalidate_subdata,
+#endif
+#ifdef GL_ARB_map_buffer_alignment
+ &__GLEW_ARB_map_buffer_alignment,
+#endif
+#ifdef GL_ARB_map_buffer_range
+ &__GLEW_ARB_map_buffer_range,
+#endif
+#ifdef GL_ARB_matrix_palette
+ &__GLEW_ARB_matrix_palette,
+#endif
+#ifdef GL_ARB_multi_bind
+ &__GLEW_ARB_multi_bind,
+#endif
+#ifdef GL_ARB_multi_draw_indirect
+ &__GLEW_ARB_multi_draw_indirect,
+#endif
+#ifdef GL_ARB_multisample
+ &__GLEW_ARB_multisample,
+#endif
+#ifdef GL_ARB_multitexture
+ &__GLEW_ARB_multitexture,
+#endif
+#ifdef GL_ARB_occlusion_query
+ &__GLEW_ARB_occlusion_query,
+#endif
+#ifdef GL_ARB_occlusion_query2
+ &__GLEW_ARB_occlusion_query2,
+#endif
+#ifdef GL_ARB_parallel_shader_compile
+ &__GLEW_ARB_parallel_shader_compile,
+#endif
+#ifdef GL_ARB_pipeline_statistics_query
+ &__GLEW_ARB_pipeline_statistics_query,
+#endif
+#ifdef GL_ARB_pixel_buffer_object
+ &__GLEW_ARB_pixel_buffer_object,
+#endif
+#ifdef GL_ARB_point_parameters
+ &__GLEW_ARB_point_parameters,
+#endif
+#ifdef GL_ARB_point_sprite
+ &__GLEW_ARB_point_sprite,
+#endif
+#ifdef GL_ARB_post_depth_coverage
+ &__GLEW_ARB_post_depth_coverage,
+#endif
+#ifdef GL_ARB_program_interface_query
+ &__GLEW_ARB_program_interface_query,
+#endif
+#ifdef GL_ARB_provoking_vertex
+ &__GLEW_ARB_provoking_vertex,
+#endif
+#ifdef GL_ARB_query_buffer_object
+ &__GLEW_ARB_query_buffer_object,
+#endif
+#ifdef GL_ARB_robust_buffer_access_behavior
+ &__GLEW_ARB_robust_buffer_access_behavior,
+#endif
+#ifdef GL_ARB_robustness
+ &__GLEW_ARB_robustness,
+#endif
+#ifdef GL_ARB_robustness_application_isolation
+ &__GLEW_ARB_robustness_application_isolation,
+#endif
+#ifdef GL_ARB_robustness_share_group_isolation
+ &__GLEW_ARB_robustness_share_group_isolation,
+#endif
+#ifdef GL_ARB_sample_locations
+ &__GLEW_ARB_sample_locations,
+#endif
+#ifdef GL_ARB_sample_shading
+ &__GLEW_ARB_sample_shading,
+#endif
+#ifdef GL_ARB_sampler_objects
+ &__GLEW_ARB_sampler_objects,
+#endif
+#ifdef GL_ARB_seamless_cube_map
+ &__GLEW_ARB_seamless_cube_map,
+#endif
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ &__GLEW_ARB_seamless_cubemap_per_texture,
+#endif
+#ifdef GL_ARB_separate_shader_objects
+ &__GLEW_ARB_separate_shader_objects,
+#endif
+#ifdef GL_ARB_shader_atomic_counter_ops
+ &__GLEW_ARB_shader_atomic_counter_ops,
+#endif
+#ifdef GL_ARB_shader_atomic_counters
+ &__GLEW_ARB_shader_atomic_counters,
+#endif
+#ifdef GL_ARB_shader_ballot
+ &__GLEW_ARB_shader_ballot,
+#endif
+#ifdef GL_ARB_shader_bit_encoding
+ &__GLEW_ARB_shader_bit_encoding,
+#endif
+#ifdef GL_ARB_shader_clock
+ &__GLEW_ARB_shader_clock,
+#endif
+#ifdef GL_ARB_shader_draw_parameters
+ &__GLEW_ARB_shader_draw_parameters,
+#endif
+#ifdef GL_ARB_shader_group_vote
+ &__GLEW_ARB_shader_group_vote,
+#endif
+#ifdef GL_ARB_shader_image_load_store
+ &__GLEW_ARB_shader_image_load_store,
+#endif
+#ifdef GL_ARB_shader_image_size
+ &__GLEW_ARB_shader_image_size,
+#endif
+#ifdef GL_ARB_shader_objects
+ &__GLEW_ARB_shader_objects,
+#endif
+#ifdef GL_ARB_shader_precision
+ &__GLEW_ARB_shader_precision,
+#endif
+#ifdef GL_ARB_shader_stencil_export
+ &__GLEW_ARB_shader_stencil_export,
+#endif
+#ifdef GL_ARB_shader_storage_buffer_object
+ &__GLEW_ARB_shader_storage_buffer_object,
+#endif
+#ifdef GL_ARB_shader_subroutine
+ &__GLEW_ARB_shader_subroutine,
+#endif
+#ifdef GL_ARB_shader_texture_image_samples
+ &__GLEW_ARB_shader_texture_image_samples,
+#endif
+#ifdef GL_ARB_shader_texture_lod
+ &__GLEW_ARB_shader_texture_lod,
+#endif
+#ifdef GL_ARB_shader_viewport_layer_array
+ &__GLEW_ARB_shader_viewport_layer_array,
+#endif
+#ifdef GL_ARB_shading_language_100
+ &__GLEW_ARB_shading_language_100,
+#endif
+#ifdef GL_ARB_shading_language_420pack
+ &__GLEW_ARB_shading_language_420pack,
+#endif
+#ifdef GL_ARB_shading_language_include
+ &__GLEW_ARB_shading_language_include,
+#endif
+#ifdef GL_ARB_shading_language_packing
+ &__GLEW_ARB_shading_language_packing,
+#endif
+#ifdef GL_ARB_shadow
+ &__GLEW_ARB_shadow,
+#endif
+#ifdef GL_ARB_shadow_ambient
+ &__GLEW_ARB_shadow_ambient,
+#endif
+#ifdef GL_ARB_sparse_buffer
+ &__GLEW_ARB_sparse_buffer,
+#endif
+#ifdef GL_ARB_sparse_texture
+ &__GLEW_ARB_sparse_texture,
+#endif
+#ifdef GL_ARB_sparse_texture2
+ &__GLEW_ARB_sparse_texture2,
+#endif
+#ifdef GL_ARB_sparse_texture_clamp
+ &__GLEW_ARB_sparse_texture_clamp,
+#endif
+#ifdef GL_ARB_stencil_texturing
+ &__GLEW_ARB_stencil_texturing,
+#endif
+#ifdef GL_ARB_sync
+ &__GLEW_ARB_sync,
+#endif
+#ifdef GL_ARB_tessellation_shader
+ &__GLEW_ARB_tessellation_shader,
+#endif
+#ifdef GL_ARB_texture_barrier
+ &__GLEW_ARB_texture_barrier,
+#endif
+#ifdef GL_ARB_texture_border_clamp
+ &__GLEW_ARB_texture_border_clamp,
+#endif
+#ifdef GL_ARB_texture_buffer_object
+ &__GLEW_ARB_texture_buffer_object,
+#endif
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ &__GLEW_ARB_texture_buffer_object_rgb32,
+#endif
+#ifdef GL_ARB_texture_buffer_range
+ &__GLEW_ARB_texture_buffer_range,
+#endif
+#ifdef GL_ARB_texture_compression
+ &__GLEW_ARB_texture_compression,
+#endif
+#ifdef GL_ARB_texture_compression_bptc
+ &__GLEW_ARB_texture_compression_bptc,
+#endif
+#ifdef GL_ARB_texture_compression_rgtc
+ &__GLEW_ARB_texture_compression_rgtc,
+#endif
+#ifdef GL_ARB_texture_cube_map
+ &__GLEW_ARB_texture_cube_map,
+#endif
+#ifdef GL_ARB_texture_cube_map_array
+ &__GLEW_ARB_texture_cube_map_array,
+#endif
+#ifdef GL_ARB_texture_env_add
+ &__GLEW_ARB_texture_env_add,
+#endif
+#ifdef GL_ARB_texture_env_combine
+ &__GLEW_ARB_texture_env_combine,
+#endif
+#ifdef GL_ARB_texture_env_crossbar
+ &__GLEW_ARB_texture_env_crossbar,
+#endif
+#ifdef GL_ARB_texture_env_dot3
+ &__GLEW_ARB_texture_env_dot3,
+#endif
+#ifdef GL_ARB_texture_filter_minmax
+ &__GLEW_ARB_texture_filter_minmax,
+#endif
+#ifdef GL_ARB_texture_float
+ &__GLEW_ARB_texture_float,
+#endif
+#ifdef GL_ARB_texture_gather
+ &__GLEW_ARB_texture_gather,
+#endif
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ &__GLEW_ARB_texture_mirror_clamp_to_edge,
+#endif
+#ifdef GL_ARB_texture_mirrored_repeat
+ &__GLEW_ARB_texture_mirrored_repeat,
+#endif
+#ifdef GL_ARB_texture_multisample
+ &__GLEW_ARB_texture_multisample,
+#endif
+#ifdef GL_ARB_texture_non_power_of_two
+ &__GLEW_ARB_texture_non_power_of_two,
+#endif
+#ifdef GL_ARB_texture_query_levels
+ &__GLEW_ARB_texture_query_levels,
+#endif
+#ifdef GL_ARB_texture_query_lod
+ &__GLEW_ARB_texture_query_lod,
+#endif
+#ifdef GL_ARB_texture_rectangle
+ &__GLEW_ARB_texture_rectangle,
+#endif
+#ifdef GL_ARB_texture_rg
+ &__GLEW_ARB_texture_rg,
+#endif
+#ifdef GL_ARB_texture_rgb10_a2ui
+ &__GLEW_ARB_texture_rgb10_a2ui,
+#endif
+#ifdef GL_ARB_texture_stencil8
+ &__GLEW_ARB_texture_stencil8,
+#endif
+#ifdef GL_ARB_texture_storage
+ &__GLEW_ARB_texture_storage,
+#endif
+#ifdef GL_ARB_texture_storage_multisample
+ &__GLEW_ARB_texture_storage_multisample,
+#endif
+#ifdef GL_ARB_texture_swizzle
+ &__GLEW_ARB_texture_swizzle,
+#endif
+#ifdef GL_ARB_texture_view
+ &__GLEW_ARB_texture_view,
+#endif
+#ifdef GL_ARB_timer_query
+ &__GLEW_ARB_timer_query,
+#endif
+#ifdef GL_ARB_transform_feedback2
+ &__GLEW_ARB_transform_feedback2,
+#endif
+#ifdef GL_ARB_transform_feedback3
+ &__GLEW_ARB_transform_feedback3,
+#endif
+#ifdef GL_ARB_transform_feedback_instanced
+ &__GLEW_ARB_transform_feedback_instanced,
+#endif
+#ifdef GL_ARB_transform_feedback_overflow_query
+ &__GLEW_ARB_transform_feedback_overflow_query,
+#endif
+#ifdef GL_ARB_transpose_matrix
+ &__GLEW_ARB_transpose_matrix,
+#endif
+#ifdef GL_ARB_uniform_buffer_object
+ &__GLEW_ARB_uniform_buffer_object,
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+ &__GLEW_ARB_vertex_array_bgra,
+#endif
+#ifdef GL_ARB_vertex_array_object
+ &__GLEW_ARB_vertex_array_object,
+#endif
+#ifdef GL_ARB_vertex_attrib_64bit
+ &__GLEW_ARB_vertex_attrib_64bit,
+#endif
+#ifdef GL_ARB_vertex_attrib_binding
+ &__GLEW_ARB_vertex_attrib_binding,
+#endif
+#ifdef GL_ARB_vertex_blend
+ &__GLEW_ARB_vertex_blend,
+#endif
+#ifdef GL_ARB_vertex_buffer_object
+ &__GLEW_ARB_vertex_buffer_object,
+#endif
+#ifdef GL_ARB_vertex_program
+ &__GLEW_ARB_vertex_program,
+#endif
+#ifdef GL_ARB_vertex_shader
+ &__GLEW_ARB_vertex_shader,
+#endif
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ &__GLEW_ARB_vertex_type_10f_11f_11f_rev,
+#endif
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ &__GLEW_ARB_vertex_type_2_10_10_10_rev,
+#endif
+#ifdef GL_ARB_viewport_array
+ &__GLEW_ARB_viewport_array,
+#endif
+#ifdef GL_ARB_window_pos
+ &__GLEW_ARB_window_pos,
+#endif
+#ifdef GL_ATIX_point_sprites
+ &__GLEW_ATIX_point_sprites,
+#endif
+#ifdef GL_ATIX_texture_env_combine3
+ &__GLEW_ATIX_texture_env_combine3,
+#endif
+#ifdef GL_ATIX_texture_env_route
+ &__GLEW_ATIX_texture_env_route,
+#endif
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ &__GLEW_ATIX_vertex_shader_output_point_size,
+#endif
+#ifdef GL_ATI_draw_buffers
+ &__GLEW_ATI_draw_buffers,
+#endif
+#ifdef GL_ATI_element_array
+ &__GLEW_ATI_element_array,
+#endif
+#ifdef GL_ATI_envmap_bumpmap
+ &__GLEW_ATI_envmap_bumpmap,
+#endif
+#ifdef GL_ATI_fragment_shader
+ &__GLEW_ATI_fragment_shader,
+#endif
+#ifdef GL_ATI_map_object_buffer
+ &__GLEW_ATI_map_object_buffer,
+#endif
+#ifdef GL_ATI_meminfo
+ &__GLEW_ATI_meminfo,
+#endif
+#ifdef GL_ATI_pn_triangles
+ &__GLEW_ATI_pn_triangles,
+#endif
+#ifdef GL_ATI_separate_stencil
+ &__GLEW_ATI_separate_stencil,
+#endif
+#ifdef GL_ATI_shader_texture_lod
+ &__GLEW_ATI_shader_texture_lod,
+#endif
+#ifdef GL_ATI_text_fragment_shader
+ &__GLEW_ATI_text_fragment_shader,
+#endif
+#ifdef GL_ATI_texture_compression_3dc
+ &__GLEW_ATI_texture_compression_3dc,
+#endif
+#ifdef GL_ATI_texture_env_combine3
+ &__GLEW_ATI_texture_env_combine3,
+#endif
+#ifdef GL_ATI_texture_float
+ &__GLEW_ATI_texture_float,
+#endif
+#ifdef GL_ATI_texture_mirror_once
+ &__GLEW_ATI_texture_mirror_once,
+#endif
+#ifdef GL_ATI_vertex_array_object
+ &__GLEW_ATI_vertex_array_object,
+#endif
+#ifdef GL_ATI_vertex_attrib_array_object
+ &__GLEW_ATI_vertex_attrib_array_object,
+#endif
+#ifdef GL_ATI_vertex_streams
+ &__GLEW_ATI_vertex_streams,
+#endif
+#ifdef GL_EGL_NV_robustness_video_memory_purge
+ &__GLEW_EGL_NV_robustness_video_memory_purge,
+#endif
+#ifdef GL_EXT_422_pixels
+ &__GLEW_EXT_422_pixels,
+#endif
+#ifdef GL_EXT_Cg_shader
+ &__GLEW_EXT_Cg_shader,
+#endif
+#ifdef GL_EXT_abgr
+ &__GLEW_EXT_abgr,
+#endif
+#ifdef GL_EXT_bgra
+ &__GLEW_EXT_bgra,
+#endif
+#ifdef GL_EXT_bindable_uniform
+ &__GLEW_EXT_bindable_uniform,
+#endif
+#ifdef GL_EXT_blend_color
+ &__GLEW_EXT_blend_color,
+#endif
+#ifdef GL_EXT_blend_equation_separate
+ &__GLEW_EXT_blend_equation_separate,
+#endif
+#ifdef GL_EXT_blend_func_separate
+ &__GLEW_EXT_blend_func_separate,
+#endif
+#ifdef GL_EXT_blend_logic_op
+ &__GLEW_EXT_blend_logic_op,
+#endif
+#ifdef GL_EXT_blend_minmax
+ &__GLEW_EXT_blend_minmax,
+#endif
+#ifdef GL_EXT_blend_subtract
+ &__GLEW_EXT_blend_subtract,
+#endif
+#ifdef GL_EXT_clip_volume_hint
+ &__GLEW_EXT_clip_volume_hint,
+#endif
+#ifdef GL_EXT_cmyka
+ &__GLEW_EXT_cmyka,
+#endif
+#ifdef GL_EXT_color_subtable
+ &__GLEW_EXT_color_subtable,
+#endif
+#ifdef GL_EXT_compiled_vertex_array
+ &__GLEW_EXT_compiled_vertex_array,
+#endif
+#ifdef GL_EXT_convolution
+ &__GLEW_EXT_convolution,
+#endif
+#ifdef GL_EXT_coordinate_frame
+ &__GLEW_EXT_coordinate_frame,
+#endif
+#ifdef GL_EXT_copy_texture
+ &__GLEW_EXT_copy_texture,
+#endif
+#ifdef GL_EXT_cull_vertex
+ &__GLEW_EXT_cull_vertex,
+#endif
+#ifdef GL_EXT_debug_label
+ &__GLEW_EXT_debug_label,
+#endif
+#ifdef GL_EXT_debug_marker
+ &__GLEW_EXT_debug_marker,
+#endif
+#ifdef GL_EXT_depth_bounds_test
+ &__GLEW_EXT_depth_bounds_test,
+#endif
+#ifdef GL_EXT_direct_state_access
+ &__GLEW_EXT_direct_state_access,
+#endif
+#ifdef GL_EXT_draw_buffers2
+ &__GLEW_EXT_draw_buffers2,
+#endif
+#ifdef GL_EXT_draw_instanced
+ &__GLEW_EXT_draw_instanced,
+#endif
+#ifdef GL_EXT_draw_range_elements
+ &__GLEW_EXT_draw_range_elements,
+#endif
+#ifdef GL_EXT_fog_coord
+ &__GLEW_EXT_fog_coord,
+#endif
+#ifdef GL_EXT_fragment_lighting
+ &__GLEW_EXT_fragment_lighting,
+#endif
+#ifdef GL_EXT_framebuffer_blit
+ &__GLEW_EXT_framebuffer_blit,
+#endif
+#ifdef GL_EXT_framebuffer_multisample
+ &__GLEW_EXT_framebuffer_multisample,
+#endif
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ &__GLEW_EXT_framebuffer_multisample_blit_scaled,
+#endif
+#ifdef GL_EXT_framebuffer_object
+ &__GLEW_EXT_framebuffer_object,
+#endif
+#ifdef GL_EXT_framebuffer_sRGB
+ &__GLEW_EXT_framebuffer_sRGB,
+#endif
+#ifdef GL_EXT_geometry_shader4
+ &__GLEW_EXT_geometry_shader4,
+#endif
+#ifdef GL_EXT_gpu_program_parameters
+ &__GLEW_EXT_gpu_program_parameters,
+#endif
+#ifdef GL_EXT_gpu_shader4
+ &__GLEW_EXT_gpu_shader4,
+#endif
+#ifdef GL_EXT_histogram
+ &__GLEW_EXT_histogram,
+#endif
+#ifdef GL_EXT_index_array_formats
+ &__GLEW_EXT_index_array_formats,
+#endif
+#ifdef GL_EXT_index_func
+ &__GLEW_EXT_index_func,
+#endif
+#ifdef GL_EXT_index_material
+ &__GLEW_EXT_index_material,
+#endif
+#ifdef GL_EXT_index_texture
+ &__GLEW_EXT_index_texture,
+#endif
+#ifdef GL_EXT_light_texture
+ &__GLEW_EXT_light_texture,
+#endif
+#ifdef GL_EXT_misc_attribute
+ &__GLEW_EXT_misc_attribute,
+#endif
+#ifdef GL_EXT_multi_draw_arrays
+ &__GLEW_EXT_multi_draw_arrays,
+#endif
+#ifdef GL_EXT_multisample
+ &__GLEW_EXT_multisample,
+#endif
+#ifdef GL_EXT_packed_depth_stencil
+ &__GLEW_EXT_packed_depth_stencil,
+#endif
+#ifdef GL_EXT_packed_float
+ &__GLEW_EXT_packed_float,
+#endif
+#ifdef GL_EXT_packed_pixels
+ &__GLEW_EXT_packed_pixels,
+#endif
+#ifdef GL_EXT_paletted_texture
+ &__GLEW_EXT_paletted_texture,
+#endif
+#ifdef GL_EXT_pixel_buffer_object
+ &__GLEW_EXT_pixel_buffer_object,
+#endif
+#ifdef GL_EXT_pixel_transform
+ &__GLEW_EXT_pixel_transform,
+#endif
+#ifdef GL_EXT_pixel_transform_color_table
+ &__GLEW_EXT_pixel_transform_color_table,
+#endif
+#ifdef GL_EXT_point_parameters
+ &__GLEW_EXT_point_parameters,
+#endif
+#ifdef GL_EXT_polygon_offset
+ &__GLEW_EXT_polygon_offset,
+#endif
+#ifdef GL_EXT_polygon_offset_clamp
+ &__GLEW_EXT_polygon_offset_clamp,
+#endif
+#ifdef GL_EXT_post_depth_coverage
+ &__GLEW_EXT_post_depth_coverage,
+#endif
+#ifdef GL_EXT_provoking_vertex
+ &__GLEW_EXT_provoking_vertex,
+#endif
+#ifdef GL_EXT_raster_multisample
+ &__GLEW_EXT_raster_multisample,
+#endif
+#ifdef GL_EXT_rescale_normal
+ &__GLEW_EXT_rescale_normal,
+#endif
+#ifdef GL_EXT_scene_marker
+ &__GLEW_EXT_scene_marker,
+#endif
+#ifdef GL_EXT_secondary_color
+ &__GLEW_EXT_secondary_color,
+#endif
+#ifdef GL_EXT_separate_shader_objects
+ &__GLEW_EXT_separate_shader_objects,
+#endif
+#ifdef GL_EXT_separate_specular_color
+ &__GLEW_EXT_separate_specular_color,
+#endif
+#ifdef GL_EXT_shader_image_load_formatted
+ &__GLEW_EXT_shader_image_load_formatted,
+#endif
+#ifdef GL_EXT_shader_image_load_store
+ &__GLEW_EXT_shader_image_load_store,
+#endif
+#ifdef GL_EXT_shader_integer_mix
+ &__GLEW_EXT_shader_integer_mix,
+#endif
+#ifdef GL_EXT_shadow_funcs
+ &__GLEW_EXT_shadow_funcs,
+#endif
+#ifdef GL_EXT_shared_texture_palette
+ &__GLEW_EXT_shared_texture_palette,
+#endif
+#ifdef GL_EXT_sparse_texture2
+ &__GLEW_EXT_sparse_texture2,
+#endif
+#ifdef GL_EXT_stencil_clear_tag
+ &__GLEW_EXT_stencil_clear_tag,
+#endif
+#ifdef GL_EXT_stencil_two_side
+ &__GLEW_EXT_stencil_two_side,
+#endif
+#ifdef GL_EXT_stencil_wrap
+ &__GLEW_EXT_stencil_wrap,
+#endif
+#ifdef GL_EXT_subtexture
+ &__GLEW_EXT_subtexture,
+#endif
+#ifdef GL_EXT_texture
+ &__GLEW_EXT_texture,
+#endif
+#ifdef GL_EXT_texture3D
+ &__GLEW_EXT_texture3D,
+#endif
+#ifdef GL_EXT_texture_array
+ &__GLEW_EXT_texture_array,
+#endif
+#ifdef GL_EXT_texture_buffer_object
+ &__GLEW_EXT_texture_buffer_object,
+#endif
+#ifdef GL_EXT_texture_compression_dxt1
+ &__GLEW_EXT_texture_compression_dxt1,
+#endif
+#ifdef GL_EXT_texture_compression_latc
+ &__GLEW_EXT_texture_compression_latc,
+#endif
+#ifdef GL_EXT_texture_compression_rgtc
+ &__GLEW_EXT_texture_compression_rgtc,
+#endif
+#ifdef GL_EXT_texture_compression_s3tc
+ &__GLEW_EXT_texture_compression_s3tc,
+#endif
+#ifdef GL_EXT_texture_cube_map
+ &__GLEW_EXT_texture_cube_map,
+#endif
+#ifdef GL_EXT_texture_edge_clamp
+ &__GLEW_EXT_texture_edge_clamp,
+#endif
+#ifdef GL_EXT_texture_env
+ &__GLEW_EXT_texture_env,
+#endif
+#ifdef GL_EXT_texture_env_add
+ &__GLEW_EXT_texture_env_add,
+#endif
+#ifdef GL_EXT_texture_env_combine
+ &__GLEW_EXT_texture_env_combine,
+#endif
+#ifdef GL_EXT_texture_env_dot3
+ &__GLEW_EXT_texture_env_dot3,
+#endif
+#ifdef GL_EXT_texture_filter_anisotropic
+ &__GLEW_EXT_texture_filter_anisotropic,
+#endif
+#ifdef GL_EXT_texture_filter_minmax
+ &__GLEW_EXT_texture_filter_minmax,
+#endif
+#ifdef GL_EXT_texture_integer
+ &__GLEW_EXT_texture_integer,
+#endif
+#ifdef GL_EXT_texture_lod_bias
+ &__GLEW_EXT_texture_lod_bias,
+#endif
+#ifdef GL_EXT_texture_mirror_clamp
+ &__GLEW_EXT_texture_mirror_clamp,
+#endif
+#ifdef GL_EXT_texture_object
+ &__GLEW_EXT_texture_object,
+#endif
+#ifdef GL_EXT_texture_perturb_normal
+ &__GLEW_EXT_texture_perturb_normal,
+#endif
+#ifdef GL_EXT_texture_rectangle
+ &__GLEW_EXT_texture_rectangle,
+#endif
+#ifdef GL_EXT_texture_sRGB
+ &__GLEW_EXT_texture_sRGB,
+#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ &__GLEW_EXT_texture_sRGB_decode,
+#endif
+#ifdef GL_EXT_texture_shared_exponent
+ &__GLEW_EXT_texture_shared_exponent,
+#endif
+#ifdef GL_EXT_texture_snorm
+ &__GLEW_EXT_texture_snorm,
+#endif
+#ifdef GL_EXT_texture_swizzle
+ &__GLEW_EXT_texture_swizzle,
+#endif
+#ifdef GL_EXT_timer_query
+ &__GLEW_EXT_timer_query,
+#endif
+#ifdef GL_EXT_transform_feedback
+ &__GLEW_EXT_transform_feedback,
+#endif
+#ifdef GL_EXT_vertex_array
+ &__GLEW_EXT_vertex_array,
+#endif
+#ifdef GL_EXT_vertex_array_bgra
+ &__GLEW_EXT_vertex_array_bgra,
+#endif
+#ifdef GL_EXT_vertex_attrib_64bit
+ &__GLEW_EXT_vertex_attrib_64bit,
+#endif
+#ifdef GL_EXT_vertex_shader
+ &__GLEW_EXT_vertex_shader,
+#endif
+#ifdef GL_EXT_vertex_weighting
+ &__GLEW_EXT_vertex_weighting,
+#endif
+#ifdef GL_EXT_window_rectangles
+ &__GLEW_EXT_window_rectangles,
+#endif
+#ifdef GL_EXT_x11_sync_object
+ &__GLEW_EXT_x11_sync_object,
+#endif
+#ifdef GL_GREMEDY_frame_terminator
+ &__GLEW_GREMEDY_frame_terminator,
+#endif
+#ifdef GL_GREMEDY_string_marker
+ &__GLEW_GREMEDY_string_marker,
+#endif
+#ifdef GL_HP_convolution_border_modes
+ &__GLEW_HP_convolution_border_modes,
+#endif
+#ifdef GL_HP_image_transform
+ &__GLEW_HP_image_transform,
+#endif
+#ifdef GL_HP_occlusion_test
+ &__GLEW_HP_occlusion_test,
+#endif
+#ifdef GL_HP_texture_lighting
+ &__GLEW_HP_texture_lighting,
+#endif
+#ifdef GL_IBM_cull_vertex
+ &__GLEW_IBM_cull_vertex,
+#endif
+#ifdef GL_IBM_multimode_draw_arrays
+ &__GLEW_IBM_multimode_draw_arrays,
+#endif
+#ifdef GL_IBM_rasterpos_clip
+ &__GLEW_IBM_rasterpos_clip,
+#endif
+#ifdef GL_IBM_static_data
+ &__GLEW_IBM_static_data,
+#endif
+#ifdef GL_IBM_texture_mirrored_repeat
+ &__GLEW_IBM_texture_mirrored_repeat,
+#endif
+#ifdef GL_IBM_vertex_array_lists
+ &__GLEW_IBM_vertex_array_lists,
+#endif
+#ifdef GL_INGR_color_clamp
+ &__GLEW_INGR_color_clamp,
+#endif
+#ifdef GL_INGR_interlace_read
+ &__GLEW_INGR_interlace_read,
+#endif
+#ifdef GL_INTEL_conservative_rasterization
+ &__GLEW_INTEL_conservative_rasterization,
+#endif
+#ifdef GL_INTEL_fragment_shader_ordering
+ &__GLEW_INTEL_fragment_shader_ordering,
+#endif
+#ifdef GL_INTEL_framebuffer_CMAA
+ &__GLEW_INTEL_framebuffer_CMAA,
+#endif
+#ifdef GL_INTEL_map_texture
+ &__GLEW_INTEL_map_texture,
+#endif
+#ifdef GL_INTEL_parallel_arrays
+ &__GLEW_INTEL_parallel_arrays,
+#endif
+#ifdef GL_INTEL_performance_query
+ &__GLEW_INTEL_performance_query,
+#endif
+#ifdef GL_INTEL_texture_scissor
+ &__GLEW_INTEL_texture_scissor,
+#endif
+#ifdef GL_KHR_blend_equation_advanced
+ &__GLEW_KHR_blend_equation_advanced,
+#endif
+#ifdef GL_KHR_blend_equation_advanced_coherent
+ &__GLEW_KHR_blend_equation_advanced_coherent,
+#endif
+#ifdef GL_KHR_context_flush_control
+ &__GLEW_KHR_context_flush_control,
+#endif
+#ifdef GL_KHR_debug
+ &__GLEW_KHR_debug,
+#endif
+#ifdef GL_KHR_no_error
+ &__GLEW_KHR_no_error,
+#endif
+#ifdef GL_KHR_robust_buffer_access_behavior
+ &__GLEW_KHR_robust_buffer_access_behavior,
+#endif
+#ifdef GL_KHR_robustness
+ &__GLEW_KHR_robustness,
+#endif
+#ifdef GL_KHR_texture_compression_astc_hdr
+ &__GLEW_KHR_texture_compression_astc_hdr,
+#endif
+#ifdef GL_KHR_texture_compression_astc_ldr
+ &__GLEW_KHR_texture_compression_astc_ldr,
+#endif
+#ifdef GL_KHR_texture_compression_astc_sliced_3d
+ &__GLEW_KHR_texture_compression_astc_sliced_3d,
+#endif
+#ifdef GL_KTX_buffer_region
+ &__GLEW_KTX_buffer_region,
+#endif
+#ifdef GL_MESAX_texture_stack
+ &__GLEW_MESAX_texture_stack,
+#endif
+#ifdef GL_MESA_pack_invert
+ &__GLEW_MESA_pack_invert,
+#endif
+#ifdef GL_MESA_resize_buffers
+ &__GLEW_MESA_resize_buffers,
+#endif
+#ifdef GL_MESA_shader_integer_functions
+ &__GLEW_MESA_shader_integer_functions,
+#endif
+#ifdef GL_MESA_window_pos
+ &__GLEW_MESA_window_pos,
+#endif
+#ifdef GL_MESA_ycbcr_texture
+ &__GLEW_MESA_ycbcr_texture,
+#endif
+#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers
+ &__GLEW_NVX_blend_equation_advanced_multi_draw_buffers,
+#endif
+#ifdef GL_NVX_conditional_render
+ &__GLEW_NVX_conditional_render,
+#endif
+#ifdef GL_NVX_gpu_memory_info
+ &__GLEW_NVX_gpu_memory_info,
+#endif
+#ifdef GL_NVX_linked_gpu_multicast
+ &__GLEW_NVX_linked_gpu_multicast,
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect
+ &__GLEW_NV_bindless_multi_draw_indirect,
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+ &__GLEW_NV_bindless_multi_draw_indirect_count,
+#endif
+#ifdef GL_NV_bindless_texture
+ &__GLEW_NV_bindless_texture,
+#endif
+#ifdef GL_NV_blend_equation_advanced
+ &__GLEW_NV_blend_equation_advanced,
+#endif
+#ifdef GL_NV_blend_equation_advanced_coherent
+ &__GLEW_NV_blend_equation_advanced_coherent,
+#endif
+#ifdef GL_NV_blend_square
+ &__GLEW_NV_blend_square,
+#endif
+#ifdef GL_NV_clip_space_w_scaling
+ &__GLEW_NV_clip_space_w_scaling,
+#endif
+#ifdef GL_NV_command_list
+ &__GLEW_NV_command_list,
+#endif
+#ifdef GL_NV_compute_program5
+ &__GLEW_NV_compute_program5,
+#endif
+#ifdef GL_NV_conditional_render
+ &__GLEW_NV_conditional_render,
+#endif
+#ifdef GL_NV_conservative_raster
+ &__GLEW_NV_conservative_raster,
+#endif
+#ifdef GL_NV_conservative_raster_dilate
+ &__GLEW_NV_conservative_raster_dilate,
+#endif
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ &__GLEW_NV_conservative_raster_pre_snap_triangles,
+#endif
+#ifdef GL_NV_copy_depth_to_color
+ &__GLEW_NV_copy_depth_to_color,
+#endif
+#ifdef GL_NV_copy_image
+ &__GLEW_NV_copy_image,
+#endif
+#ifdef GL_NV_deep_texture3D
+ &__GLEW_NV_deep_texture3D,
+#endif
+#ifdef GL_NV_depth_buffer_float
+ &__GLEW_NV_depth_buffer_float,
+#endif
+#ifdef GL_NV_depth_clamp
+ &__GLEW_NV_depth_clamp,
+#endif
+#ifdef GL_NV_depth_range_unclamped
+ &__GLEW_NV_depth_range_unclamped,
+#endif
+#ifdef GL_NV_draw_texture
+ &__GLEW_NV_draw_texture,
+#endif
+#ifdef GL_NV_draw_vulkan_image
+ &__GLEW_NV_draw_vulkan_image,
+#endif
+#ifdef GL_NV_evaluators
+ &__GLEW_NV_evaluators,
+#endif
+#ifdef GL_NV_explicit_multisample
+ &__GLEW_NV_explicit_multisample,
+#endif
+#ifdef GL_NV_fence
+ &__GLEW_NV_fence,
+#endif
+#ifdef GL_NV_fill_rectangle
+ &__GLEW_NV_fill_rectangle,
+#endif
+#ifdef GL_NV_float_buffer
+ &__GLEW_NV_float_buffer,
+#endif
+#ifdef GL_NV_fog_distance
+ &__GLEW_NV_fog_distance,
+#endif
+#ifdef GL_NV_fragment_coverage_to_color
+ &__GLEW_NV_fragment_coverage_to_color,
+#endif
+#ifdef GL_NV_fragment_program
+ &__GLEW_NV_fragment_program,
+#endif
+#ifdef GL_NV_fragment_program2
+ &__GLEW_NV_fragment_program2,
+#endif
+#ifdef GL_NV_fragment_program4
+ &__GLEW_NV_fragment_program4,
+#endif
+#ifdef GL_NV_fragment_program_option
+ &__GLEW_NV_fragment_program_option,
+#endif
+#ifdef GL_NV_fragment_shader_interlock
+ &__GLEW_NV_fragment_shader_interlock,
+#endif
+#ifdef GL_NV_framebuffer_mixed_samples
+ &__GLEW_NV_framebuffer_mixed_samples,
+#endif
+#ifdef GL_NV_framebuffer_multisample_coverage
+ &__GLEW_NV_framebuffer_multisample_coverage,
+#endif
+#ifdef GL_NV_geometry_program4
+ &__GLEW_NV_geometry_program4,
+#endif
+#ifdef GL_NV_geometry_shader4
+ &__GLEW_NV_geometry_shader4,
+#endif
+#ifdef GL_NV_geometry_shader_passthrough
+ &__GLEW_NV_geometry_shader_passthrough,
+#endif
+#ifdef GL_NV_gpu_multicast
+ &__GLEW_NV_gpu_multicast,
+#endif
+#ifdef GL_NV_gpu_program4
+ &__GLEW_NV_gpu_program4,
+#endif
+#ifdef GL_NV_gpu_program5
+ &__GLEW_NV_gpu_program5,
+#endif
+#ifdef GL_NV_gpu_program5_mem_extended
+ &__GLEW_NV_gpu_program5_mem_extended,
+#endif
+#ifdef GL_NV_gpu_program_fp64
+ &__GLEW_NV_gpu_program_fp64,
+#endif
+#ifdef GL_NV_gpu_shader5
+ &__GLEW_NV_gpu_shader5,
+#endif
+#ifdef GL_NV_half_float
+ &__GLEW_NV_half_float,
+#endif
+#ifdef GL_NV_internalformat_sample_query
+ &__GLEW_NV_internalformat_sample_query,
+#endif
+#ifdef GL_NV_light_max_exponent
+ &__GLEW_NV_light_max_exponent,
+#endif
+#ifdef GL_NV_multisample_coverage
+ &__GLEW_NV_multisample_coverage,
+#endif
+#ifdef GL_NV_multisample_filter_hint
+ &__GLEW_NV_multisample_filter_hint,
+#endif
+#ifdef GL_NV_occlusion_query
+ &__GLEW_NV_occlusion_query,
+#endif
+#ifdef GL_NV_packed_depth_stencil
+ &__GLEW_NV_packed_depth_stencil,
+#endif
+#ifdef GL_NV_parameter_buffer_object
+ &__GLEW_NV_parameter_buffer_object,
+#endif
+#ifdef GL_NV_parameter_buffer_object2
+ &__GLEW_NV_parameter_buffer_object2,
+#endif
+#ifdef GL_NV_path_rendering
+ &__GLEW_NV_path_rendering,
+#endif
+#ifdef GL_NV_path_rendering_shared_edge
+ &__GLEW_NV_path_rendering_shared_edge,
+#endif
+#ifdef GL_NV_pixel_data_range
+ &__GLEW_NV_pixel_data_range,
+#endif
+#ifdef GL_NV_point_sprite
+ &__GLEW_NV_point_sprite,
+#endif
+#ifdef GL_NV_present_video
+ &__GLEW_NV_present_video,
+#endif
+#ifdef GL_NV_primitive_restart
+ &__GLEW_NV_primitive_restart,
+#endif
+#ifdef GL_NV_register_combiners
+ &__GLEW_NV_register_combiners,
+#endif
+#ifdef GL_NV_register_combiners2
+ &__GLEW_NV_register_combiners2,
+#endif
+#ifdef GL_NV_robustness_video_memory_purge
+ &__GLEW_NV_robustness_video_memory_purge,
+#endif
+#ifdef GL_NV_sample_locations
+ &__GLEW_NV_sample_locations,
+#endif
+#ifdef GL_NV_sample_mask_override_coverage
+ &__GLEW_NV_sample_mask_override_coverage,
+#endif
+#ifdef GL_NV_shader_atomic_counters
+ &__GLEW_NV_shader_atomic_counters,
+#endif
+#ifdef GL_NV_shader_atomic_float
+ &__GLEW_NV_shader_atomic_float,
+#endif
+#ifdef GL_NV_shader_atomic_float64
+ &__GLEW_NV_shader_atomic_float64,
+#endif
+#ifdef GL_NV_shader_atomic_fp16_vector
+ &__GLEW_NV_shader_atomic_fp16_vector,
+#endif
+#ifdef GL_NV_shader_atomic_int64
+ &__GLEW_NV_shader_atomic_int64,
+#endif
+#ifdef GL_NV_shader_buffer_load
+ &__GLEW_NV_shader_buffer_load,
+#endif
+#ifdef GL_NV_shader_storage_buffer_object
+ &__GLEW_NV_shader_storage_buffer_object,
+#endif
+#ifdef GL_NV_shader_thread_group
+ &__GLEW_NV_shader_thread_group,
+#endif
+#ifdef GL_NV_shader_thread_shuffle
+ &__GLEW_NV_shader_thread_shuffle,
+#endif
+#ifdef GL_NV_stereo_view_rendering
+ &__GLEW_NV_stereo_view_rendering,
+#endif
+#ifdef GL_NV_tessellation_program5
+ &__GLEW_NV_tessellation_program5,
+#endif
+#ifdef GL_NV_texgen_emboss
+ &__GLEW_NV_texgen_emboss,
+#endif
+#ifdef GL_NV_texgen_reflection
+ &__GLEW_NV_texgen_reflection,
+#endif
+#ifdef GL_NV_texture_barrier
+ &__GLEW_NV_texture_barrier,
+#endif
+#ifdef GL_NV_texture_compression_vtc
+ &__GLEW_NV_texture_compression_vtc,
+#endif
+#ifdef GL_NV_texture_env_combine4
+ &__GLEW_NV_texture_env_combine4,
+#endif
+#ifdef GL_NV_texture_expand_normal
+ &__GLEW_NV_texture_expand_normal,
+#endif
+#ifdef GL_NV_texture_multisample
+ &__GLEW_NV_texture_multisample,
+#endif
+#ifdef GL_NV_texture_rectangle
+ &__GLEW_NV_texture_rectangle,
+#endif
+#ifdef GL_NV_texture_shader
+ &__GLEW_NV_texture_shader,
+#endif
+#ifdef GL_NV_texture_shader2
+ &__GLEW_NV_texture_shader2,
+#endif
+#ifdef GL_NV_texture_shader3
+ &__GLEW_NV_texture_shader3,
+#endif
+#ifdef GL_NV_transform_feedback
+ &__GLEW_NV_transform_feedback,
+#endif
+#ifdef GL_NV_transform_feedback2
+ &__GLEW_NV_transform_feedback2,
+#endif
+#ifdef GL_NV_uniform_buffer_unified_memory
+ &__GLEW_NV_uniform_buffer_unified_memory,
+#endif
+#ifdef GL_NV_vdpau_interop
+ &__GLEW_NV_vdpau_interop,
+#endif
+#ifdef GL_NV_vertex_array_range
+ &__GLEW_NV_vertex_array_range,
+#endif
+#ifdef GL_NV_vertex_array_range2
+ &__GLEW_NV_vertex_array_range2,
+#endif
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ &__GLEW_NV_vertex_attrib_integer_64bit,
+#endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+ &__GLEW_NV_vertex_buffer_unified_memory,
+#endif
+#ifdef GL_NV_vertex_program
+ &__GLEW_NV_vertex_program,
+#endif
+#ifdef GL_NV_vertex_program1_1
+ &__GLEW_NV_vertex_program1_1,
+#endif
+#ifdef GL_NV_vertex_program2
+ &__GLEW_NV_vertex_program2,
+#endif
+#ifdef GL_NV_vertex_program2_option
+ &__GLEW_NV_vertex_program2_option,
+#endif
+#ifdef GL_NV_vertex_program3
+ &__GLEW_NV_vertex_program3,
+#endif
+#ifdef GL_NV_vertex_program4
+ &__GLEW_NV_vertex_program4,
+#endif
+#ifdef GL_NV_video_capture
+ &__GLEW_NV_video_capture,
+#endif
+#ifdef GL_NV_viewport_array2
+ &__GLEW_NV_viewport_array2,
+#endif
+#ifdef GL_NV_viewport_swizzle
+ &__GLEW_NV_viewport_swizzle,
+#endif
+#ifdef GL_OES_byte_coordinates
+ &__GLEW_OES_byte_coordinates,
+#endif
+#ifdef GL_OES_compressed_paletted_texture
+ &__GLEW_OES_compressed_paletted_texture,
+#endif
+#ifdef GL_OES_read_format
+ &__GLEW_OES_read_format,
+#endif
+#ifdef GL_OES_single_precision
+ &__GLEW_OES_single_precision,
+#endif
+#ifdef GL_OML_interlace
+ &__GLEW_OML_interlace,
+#endif
+#ifdef GL_OML_resample
+ &__GLEW_OML_resample,
+#endif
+#ifdef GL_OML_subsample
+ &__GLEW_OML_subsample,
+#endif
+#ifdef GL_OVR_multiview
+ &__GLEW_OVR_multiview,
+#endif
+#ifdef GL_OVR_multiview2
+ &__GLEW_OVR_multiview2,
+#endif
+#ifdef GL_PGI_misc_hints
+ &__GLEW_PGI_misc_hints,
+#endif
+#ifdef GL_PGI_vertex_hints
+ &__GLEW_PGI_vertex_hints,
+#endif
+#ifdef GL_REGAL_ES1_0_compatibility
+ &__GLEW_REGAL_ES1_0_compatibility,
+#endif
+#ifdef GL_REGAL_ES1_1_compatibility
+ &__GLEW_REGAL_ES1_1_compatibility,
+#endif
+#ifdef GL_REGAL_enable
+ &__GLEW_REGAL_enable,
+#endif
+#ifdef GL_REGAL_error_string
+ &__GLEW_REGAL_error_string,
+#endif
+#ifdef GL_REGAL_extension_query
+ &__GLEW_REGAL_extension_query,
+#endif
+#ifdef GL_REGAL_log
+ &__GLEW_REGAL_log,
+#endif
+#ifdef GL_REGAL_proc_address
+ &__GLEW_REGAL_proc_address,
+#endif
+#ifdef GL_REND_screen_coordinates
+ &__GLEW_REND_screen_coordinates,
+#endif
+#ifdef GL_S3_s3tc
+ &__GLEW_S3_s3tc,
+#endif
+#ifdef GL_SGIS_color_range
+ &__GLEW_SGIS_color_range,
+#endif
+#ifdef GL_SGIS_detail_texture
+ &__GLEW_SGIS_detail_texture,
+#endif
+#ifdef GL_SGIS_fog_function
+ &__GLEW_SGIS_fog_function,
+#endif
+#ifdef GL_SGIS_generate_mipmap
+ &__GLEW_SGIS_generate_mipmap,
+#endif
+#ifdef GL_SGIS_multisample
+ &__GLEW_SGIS_multisample,
+#endif
+#ifdef GL_SGIS_pixel_texture
+ &__GLEW_SGIS_pixel_texture,
+#endif
+#ifdef GL_SGIS_point_line_texgen
+ &__GLEW_SGIS_point_line_texgen,
+#endif
+#ifdef GL_SGIS_sharpen_texture
+ &__GLEW_SGIS_sharpen_texture,
+#endif
+#ifdef GL_SGIS_texture4D
+ &__GLEW_SGIS_texture4D,
+#endif
+#ifdef GL_SGIS_texture_border_clamp
+ &__GLEW_SGIS_texture_border_clamp,
+#endif
+#ifdef GL_SGIS_texture_edge_clamp
+ &__GLEW_SGIS_texture_edge_clamp,
+#endif
+#ifdef GL_SGIS_texture_filter4
+ &__GLEW_SGIS_texture_filter4,
+#endif
+#ifdef GL_SGIS_texture_lod
+ &__GLEW_SGIS_texture_lod,
+#endif
+#ifdef GL_SGIS_texture_select
+ &__GLEW_SGIS_texture_select,
+#endif
+#ifdef GL_SGIX_async
+ &__GLEW_SGIX_async,
+#endif
+#ifdef GL_SGIX_async_histogram
+ &__GLEW_SGIX_async_histogram,
+#endif
+#ifdef GL_SGIX_async_pixel
+ &__GLEW_SGIX_async_pixel,
+#endif
+#ifdef GL_SGIX_blend_alpha_minmax
+ &__GLEW_SGIX_blend_alpha_minmax,
+#endif
+#ifdef GL_SGIX_clipmap
+ &__GLEW_SGIX_clipmap,
+#endif
+#ifdef GL_SGIX_convolution_accuracy
+ &__GLEW_SGIX_convolution_accuracy,
+#endif
+#ifdef GL_SGIX_depth_texture
+ &__GLEW_SGIX_depth_texture,
+#endif
+#ifdef GL_SGIX_flush_raster
+ &__GLEW_SGIX_flush_raster,
+#endif
+#ifdef GL_SGIX_fog_offset
+ &__GLEW_SGIX_fog_offset,
+#endif
+#ifdef GL_SGIX_fog_texture
+ &__GLEW_SGIX_fog_texture,
+#endif
+#ifdef GL_SGIX_fragment_specular_lighting
+ &__GLEW_SGIX_fragment_specular_lighting,
+#endif
+#ifdef GL_SGIX_framezoom
+ &__GLEW_SGIX_framezoom,
+#endif
+#ifdef GL_SGIX_interlace
+ &__GLEW_SGIX_interlace,
+#endif
+#ifdef GL_SGIX_ir_instrument1
+ &__GLEW_SGIX_ir_instrument1,
+#endif
+#ifdef GL_SGIX_list_priority
+ &__GLEW_SGIX_list_priority,
+#endif
+#ifdef GL_SGIX_pixel_texture
+ &__GLEW_SGIX_pixel_texture,
+#endif
+#ifdef GL_SGIX_pixel_texture_bits
+ &__GLEW_SGIX_pixel_texture_bits,
+#endif
+#ifdef GL_SGIX_reference_plane
+ &__GLEW_SGIX_reference_plane,
+#endif
+#ifdef GL_SGIX_resample
+ &__GLEW_SGIX_resample,
+#endif
+#ifdef GL_SGIX_shadow
+ &__GLEW_SGIX_shadow,
+#endif
+#ifdef GL_SGIX_shadow_ambient
+ &__GLEW_SGIX_shadow_ambient,
+#endif
+#ifdef GL_SGIX_sprite
+ &__GLEW_SGIX_sprite,
+#endif
+#ifdef GL_SGIX_tag_sample_buffer
+ &__GLEW_SGIX_tag_sample_buffer,
+#endif
+#ifdef GL_SGIX_texture_add_env
+ &__GLEW_SGIX_texture_add_env,
+#endif
+#ifdef GL_SGIX_texture_coordinate_clamp
+ &__GLEW_SGIX_texture_coordinate_clamp,
+#endif
+#ifdef GL_SGIX_texture_lod_bias
+ &__GLEW_SGIX_texture_lod_bias,
+#endif
+#ifdef GL_SGIX_texture_multi_buffer
+ &__GLEW_SGIX_texture_multi_buffer,
+#endif
+#ifdef GL_SGIX_texture_range
+ &__GLEW_SGIX_texture_range,
+#endif
+#ifdef GL_SGIX_texture_scale_bias
+ &__GLEW_SGIX_texture_scale_bias,
+#endif
+#ifdef GL_SGIX_vertex_preclip
+ &__GLEW_SGIX_vertex_preclip,
+#endif
+#ifdef GL_SGIX_vertex_preclip_hint
+ &__GLEW_SGIX_vertex_preclip_hint,
+#endif
+#ifdef GL_SGIX_ycrcb
+ &__GLEW_SGIX_ycrcb,
+#endif
+#ifdef GL_SGI_color_matrix
+ &__GLEW_SGI_color_matrix,
+#endif
+#ifdef GL_SGI_color_table
+ &__GLEW_SGI_color_table,
+#endif
+#ifdef GL_SGI_texture_color_table
+ &__GLEW_SGI_texture_color_table,
+#endif
+#ifdef GL_SUNX_constant_data
+ &__GLEW_SUNX_constant_data,
+#endif
+#ifdef GL_SUN_convolution_border_modes
+ &__GLEW_SUN_convolution_border_modes,
+#endif
+#ifdef GL_SUN_global_alpha
+ &__GLEW_SUN_global_alpha,
+#endif
+#ifdef GL_SUN_mesh_array
+ &__GLEW_SUN_mesh_array,
+#endif
+#ifdef GL_SUN_read_video_pixels
+ &__GLEW_SUN_read_video_pixels,
+#endif
+#ifdef GL_SUN_slice_accum
+ &__GLEW_SUN_slice_accum,
+#endif
+#ifdef GL_SUN_triangle_list
+ &__GLEW_SUN_triangle_list,
+#endif
+#ifdef GL_SUN_vertex
+ &__GLEW_SUN_vertex,
+#endif
+#ifdef GL_WIN_phong_shading
+ &__GLEW_WIN_phong_shading,
+#endif
+#ifdef GL_WIN_specular_fog
+ &__GLEW_WIN_specular_fog,
+#endif
+#ifdef GL_WIN_swap_hint
+ &__GLEW_WIN_swap_hint,
+#endif
+ NULL
+};
+static GLboolean _glewInit_GL_VERSION_1_2 ();
+static GLboolean _glewInit_GL_VERSION_1_3 ();
+static GLboolean _glewInit_GL_VERSION_1_4 ();
+static GLboolean _glewInit_GL_VERSION_1_5 ();
+static GLboolean _glewInit_GL_VERSION_2_0 ();
+static GLboolean _glewInit_GL_VERSION_2_1 ();
+static GLboolean _glewInit_GL_VERSION_3_0 ();
+static GLboolean _glewInit_GL_VERSION_3_1 ();
+static GLboolean _glewInit_GL_VERSION_3_2 ();
+static GLboolean _glewInit_GL_VERSION_3_3 ();
+static GLboolean _glewInit_GL_VERSION_4_0 ();
+static GLboolean _glewInit_GL_VERSION_4_5 ();
+static GLboolean _glewInit_GL_3DFX_tbuffer ();
+static GLboolean _glewInit_GL_AMD_debug_output ();
+static GLboolean _glewInit_GL_AMD_draw_buffers_blend ();
+static GLboolean _glewInit_GL_AMD_interleaved_elements ();
+static GLboolean _glewInit_GL_AMD_multi_draw_indirect ();
+static GLboolean _glewInit_GL_AMD_name_gen_delete ();
+static GLboolean _glewInit_GL_AMD_occlusion_query_event ();
+static GLboolean _glewInit_GL_AMD_performance_monitor ();
+static GLboolean _glewInit_GL_AMD_sample_positions ();
+static GLboolean _glewInit_GL_AMD_sparse_texture ();
+static GLboolean _glewInit_GL_AMD_stencil_operation_extended ();
+static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator ();
+static GLboolean _glewInit_GL_ANGLE_framebuffer_blit ();
+static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample ();
+static GLboolean _glewInit_GL_ANGLE_instanced_arrays ();
+static GLboolean _glewInit_GL_ANGLE_timer_query ();
+static GLboolean _glewInit_GL_ANGLE_translated_shader_source ();
+static GLboolean _glewInit_GL_APPLE_element_array ();
+static GLboolean _glewInit_GL_APPLE_fence ();
+static GLboolean _glewInit_GL_APPLE_flush_buffer_range ();
+static GLboolean _glewInit_GL_APPLE_object_purgeable ();
+static GLboolean _glewInit_GL_APPLE_texture_range ();
+static GLboolean _glewInit_GL_APPLE_vertex_array_object ();
+static GLboolean _glewInit_GL_APPLE_vertex_array_range ();
+static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators ();
+static GLboolean _glewInit_GL_ARB_ES2_compatibility ();
+static GLboolean _glewInit_GL_ARB_ES3_1_compatibility ();
+static GLboolean _glewInit_GL_ARB_ES3_2_compatibility ();
+static GLboolean _glewInit_GL_ARB_base_instance ();
+static GLboolean _glewInit_GL_ARB_bindless_texture ();
+static GLboolean _glewInit_GL_ARB_blend_func_extended ();
+static GLboolean _glewInit_GL_ARB_buffer_storage ();
+static GLboolean _glewInit_GL_ARB_cl_event ();
+static GLboolean _glewInit_GL_ARB_clear_buffer_object ();
+static GLboolean _glewInit_GL_ARB_clear_texture ();
+static GLboolean _glewInit_GL_ARB_clip_control ();
+static GLboolean _glewInit_GL_ARB_color_buffer_float ();
+static GLboolean _glewInit_GL_ARB_compute_shader ();
+static GLboolean _glewInit_GL_ARB_compute_variable_group_size ();
+static GLboolean _glewInit_GL_ARB_copy_buffer ();
+static GLboolean _glewInit_GL_ARB_copy_image ();
+static GLboolean _glewInit_GL_ARB_debug_output ();
+static GLboolean _glewInit_GL_ARB_direct_state_access ();
+static GLboolean _glewInit_GL_ARB_draw_buffers ();
+static GLboolean _glewInit_GL_ARB_draw_buffers_blend ();
+static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex ();
+static GLboolean _glewInit_GL_ARB_draw_indirect ();
+static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments ();
+static GLboolean _glewInit_GL_ARB_framebuffer_object ();
+static GLboolean _glewInit_GL_ARB_geometry_shader4 ();
+static GLboolean _glewInit_GL_ARB_get_program_binary ();
+static GLboolean _glewInit_GL_ARB_get_texture_sub_image ();
+static GLboolean _glewInit_GL_ARB_gl_spirv ();
+static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 ();
+static GLboolean _glewInit_GL_ARB_gpu_shader_int64 ();
+static GLboolean _glewInit_GL_ARB_imaging ();
+static GLboolean _glewInit_GL_ARB_indirect_parameters ();
+static GLboolean _glewInit_GL_ARB_instanced_arrays ();
+static GLboolean _glewInit_GL_ARB_internalformat_query ();
+static GLboolean _glewInit_GL_ARB_internalformat_query2 ();
+static GLboolean _glewInit_GL_ARB_invalidate_subdata ();
+static GLboolean _glewInit_GL_ARB_map_buffer_range ();
+static GLboolean _glewInit_GL_ARB_matrix_palette ();
+static GLboolean _glewInit_GL_ARB_multi_bind ();
+static GLboolean _glewInit_GL_ARB_multi_draw_indirect ();
+static GLboolean _glewInit_GL_ARB_multisample ();
+static GLboolean _glewInit_GL_ARB_multitexture ();
+static GLboolean _glewInit_GL_ARB_occlusion_query ();
+static GLboolean _glewInit_GL_ARB_parallel_shader_compile ();
+static GLboolean _glewInit_GL_ARB_point_parameters ();
+static GLboolean _glewInit_GL_ARB_program_interface_query ();
+static GLboolean _glewInit_GL_ARB_provoking_vertex ();
+static GLboolean _glewInit_GL_ARB_robustness ();
+static GLboolean _glewInit_GL_ARB_sample_locations ();
+static GLboolean _glewInit_GL_ARB_sample_shading ();
+static GLboolean _glewInit_GL_ARB_sampler_objects ();
+static GLboolean _glewInit_GL_ARB_separate_shader_objects ();
+static GLboolean _glewInit_GL_ARB_shader_atomic_counters ();
+static GLboolean _glewInit_GL_ARB_shader_image_load_store ();
+static GLboolean _glewInit_GL_ARB_shader_objects ();
+static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object ();
+static GLboolean _glewInit_GL_ARB_shader_subroutine ();
+static GLboolean _glewInit_GL_ARB_shading_language_include ();
+static GLboolean _glewInit_GL_ARB_sparse_buffer ();
+static GLboolean _glewInit_GL_ARB_sparse_texture ();
+static GLboolean _glewInit_GL_ARB_sync ();
+static GLboolean _glewInit_GL_ARB_tessellation_shader ();
+static GLboolean _glewInit_GL_ARB_texture_barrier ();
+static GLboolean _glewInit_GL_ARB_texture_buffer_object ();
+static GLboolean _glewInit_GL_ARB_texture_buffer_range ();
+static GLboolean _glewInit_GL_ARB_texture_compression ();
+static GLboolean _glewInit_GL_ARB_texture_multisample ();
+static GLboolean _glewInit_GL_ARB_texture_storage ();
+static GLboolean _glewInit_GL_ARB_texture_storage_multisample ();
+static GLboolean _glewInit_GL_ARB_texture_view ();
+static GLboolean _glewInit_GL_ARB_timer_query ();
+static GLboolean _glewInit_GL_ARB_transform_feedback2 ();
+static GLboolean _glewInit_GL_ARB_transform_feedback3 ();
+static GLboolean _glewInit_GL_ARB_transform_feedback_instanced ();
+static GLboolean _glewInit_GL_ARB_transpose_matrix ();
+static GLboolean _glewInit_GL_ARB_uniform_buffer_object ();
+static GLboolean _glewInit_GL_ARB_vertex_array_object ();
+static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit ();
+static GLboolean _glewInit_GL_ARB_vertex_attrib_binding ();
+static GLboolean _glewInit_GL_ARB_vertex_blend ();
+static GLboolean _glewInit_GL_ARB_vertex_buffer_object ();
+static GLboolean _glewInit_GL_ARB_vertex_program ();
+static GLboolean _glewInit_GL_ARB_vertex_shader ();
+static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev ();
+static GLboolean _glewInit_GL_ARB_viewport_array ();
+static GLboolean _glewInit_GL_ARB_window_pos ();
+static GLboolean _glewInit_GL_ATI_draw_buffers ();
+static GLboolean _glewInit_GL_ATI_element_array ();
+static GLboolean _glewInit_GL_ATI_envmap_bumpmap ();
+static GLboolean _glewInit_GL_ATI_fragment_shader ();
+static GLboolean _glewInit_GL_ATI_map_object_buffer ();
+static GLboolean _glewInit_GL_ATI_pn_triangles ();
+static GLboolean _glewInit_GL_ATI_separate_stencil ();
+static GLboolean _glewInit_GL_ATI_vertex_array_object ();
+static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object ();
+static GLboolean _glewInit_GL_ATI_vertex_streams ();
+static GLboolean _glewInit_GL_EXT_bindable_uniform ();
+static GLboolean _glewInit_GL_EXT_blend_color ();
+static GLboolean _glewInit_GL_EXT_blend_equation_separate ();
+static GLboolean _glewInit_GL_EXT_blend_func_separate ();
+static GLboolean _glewInit_GL_EXT_blend_minmax ();
+static GLboolean _glewInit_GL_EXT_color_subtable ();
+static GLboolean _glewInit_GL_EXT_compiled_vertex_array ();
+static GLboolean _glewInit_GL_EXT_convolution ();
+static GLboolean _glewInit_GL_EXT_coordinate_frame ();
+static GLboolean _glewInit_GL_EXT_copy_texture ();
+static GLboolean _glewInit_GL_EXT_cull_vertex ();
+static GLboolean _glewInit_GL_EXT_debug_label ();
+static GLboolean _glewInit_GL_EXT_debug_marker ();
+static GLboolean _glewInit_GL_EXT_depth_bounds_test ();
+static GLboolean _glewInit_GL_EXT_direct_state_access ();
+static GLboolean _glewInit_GL_EXT_draw_buffers2 ();
+static GLboolean _glewInit_GL_EXT_draw_instanced ();
+static GLboolean _glewInit_GL_EXT_draw_range_elements ();
+static GLboolean _glewInit_GL_EXT_fog_coord ();
+static GLboolean _glewInit_GL_EXT_fragment_lighting ();
+static GLboolean _glewInit_GL_EXT_framebuffer_blit ();
+static GLboolean _glewInit_GL_EXT_framebuffer_multisample ();
+static GLboolean _glewInit_GL_EXT_framebuffer_object ();
+static GLboolean _glewInit_GL_EXT_geometry_shader4 ();
+static GLboolean _glewInit_GL_EXT_gpu_program_parameters ();
+static GLboolean _glewInit_GL_EXT_gpu_shader4 ();
+static GLboolean _glewInit_GL_EXT_histogram ();
+static GLboolean _glewInit_GL_EXT_index_func ();
+static GLboolean _glewInit_GL_EXT_index_material ();
+static GLboolean _glewInit_GL_EXT_light_texture ();
+static GLboolean _glewInit_GL_EXT_multi_draw_arrays ();
+static GLboolean _glewInit_GL_EXT_multisample ();
+static GLboolean _glewInit_GL_EXT_paletted_texture ();
+static GLboolean _glewInit_GL_EXT_pixel_transform ();
+static GLboolean _glewInit_GL_EXT_point_parameters ();
+static GLboolean _glewInit_GL_EXT_polygon_offset ();
+static GLboolean _glewInit_GL_EXT_polygon_offset_clamp ();
+static GLboolean _glewInit_GL_EXT_provoking_vertex ();
+static GLboolean _glewInit_GL_EXT_raster_multisample ();
+static GLboolean _glewInit_GL_EXT_scene_marker ();
+static GLboolean _glewInit_GL_EXT_secondary_color ();
+static GLboolean _glewInit_GL_EXT_separate_shader_objects ();
+static GLboolean _glewInit_GL_EXT_shader_image_load_store ();
+static GLboolean _glewInit_GL_EXT_stencil_two_side ();
+static GLboolean _glewInit_GL_EXT_subtexture ();
+static GLboolean _glewInit_GL_EXT_texture3D ();
+static GLboolean _glewInit_GL_EXT_texture_array ();
+static GLboolean _glewInit_GL_EXT_texture_buffer_object ();
+static GLboolean _glewInit_GL_EXT_texture_integer ();
+static GLboolean _glewInit_GL_EXT_texture_object ();
+static GLboolean _glewInit_GL_EXT_texture_perturb_normal ();
+static GLboolean _glewInit_GL_EXT_timer_query ();
+static GLboolean _glewInit_GL_EXT_transform_feedback ();
+static GLboolean _glewInit_GL_EXT_vertex_array ();
+static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit ();
+static GLboolean _glewInit_GL_EXT_vertex_shader ();
+static GLboolean _glewInit_GL_EXT_vertex_weighting ();
+static GLboolean _glewInit_GL_EXT_window_rectangles ();
+static GLboolean _glewInit_GL_EXT_x11_sync_object ();
+static GLboolean _glewInit_GL_GREMEDY_frame_terminator ();
+static GLboolean _glewInit_GL_GREMEDY_string_marker ();
+static GLboolean _glewInit_GL_HP_image_transform ();
+static GLboolean _glewInit_GL_IBM_multimode_draw_arrays ();
+static GLboolean _glewInit_GL_IBM_vertex_array_lists ();
+static GLboolean _glewInit_GL_INTEL_map_texture ();
+static GLboolean _glewInit_GL_INTEL_parallel_arrays ();
+static GLboolean _glewInit_GL_INTEL_performance_query ();
+static GLboolean _glewInit_GL_INTEL_texture_scissor ();
+static GLboolean _glewInit_GL_KHR_blend_equation_advanced ();
+static GLboolean _glewInit_GL_KHR_debug ();
+static GLboolean _glewInit_GL_KHR_robustness ();
+static GLboolean _glewInit_GL_KTX_buffer_region ();
+static GLboolean _glewInit_GL_MESA_resize_buffers ();
+static GLboolean _glewInit_GL_MESA_window_pos ();
+static GLboolean _glewInit_GL_NVX_conditional_render ();
+static GLboolean _glewInit_GL_NVX_linked_gpu_multicast ();
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect ();
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count ();
+static GLboolean _glewInit_GL_NV_bindless_texture ();
+static GLboolean _glewInit_GL_NV_blend_equation_advanced ();
+static GLboolean _glewInit_GL_NV_clip_space_w_scaling ();
+static GLboolean _glewInit_GL_NV_command_list ();
+static GLboolean _glewInit_GL_NV_conditional_render ();
+static GLboolean _glewInit_GL_NV_conservative_raster ();
+static GLboolean _glewInit_GL_NV_conservative_raster_dilate ();
+static GLboolean _glewInit_GL_NV_conservative_raster_pre_snap_triangles ();
+static GLboolean _glewInit_GL_NV_copy_image ();
+static GLboolean _glewInit_GL_NV_depth_buffer_float ();
+static GLboolean _glewInit_GL_NV_draw_texture ();
+static GLboolean _glewInit_GL_NV_draw_vulkan_image ();
+static GLboolean _glewInit_GL_NV_evaluators ();
+static GLboolean _glewInit_GL_NV_explicit_multisample ();
+static GLboolean _glewInit_GL_NV_fence ();
+static GLboolean _glewInit_GL_NV_fragment_coverage_to_color ();
+static GLboolean _glewInit_GL_NV_fragment_program ();
+static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage ();
+static GLboolean _glewInit_GL_NV_geometry_program4 ();
+static GLboolean _glewInit_GL_NV_gpu_multicast ();
+static GLboolean _glewInit_GL_NV_gpu_program4 ();
+static GLboolean _glewInit_GL_NV_gpu_shader5 ();
+static GLboolean _glewInit_GL_NV_half_float ();
+static GLboolean _glewInit_GL_NV_internalformat_sample_query ();
+static GLboolean _glewInit_GL_NV_occlusion_query ();
+static GLboolean _glewInit_GL_NV_parameter_buffer_object ();
+static GLboolean _glewInit_GL_NV_path_rendering ();
+static GLboolean _glewInit_GL_NV_pixel_data_range ();
+static GLboolean _glewInit_GL_NV_point_sprite ();
+static GLboolean _glewInit_GL_NV_present_video ();
+static GLboolean _glewInit_GL_NV_primitive_restart ();
+static GLboolean _glewInit_GL_NV_register_combiners ();
+static GLboolean _glewInit_GL_NV_register_combiners2 ();
+static GLboolean _glewInit_GL_NV_sample_locations ();
+static GLboolean _glewInit_GL_NV_shader_buffer_load ();
+static GLboolean _glewInit_GL_NV_texture_barrier ();
+static GLboolean _glewInit_GL_NV_texture_multisample ();
+static GLboolean _glewInit_GL_NV_transform_feedback ();
+static GLboolean _glewInit_GL_NV_transform_feedback2 ();
+static GLboolean _glewInit_GL_NV_vdpau_interop ();
+static GLboolean _glewInit_GL_NV_vertex_array_range ();
+static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit ();
+static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory ();
+static GLboolean _glewInit_GL_NV_vertex_program ();
+static GLboolean _glewInit_GL_NV_video_capture ();
+static GLboolean _glewInit_GL_NV_viewport_swizzle ();
+static GLboolean _glewInit_GL_OES_single_precision ();
+static GLboolean _glewInit_GL_OVR_multiview ();
+static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility ();
+static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility ();
+static GLboolean _glewInit_GL_REGAL_error_string ();
+static GLboolean _glewInit_GL_REGAL_extension_query ();
+static GLboolean _glewInit_GL_REGAL_log ();
+static GLboolean _glewInit_GL_REGAL_proc_address ();
+static GLboolean _glewInit_GL_SGIS_detail_texture ();
+static GLboolean _glewInit_GL_SGIS_fog_function ();
+static GLboolean _glewInit_GL_SGIS_multisample ();
+static GLboolean _glewInit_GL_SGIS_sharpen_texture ();
+static GLboolean _glewInit_GL_SGIS_texture4D ();
+static GLboolean _glewInit_GL_SGIS_texture_filter4 ();
+static GLboolean _glewInit_GL_SGIX_async ();
+static GLboolean _glewInit_GL_SGIX_flush_raster ();
+static GLboolean _glewInit_GL_SGIX_fog_texture ();
+static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting ();
+static GLboolean _glewInit_GL_SGIX_framezoom ();
+static GLboolean _glewInit_GL_SGIX_pixel_texture ();
+static GLboolean _glewInit_GL_SGIX_reference_plane ();
+static GLboolean _glewInit_GL_SGIX_sprite ();
+static GLboolean _glewInit_GL_SGIX_tag_sample_buffer ();
+static GLboolean _glewInit_GL_SGI_color_table ();
+static GLboolean _glewInit_GL_SUNX_constant_data ();
+static GLboolean _glewInit_GL_SUN_global_alpha ();
+static GLboolean _glewInit_GL_SUN_read_video_pixels ();
+static GLboolean _glewInit_GL_SUN_triangle_list ();
+static GLboolean _glewInit_GL_SUN_vertex ();
+static GLboolean _glewInit_GL_WIN_swap_hint ();
#ifdef GL_VERSION_1_2
-static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_1_2 ()
{
GLboolean r = GL_FALSE;
@@ -3578,7 +7547,7 @@ static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_1_3
-static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_1_3 ()
{
GLboolean r = GL_FALSE;
@@ -3636,7 +7605,7 @@ static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_1_4
-static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_1_4 ()
{
GLboolean r = GL_FALSE;
@@ -3695,7 +7664,7 @@ static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_1_5
-static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_1_5 ()
{
GLboolean r = GL_FALSE;
@@ -3726,7 +7695,7 @@ static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_2_0
-static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_2_0 ()
{
GLboolean r = GL_FALSE;
@@ -3831,7 +7800,7 @@ static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_2_1
-static GLboolean _glewInit_GL_VERSION_2_1 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_2_1 ()
{
GLboolean r = GL_FALSE;
@@ -3849,10 +7818,15 @@ static GLboolean _glewInit_GL_VERSION_2_1 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_3_0
-static GLboolean _glewInit_GL_VERSION_3_0 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_3_0 ()
{
GLboolean r = GL_FALSE;
+ r = _glewInit_GL_ARB_framebuffer_object() || r;
+ r = _glewInit_GL_ARB_map_buffer_range() || r;
+ r = _glewInit_GL_ARB_uniform_buffer_object() || r;
+ r = _glewInit_GL_ARB_vertex_array_object() || r;
+
r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r;
r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r;
r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r;
@@ -3916,10 +7890,12 @@ static GLboolean _glewInit_GL_VERSION_3_0 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_3_1
-static GLboolean _glewInit_GL_VERSION_3_1 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_3_1 ()
{
GLboolean r = GL_FALSE;
+ r = _glewInit_GL_ARB_copy_buffer() || r;
+
r = ((glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstanced")) == NULL) || r;
r = ((glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r;
r = ((glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndex")) == NULL) || r;
@@ -3932,10 +7908,15 @@ static GLboolean _glewInit_GL_VERSION_3_1 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_3_2
-static GLboolean _glewInit_GL_VERSION_3_2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_3_2 ()
{
GLboolean r = GL_FALSE;
+ r = _glewInit_GL_ARB_draw_elements_base_vertex() || r;
+ r = _glewInit_GL_ARB_provoking_vertex() || r;
+ r = _glewInit_GL_ARB_sync() || r;
+ r = _glewInit_GL_ARB_texture_multisample() || r;
+
r = ((glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture")) == NULL) || r;
r = ((glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteri64v")) == NULL) || r;
r = ((glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64i_v")) == NULL) || r;
@@ -3947,7 +7928,7 @@ static GLboolean _glewInit_GL_VERSION_3_2 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_3_3
-static GLboolean _glewInit_GL_VERSION_3_3 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_3_3 ()
{
GLboolean r = GL_FALSE;
@@ -3960,7 +7941,7 @@ static GLboolean _glewInit_GL_VERSION_3_3 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_4_0
-static GLboolean _glewInit_GL_VERSION_4_0 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_4_0 ()
{
GLboolean r = GL_FALSE;
@@ -3977,7 +7958,7 @@ static GLboolean _glewInit_GL_VERSION_4_0 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_4_5
-static GLboolean _glewInit_GL_VERSION_4_5 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_VERSION_4_5 ()
{
GLboolean r = GL_FALSE;
@@ -3993,7 +7974,7 @@ static GLboolean _glewInit_GL_VERSION_4_5 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_3DFX_tbuffer
-static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_3DFX_tbuffer ()
{
GLboolean r = GL_FALSE;
@@ -4006,7 +7987,7 @@ static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_AMD_debug_output
-static GLboolean _glewInit_GL_AMD_debug_output (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_debug_output ()
{
GLboolean r = GL_FALSE;
@@ -4022,7 +8003,7 @@ static GLboolean _glewInit_GL_AMD_debug_output (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_AMD_draw_buffers_blend
-static GLboolean _glewInit_GL_AMD_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_draw_buffers_blend ()
{
GLboolean r = GL_FALSE;
@@ -4038,7 +8019,7 @@ static GLboolean _glewInit_GL_AMD_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_AMD_interleaved_elements
-static GLboolean _glewInit_GL_AMD_interleaved_elements (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_interleaved_elements ()
{
GLboolean r = GL_FALSE;
@@ -4051,7 +8032,7 @@ static GLboolean _glewInit_GL_AMD_interleaved_elements (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_AMD_multi_draw_indirect
-static GLboolean _glewInit_GL_AMD_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_multi_draw_indirect ()
{
GLboolean r = GL_FALSE;
@@ -4065,7 +8046,7 @@ static GLboolean _glewInit_GL_AMD_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_AMD_name_gen_delete
-static GLboolean _glewInit_GL_AMD_name_gen_delete (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_name_gen_delete ()
{
GLboolean r = GL_FALSE;
@@ -4080,7 +8061,7 @@ static GLboolean _glewInit_GL_AMD_name_gen_delete (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_AMD_occlusion_query_event
-static GLboolean _glewInit_GL_AMD_occlusion_query_event (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_occlusion_query_event ()
{
GLboolean r = GL_FALSE;
@@ -4093,7 +8074,7 @@ static GLboolean _glewInit_GL_AMD_occlusion_query_event (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_AMD_performance_monitor
-static GLboolean _glewInit_GL_AMD_performance_monitor (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_performance_monitor ()
{
GLboolean r = GL_FALSE;
@@ -4116,7 +8097,7 @@ static GLboolean _glewInit_GL_AMD_performance_monitor (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_AMD_sample_positions
-static GLboolean _glewInit_GL_AMD_sample_positions (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_sample_positions ()
{
GLboolean r = GL_FALSE;
@@ -4129,7 +8110,7 @@ static GLboolean _glewInit_GL_AMD_sample_positions (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_AMD_sparse_texture
-static GLboolean _glewInit_GL_AMD_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_sparse_texture ()
{
GLboolean r = GL_FALSE;
@@ -4143,7 +8124,7 @@ static GLboolean _glewInit_GL_AMD_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_AMD_stencil_operation_extended
-static GLboolean _glewInit_GL_AMD_stencil_operation_extended (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_stencil_operation_extended ()
{
GLboolean r = GL_FALSE;
@@ -4156,7 +8137,7 @@ static GLboolean _glewInit_GL_AMD_stencil_operation_extended (GLEW_CONTEXT_ARG_D
#ifdef GL_AMD_vertex_shader_tessellator
-static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator ()
{
GLboolean r = GL_FALSE;
@@ -4170,7 +8151,7 @@ static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator (GLEW_CONTEXT_ARG_DE
#ifdef GL_ANGLE_framebuffer_blit
-static GLboolean _glewInit_GL_ANGLE_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ANGLE_framebuffer_blit ()
{
GLboolean r = GL_FALSE;
@@ -4183,7 +8164,7 @@ static GLboolean _glewInit_GL_ANGLE_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ANGLE_framebuffer_multisample
-static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample ()
{
GLboolean r = GL_FALSE;
@@ -4196,7 +8177,7 @@ static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample (GLEW_CONTEXT_ARG_DE
#ifdef GL_ANGLE_instanced_arrays
-static GLboolean _glewInit_GL_ANGLE_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ANGLE_instanced_arrays ()
{
GLboolean r = GL_FALSE;
@@ -4211,7 +8192,7 @@ static GLboolean _glewInit_GL_ANGLE_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ANGLE_timer_query
-static GLboolean _glewInit_GL_ANGLE_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ANGLE_timer_query ()
{
GLboolean r = GL_FALSE;
@@ -4234,7 +8215,7 @@ static GLboolean _glewInit_GL_ANGLE_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ANGLE_translated_shader_source
-static GLboolean _glewInit_GL_ANGLE_translated_shader_source (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ANGLE_translated_shader_source ()
{
GLboolean r = GL_FALSE;
@@ -4247,7 +8228,7 @@ static GLboolean _glewInit_GL_ANGLE_translated_shader_source (GLEW_CONTEXT_ARG_D
#ifdef GL_APPLE_element_array
-static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_element_array ()
{
GLboolean r = GL_FALSE;
@@ -4264,7 +8245,7 @@ static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_APPLE_fence
-static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_fence ()
{
GLboolean r = GL_FALSE;
@@ -4284,7 +8265,7 @@ static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_APPLE_flush_buffer_range
-static GLboolean _glewInit_GL_APPLE_flush_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_flush_buffer_range ()
{
GLboolean r = GL_FALSE;
@@ -4298,7 +8279,7 @@ static GLboolean _glewInit_GL_APPLE_flush_buffer_range (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_APPLE_object_purgeable
-static GLboolean _glewInit_GL_APPLE_object_purgeable (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_object_purgeable ()
{
GLboolean r = GL_FALSE;
@@ -4313,7 +8294,7 @@ static GLboolean _glewInit_GL_APPLE_object_purgeable (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_APPLE_texture_range
-static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_texture_range ()
{
GLboolean r = GL_FALSE;
@@ -4327,7 +8308,7 @@ static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_APPLE_vertex_array_object
-static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_vertex_array_object ()
{
GLboolean r = GL_FALSE;
@@ -4343,7 +8324,7 @@ static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_APPLE_vertex_array_range
-static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_vertex_array_range ()
{
GLboolean r = GL_FALSE;
@@ -4358,7 +8339,7 @@ static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_APPLE_vertex_program_evaluators
-static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators ()
{
GLboolean r = GL_FALSE;
@@ -4377,7 +8358,7 @@ static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators (GLEW_CONTEXT_ARG_
#ifdef GL_ARB_ES2_compatibility
-static GLboolean _glewInit_GL_ARB_ES2_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_ES2_compatibility ()
{
GLboolean r = GL_FALSE;
@@ -4394,7 +8375,7 @@ static GLboolean _glewInit_GL_ARB_ES2_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_ES3_1_compatibility
-static GLboolean _glewInit_GL_ARB_ES3_1_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_ES3_1_compatibility ()
{
GLboolean r = GL_FALSE;
@@ -4407,7 +8388,7 @@ static GLboolean _glewInit_GL_ARB_ES3_1_compatibility (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_ES3_2_compatibility
-static GLboolean _glewInit_GL_ARB_ES3_2_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_ES3_2_compatibility ()
{
GLboolean r = GL_FALSE;
@@ -4420,7 +8401,7 @@ static GLboolean _glewInit_GL_ARB_ES3_2_compatibility (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_base_instance
-static GLboolean _glewInit_GL_ARB_base_instance (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_base_instance ()
{
GLboolean r = GL_FALSE;
@@ -4435,7 +8416,7 @@ static GLboolean _glewInit_GL_ARB_base_instance (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_bindless_texture
-static GLboolean _glewInit_GL_ARB_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_bindless_texture ()
{
GLboolean r = GL_FALSE;
@@ -4463,7 +8444,7 @@ static GLboolean _glewInit_GL_ARB_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_blend_func_extended
-static GLboolean _glewInit_GL_ARB_blend_func_extended (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_blend_func_extended ()
{
GLboolean r = GL_FALSE;
@@ -4477,7 +8458,7 @@ static GLboolean _glewInit_GL_ARB_blend_func_extended (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_buffer_storage
-static GLboolean _glewInit_GL_ARB_buffer_storage (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_buffer_storage ()
{
GLboolean r = GL_FALSE;
@@ -4491,7 +8472,7 @@ static GLboolean _glewInit_GL_ARB_buffer_storage (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_cl_event
-static GLboolean _glewInit_GL_ARB_cl_event (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_cl_event ()
{
GLboolean r = GL_FALSE;
@@ -4504,7 +8485,7 @@ static GLboolean _glewInit_GL_ARB_cl_event (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_clear_buffer_object
-static GLboolean _glewInit_GL_ARB_clear_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_clear_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -4520,7 +8501,7 @@ static GLboolean _glewInit_GL_ARB_clear_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_clear_texture
-static GLboolean _glewInit_GL_ARB_clear_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_clear_texture ()
{
GLboolean r = GL_FALSE;
@@ -4534,7 +8515,7 @@ static GLboolean _glewInit_GL_ARB_clear_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_clip_control
-static GLboolean _glewInit_GL_ARB_clip_control (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_clip_control ()
{
GLboolean r = GL_FALSE;
@@ -4547,7 +8528,7 @@ static GLboolean _glewInit_GL_ARB_clip_control (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_color_buffer_float
-static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_color_buffer_float ()
{
GLboolean r = GL_FALSE;
@@ -4560,7 +8541,7 @@ static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_compute_shader
-static GLboolean _glewInit_GL_ARB_compute_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_compute_shader ()
{
GLboolean r = GL_FALSE;
@@ -4574,7 +8555,7 @@ static GLboolean _glewInit_GL_ARB_compute_shader (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_compute_variable_group_size
-static GLboolean _glewInit_GL_ARB_compute_variable_group_size (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_compute_variable_group_size ()
{
GLboolean r = GL_FALSE;
@@ -4587,7 +8568,7 @@ static GLboolean _glewInit_GL_ARB_compute_variable_group_size (GLEW_CONTEXT_ARG_
#ifdef GL_ARB_copy_buffer
-static GLboolean _glewInit_GL_ARB_copy_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_copy_buffer ()
{
GLboolean r = GL_FALSE;
@@ -4600,7 +8581,7 @@ static GLboolean _glewInit_GL_ARB_copy_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_copy_image
-static GLboolean _glewInit_GL_ARB_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_copy_image ()
{
GLboolean r = GL_FALSE;
@@ -4613,7 +8594,7 @@ static GLboolean _glewInit_GL_ARB_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_debug_output
-static GLboolean _glewInit_GL_ARB_debug_output (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_debug_output ()
{
GLboolean r = GL_FALSE;
@@ -4629,7 +8610,7 @@ static GLboolean _glewInit_GL_ARB_debug_output (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_direct_state_access
-static GLboolean _glewInit_GL_ARB_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_direct_state_access ()
{
GLboolean r = GL_FALSE;
@@ -4738,7 +8719,7 @@ static GLboolean _glewInit_GL_ARB_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_draw_buffers
-static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_draw_buffers ()
{
GLboolean r = GL_FALSE;
@@ -4751,7 +8732,7 @@ static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_draw_buffers_blend
-static GLboolean _glewInit_GL_ARB_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_draw_buffers_blend ()
{
GLboolean r = GL_FALSE;
@@ -4767,7 +8748,7 @@ static GLboolean _glewInit_GL_ARB_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_draw_elements_base_vertex
-static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex ()
{
GLboolean r = GL_FALSE;
@@ -4783,7 +8764,7 @@ static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex (GLEW_CONTEXT_ARG_DE
#ifdef GL_ARB_draw_indirect
-static GLboolean _glewInit_GL_ARB_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_draw_indirect ()
{
GLboolean r = GL_FALSE;
@@ -4797,7 +8778,7 @@ static GLboolean _glewInit_GL_ARB_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_framebuffer_no_attachments
-static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments ()
{
GLboolean r = GL_FALSE;
@@ -4813,7 +8794,7 @@ static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments (GLEW_CONTEXT_ARG_D
#ifdef GL_ARB_framebuffer_object
-static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_framebuffer_object ()
{
GLboolean r = GL_FALSE;
@@ -4845,7 +8826,7 @@ static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_geometry_shader4
-static GLboolean _glewInit_GL_ARB_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_geometry_shader4 ()
{
GLboolean r = GL_FALSE;
@@ -4861,7 +8842,7 @@ static GLboolean _glewInit_GL_ARB_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_get_program_binary
-static GLboolean _glewInit_GL_ARB_get_program_binary (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_get_program_binary ()
{
GLboolean r = GL_FALSE;
@@ -4876,7 +8857,7 @@ static GLboolean _glewInit_GL_ARB_get_program_binary (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_get_texture_sub_image
-static GLboolean _glewInit_GL_ARB_get_texture_sub_image (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_get_texture_sub_image ()
{
GLboolean r = GL_FALSE;
@@ -4888,9 +8869,22 @@ static GLboolean _glewInit_GL_ARB_get_texture_sub_image (GLEW_CONTEXT_ARG_DEF_IN
#endif /* GL_ARB_get_texture_sub_image */
+#ifdef GL_ARB_gl_spirv
+
+static GLboolean _glewInit_GL_ARB_gl_spirv ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glSpecializeShaderARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_gl_spirv */
+
#ifdef GL_ARB_gpu_shader_fp64
-static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 ()
{
GLboolean r = GL_FALSE;
@@ -4920,7 +8914,7 @@ static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_gpu_shader_int64
-static GLboolean _glewInit_GL_ARB_gpu_shader_int64 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_gpu_shader_int64 ()
{
GLboolean r = GL_FALSE;
@@ -4968,7 +8962,7 @@ static GLboolean _glewInit_GL_ARB_gpu_shader_int64 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_imaging
-static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_imaging ()
{
GLboolean r = GL_FALSE;
@@ -5013,7 +9007,7 @@ static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_indirect_parameters
-static GLboolean _glewInit_GL_ARB_indirect_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_indirect_parameters ()
{
GLboolean r = GL_FALSE;
@@ -5027,7 +9021,7 @@ static GLboolean _glewInit_GL_ARB_indirect_parameters (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_instanced_arrays
-static GLboolean _glewInit_GL_ARB_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_instanced_arrays ()
{
GLboolean r = GL_FALSE;
@@ -5042,7 +9036,7 @@ static GLboolean _glewInit_GL_ARB_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_internalformat_query
-static GLboolean _glewInit_GL_ARB_internalformat_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_internalformat_query ()
{
GLboolean r = GL_FALSE;
@@ -5055,7 +9049,7 @@ static GLboolean _glewInit_GL_ARB_internalformat_query (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_ARB_internalformat_query2
-static GLboolean _glewInit_GL_ARB_internalformat_query2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_internalformat_query2 ()
{
GLboolean r = GL_FALSE;
@@ -5068,7 +9062,7 @@ static GLboolean _glewInit_GL_ARB_internalformat_query2 (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_ARB_invalidate_subdata
-static GLboolean _glewInit_GL_ARB_invalidate_subdata (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_invalidate_subdata ()
{
GLboolean r = GL_FALSE;
@@ -5086,7 +9080,7 @@ static GLboolean _glewInit_GL_ARB_invalidate_subdata (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_map_buffer_range
-static GLboolean _glewInit_GL_ARB_map_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_map_buffer_range ()
{
GLboolean r = GL_FALSE;
@@ -5100,7 +9094,7 @@ static GLboolean _glewInit_GL_ARB_map_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_matrix_palette
-static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_matrix_palette ()
{
GLboolean r = GL_FALSE;
@@ -5117,7 +9111,7 @@ static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_multi_bind
-static GLboolean _glewInit_GL_ARB_multi_bind (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_multi_bind ()
{
GLboolean r = GL_FALSE;
@@ -5135,7 +9129,7 @@ static GLboolean _glewInit_GL_ARB_multi_bind (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_multi_draw_indirect
-static GLboolean _glewInit_GL_ARB_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_multi_draw_indirect ()
{
GLboolean r = GL_FALSE;
@@ -5149,7 +9143,7 @@ static GLboolean _glewInit_GL_ARB_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_multisample
-static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_multisample ()
{
GLboolean r = GL_FALSE;
@@ -5162,7 +9156,7 @@ static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_multitexture
-static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_multitexture ()
{
GLboolean r = GL_FALSE;
@@ -5208,7 +9202,7 @@ static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_occlusion_query
-static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_occlusion_query ()
{
GLboolean r = GL_FALSE;
@@ -5228,7 +9222,7 @@ static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_parallel_shader_compile
-static GLboolean _glewInit_GL_ARB_parallel_shader_compile (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_parallel_shader_compile ()
{
GLboolean r = GL_FALSE;
@@ -5241,7 +9235,7 @@ static GLboolean _glewInit_GL_ARB_parallel_shader_compile (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_ARB_point_parameters
-static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_point_parameters ()
{
GLboolean r = GL_FALSE;
@@ -5255,7 +9249,7 @@ static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_program_interface_query
-static GLboolean _glewInit_GL_ARB_program_interface_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_program_interface_query ()
{
GLboolean r = GL_FALSE;
@@ -5273,7 +9267,7 @@ static GLboolean _glewInit_GL_ARB_program_interface_query (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_ARB_provoking_vertex
-static GLboolean _glewInit_GL_ARB_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_provoking_vertex ()
{
GLboolean r = GL_FALSE;
@@ -5286,7 +9280,7 @@ static GLboolean _glewInit_GL_ARB_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_robustness
-static GLboolean _glewInit_GL_ARB_robustness (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_robustness ()
{
GLboolean r = GL_FALSE;
@@ -5318,7 +9312,7 @@ static GLboolean _glewInit_GL_ARB_robustness (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_sample_locations
-static GLboolean _glewInit_GL_ARB_sample_locations (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_sample_locations ()
{
GLboolean r = GL_FALSE;
@@ -5332,7 +9326,7 @@ static GLboolean _glewInit_GL_ARB_sample_locations (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_sample_shading
-static GLboolean _glewInit_GL_ARB_sample_shading (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_sample_shading ()
{
GLboolean r = GL_FALSE;
@@ -5345,7 +9339,7 @@ static GLboolean _glewInit_GL_ARB_sample_shading (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_sampler_objects
-static GLboolean _glewInit_GL_ARB_sampler_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_sampler_objects ()
{
GLboolean r = GL_FALSE;
@@ -5371,7 +9365,7 @@ static GLboolean _glewInit_GL_ARB_sampler_objects (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_separate_shader_objects
-static GLboolean _glewInit_GL_ARB_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_separate_shader_objects ()
{
GLboolean r = GL_FALSE;
@@ -5443,7 +9437,7 @@ static GLboolean _glewInit_GL_ARB_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_ARB_shader_atomic_counters
-static GLboolean _glewInit_GL_ARB_shader_atomic_counters (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_shader_atomic_counters ()
{
GLboolean r = GL_FALSE;
@@ -5456,7 +9450,7 @@ static GLboolean _glewInit_GL_ARB_shader_atomic_counters (GLEW_CONTEXT_ARG_DEF_I
#ifdef GL_ARB_shader_image_load_store
-static GLboolean _glewInit_GL_ARB_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_shader_image_load_store ()
{
GLboolean r = GL_FALSE;
@@ -5470,7 +9464,7 @@ static GLboolean _glewInit_GL_ARB_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_ARB_shader_objects
-static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_shader_objects ()
{
GLboolean r = GL_FALSE;
@@ -5521,7 +9515,7 @@ static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_shader_storage_buffer_object
-static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -5534,7 +9528,7 @@ static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object (GLEW_CONTEXT_ARG
#ifdef GL_ARB_shader_subroutine
-static GLboolean _glewInit_GL_ARB_shader_subroutine (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_shader_subroutine ()
{
GLboolean r = GL_FALSE;
@@ -5554,7 +9548,7 @@ static GLboolean _glewInit_GL_ARB_shader_subroutine (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_shading_language_include
-static GLboolean _glewInit_GL_ARB_shading_language_include (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_shading_language_include ()
{
GLboolean r = GL_FALSE;
@@ -5572,7 +9566,7 @@ static GLboolean _glewInit_GL_ARB_shading_language_include (GLEW_CONTEXT_ARG_DEF
#ifdef GL_ARB_sparse_buffer
-static GLboolean _glewInit_GL_ARB_sparse_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_sparse_buffer ()
{
GLboolean r = GL_FALSE;
@@ -5585,7 +9579,7 @@ static GLboolean _glewInit_GL_ARB_sparse_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_sparse_texture
-static GLboolean _glewInit_GL_ARB_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_sparse_texture ()
{
GLboolean r = GL_FALSE;
@@ -5599,7 +9593,7 @@ static GLboolean _glewInit_GL_ARB_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_sync
-static GLboolean _glewInit_GL_ARB_sync (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_sync ()
{
GLboolean r = GL_FALSE;
@@ -5618,7 +9612,7 @@ static GLboolean _glewInit_GL_ARB_sync (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_tessellation_shader
-static GLboolean _glewInit_GL_ARB_tessellation_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_tessellation_shader ()
{
GLboolean r = GL_FALSE;
@@ -5632,7 +9626,7 @@ static GLboolean _glewInit_GL_ARB_tessellation_shader (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_texture_barrier
-static GLboolean _glewInit_GL_ARB_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_barrier ()
{
GLboolean r = GL_FALSE;
@@ -5645,7 +9639,7 @@ static GLboolean _glewInit_GL_ARB_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_texture_buffer_object
-static GLboolean _glewInit_GL_ARB_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -5658,7 +9652,7 @@ static GLboolean _glewInit_GL_ARB_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_ARB_texture_buffer_range
-static GLboolean _glewInit_GL_ARB_texture_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_buffer_range ()
{
GLboolean r = GL_FALSE;
@@ -5672,7 +9666,7 @@ static GLboolean _glewInit_GL_ARB_texture_buffer_range (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_ARB_texture_compression
-static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_compression ()
{
GLboolean r = GL_FALSE;
@@ -5691,7 +9685,7 @@ static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_texture_multisample
-static GLboolean _glewInit_GL_ARB_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_multisample ()
{
GLboolean r = GL_FALSE;
@@ -5707,7 +9701,7 @@ static GLboolean _glewInit_GL_ARB_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_texture_storage
-static GLboolean _glewInit_GL_ARB_texture_storage (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_storage ()
{
GLboolean r = GL_FALSE;
@@ -5725,7 +9719,7 @@ static GLboolean _glewInit_GL_ARB_texture_storage (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_texture_storage_multisample
-static GLboolean _glewInit_GL_ARB_texture_storage_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_storage_multisample ()
{
GLboolean r = GL_FALSE;
@@ -5741,7 +9735,7 @@ static GLboolean _glewInit_GL_ARB_texture_storage_multisample (GLEW_CONTEXT_ARG_
#ifdef GL_ARB_texture_view
-static GLboolean _glewInit_GL_ARB_texture_view (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_texture_view ()
{
GLboolean r = GL_FALSE;
@@ -5754,7 +9748,7 @@ static GLboolean _glewInit_GL_ARB_texture_view (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_timer_query
-static GLboolean _glewInit_GL_ARB_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_timer_query ()
{
GLboolean r = GL_FALSE;
@@ -5769,7 +9763,7 @@ static GLboolean _glewInit_GL_ARB_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_transform_feedback2
-static GLboolean _glewInit_GL_ARB_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_transform_feedback2 ()
{
GLboolean r = GL_FALSE;
@@ -5788,7 +9782,7 @@ static GLboolean _glewInit_GL_ARB_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_transform_feedback3
-static GLboolean _glewInit_GL_ARB_transform_feedback3 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_transform_feedback3 ()
{
GLboolean r = GL_FALSE;
@@ -5804,7 +9798,7 @@ static GLboolean _glewInit_GL_ARB_transform_feedback3 (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_transform_feedback_instanced
-static GLboolean _glewInit_GL_ARB_transform_feedback_instanced (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_transform_feedback_instanced ()
{
GLboolean r = GL_FALSE;
@@ -5818,7 +9812,7 @@ static GLboolean _glewInit_GL_ARB_transform_feedback_instanced (GLEW_CONTEXT_ARG
#ifdef GL_ARB_transpose_matrix
-static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_transpose_matrix ()
{
GLboolean r = GL_FALSE;
@@ -5834,7 +9828,7 @@ static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_uniform_buffer_object
-static GLboolean _glewInit_GL_ARB_uniform_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_uniform_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -5856,7 +9850,7 @@ static GLboolean _glewInit_GL_ARB_uniform_buffer_object (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_ARB_vertex_array_object
-static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_array_object ()
{
GLboolean r = GL_FALSE;
@@ -5872,7 +9866,7 @@ static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_vertex_attrib_64bit
-static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit ()
{
GLboolean r = GL_FALSE;
@@ -5894,7 +9888,7 @@ static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ARB_vertex_attrib_binding
-static GLboolean _glewInit_GL_ARB_vertex_attrib_binding (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_attrib_binding ()
{
GLboolean r = GL_FALSE;
@@ -5918,7 +9912,7 @@ static GLboolean _glewInit_GL_ARB_vertex_attrib_binding (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_ARB_vertex_blend
-static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_blend ()
{
GLboolean r = GL_FALSE;
@@ -5940,7 +9934,7 @@ static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_vertex_buffer_object
-static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -5963,7 +9957,7 @@ static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_ARB_vertex_program
-static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_program ()
{
GLboolean r = GL_FALSE;
@@ -6037,7 +10031,7 @@ static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_vertex_shader
-static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_shader ()
{
GLboolean r = GL_FALSE;
@@ -6052,7 +10046,7 @@ static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_vertex_type_2_10_10_10_rev
-static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev ()
{
GLboolean r = GL_FALSE;
@@ -6102,7 +10096,7 @@ static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev (GLEW_CONTEXT_ARG_D
#ifdef GL_ARB_viewport_array
-static GLboolean _glewInit_GL_ARB_viewport_array (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_viewport_array ()
{
GLboolean r = GL_FALSE;
@@ -6124,7 +10118,7 @@ static GLboolean _glewInit_GL_ARB_viewport_array (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ARB_window_pos
-static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ARB_window_pos ()
{
GLboolean r = GL_FALSE;
@@ -6152,7 +10146,7 @@ static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_draw_buffers
-static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_draw_buffers ()
{
GLboolean r = GL_FALSE;
@@ -6165,7 +10159,7 @@ static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_element_array
-static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_element_array ()
{
GLboolean r = GL_FALSE;
@@ -6180,7 +10174,7 @@ static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_envmap_bumpmap
-static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_envmap_bumpmap ()
{
GLboolean r = GL_FALSE;
@@ -6196,7 +10190,7 @@ static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_fragment_shader
-static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_fragment_shader ()
{
GLboolean r = GL_FALSE;
@@ -6222,7 +10216,7 @@ static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_map_object_buffer
-static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_map_object_buffer ()
{
GLboolean r = GL_FALSE;
@@ -6236,7 +10230,7 @@ static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_pn_triangles
-static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_pn_triangles ()
{
GLboolean r = GL_FALSE;
@@ -6250,7 +10244,7 @@ static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_separate_stencil
-static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_separate_stencil ()
{
GLboolean r = GL_FALSE;
@@ -6264,7 +10258,7 @@ static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_ATI_vertex_array_object
-static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_vertex_array_object ()
{
GLboolean r = GL_FALSE;
@@ -6288,7 +10282,7 @@ static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_ATI_vertex_attrib_array_object
-static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object ()
{
GLboolean r = GL_FALSE;
@@ -6303,7 +10297,7 @@ static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_D
#ifdef GL_ATI_vertex_streams
-static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_ATI_vertex_streams ()
{
GLboolean r = GL_FALSE;
@@ -6360,7 +10354,7 @@ static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_bindable_uniform
-static GLboolean _glewInit_GL_EXT_bindable_uniform (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_bindable_uniform ()
{
GLboolean r = GL_FALSE;
@@ -6375,7 +10369,7 @@ static GLboolean _glewInit_GL_EXT_bindable_uniform (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_blend_color
-static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_blend_color ()
{
GLboolean r = GL_FALSE;
@@ -6388,7 +10382,7 @@ static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_blend_equation_separate
-static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_blend_equation_separate ()
{
GLboolean r = GL_FALSE;
@@ -6401,7 +10395,7 @@ static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_EXT_blend_func_separate
-static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_blend_func_separate ()
{
GLboolean r = GL_FALSE;
@@ -6414,7 +10408,7 @@ static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_EXT_blend_minmax
-static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_blend_minmax ()
{
GLboolean r = GL_FALSE;
@@ -6427,7 +10421,7 @@ static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_color_subtable
-static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_color_subtable ()
{
GLboolean r = GL_FALSE;
@@ -6441,7 +10435,7 @@ static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_compiled_vertex_array
-static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_compiled_vertex_array ()
{
GLboolean r = GL_FALSE;
@@ -6455,7 +10449,7 @@ static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_EXT_convolution
-static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_convolution ()
{
GLboolean r = GL_FALSE;
@@ -6480,7 +10474,7 @@ static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_coordinate_frame
-static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_coordinate_frame ()
{
GLboolean r = GL_FALSE;
@@ -6494,7 +10488,7 @@ static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_copy_texture
-static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_copy_texture ()
{
GLboolean r = GL_FALSE;
@@ -6511,7 +10505,7 @@ static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_cull_vertex
-static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_cull_vertex ()
{
GLboolean r = GL_FALSE;
@@ -6525,7 +10519,7 @@ static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_debug_label
-static GLboolean _glewInit_GL_EXT_debug_label (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_debug_label ()
{
GLboolean r = GL_FALSE;
@@ -6539,7 +10533,7 @@ static GLboolean _glewInit_GL_EXT_debug_label (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_debug_marker
-static GLboolean _glewInit_GL_EXT_debug_marker (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_debug_marker ()
{
GLboolean r = GL_FALSE;
@@ -6554,7 +10548,7 @@ static GLboolean _glewInit_GL_EXT_debug_marker (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_depth_bounds_test
-static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_depth_bounds_test ()
{
GLboolean r = GL_FALSE;
@@ -6567,7 +10561,7 @@ static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_direct_state_access
-static GLboolean _glewInit_GL_EXT_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_direct_state_access ()
{
GLboolean r = GL_FALSE;
@@ -6793,7 +10787,7 @@ static GLboolean _glewInit_GL_EXT_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_EXT_draw_buffers2
-static GLboolean _glewInit_GL_EXT_draw_buffers2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_draw_buffers2 ()
{
GLboolean r = GL_FALSE;
@@ -6811,7 +10805,7 @@ static GLboolean _glewInit_GL_EXT_draw_buffers2 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_draw_instanced
-static GLboolean _glewInit_GL_EXT_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_draw_instanced ()
{
GLboolean r = GL_FALSE;
@@ -6825,7 +10819,7 @@ static GLboolean _glewInit_GL_EXT_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_draw_range_elements
-static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_draw_range_elements ()
{
GLboolean r = GL_FALSE;
@@ -6838,7 +10832,7 @@ static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_EXT_fog_coord
-static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_fog_coord ()
{
GLboolean r = GL_FALSE;
@@ -6855,7 +10849,7 @@ static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_fragment_lighting
-static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_fragment_lighting ()
{
GLboolean r = GL_FALSE;
@@ -6885,7 +10879,7 @@ static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_framebuffer_blit
-static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_framebuffer_blit ()
{
GLboolean r = GL_FALSE;
@@ -6898,7 +10892,7 @@ static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_framebuffer_multisample
-static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_framebuffer_multisample ()
{
GLboolean r = GL_FALSE;
@@ -6911,7 +10905,7 @@ static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_EXT_framebuffer_object
-static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_framebuffer_object ()
{
GLboolean r = GL_FALSE;
@@ -6940,7 +10934,7 @@ static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_geometry_shader4
-static GLboolean _glewInit_GL_EXT_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_geometry_shader4 ()
{
GLboolean r = GL_FALSE;
@@ -6955,7 +10949,7 @@ static GLboolean _glewInit_GL_EXT_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_gpu_program_parameters
-static GLboolean _glewInit_GL_EXT_gpu_program_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_gpu_program_parameters ()
{
GLboolean r = GL_FALSE;
@@ -6969,7 +10963,7 @@ static GLboolean _glewInit_GL_EXT_gpu_program_parameters (GLEW_CONTEXT_ARG_DEF_I
#ifdef GL_EXT_gpu_shader4
-static GLboolean _glewInit_GL_EXT_gpu_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_gpu_shader4 ()
{
GLboolean r = GL_FALSE;
@@ -7015,7 +11009,7 @@ static GLboolean _glewInit_GL_EXT_gpu_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_histogram
-static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_histogram ()
{
GLboolean r = GL_FALSE;
@@ -7037,7 +11031,7 @@ static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_index_func
-static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_index_func ()
{
GLboolean r = GL_FALSE;
@@ -7050,7 +11044,7 @@ static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_index_material
-static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_index_material ()
{
GLboolean r = GL_FALSE;
@@ -7063,7 +11057,7 @@ static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_light_texture
-static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_light_texture ()
{
GLboolean r = GL_FALSE;
@@ -7078,7 +11072,7 @@ static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_multi_draw_arrays
-static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_multi_draw_arrays ()
{
GLboolean r = GL_FALSE;
@@ -7092,7 +11086,7 @@ static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_multisample
-static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_multisample ()
{
GLboolean r = GL_FALSE;
@@ -7106,7 +11100,7 @@ static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_paletted_texture
-static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_paletted_texture ()
{
GLboolean r = GL_FALSE;
@@ -7122,7 +11116,7 @@ static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_pixel_transform
-static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_pixel_transform ()
{
GLboolean r = GL_FALSE;
@@ -7140,7 +11134,7 @@ static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_point_parameters
-static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_point_parameters ()
{
GLboolean r = GL_FALSE;
@@ -7154,7 +11148,7 @@ static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_polygon_offset
-static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_polygon_offset ()
{
GLboolean r = GL_FALSE;
@@ -7167,7 +11161,7 @@ static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_polygon_offset_clamp
-static GLboolean _glewInit_GL_EXT_polygon_offset_clamp (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_polygon_offset_clamp ()
{
GLboolean r = GL_FALSE;
@@ -7180,7 +11174,7 @@ static GLboolean _glewInit_GL_EXT_polygon_offset_clamp (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_EXT_provoking_vertex
-static GLboolean _glewInit_GL_EXT_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_provoking_vertex ()
{
GLboolean r = GL_FALSE;
@@ -7193,7 +11187,7 @@ static GLboolean _glewInit_GL_EXT_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_raster_multisample
-static GLboolean _glewInit_GL_EXT_raster_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_raster_multisample ()
{
GLboolean r = GL_FALSE;
@@ -7209,7 +11203,7 @@ static GLboolean _glewInit_GL_EXT_raster_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_scene_marker
-static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_scene_marker ()
{
GLboolean r = GL_FALSE;
@@ -7223,7 +11217,7 @@ static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_secondary_color
-static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_secondary_color ()
{
GLboolean r = GL_FALSE;
@@ -7252,7 +11246,7 @@ static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_separate_shader_objects
-static GLboolean _glewInit_GL_EXT_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_separate_shader_objects ()
{
GLboolean r = GL_FALSE;
@@ -7267,7 +11261,7 @@ static GLboolean _glewInit_GL_EXT_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_EXT_shader_image_load_store
-static GLboolean _glewInit_GL_EXT_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_shader_image_load_store ()
{
GLboolean r = GL_FALSE;
@@ -7281,7 +11275,7 @@ static GLboolean _glewInit_GL_EXT_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_EXT_stencil_two_side
-static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_stencil_two_side ()
{
GLboolean r = GL_FALSE;
@@ -7294,7 +11288,7 @@ static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_subtexture
-static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_subtexture ()
{
GLboolean r = GL_FALSE;
@@ -7309,7 +11303,7 @@ static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_texture3D
-static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_texture3D ()
{
GLboolean r = GL_FALSE;
@@ -7322,7 +11316,7 @@ static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_texture_array
-static GLboolean _glewInit_GL_EXT_texture_array (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_texture_array ()
{
GLboolean r = GL_FALSE;
@@ -7335,7 +11329,7 @@ static GLboolean _glewInit_GL_EXT_texture_array (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_texture_buffer_object
-static GLboolean _glewInit_GL_EXT_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_texture_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -7348,7 +11342,7 @@ static GLboolean _glewInit_GL_EXT_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_EXT_texture_integer
-static GLboolean _glewInit_GL_EXT_texture_integer (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_texture_integer ()
{
GLboolean r = GL_FALSE;
@@ -7366,7 +11360,7 @@ static GLboolean _glewInit_GL_EXT_texture_integer (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_texture_object
-static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_texture_object ()
{
GLboolean r = GL_FALSE;
@@ -7384,7 +11378,7 @@ static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_texture_perturb_normal
-static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_texture_perturb_normal ()
{
GLboolean r = GL_FALSE;
@@ -7397,7 +11391,7 @@ static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_I
#ifdef GL_EXT_timer_query
-static GLboolean _glewInit_GL_EXT_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_timer_query ()
{
GLboolean r = GL_FALSE;
@@ -7411,7 +11405,7 @@ static GLboolean _glewInit_GL_EXT_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_transform_feedback
-static GLboolean _glewInit_GL_EXT_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_transform_feedback ()
{
GLboolean r = GL_FALSE;
@@ -7430,7 +11424,7 @@ static GLboolean _glewInit_GL_EXT_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_vertex_array
-static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_vertex_array ()
{
GLboolean r = GL_FALSE;
@@ -7450,7 +11444,7 @@ static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_vertex_attrib_64bit
-static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit ()
{
GLboolean r = GL_FALSE;
@@ -7473,7 +11467,7 @@ static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_EXT_vertex_shader
-static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_vertex_shader ()
{
GLboolean r = GL_FALSE;
@@ -7527,7 +11521,7 @@ static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_EXT_vertex_weighting
-static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_vertex_weighting ()
{
GLboolean r = GL_FALSE;
@@ -7540,9 +11534,22 @@ static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT)
#endif /* GL_EXT_vertex_weighting */
+#ifdef GL_EXT_window_rectangles
+
+static GLboolean _glewInit_GL_EXT_window_rectangles ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glWindowRectanglesEXT = (PFNGLWINDOWRECTANGLESEXTPROC)glewGetProcAddress((const GLubyte*)"glWindowRectanglesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_window_rectangles */
+
#ifdef GL_EXT_x11_sync_object
-static GLboolean _glewInit_GL_EXT_x11_sync_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_EXT_x11_sync_object ()
{
GLboolean r = GL_FALSE;
@@ -7555,7 +11562,7 @@ static GLboolean _glewInit_GL_EXT_x11_sync_object (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_GREMEDY_frame_terminator
-static GLboolean _glewInit_GL_GREMEDY_frame_terminator (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_GREMEDY_frame_terminator ()
{
GLboolean r = GL_FALSE;
@@ -7568,7 +11575,7 @@ static GLboolean _glewInit_GL_GREMEDY_frame_terminator (GLEW_CONTEXT_ARG_DEF_INI
#ifdef GL_GREMEDY_string_marker
-static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_GREMEDY_string_marker ()
{
GLboolean r = GL_FALSE;
@@ -7581,7 +11588,7 @@ static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_HP_image_transform
-static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_HP_image_transform ()
{
GLboolean r = GL_FALSE;
@@ -7599,7 +11606,7 @@ static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_IBM_multimode_draw_arrays
-static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_IBM_multimode_draw_arrays ()
{
GLboolean r = GL_FALSE;
@@ -7613,7 +11620,7 @@ static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_IBM_vertex_array_lists
-static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_IBM_vertex_array_lists ()
{
GLboolean r = GL_FALSE;
@@ -7633,7 +11640,7 @@ static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_INTEL_map_texture
-static GLboolean _glewInit_GL_INTEL_map_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_INTEL_map_texture ()
{
GLboolean r = GL_FALSE;
@@ -7648,7 +11655,7 @@ static GLboolean _glewInit_GL_INTEL_map_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_INTEL_parallel_arrays
-static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_INTEL_parallel_arrays ()
{
GLboolean r = GL_FALSE;
@@ -7664,7 +11671,7 @@ static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_INTEL_performance_query
-static GLboolean _glewInit_GL_INTEL_performance_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_INTEL_performance_query ()
{
GLboolean r = GL_FALSE;
@@ -7686,7 +11693,7 @@ static GLboolean _glewInit_GL_INTEL_performance_query (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_INTEL_texture_scissor
-static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_INTEL_texture_scissor ()
{
GLboolean r = GL_FALSE;
@@ -7700,7 +11707,7 @@ static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_KHR_blend_equation_advanced
-static GLboolean _glewInit_GL_KHR_blend_equation_advanced (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_KHR_blend_equation_advanced ()
{
GLboolean r = GL_FALSE;
@@ -7713,7 +11720,7 @@ static GLboolean _glewInit_GL_KHR_blend_equation_advanced (GLEW_CONTEXT_ARG_DEF_
#ifdef GL_KHR_debug
-static GLboolean _glewInit_GL_KHR_debug (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_KHR_debug ()
{
GLboolean r = GL_FALSE;
@@ -7735,7 +11742,7 @@ static GLboolean _glewInit_GL_KHR_debug (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_KHR_robustness
-static GLboolean _glewInit_GL_KHR_robustness (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_KHR_robustness ()
{
GLboolean r = GL_FALSE;
@@ -7751,7 +11758,7 @@ static GLboolean _glewInit_GL_KHR_robustness (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_KTX_buffer_region
-static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_KTX_buffer_region ()
{
GLboolean r = GL_FALSE;
@@ -7768,7 +11775,7 @@ static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_MESA_resize_buffers
-static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_MESA_resize_buffers ()
{
GLboolean r = GL_FALSE;
@@ -7781,7 +11788,7 @@ static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_MESA_window_pos
-static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_MESA_window_pos ()
{
GLboolean r = GL_FALSE;
@@ -7817,7 +11824,7 @@ static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NVX_conditional_render
-static GLboolean _glewInit_GL_NVX_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NVX_conditional_render ()
{
GLboolean r = GL_FALSE;
@@ -7829,9 +11836,24 @@ static GLboolean _glewInit_GL_NVX_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT)
#endif /* GL_NVX_conditional_render */
+#ifdef GL_NVX_linked_gpu_multicast
+
+static GLboolean _glewInit_GL_NVX_linked_gpu_multicast ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLGPUCopyImageSubDataNVX = (PFNGLLGPUCOPYIMAGESUBDATANVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUCopyImageSubDataNVX")) == NULL) || r;
+ r = ((glLGPUInterlockNVX = (PFNGLLGPUINTERLOCKNVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUInterlockNVX")) == NULL) || r;
+ r = ((glLGPUNamedBufferSubDataNVX = (PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUNamedBufferSubDataNVX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NVX_linked_gpu_multicast */
+
#ifdef GL_NV_bindless_multi_draw_indirect
-static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect ()
{
GLboolean r = GL_FALSE;
@@ -7845,7 +11867,7 @@ static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect (GLEW_CONTEXT_ARG_
#ifdef GL_NV_bindless_multi_draw_indirect_count
-static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count ()
{
GLboolean r = GL_FALSE;
@@ -7859,7 +11881,7 @@ static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count (GLEW_CONTEX
#ifdef GL_NV_bindless_texture
-static GLboolean _glewInit_GL_NV_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_bindless_texture ()
{
GLboolean r = GL_FALSE;
@@ -7884,7 +11906,7 @@ static GLboolean _glewInit_GL_NV_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_blend_equation_advanced
-static GLboolean _glewInit_GL_NV_blend_equation_advanced (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_blend_equation_advanced ()
{
GLboolean r = GL_FALSE;
@@ -7896,9 +11918,51 @@ static GLboolean _glewInit_GL_NV_blend_equation_advanced (GLEW_CONTEXT_ARG_DEF_I
#endif /* GL_NV_blend_equation_advanced */
+#ifdef GL_NV_clip_space_w_scaling
+
+static GLboolean _glewInit_GL_NV_clip_space_w_scaling ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glViewportPositionWScaleNV = (PFNGLVIEWPORTPOSITIONWSCALENVPROC)glewGetProcAddress((const GLubyte*)"glViewportPositionWScaleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_clip_space_w_scaling */
+
+#ifdef GL_NV_command_list
+
+static GLboolean _glewInit_GL_NV_command_list ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCallCommandListNV = (PFNGLCALLCOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glCallCommandListNV")) == NULL) || r;
+ r = ((glCommandListSegmentsNV = (PFNGLCOMMANDLISTSEGMENTSNVPROC)glewGetProcAddress((const GLubyte*)"glCommandListSegmentsNV")) == NULL) || r;
+ r = ((glCompileCommandListNV = (PFNGLCOMPILECOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glCompileCommandListNV")) == NULL) || r;
+ r = ((glCreateCommandListsNV = (PFNGLCREATECOMMANDLISTSNVPROC)glewGetProcAddress((const GLubyte*)"glCreateCommandListsNV")) == NULL) || r;
+ r = ((glCreateStatesNV = (PFNGLCREATESTATESNVPROC)glewGetProcAddress((const GLubyte*)"glCreateStatesNV")) == NULL) || r;
+ r = ((glDeleteCommandListsNV = (PFNGLDELETECOMMANDLISTSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteCommandListsNV")) == NULL) || r;
+ r = ((glDeleteStatesNV = (PFNGLDELETESTATESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteStatesNV")) == NULL) || r;
+ r = ((glDrawCommandsAddressNV = (PFNGLDRAWCOMMANDSADDRESSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsAddressNV")) == NULL) || r;
+ r = ((glDrawCommandsNV = (PFNGLDRAWCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsNV")) == NULL) || r;
+ r = ((glDrawCommandsStatesAddressNV = (PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsStatesAddressNV")) == NULL) || r;
+ r = ((glDrawCommandsStatesNV = (PFNGLDRAWCOMMANDSSTATESNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsStatesNV")) == NULL) || r;
+ r = ((glGetCommandHeaderNV = (PFNGLGETCOMMANDHEADERNVPROC)glewGetProcAddress((const GLubyte*)"glGetCommandHeaderNV")) == NULL) || r;
+ r = ((glGetStageIndexNV = (PFNGLGETSTAGEINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glGetStageIndexNV")) == NULL) || r;
+ r = ((glIsCommandListNV = (PFNGLISCOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glIsCommandListNV")) == NULL) || r;
+ r = ((glIsStateNV = (PFNGLISSTATENVPROC)glewGetProcAddress((const GLubyte*)"glIsStateNV")) == NULL) || r;
+ r = ((glListDrawCommandsStatesClientNV = (PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC)glewGetProcAddress((const GLubyte*)"glListDrawCommandsStatesClientNV")) == NULL) || r;
+ r = ((glStateCaptureNV = (PFNGLSTATECAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glStateCaptureNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_command_list */
+
#ifdef GL_NV_conditional_render
-static GLboolean _glewInit_GL_NV_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_conditional_render ()
{
GLboolean r = GL_FALSE;
@@ -7912,7 +11976,7 @@ static GLboolean _glewInit_GL_NV_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_conservative_raster
-static GLboolean _glewInit_GL_NV_conservative_raster (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_conservative_raster ()
{
GLboolean r = GL_FALSE;
@@ -7925,7 +11989,7 @@ static GLboolean _glewInit_GL_NV_conservative_raster (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_conservative_raster_dilate
-static GLboolean _glewInit_GL_NV_conservative_raster_dilate (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_conservative_raster_dilate ()
{
GLboolean r = GL_FALSE;
@@ -7936,9 +12000,22 @@ static GLboolean _glewInit_GL_NV_conservative_raster_dilate (GLEW_CONTEXT_ARG_DE
#endif /* GL_NV_conservative_raster_dilate */
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+
+static GLboolean _glewInit_GL_NV_conservative_raster_pre_snap_triangles ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glConservativeRasterParameteriNV = (PFNGLCONSERVATIVERASTERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glConservativeRasterParameteriNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+
#ifdef GL_NV_copy_image
-static GLboolean _glewInit_GL_NV_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_copy_image ()
{
GLboolean r = GL_FALSE;
@@ -7951,7 +12028,7 @@ static GLboolean _glewInit_GL_NV_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_depth_buffer_float
-static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_depth_buffer_float ()
{
GLboolean r = GL_FALSE;
@@ -7966,7 +12043,7 @@ static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_draw_texture
-static GLboolean _glewInit_GL_NV_draw_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_draw_texture ()
{
GLboolean r = GL_FALSE;
@@ -7977,9 +12054,26 @@ static GLboolean _glewInit_GL_NV_draw_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#endif /* GL_NV_draw_texture */
+#ifdef GL_NV_draw_vulkan_image
+
+static GLboolean _glewInit_GL_NV_draw_vulkan_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawVkImageNV = (PFNGLDRAWVKIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glDrawVkImageNV")) == NULL) || r;
+ r = ((glGetVkProcAddrNV = (PFNGLGETVKPROCADDRNVPROC)glewGetProcAddress((const GLubyte*)"glGetVkProcAddrNV")) == NULL) || r;
+ r = ((glSignalVkFenceNV = (PFNGLSIGNALVKFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSignalVkFenceNV")) == NULL) || r;
+ r = ((glSignalVkSemaphoreNV = (PFNGLSIGNALVKSEMAPHORENVPROC)glewGetProcAddress((const GLubyte*)"glSignalVkSemaphoreNV")) == NULL) || r;
+ r = ((glWaitVkSemaphoreNV = (PFNGLWAITVKSEMAPHORENVPROC)glewGetProcAddress((const GLubyte*)"glWaitVkSemaphoreNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_draw_vulkan_image */
+
#ifdef GL_NV_evaluators
-static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_evaluators ()
{
GLboolean r = GL_FALSE;
@@ -8000,7 +12094,7 @@ static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_explicit_multisample
-static GLboolean _glewInit_GL_NV_explicit_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_explicit_multisample ()
{
GLboolean r = GL_FALSE;
@@ -8015,7 +12109,7 @@ static GLboolean _glewInit_GL_NV_explicit_multisample (GLEW_CONTEXT_ARG_DEF_INIT
#ifdef GL_NV_fence
-static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_fence ()
{
GLboolean r = GL_FALSE;
@@ -8034,7 +12128,7 @@ static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_fragment_coverage_to_color
-static GLboolean _glewInit_GL_NV_fragment_coverage_to_color (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_fragment_coverage_to_color ()
{
GLboolean r = GL_FALSE;
@@ -8047,7 +12141,7 @@ static GLboolean _glewInit_GL_NV_fragment_coverage_to_color (GLEW_CONTEXT_ARG_DE
#ifdef GL_NV_fragment_program
-static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_fragment_program ()
{
GLboolean r = GL_FALSE;
@@ -8065,7 +12159,7 @@ static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_framebuffer_multisample_coverage
-static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage ()
{
GLboolean r = GL_FALSE;
@@ -8078,7 +12172,7 @@ static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (GLEW_CONTEXT_
#ifdef GL_NV_geometry_program4
-static GLboolean _glewInit_GL_NV_geometry_program4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_geometry_program4 ()
{
GLboolean r = GL_FALSE;
@@ -8089,9 +12183,33 @@ static GLboolean _glewInit_GL_NV_geometry_program4 (GLEW_CONTEXT_ARG_DEF_INIT)
#endif /* GL_NV_geometry_program4 */
+#ifdef GL_NV_gpu_multicast
+
+static GLboolean _glewInit_GL_NV_gpu_multicast ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMulticastBarrierNV = (PFNGLMULTICASTBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBarrierNV")) == NULL) || r;
+ r = ((glMulticastBlitFramebufferNV = (PFNGLMULTICASTBLITFRAMEBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBlitFramebufferNV")) == NULL) || r;
+ r = ((glMulticastBufferSubDataNV = (PFNGLMULTICASTBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBufferSubDataNV")) == NULL) || r;
+ r = ((glMulticastCopyBufferSubDataNV = (PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastCopyBufferSubDataNV")) == NULL) || r;
+ r = ((glMulticastCopyImageSubDataNV = (PFNGLMULTICASTCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastCopyImageSubDataNV")) == NULL) || r;
+ r = ((glMulticastFramebufferSampleLocationsfvNV = (PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastFramebufferSampleLocationsfvNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjecti64vNV = (PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjecti64vNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjectivNV = (PFNGLMULTICASTGETQUERYOBJECTIVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectivNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjectui64vNV = (PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectui64vNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjectuivNV = (PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectuivNV")) == NULL) || r;
+ r = ((glMulticastWaitSyncNV = (PFNGLMULTICASTWAITSYNCNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastWaitSyncNV")) == NULL) || r;
+ r = ((glRenderGpuMaskNV = (PFNGLRENDERGPUMASKNVPROC)glewGetProcAddress((const GLubyte*)"glRenderGpuMaskNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_gpu_multicast */
+
#ifdef GL_NV_gpu_program4
-static GLboolean _glewInit_GL_NV_gpu_program4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_gpu_program4 ()
{
GLboolean r = GL_FALSE;
@@ -8115,7 +12233,7 @@ static GLboolean _glewInit_GL_NV_gpu_program4 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_gpu_shader5
-static GLboolean _glewInit_GL_NV_gpu_shader5 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_gpu_shader5 ()
{
GLboolean r = GL_FALSE;
@@ -8161,7 +12279,7 @@ static GLboolean _glewInit_GL_NV_gpu_shader5 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_half_float
-static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_half_float ()
{
GLboolean r = GL_FALSE;
@@ -8219,7 +12337,7 @@ static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_internalformat_sample_query
-static GLboolean _glewInit_GL_NV_internalformat_sample_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_internalformat_sample_query ()
{
GLboolean r = GL_FALSE;
@@ -8232,7 +12350,7 @@ static GLboolean _glewInit_GL_NV_internalformat_sample_query (GLEW_CONTEXT_ARG_D
#ifdef GL_NV_occlusion_query
-static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_occlusion_query ()
{
GLboolean r = GL_FALSE;
@@ -8251,7 +12369,7 @@ static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_parameter_buffer_object
-static GLboolean _glewInit_GL_NV_parameter_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_parameter_buffer_object ()
{
GLboolean r = GL_FALSE;
@@ -8266,7 +12384,7 @@ static GLboolean _glewInit_GL_NV_parameter_buffer_object (GLEW_CONTEXT_ARG_DEF_I
#ifdef GL_NV_path_rendering
-static GLboolean _glewInit_GL_NV_path_rendering (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_path_rendering ()
{
GLboolean r = GL_FALSE;
@@ -8342,7 +12460,7 @@ static GLboolean _glewInit_GL_NV_path_rendering (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_pixel_data_range
-static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_pixel_data_range ()
{
GLboolean r = GL_FALSE;
@@ -8356,7 +12474,7 @@ static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_point_sprite
-static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_point_sprite ()
{
GLboolean r = GL_FALSE;
@@ -8370,7 +12488,7 @@ static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_present_video
-static GLboolean _glewInit_GL_NV_present_video (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_present_video ()
{
GLboolean r = GL_FALSE;
@@ -8388,7 +12506,7 @@ static GLboolean _glewInit_GL_NV_present_video (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_primitive_restart
-static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_primitive_restart ()
{
GLboolean r = GL_FALSE;
@@ -8402,7 +12520,7 @@ static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_register_combiners
-static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_register_combiners ()
{
GLboolean r = GL_FALSE;
@@ -8427,7 +12545,7 @@ static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_register_combiners2
-static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_register_combiners2 ()
{
GLboolean r = GL_FALSE;
@@ -8441,7 +12559,7 @@ static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_sample_locations
-static GLboolean _glewInit_GL_NV_sample_locations (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_sample_locations ()
{
GLboolean r = GL_FALSE;
@@ -8455,7 +12573,7 @@ static GLboolean _glewInit_GL_NV_sample_locations (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_shader_buffer_load
-static GLboolean _glewInit_GL_NV_shader_buffer_load (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_shader_buffer_load ()
{
GLboolean r = GL_FALSE;
@@ -8480,7 +12598,7 @@ static GLboolean _glewInit_GL_NV_shader_buffer_load (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_texture_barrier
-static GLboolean _glewInit_GL_NV_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_texture_barrier ()
{
GLboolean r = GL_FALSE;
@@ -8493,7 +12611,7 @@ static GLboolean _glewInit_GL_NV_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_texture_multisample
-static GLboolean _glewInit_GL_NV_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_texture_multisample ()
{
GLboolean r = GL_FALSE;
@@ -8511,7 +12629,7 @@ static GLboolean _glewInit_GL_NV_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_transform_feedback
-static GLboolean _glewInit_GL_NV_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_transform_feedback ()
{
GLboolean r = GL_FALSE;
@@ -8534,7 +12652,7 @@ static GLboolean _glewInit_GL_NV_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_transform_feedback2
-static GLboolean _glewInit_GL_NV_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_transform_feedback2 ()
{
GLboolean r = GL_FALSE;
@@ -8553,7 +12671,7 @@ static GLboolean _glewInit_GL_NV_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_vdpau_interop
-static GLboolean _glewInit_GL_NV_vdpau_interop (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_vdpau_interop ()
{
GLboolean r = GL_FALSE;
@@ -8575,7 +12693,7 @@ static GLboolean _glewInit_GL_NV_vdpau_interop (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_vertex_array_range
-static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_vertex_array_range ()
{
GLboolean r = GL_FALSE;
@@ -8589,7 +12707,7 @@ static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_vertex_attrib_integer_64bit
-static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit ()
{
GLboolean r = GL_FALSE;
@@ -8620,7 +12738,7 @@ static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit (GLEW_CONTEXT_ARG_D
#ifdef GL_NV_vertex_buffer_unified_memory
-static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory ()
{
GLboolean r = GL_FALSE;
@@ -8644,7 +12762,7 @@ static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory (GLEW_CONTEXT_ARG_
#ifdef GL_NV_vertex_program
-static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_vertex_program ()
{
GLboolean r = GL_FALSE;
@@ -8720,7 +12838,7 @@ static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_NV_video_capture
-static GLboolean _glewInit_GL_NV_video_capture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_NV_video_capture ()
{
GLboolean r = GL_FALSE;
@@ -8742,9 +12860,22 @@ static GLboolean _glewInit_GL_NV_video_capture (GLEW_CONTEXT_ARG_DEF_INIT)
#endif /* GL_NV_video_capture */
+#ifdef GL_NV_viewport_swizzle
+
+static GLboolean _glewInit_GL_NV_viewport_swizzle ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glViewportSwizzleNV = (PFNGLVIEWPORTSWIZZLENVPROC)glewGetProcAddress((const GLubyte*)"glViewportSwizzleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_viewport_swizzle */
+
#ifdef GL_OES_single_precision
-static GLboolean _glewInit_GL_OES_single_precision (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_OES_single_precision ()
{
GLboolean r = GL_FALSE;
@@ -8762,7 +12893,7 @@ static GLboolean _glewInit_GL_OES_single_precision (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_OVR_multiview
-static GLboolean _glewInit_GL_OVR_multiview (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_OVR_multiview ()
{
GLboolean r = GL_FALSE;
@@ -8775,7 +12906,7 @@ static GLboolean _glewInit_GL_OVR_multiview (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_REGAL_ES1_0_compatibility
-static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility ()
{
GLboolean r = GL_FALSE;
@@ -8818,7 +12949,7 @@ static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_REGAL_ES1_1_compatibility
-static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility ()
{
GLboolean r = GL_FALSE;
@@ -8843,7 +12974,7 @@ static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility (GLEW_CONTEXT_ARG_DEF_IN
#ifdef GL_REGAL_error_string
-static GLboolean _glewInit_GL_REGAL_error_string (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_REGAL_error_string ()
{
GLboolean r = GL_FALSE;
@@ -8856,7 +12987,7 @@ static GLboolean _glewInit_GL_REGAL_error_string (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_REGAL_extension_query
-static GLboolean _glewInit_GL_REGAL_extension_query (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_REGAL_extension_query ()
{
GLboolean r = GL_FALSE;
@@ -8870,7 +13001,7 @@ static GLboolean _glewInit_GL_REGAL_extension_query (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_REGAL_log
-static GLboolean _glewInit_GL_REGAL_log (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_REGAL_log ()
{
GLboolean r = GL_FALSE;
@@ -8883,7 +13014,7 @@ static GLboolean _glewInit_GL_REGAL_log (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_REGAL_proc_address
-static GLboolean _glewInit_GL_REGAL_proc_address (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_REGAL_proc_address ()
{
GLboolean r = GL_FALSE;
@@ -8896,7 +13027,7 @@ static GLboolean _glewInit_GL_REGAL_proc_address (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIS_detail_texture
-static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIS_detail_texture ()
{
GLboolean r = GL_FALSE;
@@ -8910,7 +13041,7 @@ static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIS_fog_function
-static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIS_fog_function ()
{
GLboolean r = GL_FALSE;
@@ -8924,7 +13055,7 @@ static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIS_multisample
-static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIS_multisample ()
{
GLboolean r = GL_FALSE;
@@ -8938,7 +13069,7 @@ static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIS_sharpen_texture
-static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIS_sharpen_texture ()
{
GLboolean r = GL_FALSE;
@@ -8952,7 +13083,7 @@ static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIS_texture4D
-static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIS_texture4D ()
{
GLboolean r = GL_FALSE;
@@ -8966,7 +13097,7 @@ static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIS_texture_filter4
-static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIS_texture_filter4 ()
{
GLboolean r = GL_FALSE;
@@ -8980,7 +13111,7 @@ static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_async
-static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_async ()
{
GLboolean r = GL_FALSE;
@@ -8998,7 +13129,7 @@ static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_flush_raster
-static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_flush_raster ()
{
GLboolean r = GL_FALSE;
@@ -9011,7 +13142,7 @@ static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_fog_texture
-static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_fog_texture ()
{
GLboolean r = GL_FALSE;
@@ -9024,7 +13155,7 @@ static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_fragment_specular_lighting
-static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting ()
{
GLboolean r = GL_FALSE;
@@ -9053,7 +13184,7 @@ static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_
#ifdef GL_SGIX_framezoom
-static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_framezoom ()
{
GLboolean r = GL_FALSE;
@@ -9066,7 +13197,7 @@ static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_pixel_texture
-static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_pixel_texture ()
{
GLboolean r = GL_FALSE;
@@ -9079,7 +13210,7 @@ static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_reference_plane
-static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_reference_plane ()
{
GLboolean r = GL_FALSE;
@@ -9092,7 +13223,7 @@ static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_sprite
-static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_sprite ()
{
GLboolean r = GL_FALSE;
@@ -9108,7 +13239,7 @@ static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGIX_tag_sample_buffer
-static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGIX_tag_sample_buffer ()
{
GLboolean r = GL_FALSE;
@@ -9121,7 +13252,7 @@ static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SGI_color_table
-static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SGI_color_table ()
{
GLboolean r = GL_FALSE;
@@ -9140,7 +13271,7 @@ static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SUNX_constant_data
-static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SUNX_constant_data ()
{
GLboolean r = GL_FALSE;
@@ -9153,7 +13284,7 @@ static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SUN_global_alpha
-static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SUN_global_alpha ()
{
GLboolean r = GL_FALSE;
@@ -9173,7 +13304,7 @@ static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SUN_read_video_pixels
-static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SUN_read_video_pixels ()
{
GLboolean r = GL_FALSE;
@@ -9186,7 +13317,7 @@ static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SUN_triangle_list
-static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SUN_triangle_list ()
{
GLboolean r = GL_FALSE;
@@ -9205,7 +13336,7 @@ static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_SUN_vertex
-static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_SUN_vertex ()
{
GLboolean r = GL_FALSE;
@@ -9257,7 +13388,7 @@ static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_WIN_swap_hint
-static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GL_WIN_swap_hint ()
{
GLboolean r = GL_FALSE;
@@ -9270,35 +13401,101 @@ static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT)
/* ------------------------------------------------------------------------- */
+static int _glewExtensionCompare(const char *s1, const char *s2)
+{
+ /* http://www.chanduthedev.com/2012/07/strcmp-implementation-in-c.html */
+ while (*s1 || *s2)
+ {
+ if (*s1 > *s2)
+ return 1;
+ if (*s1 < *s2)
+ return -1;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+
+static ptrdiff_t _glewBsearchExtension(const char* name)
+{
+ ptrdiff_t lo = 0, hi = sizeof(_glewExtensionLookup) / sizeof(char*) - 2;
+
+ while (lo <= hi)
+ {
+ ptrdiff_t mid = (lo + hi) / 2;
+ const int cmp = _glewExtensionCompare(name, _glewExtensionLookup[mid]);
+ if (cmp < 0) hi = mid - 1;
+ else if (cmp > 0) lo = mid + 1;
+ else return mid;
+ }
+ return -1;
+}
+
+static GLboolean *_glewGetExtensionString(const char *name)
+{
+ ptrdiff_t n = _glewBsearchExtension(name);
+ if (n >= 0) return &_glewExtensionString[n];
+ return NULL;
+}
+
+static GLboolean *_glewGetExtensionEnable(const char *name)
+{
+ ptrdiff_t n = _glewBsearchExtension(name);
+ if (n >= 0) return _glewExtensionEnabled[n];
+ return NULL;
+}
+
+static const char *_glewNextSpace(const char *i)
+{
+ const char *j = i;
+ if (j)
+ while (*j!=' ' && *j) ++j;
+ return j;
+}
+
+static const char *_glewNextNonSpace(const char *i)
+{
+ const char *j = i;
+ if (j)
+ while (*j==' ') ++j;
+ return j;
+}
+
GLboolean GLEWAPIENTRY glewGetExtension (const char* name)
-{
- const GLubyte* start;
- const GLubyte* end;
- start = (const GLubyte*)glGetString(GL_EXTENSIONS);
- if (start == 0)
- return GL_FALSE;
- end = start + _glewStrLen(start);
- return _glewSearchExtension(name, start, end);
+{
+ GLboolean *enable = _glewGetExtensionString(name);
+ if (enable)
+ return *enable;
+ return GL_FALSE;
}
/* ------------------------------------------------------------------------- */
-#ifndef GLEW_MX
-static
-#endif
-GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST)
+typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
+
+static GLenum GLEWAPIENTRY glewContextInit ()
{
+ PFNGLGETSTRINGPROC getString;
const GLubyte* s;
GLuint dot;
GLint major, minor;
- const GLubyte* extStart;
- const GLubyte* extEnd;
+ size_t n;
+
+ #ifdef _WIN32
+ getString = glGetString;
+ #else
+ getString = (PFNGLGETSTRINGPROC) glewGetProcAddress((const GLubyte*)"glGetString");
+ if (!getString)
+ return GLEW_ERROR_NO_GL_VERSION;
+ #endif
+
/* query opengl version */
- s = glGetString(GL_VERSION);
+ s = getString(GL_VERSION);
dot = _glewStrCLen(s, '.');
if (dot == 0)
return GLEW_ERROR_NO_GL_VERSION;
-
+
major = s[dot-1]-'0';
minor = s[dot+1]-'0';
@@ -9306,7 +13503,6 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST)
minor = 0;
if (major<0 || major>9)
return GLEW_ERROR_NO_GL_VERSION;
-
if (major == 1 && minor == 0)
{
@@ -9324,2047 +13520,2262 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST)
GLEW_VERSION_3_2 = GLEW_VERSION_3_3 == GL_TRUE || ( major == 3 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_3_1 = GLEW_VERSION_3_2 == GL_TRUE || ( major == 3 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_3_0 = GLEW_VERSION_3_1 == GL_TRUE || ( major == 3 ) ? GL_TRUE : GL_FALSE;
- GLEW_VERSION_2_1 = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_2_1 = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_2_0 = GLEW_VERSION_2_1 == GL_TRUE || ( major == 2 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_1_5 = GLEW_VERSION_2_0 == GL_TRUE || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_1_4 = GLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_1_3 = GLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
- GLEW_VERSION_1_2_1 = GLEW_VERSION_1_3 == GL_TRUE ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_2_1 = GLEW_VERSION_1_3 == GL_TRUE ? GL_TRUE : GL_FALSE;
GLEW_VERSION_1_2 = GLEW_VERSION_1_2_1 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
GLEW_VERSION_1_1 = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
}
- /* query opengl extensions string */
- extStart = glGetString(GL_EXTENSIONS);
- if (extStart == 0)
- extStart = (const GLubyte*)"";
- extEnd = extStart + _glewStrLen(extStart);
+ for (n = 0; n < sizeof(_glewExtensionString) / sizeof(_glewExtensionString[0]); ++n)
+ _glewExtensionString[n] = GL_FALSE;
- /* initialize extensions */
+ if (GLEW_VERSION_3_0)
+ {
+ GLint n = 0;
+ GLint i;
+ PFNGLGETINTEGERVPROC getIntegerv;
+ PFNGLGETSTRINGIPROC getStringi;
+ const char *ext;
+ GLboolean *enable;
+
+ #ifdef _WIN32
+ getIntegerv = glGetIntegerv;
+ #else
+ getIntegerv = (PFNGLGETINTEGERVPROC) glewGetProcAddress((const GLubyte*)"glGetIntegerv");
+ #endif
+
+ if (getIntegerv)
+ getIntegerv(GL_NUM_EXTENSIONS, &n);
+
+ /* glGetStringi is OpenGL 3.0 */
+ getStringi = (PFNGLGETSTRINGIPROC) glewGetProcAddress((const GLubyte*)"glGetStringi");
+ if (getStringi)
+ for (i = 0; i<n; ++i)
+ {
+ ext = (const char *) getStringi(GL_EXTENSIONS, i);
+
+ /* Based on extension string(s), glewGetExtension purposes */
+ enable = _glewGetExtensionString(ext);
+ if (enable)
+ *enable = GL_TRUE;
+
+ /* Based on extension string(s), experimental mode, glewIsSupported purposes */
+ enable = _glewGetExtensionEnable(ext);
+ if (enable)
+ *enable = GL_TRUE;
+ }
+ }
+ else
+ {
+ const char *extensions;
+ const char *end;
+ const char *i;
+ const char *j;
+ char ext[128];
+ GLboolean *enable;
+
+ extensions = (const char *) getString(GL_EXTENSIONS);
+
+ if (extensions)
+ {
+ end = extensions + _glewStrLen((const GLubyte *) extensions);
+ for (i=extensions; i<end; i = j + 1)
+ {
+ i = _glewNextNonSpace(i);
+ j = _glewNextSpace(i);
+
+ /* Copy extension into NUL terminated string */
+ if (j-i >= (ptrdiff_t) sizeof(ext))
+ continue;
+ _glewStrCopy(ext, i, ' ');
+
+ /* Based on extension string(s), glewGetExtension purposes */
+ enable = _glewGetExtensionString(ext);
+ if (enable)
+ *enable = GL_TRUE;
+
+ /* Based on extension string(s), experimental mode, glewIsSupported purposes */
+ enable = _glewGetExtensionEnable(ext);
+ if (enable)
+ *enable = GL_TRUE;
+ }
+ }
+ }
#ifdef GL_VERSION_1_2
- if (glewExperimental || GLEW_VERSION_1_2) GLEW_VERSION_1_2 = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_1_2) GLEW_VERSION_1_2 = !_glewInit_GL_VERSION_1_2();
#endif /* GL_VERSION_1_2 */
-#ifdef GL_VERSION_1_2_1
-#endif /* GL_VERSION_1_2_1 */
#ifdef GL_VERSION_1_3
- if (glewExperimental || GLEW_VERSION_1_3) GLEW_VERSION_1_3 = !_glewInit_GL_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_1_3) GLEW_VERSION_1_3 = !_glewInit_GL_VERSION_1_3();
#endif /* GL_VERSION_1_3 */
#ifdef GL_VERSION_1_4
- if (glewExperimental || GLEW_VERSION_1_4) GLEW_VERSION_1_4 = !_glewInit_GL_VERSION_1_4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_1_4) GLEW_VERSION_1_4 = !_glewInit_GL_VERSION_1_4();
#endif /* GL_VERSION_1_4 */
#ifdef GL_VERSION_1_5
- if (glewExperimental || GLEW_VERSION_1_5) GLEW_VERSION_1_5 = !_glewInit_GL_VERSION_1_5(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_1_5) GLEW_VERSION_1_5 = !_glewInit_GL_VERSION_1_5();
#endif /* GL_VERSION_1_5 */
#ifdef GL_VERSION_2_0
- if (glewExperimental || GLEW_VERSION_2_0) GLEW_VERSION_2_0 = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_2_0) GLEW_VERSION_2_0 = !_glewInit_GL_VERSION_2_0();
#endif /* GL_VERSION_2_0 */
#ifdef GL_VERSION_2_1
- if (glewExperimental || GLEW_VERSION_2_1) GLEW_VERSION_2_1 = !_glewInit_GL_VERSION_2_1(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_2_1) GLEW_VERSION_2_1 = !_glewInit_GL_VERSION_2_1();
#endif /* GL_VERSION_2_1 */
#ifdef GL_VERSION_3_0
- if (glewExperimental || GLEW_VERSION_3_0) GLEW_VERSION_3_0 = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_3_0) GLEW_VERSION_3_0 = !_glewInit_GL_VERSION_3_0();
#endif /* GL_VERSION_3_0 */
#ifdef GL_VERSION_3_1
- if (glewExperimental || GLEW_VERSION_3_1) GLEW_VERSION_3_1 = !_glewInit_GL_VERSION_3_1(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_3_1) GLEW_VERSION_3_1 = !_glewInit_GL_VERSION_3_1();
#endif /* GL_VERSION_3_1 */
#ifdef GL_VERSION_3_2
- if (glewExperimental || GLEW_VERSION_3_2) GLEW_VERSION_3_2 = !_glewInit_GL_VERSION_3_2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_3_2) GLEW_VERSION_3_2 = !_glewInit_GL_VERSION_3_2();
#endif /* GL_VERSION_3_2 */
#ifdef GL_VERSION_3_3
- if (glewExperimental || GLEW_VERSION_3_3) GLEW_VERSION_3_3 = !_glewInit_GL_VERSION_3_3(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_3_3) GLEW_VERSION_3_3 = !_glewInit_GL_VERSION_3_3();
#endif /* GL_VERSION_3_3 */
#ifdef GL_VERSION_4_0
- if (glewExperimental || GLEW_VERSION_4_0) GLEW_VERSION_4_0 = !_glewInit_GL_VERSION_4_0(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_4_0) GLEW_VERSION_4_0 = !_glewInit_GL_VERSION_4_0();
#endif /* GL_VERSION_4_0 */
-#ifdef GL_VERSION_4_1
-#endif /* GL_VERSION_4_1 */
-#ifdef GL_VERSION_4_2
-#endif /* GL_VERSION_4_2 */
-#ifdef GL_VERSION_4_3
-#endif /* GL_VERSION_4_3 */
-#ifdef GL_VERSION_4_4
-#endif /* GL_VERSION_4_4 */
#ifdef GL_VERSION_4_5
- if (glewExperimental || GLEW_VERSION_4_5) GLEW_VERSION_4_5 = !_glewInit_GL_VERSION_4_5(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_VERSION_4_5) GLEW_VERSION_4_5 = !_glewInit_GL_VERSION_4_5();
#endif /* GL_VERSION_4_5 */
-#ifdef GL_3DFX_multisample
- GLEW_3DFX_multisample = _glewSearchExtension("GL_3DFX_multisample", extStart, extEnd);
-#endif /* GL_3DFX_multisample */
#ifdef GL_3DFX_tbuffer
- GLEW_3DFX_tbuffer = _glewSearchExtension("GL_3DFX_tbuffer", extStart, extEnd);
- if (glewExperimental || GLEW_3DFX_tbuffer) GLEW_3DFX_tbuffer = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_3DFX_tbuffer) GLEW_3DFX_tbuffer = !_glewInit_GL_3DFX_tbuffer();
#endif /* GL_3DFX_tbuffer */
-#ifdef GL_3DFX_texture_compression_FXT1
- GLEW_3DFX_texture_compression_FXT1 = _glewSearchExtension("GL_3DFX_texture_compression_FXT1", extStart, extEnd);
-#endif /* GL_3DFX_texture_compression_FXT1 */
-#ifdef GL_AMD_blend_minmax_factor
- GLEW_AMD_blend_minmax_factor = _glewSearchExtension("GL_AMD_blend_minmax_factor", extStart, extEnd);
-#endif /* GL_AMD_blend_minmax_factor */
-#ifdef GL_AMD_conservative_depth
- GLEW_AMD_conservative_depth = _glewSearchExtension("GL_AMD_conservative_depth", extStart, extEnd);
-#endif /* GL_AMD_conservative_depth */
#ifdef GL_AMD_debug_output
- GLEW_AMD_debug_output = _glewSearchExtension("GL_AMD_debug_output", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_debug_output) GLEW_AMD_debug_output = !_glewInit_GL_AMD_debug_output(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_debug_output) GLEW_AMD_debug_output = !_glewInit_GL_AMD_debug_output();
#endif /* GL_AMD_debug_output */
-#ifdef GL_AMD_depth_clamp_separate
- GLEW_AMD_depth_clamp_separate = _glewSearchExtension("GL_AMD_depth_clamp_separate", extStart, extEnd);
-#endif /* GL_AMD_depth_clamp_separate */
#ifdef GL_AMD_draw_buffers_blend
- GLEW_AMD_draw_buffers_blend = _glewSearchExtension("GL_AMD_draw_buffers_blend", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_draw_buffers_blend) GLEW_AMD_draw_buffers_blend = !_glewInit_GL_AMD_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_draw_buffers_blend) GLEW_AMD_draw_buffers_blend = !_glewInit_GL_AMD_draw_buffers_blend();
#endif /* GL_AMD_draw_buffers_blend */
-#ifdef GL_AMD_gcn_shader
- GLEW_AMD_gcn_shader = _glewSearchExtension("GL_AMD_gcn_shader", extStart, extEnd);
-#endif /* GL_AMD_gcn_shader */
-#ifdef GL_AMD_gpu_shader_int64
- GLEW_AMD_gpu_shader_int64 = _glewSearchExtension("GL_AMD_gpu_shader_int64", extStart, extEnd);
-#endif /* GL_AMD_gpu_shader_int64 */
#ifdef GL_AMD_interleaved_elements
- GLEW_AMD_interleaved_elements = _glewSearchExtension("GL_AMD_interleaved_elements", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_interleaved_elements) GLEW_AMD_interleaved_elements = !_glewInit_GL_AMD_interleaved_elements(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_interleaved_elements) GLEW_AMD_interleaved_elements = !_glewInit_GL_AMD_interleaved_elements();
#endif /* GL_AMD_interleaved_elements */
#ifdef GL_AMD_multi_draw_indirect
- GLEW_AMD_multi_draw_indirect = _glewSearchExtension("GL_AMD_multi_draw_indirect", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_multi_draw_indirect) GLEW_AMD_multi_draw_indirect = !_glewInit_GL_AMD_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_multi_draw_indirect) GLEW_AMD_multi_draw_indirect = !_glewInit_GL_AMD_multi_draw_indirect();
#endif /* GL_AMD_multi_draw_indirect */
#ifdef GL_AMD_name_gen_delete
- GLEW_AMD_name_gen_delete = _glewSearchExtension("GL_AMD_name_gen_delete", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_name_gen_delete) GLEW_AMD_name_gen_delete = !_glewInit_GL_AMD_name_gen_delete(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_name_gen_delete) GLEW_AMD_name_gen_delete = !_glewInit_GL_AMD_name_gen_delete();
#endif /* GL_AMD_name_gen_delete */
#ifdef GL_AMD_occlusion_query_event
- GLEW_AMD_occlusion_query_event = _glewSearchExtension("GL_AMD_occlusion_query_event", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_occlusion_query_event) GLEW_AMD_occlusion_query_event = !_glewInit_GL_AMD_occlusion_query_event(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_occlusion_query_event) GLEW_AMD_occlusion_query_event = !_glewInit_GL_AMD_occlusion_query_event();
#endif /* GL_AMD_occlusion_query_event */
#ifdef GL_AMD_performance_monitor
- GLEW_AMD_performance_monitor = _glewSearchExtension("GL_AMD_performance_monitor", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_performance_monitor) GLEW_AMD_performance_monitor = !_glewInit_GL_AMD_performance_monitor(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_performance_monitor) GLEW_AMD_performance_monitor = !_glewInit_GL_AMD_performance_monitor();
#endif /* GL_AMD_performance_monitor */
-#ifdef GL_AMD_pinned_memory
- GLEW_AMD_pinned_memory = _glewSearchExtension("GL_AMD_pinned_memory", extStart, extEnd);
-#endif /* GL_AMD_pinned_memory */
-#ifdef GL_AMD_query_buffer_object
- GLEW_AMD_query_buffer_object = _glewSearchExtension("GL_AMD_query_buffer_object", extStart, extEnd);
-#endif /* GL_AMD_query_buffer_object */
#ifdef GL_AMD_sample_positions
- GLEW_AMD_sample_positions = _glewSearchExtension("GL_AMD_sample_positions", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_sample_positions) GLEW_AMD_sample_positions = !_glewInit_GL_AMD_sample_positions(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_sample_positions) GLEW_AMD_sample_positions = !_glewInit_GL_AMD_sample_positions();
#endif /* GL_AMD_sample_positions */
-#ifdef GL_AMD_seamless_cubemap_per_texture
- GLEW_AMD_seamless_cubemap_per_texture = _glewSearchExtension("GL_AMD_seamless_cubemap_per_texture", extStart, extEnd);
-#endif /* GL_AMD_seamless_cubemap_per_texture */
-#ifdef GL_AMD_shader_atomic_counter_ops
- GLEW_AMD_shader_atomic_counter_ops = _glewSearchExtension("GL_AMD_shader_atomic_counter_ops", extStart, extEnd);
-#endif /* GL_AMD_shader_atomic_counter_ops */
-#ifdef GL_AMD_shader_stencil_export
- GLEW_AMD_shader_stencil_export = _glewSearchExtension("GL_AMD_shader_stencil_export", extStart, extEnd);
-#endif /* GL_AMD_shader_stencil_export */
-#ifdef GL_AMD_shader_stencil_value_export
- GLEW_AMD_shader_stencil_value_export = _glewSearchExtension("GL_AMD_shader_stencil_value_export", extStart, extEnd);
-#endif /* GL_AMD_shader_stencil_value_export */
-#ifdef GL_AMD_shader_trinary_minmax
- GLEW_AMD_shader_trinary_minmax = _glewSearchExtension("GL_AMD_shader_trinary_minmax", extStart, extEnd);
-#endif /* GL_AMD_shader_trinary_minmax */
#ifdef GL_AMD_sparse_texture
- GLEW_AMD_sparse_texture = _glewSearchExtension("GL_AMD_sparse_texture", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_sparse_texture) GLEW_AMD_sparse_texture = !_glewInit_GL_AMD_sparse_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_sparse_texture) GLEW_AMD_sparse_texture = !_glewInit_GL_AMD_sparse_texture();
#endif /* GL_AMD_sparse_texture */
#ifdef GL_AMD_stencil_operation_extended
- GLEW_AMD_stencil_operation_extended = _glewSearchExtension("GL_AMD_stencil_operation_extended", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_stencil_operation_extended) GLEW_AMD_stencil_operation_extended = !_glewInit_GL_AMD_stencil_operation_extended(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_stencil_operation_extended) GLEW_AMD_stencil_operation_extended = !_glewInit_GL_AMD_stencil_operation_extended();
#endif /* GL_AMD_stencil_operation_extended */
-#ifdef GL_AMD_texture_texture4
- GLEW_AMD_texture_texture4 = _glewSearchExtension("GL_AMD_texture_texture4", extStart, extEnd);
-#endif /* GL_AMD_texture_texture4 */
-#ifdef GL_AMD_transform_feedback3_lines_triangles
- GLEW_AMD_transform_feedback3_lines_triangles = _glewSearchExtension("GL_AMD_transform_feedback3_lines_triangles", extStart, extEnd);
-#endif /* GL_AMD_transform_feedback3_lines_triangles */
-#ifdef GL_AMD_transform_feedback4
- GLEW_AMD_transform_feedback4 = _glewSearchExtension("GL_AMD_transform_feedback4", extStart, extEnd);
-#endif /* GL_AMD_transform_feedback4 */
-#ifdef GL_AMD_vertex_shader_layer
- GLEW_AMD_vertex_shader_layer = _glewSearchExtension("GL_AMD_vertex_shader_layer", extStart, extEnd);
-#endif /* GL_AMD_vertex_shader_layer */
#ifdef GL_AMD_vertex_shader_tessellator
- GLEW_AMD_vertex_shader_tessellator = _glewSearchExtension("GL_AMD_vertex_shader_tessellator", extStart, extEnd);
- if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) GLEW_AMD_vertex_shader_tessellator = !_glewInit_GL_AMD_vertex_shader_tessellator(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) GLEW_AMD_vertex_shader_tessellator = !_glewInit_GL_AMD_vertex_shader_tessellator();
#endif /* GL_AMD_vertex_shader_tessellator */
-#ifdef GL_AMD_vertex_shader_viewport_index
- GLEW_AMD_vertex_shader_viewport_index = _glewSearchExtension("GL_AMD_vertex_shader_viewport_index", extStart, extEnd);
-#endif /* GL_AMD_vertex_shader_viewport_index */
-#ifdef GL_ANGLE_depth_texture
- GLEW_ANGLE_depth_texture = _glewSearchExtension("GL_ANGLE_depth_texture", extStart, extEnd);
-#endif /* GL_ANGLE_depth_texture */
#ifdef GL_ANGLE_framebuffer_blit
- GLEW_ANGLE_framebuffer_blit = _glewSearchExtension("GL_ANGLE_framebuffer_blit", extStart, extEnd);
- if (glewExperimental || GLEW_ANGLE_framebuffer_blit) GLEW_ANGLE_framebuffer_blit = !_glewInit_GL_ANGLE_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ANGLE_framebuffer_blit) GLEW_ANGLE_framebuffer_blit = !_glewInit_GL_ANGLE_framebuffer_blit();
#endif /* GL_ANGLE_framebuffer_blit */
#ifdef GL_ANGLE_framebuffer_multisample
- GLEW_ANGLE_framebuffer_multisample = _glewSearchExtension("GL_ANGLE_framebuffer_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_ANGLE_framebuffer_multisample) GLEW_ANGLE_framebuffer_multisample = !_glewInit_GL_ANGLE_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ANGLE_framebuffer_multisample) GLEW_ANGLE_framebuffer_multisample = !_glewInit_GL_ANGLE_framebuffer_multisample();
#endif /* GL_ANGLE_framebuffer_multisample */
#ifdef GL_ANGLE_instanced_arrays
- GLEW_ANGLE_instanced_arrays = _glewSearchExtension("GL_ANGLE_instanced_arrays", extStart, extEnd);
- if (glewExperimental || GLEW_ANGLE_instanced_arrays) GLEW_ANGLE_instanced_arrays = !_glewInit_GL_ANGLE_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ANGLE_instanced_arrays) GLEW_ANGLE_instanced_arrays = !_glewInit_GL_ANGLE_instanced_arrays();
#endif /* GL_ANGLE_instanced_arrays */
-#ifdef GL_ANGLE_pack_reverse_row_order
- GLEW_ANGLE_pack_reverse_row_order = _glewSearchExtension("GL_ANGLE_pack_reverse_row_order", extStart, extEnd);
-#endif /* GL_ANGLE_pack_reverse_row_order */
-#ifdef GL_ANGLE_program_binary
- GLEW_ANGLE_program_binary = _glewSearchExtension("GL_ANGLE_program_binary", extStart, extEnd);
-#endif /* GL_ANGLE_program_binary */
-#ifdef GL_ANGLE_texture_compression_dxt1
- GLEW_ANGLE_texture_compression_dxt1 = _glewSearchExtension("GL_ANGLE_texture_compression_dxt1", extStart, extEnd);
-#endif /* GL_ANGLE_texture_compression_dxt1 */
-#ifdef GL_ANGLE_texture_compression_dxt3
- GLEW_ANGLE_texture_compression_dxt3 = _glewSearchExtension("GL_ANGLE_texture_compression_dxt3", extStart, extEnd);
-#endif /* GL_ANGLE_texture_compression_dxt3 */
-#ifdef GL_ANGLE_texture_compression_dxt5
- GLEW_ANGLE_texture_compression_dxt5 = _glewSearchExtension("GL_ANGLE_texture_compression_dxt5", extStart, extEnd);
-#endif /* GL_ANGLE_texture_compression_dxt5 */
-#ifdef GL_ANGLE_texture_usage
- GLEW_ANGLE_texture_usage = _glewSearchExtension("GL_ANGLE_texture_usage", extStart, extEnd);
-#endif /* GL_ANGLE_texture_usage */
#ifdef GL_ANGLE_timer_query
- GLEW_ANGLE_timer_query = _glewSearchExtension("GL_ANGLE_timer_query", extStart, extEnd);
- if (glewExperimental || GLEW_ANGLE_timer_query) GLEW_ANGLE_timer_query = !_glewInit_GL_ANGLE_timer_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ANGLE_timer_query) GLEW_ANGLE_timer_query = !_glewInit_GL_ANGLE_timer_query();
#endif /* GL_ANGLE_timer_query */
#ifdef GL_ANGLE_translated_shader_source
- GLEW_ANGLE_translated_shader_source = _glewSearchExtension("GL_ANGLE_translated_shader_source", extStart, extEnd);
- if (glewExperimental || GLEW_ANGLE_translated_shader_source) GLEW_ANGLE_translated_shader_source = !_glewInit_GL_ANGLE_translated_shader_source(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ANGLE_translated_shader_source) GLEW_ANGLE_translated_shader_source = !_glewInit_GL_ANGLE_translated_shader_source();
#endif /* GL_ANGLE_translated_shader_source */
-#ifdef GL_APPLE_aux_depth_stencil
- GLEW_APPLE_aux_depth_stencil = _glewSearchExtension("GL_APPLE_aux_depth_stencil", extStart, extEnd);
-#endif /* GL_APPLE_aux_depth_stencil */
-#ifdef GL_APPLE_client_storage
- GLEW_APPLE_client_storage = _glewSearchExtension("GL_APPLE_client_storage", extStart, extEnd);
-#endif /* GL_APPLE_client_storage */
#ifdef GL_APPLE_element_array
- GLEW_APPLE_element_array = _glewSearchExtension("GL_APPLE_element_array", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_element_array) GLEW_APPLE_element_array = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_element_array) GLEW_APPLE_element_array = !_glewInit_GL_APPLE_element_array();
#endif /* GL_APPLE_element_array */
#ifdef GL_APPLE_fence
- GLEW_APPLE_fence = _glewSearchExtension("GL_APPLE_fence", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_fence) GLEW_APPLE_fence = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_fence) GLEW_APPLE_fence = !_glewInit_GL_APPLE_fence();
#endif /* GL_APPLE_fence */
-#ifdef GL_APPLE_float_pixels
- GLEW_APPLE_float_pixels = _glewSearchExtension("GL_APPLE_float_pixels", extStart, extEnd);
-#endif /* GL_APPLE_float_pixels */
#ifdef GL_APPLE_flush_buffer_range
- GLEW_APPLE_flush_buffer_range = _glewSearchExtension("GL_APPLE_flush_buffer_range", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_flush_buffer_range) GLEW_APPLE_flush_buffer_range = !_glewInit_GL_APPLE_flush_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_flush_buffer_range) GLEW_APPLE_flush_buffer_range = !_glewInit_GL_APPLE_flush_buffer_range();
#endif /* GL_APPLE_flush_buffer_range */
#ifdef GL_APPLE_object_purgeable
- GLEW_APPLE_object_purgeable = _glewSearchExtension("GL_APPLE_object_purgeable", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_object_purgeable) GLEW_APPLE_object_purgeable = !_glewInit_GL_APPLE_object_purgeable(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_object_purgeable) GLEW_APPLE_object_purgeable = !_glewInit_GL_APPLE_object_purgeable();
#endif /* GL_APPLE_object_purgeable */
-#ifdef GL_APPLE_pixel_buffer
- GLEW_APPLE_pixel_buffer = _glewSearchExtension("GL_APPLE_pixel_buffer", extStart, extEnd);
-#endif /* GL_APPLE_pixel_buffer */
-#ifdef GL_APPLE_rgb_422
- GLEW_APPLE_rgb_422 = _glewSearchExtension("GL_APPLE_rgb_422", extStart, extEnd);
-#endif /* GL_APPLE_rgb_422 */
-#ifdef GL_APPLE_row_bytes
- GLEW_APPLE_row_bytes = _glewSearchExtension("GL_APPLE_row_bytes", extStart, extEnd);
-#endif /* GL_APPLE_row_bytes */
-#ifdef GL_APPLE_specular_vector
- GLEW_APPLE_specular_vector = _glewSearchExtension("GL_APPLE_specular_vector", extStart, extEnd);
-#endif /* GL_APPLE_specular_vector */
#ifdef GL_APPLE_texture_range
- GLEW_APPLE_texture_range = _glewSearchExtension("GL_APPLE_texture_range", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_texture_range) GLEW_APPLE_texture_range = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_texture_range) GLEW_APPLE_texture_range = !_glewInit_GL_APPLE_texture_range();
#endif /* GL_APPLE_texture_range */
-#ifdef GL_APPLE_transform_hint
- GLEW_APPLE_transform_hint = _glewSearchExtension("GL_APPLE_transform_hint", extStart, extEnd);
-#endif /* GL_APPLE_transform_hint */
#ifdef GL_APPLE_vertex_array_object
- GLEW_APPLE_vertex_array_object = _glewSearchExtension("GL_APPLE_vertex_array_object", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_vertex_array_object) GLEW_APPLE_vertex_array_object = !_glewInit_GL_APPLE_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_vertex_array_object) GLEW_APPLE_vertex_array_object = !_glewInit_GL_APPLE_vertex_array_object();
#endif /* GL_APPLE_vertex_array_object */
#ifdef GL_APPLE_vertex_array_range
- GLEW_APPLE_vertex_array_range = _glewSearchExtension("GL_APPLE_vertex_array_range", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_vertex_array_range) GLEW_APPLE_vertex_array_range = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_vertex_array_range) GLEW_APPLE_vertex_array_range = !_glewInit_GL_APPLE_vertex_array_range();
#endif /* GL_APPLE_vertex_array_range */
#ifdef GL_APPLE_vertex_program_evaluators
- GLEW_APPLE_vertex_program_evaluators = _glewSearchExtension("GL_APPLE_vertex_program_evaluators", extStart, extEnd);
- if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) GLEW_APPLE_vertex_program_evaluators = !_glewInit_GL_APPLE_vertex_program_evaluators(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) GLEW_APPLE_vertex_program_evaluators = !_glewInit_GL_APPLE_vertex_program_evaluators();
#endif /* GL_APPLE_vertex_program_evaluators */
-#ifdef GL_APPLE_ycbcr_422
- GLEW_APPLE_ycbcr_422 = _glewSearchExtension("GL_APPLE_ycbcr_422", extStart, extEnd);
-#endif /* GL_APPLE_ycbcr_422 */
#ifdef GL_ARB_ES2_compatibility
- GLEW_ARB_ES2_compatibility = _glewSearchExtension("GL_ARB_ES2_compatibility", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_ES2_compatibility) GLEW_ARB_ES2_compatibility = !_glewInit_GL_ARB_ES2_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_ES2_compatibility) GLEW_ARB_ES2_compatibility = !_glewInit_GL_ARB_ES2_compatibility();
#endif /* GL_ARB_ES2_compatibility */
#ifdef GL_ARB_ES3_1_compatibility
- GLEW_ARB_ES3_1_compatibility = _glewSearchExtension("GL_ARB_ES3_1_compatibility", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_ES3_1_compatibility) GLEW_ARB_ES3_1_compatibility = !_glewInit_GL_ARB_ES3_1_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_ES3_1_compatibility) GLEW_ARB_ES3_1_compatibility = !_glewInit_GL_ARB_ES3_1_compatibility();
#endif /* GL_ARB_ES3_1_compatibility */
#ifdef GL_ARB_ES3_2_compatibility
- GLEW_ARB_ES3_2_compatibility = _glewSearchExtension("GL_ARB_ES3_2_compatibility", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_ES3_2_compatibility) GLEW_ARB_ES3_2_compatibility = !_glewInit_GL_ARB_ES3_2_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_ES3_2_compatibility) GLEW_ARB_ES3_2_compatibility = !_glewInit_GL_ARB_ES3_2_compatibility();
#endif /* GL_ARB_ES3_2_compatibility */
-#ifdef GL_ARB_ES3_compatibility
- GLEW_ARB_ES3_compatibility = _glewSearchExtension("GL_ARB_ES3_compatibility", extStart, extEnd);
-#endif /* GL_ARB_ES3_compatibility */
-#ifdef GL_ARB_arrays_of_arrays
- GLEW_ARB_arrays_of_arrays = _glewSearchExtension("GL_ARB_arrays_of_arrays", extStart, extEnd);
-#endif /* GL_ARB_arrays_of_arrays */
#ifdef GL_ARB_base_instance
- GLEW_ARB_base_instance = _glewSearchExtension("GL_ARB_base_instance", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_base_instance) GLEW_ARB_base_instance = !_glewInit_GL_ARB_base_instance(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_base_instance) GLEW_ARB_base_instance = !_glewInit_GL_ARB_base_instance();
#endif /* GL_ARB_base_instance */
#ifdef GL_ARB_bindless_texture
- GLEW_ARB_bindless_texture = _glewSearchExtension("GL_ARB_bindless_texture", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_bindless_texture) GLEW_ARB_bindless_texture = !_glewInit_GL_ARB_bindless_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_bindless_texture) GLEW_ARB_bindless_texture = !_glewInit_GL_ARB_bindless_texture();
#endif /* GL_ARB_bindless_texture */
#ifdef GL_ARB_blend_func_extended
- GLEW_ARB_blend_func_extended = _glewSearchExtension("GL_ARB_blend_func_extended", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_blend_func_extended) GLEW_ARB_blend_func_extended = !_glewInit_GL_ARB_blend_func_extended(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_blend_func_extended) GLEW_ARB_blend_func_extended = !_glewInit_GL_ARB_blend_func_extended();
#endif /* GL_ARB_blend_func_extended */
#ifdef GL_ARB_buffer_storage
- GLEW_ARB_buffer_storage = _glewSearchExtension("GL_ARB_buffer_storage", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_buffer_storage) GLEW_ARB_buffer_storage = !_glewInit_GL_ARB_buffer_storage(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_buffer_storage) GLEW_ARB_buffer_storage = !_glewInit_GL_ARB_buffer_storage();
#endif /* GL_ARB_buffer_storage */
#ifdef GL_ARB_cl_event
- GLEW_ARB_cl_event = _glewSearchExtension("GL_ARB_cl_event", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_cl_event) GLEW_ARB_cl_event = !_glewInit_GL_ARB_cl_event(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_cl_event) GLEW_ARB_cl_event = !_glewInit_GL_ARB_cl_event();
#endif /* GL_ARB_cl_event */
#ifdef GL_ARB_clear_buffer_object
- GLEW_ARB_clear_buffer_object = _glewSearchExtension("GL_ARB_clear_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_clear_buffer_object) GLEW_ARB_clear_buffer_object = !_glewInit_GL_ARB_clear_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_clear_buffer_object) GLEW_ARB_clear_buffer_object = !_glewInit_GL_ARB_clear_buffer_object();
#endif /* GL_ARB_clear_buffer_object */
#ifdef GL_ARB_clear_texture
- GLEW_ARB_clear_texture = _glewSearchExtension("GL_ARB_clear_texture", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_clear_texture) GLEW_ARB_clear_texture = !_glewInit_GL_ARB_clear_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_clear_texture) GLEW_ARB_clear_texture = !_glewInit_GL_ARB_clear_texture();
#endif /* GL_ARB_clear_texture */
#ifdef GL_ARB_clip_control
- GLEW_ARB_clip_control = _glewSearchExtension("GL_ARB_clip_control", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_clip_control) GLEW_ARB_clip_control = !_glewInit_GL_ARB_clip_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_clip_control) GLEW_ARB_clip_control = !_glewInit_GL_ARB_clip_control();
#endif /* GL_ARB_clip_control */
#ifdef GL_ARB_color_buffer_float
- GLEW_ARB_color_buffer_float = _glewSearchExtension("GL_ARB_color_buffer_float", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_color_buffer_float) GLEW_ARB_color_buffer_float = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_color_buffer_float) GLEW_ARB_color_buffer_float = !_glewInit_GL_ARB_color_buffer_float();
#endif /* GL_ARB_color_buffer_float */
-#ifdef GL_ARB_compatibility
- GLEW_ARB_compatibility = _glewSearchExtension("GL_ARB_compatibility", extStart, extEnd);
-#endif /* GL_ARB_compatibility */
-#ifdef GL_ARB_compressed_texture_pixel_storage
- GLEW_ARB_compressed_texture_pixel_storage = _glewSearchExtension("GL_ARB_compressed_texture_pixel_storage", extStart, extEnd);
-#endif /* GL_ARB_compressed_texture_pixel_storage */
#ifdef GL_ARB_compute_shader
- GLEW_ARB_compute_shader = _glewSearchExtension("GL_ARB_compute_shader", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_compute_shader) GLEW_ARB_compute_shader = !_glewInit_GL_ARB_compute_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_compute_shader) GLEW_ARB_compute_shader = !_glewInit_GL_ARB_compute_shader();
#endif /* GL_ARB_compute_shader */
#ifdef GL_ARB_compute_variable_group_size
- GLEW_ARB_compute_variable_group_size = _glewSearchExtension("GL_ARB_compute_variable_group_size", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_compute_variable_group_size) GLEW_ARB_compute_variable_group_size = !_glewInit_GL_ARB_compute_variable_group_size(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_compute_variable_group_size) GLEW_ARB_compute_variable_group_size = !_glewInit_GL_ARB_compute_variable_group_size();
#endif /* GL_ARB_compute_variable_group_size */
-#ifdef GL_ARB_conditional_render_inverted
- GLEW_ARB_conditional_render_inverted = _glewSearchExtension("GL_ARB_conditional_render_inverted", extStart, extEnd);
-#endif /* GL_ARB_conditional_render_inverted */
-#ifdef GL_ARB_conservative_depth
- GLEW_ARB_conservative_depth = _glewSearchExtension("GL_ARB_conservative_depth", extStart, extEnd);
-#endif /* GL_ARB_conservative_depth */
#ifdef GL_ARB_copy_buffer
- GLEW_ARB_copy_buffer = _glewSearchExtension("GL_ARB_copy_buffer", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_copy_buffer) GLEW_ARB_copy_buffer = !_glewInit_GL_ARB_copy_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_copy_buffer) GLEW_ARB_copy_buffer = !_glewInit_GL_ARB_copy_buffer();
#endif /* GL_ARB_copy_buffer */
#ifdef GL_ARB_copy_image
- GLEW_ARB_copy_image = _glewSearchExtension("GL_ARB_copy_image", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_copy_image) GLEW_ARB_copy_image = !_glewInit_GL_ARB_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_copy_image) GLEW_ARB_copy_image = !_glewInit_GL_ARB_copy_image();
#endif /* GL_ARB_copy_image */
-#ifdef GL_ARB_cull_distance
- GLEW_ARB_cull_distance = _glewSearchExtension("GL_ARB_cull_distance", extStart, extEnd);
-#endif /* GL_ARB_cull_distance */
#ifdef GL_ARB_debug_output
- GLEW_ARB_debug_output = _glewSearchExtension("GL_ARB_debug_output", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_debug_output) GLEW_ARB_debug_output = !_glewInit_GL_ARB_debug_output(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_debug_output) GLEW_ARB_debug_output = !_glewInit_GL_ARB_debug_output();
#endif /* GL_ARB_debug_output */
-#ifdef GL_ARB_depth_buffer_float
- GLEW_ARB_depth_buffer_float = _glewSearchExtension("GL_ARB_depth_buffer_float", extStart, extEnd);
-#endif /* GL_ARB_depth_buffer_float */
-#ifdef GL_ARB_depth_clamp
- GLEW_ARB_depth_clamp = _glewSearchExtension("GL_ARB_depth_clamp", extStart, extEnd);
-#endif /* GL_ARB_depth_clamp */
-#ifdef GL_ARB_depth_texture
- GLEW_ARB_depth_texture = _glewSearchExtension("GL_ARB_depth_texture", extStart, extEnd);
-#endif /* GL_ARB_depth_texture */
-#ifdef GL_ARB_derivative_control
- GLEW_ARB_derivative_control = _glewSearchExtension("GL_ARB_derivative_control", extStart, extEnd);
-#endif /* GL_ARB_derivative_control */
#ifdef GL_ARB_direct_state_access
- GLEW_ARB_direct_state_access = _glewSearchExtension("GL_ARB_direct_state_access", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_direct_state_access) GLEW_ARB_direct_state_access = !_glewInit_GL_ARB_direct_state_access(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_direct_state_access) GLEW_ARB_direct_state_access = !_glewInit_GL_ARB_direct_state_access();
#endif /* GL_ARB_direct_state_access */
#ifdef GL_ARB_draw_buffers
- GLEW_ARB_draw_buffers = _glewSearchExtension("GL_ARB_draw_buffers", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_draw_buffers) GLEW_ARB_draw_buffers = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_draw_buffers) GLEW_ARB_draw_buffers = !_glewInit_GL_ARB_draw_buffers();
#endif /* GL_ARB_draw_buffers */
#ifdef GL_ARB_draw_buffers_blend
- GLEW_ARB_draw_buffers_blend = _glewSearchExtension("GL_ARB_draw_buffers_blend", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_draw_buffers_blend) GLEW_ARB_draw_buffers_blend = !_glewInit_GL_ARB_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_draw_buffers_blend) GLEW_ARB_draw_buffers_blend = !_glewInit_GL_ARB_draw_buffers_blend();
#endif /* GL_ARB_draw_buffers_blend */
#ifdef GL_ARB_draw_elements_base_vertex
- GLEW_ARB_draw_elements_base_vertex = _glewSearchExtension("GL_ARB_draw_elements_base_vertex", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) GLEW_ARB_draw_elements_base_vertex = !_glewInit_GL_ARB_draw_elements_base_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) GLEW_ARB_draw_elements_base_vertex = !_glewInit_GL_ARB_draw_elements_base_vertex();
#endif /* GL_ARB_draw_elements_base_vertex */
#ifdef GL_ARB_draw_indirect
- GLEW_ARB_draw_indirect = _glewSearchExtension("GL_ARB_draw_indirect", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_draw_indirect) GLEW_ARB_draw_indirect = !_glewInit_GL_ARB_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_draw_indirect) GLEW_ARB_draw_indirect = !_glewInit_GL_ARB_draw_indirect();
#endif /* GL_ARB_draw_indirect */
-#ifdef GL_ARB_draw_instanced
- GLEW_ARB_draw_instanced = _glewSearchExtension("GL_ARB_draw_instanced", extStart, extEnd);
-#endif /* GL_ARB_draw_instanced */
-#ifdef GL_ARB_enhanced_layouts
- GLEW_ARB_enhanced_layouts = _glewSearchExtension("GL_ARB_enhanced_layouts", extStart, extEnd);
-#endif /* GL_ARB_enhanced_layouts */
-#ifdef GL_ARB_explicit_attrib_location
- GLEW_ARB_explicit_attrib_location = _glewSearchExtension("GL_ARB_explicit_attrib_location", extStart, extEnd);
-#endif /* GL_ARB_explicit_attrib_location */
-#ifdef GL_ARB_explicit_uniform_location
- GLEW_ARB_explicit_uniform_location = _glewSearchExtension("GL_ARB_explicit_uniform_location", extStart, extEnd);
-#endif /* GL_ARB_explicit_uniform_location */
-#ifdef GL_ARB_fragment_coord_conventions
- GLEW_ARB_fragment_coord_conventions = _glewSearchExtension("GL_ARB_fragment_coord_conventions", extStart, extEnd);
-#endif /* GL_ARB_fragment_coord_conventions */
-#ifdef GL_ARB_fragment_layer_viewport
- GLEW_ARB_fragment_layer_viewport = _glewSearchExtension("GL_ARB_fragment_layer_viewport", extStart, extEnd);
-#endif /* GL_ARB_fragment_layer_viewport */
-#ifdef GL_ARB_fragment_program
- GLEW_ARB_fragment_program = _glewSearchExtension("GL_ARB_fragment_program", extStart, extEnd);
-#endif /* GL_ARB_fragment_program */
-#ifdef GL_ARB_fragment_program_shadow
- GLEW_ARB_fragment_program_shadow = _glewSearchExtension("GL_ARB_fragment_program_shadow", extStart, extEnd);
-#endif /* GL_ARB_fragment_program_shadow */
-#ifdef GL_ARB_fragment_shader
- GLEW_ARB_fragment_shader = _glewSearchExtension("GL_ARB_fragment_shader", extStart, extEnd);
-#endif /* GL_ARB_fragment_shader */
-#ifdef GL_ARB_fragment_shader_interlock
- GLEW_ARB_fragment_shader_interlock = _glewSearchExtension("GL_ARB_fragment_shader_interlock", extStart, extEnd);
-#endif /* GL_ARB_fragment_shader_interlock */
#ifdef GL_ARB_framebuffer_no_attachments
- GLEW_ARB_framebuffer_no_attachments = _glewSearchExtension("GL_ARB_framebuffer_no_attachments", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_framebuffer_no_attachments) GLEW_ARB_framebuffer_no_attachments = !_glewInit_GL_ARB_framebuffer_no_attachments(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_framebuffer_no_attachments) GLEW_ARB_framebuffer_no_attachments = !_glewInit_GL_ARB_framebuffer_no_attachments();
#endif /* GL_ARB_framebuffer_no_attachments */
#ifdef GL_ARB_framebuffer_object
- GLEW_ARB_framebuffer_object = _glewSearchExtension("GL_ARB_framebuffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_framebuffer_object) GLEW_ARB_framebuffer_object = !_glewInit_GL_ARB_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_framebuffer_object) GLEW_ARB_framebuffer_object = !_glewInit_GL_ARB_framebuffer_object();
#endif /* GL_ARB_framebuffer_object */
-#ifdef GL_ARB_framebuffer_sRGB
- GLEW_ARB_framebuffer_sRGB = _glewSearchExtension("GL_ARB_framebuffer_sRGB", extStart, extEnd);
-#endif /* GL_ARB_framebuffer_sRGB */
#ifdef GL_ARB_geometry_shader4
- GLEW_ARB_geometry_shader4 = _glewSearchExtension("GL_ARB_geometry_shader4", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_geometry_shader4) GLEW_ARB_geometry_shader4 = !_glewInit_GL_ARB_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_geometry_shader4) GLEW_ARB_geometry_shader4 = !_glewInit_GL_ARB_geometry_shader4();
#endif /* GL_ARB_geometry_shader4 */
#ifdef GL_ARB_get_program_binary
- GLEW_ARB_get_program_binary = _glewSearchExtension("GL_ARB_get_program_binary", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_get_program_binary) GLEW_ARB_get_program_binary = !_glewInit_GL_ARB_get_program_binary(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_get_program_binary) GLEW_ARB_get_program_binary = !_glewInit_GL_ARB_get_program_binary();
#endif /* GL_ARB_get_program_binary */
#ifdef GL_ARB_get_texture_sub_image
- GLEW_ARB_get_texture_sub_image = _glewSearchExtension("GL_ARB_get_texture_sub_image", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_get_texture_sub_image) GLEW_ARB_get_texture_sub_image = !_glewInit_GL_ARB_get_texture_sub_image(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_get_texture_sub_image) GLEW_ARB_get_texture_sub_image = !_glewInit_GL_ARB_get_texture_sub_image();
#endif /* GL_ARB_get_texture_sub_image */
-#ifdef GL_ARB_gpu_shader5
- GLEW_ARB_gpu_shader5 = _glewSearchExtension("GL_ARB_gpu_shader5", extStart, extEnd);
-#endif /* GL_ARB_gpu_shader5 */
+#ifdef GL_ARB_gl_spirv
+ if (glewExperimental || GLEW_ARB_gl_spirv) GLEW_ARB_gl_spirv = !_glewInit_GL_ARB_gl_spirv();
+#endif /* GL_ARB_gl_spirv */
#ifdef GL_ARB_gpu_shader_fp64
- GLEW_ARB_gpu_shader_fp64 = _glewSearchExtension("GL_ARB_gpu_shader_fp64", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_gpu_shader_fp64) GLEW_ARB_gpu_shader_fp64 = !_glewInit_GL_ARB_gpu_shader_fp64(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_gpu_shader_fp64) GLEW_ARB_gpu_shader_fp64 = !_glewInit_GL_ARB_gpu_shader_fp64();
#endif /* GL_ARB_gpu_shader_fp64 */
#ifdef GL_ARB_gpu_shader_int64
- GLEW_ARB_gpu_shader_int64 = _glewSearchExtension("GL_ARB_gpu_shader_int64", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_gpu_shader_int64) GLEW_ARB_gpu_shader_int64 = !_glewInit_GL_ARB_gpu_shader_int64(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_gpu_shader_int64) GLEW_ARB_gpu_shader_int64 = !_glewInit_GL_ARB_gpu_shader_int64();
#endif /* GL_ARB_gpu_shader_int64 */
-#ifdef GL_ARB_half_float_pixel
- GLEW_ARB_half_float_pixel = _glewSearchExtension("GL_ARB_half_float_pixel", extStart, extEnd);
-#endif /* GL_ARB_half_float_pixel */
-#ifdef GL_ARB_half_float_vertex
- GLEW_ARB_half_float_vertex = _glewSearchExtension("GL_ARB_half_float_vertex", extStart, extEnd);
-#endif /* GL_ARB_half_float_vertex */
#ifdef GL_ARB_imaging
- GLEW_ARB_imaging = _glewSearchExtension("GL_ARB_imaging", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_imaging) GLEW_ARB_imaging = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_imaging) GLEW_ARB_imaging = !_glewInit_GL_ARB_imaging();
#endif /* GL_ARB_imaging */
#ifdef GL_ARB_indirect_parameters
- GLEW_ARB_indirect_parameters = _glewSearchExtension("GL_ARB_indirect_parameters", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_indirect_parameters) GLEW_ARB_indirect_parameters = !_glewInit_GL_ARB_indirect_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_indirect_parameters) GLEW_ARB_indirect_parameters = !_glewInit_GL_ARB_indirect_parameters();
#endif /* GL_ARB_indirect_parameters */
#ifdef GL_ARB_instanced_arrays
- GLEW_ARB_instanced_arrays = _glewSearchExtension("GL_ARB_instanced_arrays", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_instanced_arrays) GLEW_ARB_instanced_arrays = !_glewInit_GL_ARB_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_instanced_arrays) GLEW_ARB_instanced_arrays = !_glewInit_GL_ARB_instanced_arrays();
#endif /* GL_ARB_instanced_arrays */
#ifdef GL_ARB_internalformat_query
- GLEW_ARB_internalformat_query = _glewSearchExtension("GL_ARB_internalformat_query", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_internalformat_query) GLEW_ARB_internalformat_query = !_glewInit_GL_ARB_internalformat_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_internalformat_query) GLEW_ARB_internalformat_query = !_glewInit_GL_ARB_internalformat_query();
#endif /* GL_ARB_internalformat_query */
#ifdef GL_ARB_internalformat_query2
- GLEW_ARB_internalformat_query2 = _glewSearchExtension("GL_ARB_internalformat_query2", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_internalformat_query2) GLEW_ARB_internalformat_query2 = !_glewInit_GL_ARB_internalformat_query2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_internalformat_query2) GLEW_ARB_internalformat_query2 = !_glewInit_GL_ARB_internalformat_query2();
#endif /* GL_ARB_internalformat_query2 */
#ifdef GL_ARB_invalidate_subdata
- GLEW_ARB_invalidate_subdata = _glewSearchExtension("GL_ARB_invalidate_subdata", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_invalidate_subdata) GLEW_ARB_invalidate_subdata = !_glewInit_GL_ARB_invalidate_subdata(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_invalidate_subdata) GLEW_ARB_invalidate_subdata = !_glewInit_GL_ARB_invalidate_subdata();
#endif /* GL_ARB_invalidate_subdata */
-#ifdef GL_ARB_map_buffer_alignment
- GLEW_ARB_map_buffer_alignment = _glewSearchExtension("GL_ARB_map_buffer_alignment", extStart, extEnd);
-#endif /* GL_ARB_map_buffer_alignment */
#ifdef GL_ARB_map_buffer_range
- GLEW_ARB_map_buffer_range = _glewSearchExtension("GL_ARB_map_buffer_range", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_map_buffer_range) GLEW_ARB_map_buffer_range = !_glewInit_GL_ARB_map_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_map_buffer_range) GLEW_ARB_map_buffer_range = !_glewInit_GL_ARB_map_buffer_range();
#endif /* GL_ARB_map_buffer_range */
#ifdef GL_ARB_matrix_palette
- GLEW_ARB_matrix_palette = _glewSearchExtension("GL_ARB_matrix_palette", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_matrix_palette) GLEW_ARB_matrix_palette = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_matrix_palette) GLEW_ARB_matrix_palette = !_glewInit_GL_ARB_matrix_palette();
#endif /* GL_ARB_matrix_palette */
#ifdef GL_ARB_multi_bind
- GLEW_ARB_multi_bind = _glewSearchExtension("GL_ARB_multi_bind", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_multi_bind) GLEW_ARB_multi_bind = !_glewInit_GL_ARB_multi_bind(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_multi_bind) GLEW_ARB_multi_bind = !_glewInit_GL_ARB_multi_bind();
#endif /* GL_ARB_multi_bind */
#ifdef GL_ARB_multi_draw_indirect
- GLEW_ARB_multi_draw_indirect = _glewSearchExtension("GL_ARB_multi_draw_indirect", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_multi_draw_indirect) GLEW_ARB_multi_draw_indirect = !_glewInit_GL_ARB_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_multi_draw_indirect) GLEW_ARB_multi_draw_indirect = !_glewInit_GL_ARB_multi_draw_indirect();
#endif /* GL_ARB_multi_draw_indirect */
#ifdef GL_ARB_multisample
- GLEW_ARB_multisample = _glewSearchExtension("GL_ARB_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_multisample) GLEW_ARB_multisample = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_multisample) GLEW_ARB_multisample = !_glewInit_GL_ARB_multisample();
#endif /* GL_ARB_multisample */
#ifdef GL_ARB_multitexture
- GLEW_ARB_multitexture = _glewSearchExtension("GL_ARB_multitexture", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture();
#endif /* GL_ARB_multitexture */
#ifdef GL_ARB_occlusion_query
- GLEW_ARB_occlusion_query = _glewSearchExtension("GL_ARB_occlusion_query", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_occlusion_query) GLEW_ARB_occlusion_query = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_occlusion_query) GLEW_ARB_occlusion_query = !_glewInit_GL_ARB_occlusion_query();
#endif /* GL_ARB_occlusion_query */
-#ifdef GL_ARB_occlusion_query2
- GLEW_ARB_occlusion_query2 = _glewSearchExtension("GL_ARB_occlusion_query2", extStart, extEnd);
-#endif /* GL_ARB_occlusion_query2 */
#ifdef GL_ARB_parallel_shader_compile
- GLEW_ARB_parallel_shader_compile = _glewSearchExtension("GL_ARB_parallel_shader_compile", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_parallel_shader_compile) GLEW_ARB_parallel_shader_compile = !_glewInit_GL_ARB_parallel_shader_compile(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_parallel_shader_compile) GLEW_ARB_parallel_shader_compile = !_glewInit_GL_ARB_parallel_shader_compile();
#endif /* GL_ARB_parallel_shader_compile */
-#ifdef GL_ARB_pipeline_statistics_query
- GLEW_ARB_pipeline_statistics_query = _glewSearchExtension("GL_ARB_pipeline_statistics_query", extStart, extEnd);
-#endif /* GL_ARB_pipeline_statistics_query */
-#ifdef GL_ARB_pixel_buffer_object
- GLEW_ARB_pixel_buffer_object = _glewSearchExtension("GL_ARB_pixel_buffer_object", extStart, extEnd);
-#endif /* GL_ARB_pixel_buffer_object */
#ifdef GL_ARB_point_parameters
- GLEW_ARB_point_parameters = _glewSearchExtension("GL_ARB_point_parameters", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters();
#endif /* GL_ARB_point_parameters */
-#ifdef GL_ARB_point_sprite
- GLEW_ARB_point_sprite = _glewSearchExtension("GL_ARB_point_sprite", extStart, extEnd);
-#endif /* GL_ARB_point_sprite */
-#ifdef GL_ARB_post_depth_coverage
- GLEW_ARB_post_depth_coverage = _glewSearchExtension("GL_ARB_post_depth_coverage", extStart, extEnd);
-#endif /* GL_ARB_post_depth_coverage */
#ifdef GL_ARB_program_interface_query
- GLEW_ARB_program_interface_query = _glewSearchExtension("GL_ARB_program_interface_query", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_program_interface_query) GLEW_ARB_program_interface_query = !_glewInit_GL_ARB_program_interface_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_program_interface_query) GLEW_ARB_program_interface_query = !_glewInit_GL_ARB_program_interface_query();
#endif /* GL_ARB_program_interface_query */
#ifdef GL_ARB_provoking_vertex
- GLEW_ARB_provoking_vertex = _glewSearchExtension("GL_ARB_provoking_vertex", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_provoking_vertex) GLEW_ARB_provoking_vertex = !_glewInit_GL_ARB_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_provoking_vertex) GLEW_ARB_provoking_vertex = !_glewInit_GL_ARB_provoking_vertex();
#endif /* GL_ARB_provoking_vertex */
-#ifdef GL_ARB_query_buffer_object
- GLEW_ARB_query_buffer_object = _glewSearchExtension("GL_ARB_query_buffer_object", extStart, extEnd);
-#endif /* GL_ARB_query_buffer_object */
-#ifdef GL_ARB_robust_buffer_access_behavior
- GLEW_ARB_robust_buffer_access_behavior = _glewSearchExtension("GL_ARB_robust_buffer_access_behavior", extStart, extEnd);
-#endif /* GL_ARB_robust_buffer_access_behavior */
#ifdef GL_ARB_robustness
- GLEW_ARB_robustness = _glewSearchExtension("GL_ARB_robustness", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_robustness) GLEW_ARB_robustness = !_glewInit_GL_ARB_robustness(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_robustness) GLEW_ARB_robustness = !_glewInit_GL_ARB_robustness();
#endif /* GL_ARB_robustness */
-#ifdef GL_ARB_robustness_application_isolation
- GLEW_ARB_robustness_application_isolation = _glewSearchExtension("GL_ARB_robustness_application_isolation", extStart, extEnd);
-#endif /* GL_ARB_robustness_application_isolation */
-#ifdef GL_ARB_robustness_share_group_isolation
- GLEW_ARB_robustness_share_group_isolation = _glewSearchExtension("GL_ARB_robustness_share_group_isolation", extStart, extEnd);
-#endif /* GL_ARB_robustness_share_group_isolation */
#ifdef GL_ARB_sample_locations
- GLEW_ARB_sample_locations = _glewSearchExtension("GL_ARB_sample_locations", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_sample_locations) GLEW_ARB_sample_locations = !_glewInit_GL_ARB_sample_locations(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_sample_locations) GLEW_ARB_sample_locations = !_glewInit_GL_ARB_sample_locations();
#endif /* GL_ARB_sample_locations */
#ifdef GL_ARB_sample_shading
- GLEW_ARB_sample_shading = _glewSearchExtension("GL_ARB_sample_shading", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_sample_shading) GLEW_ARB_sample_shading = !_glewInit_GL_ARB_sample_shading(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_sample_shading) GLEW_ARB_sample_shading = !_glewInit_GL_ARB_sample_shading();
#endif /* GL_ARB_sample_shading */
#ifdef GL_ARB_sampler_objects
- GLEW_ARB_sampler_objects = _glewSearchExtension("GL_ARB_sampler_objects", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_sampler_objects) GLEW_ARB_sampler_objects = !_glewInit_GL_ARB_sampler_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_sampler_objects) GLEW_ARB_sampler_objects = !_glewInit_GL_ARB_sampler_objects();
#endif /* GL_ARB_sampler_objects */
-#ifdef GL_ARB_seamless_cube_map
- GLEW_ARB_seamless_cube_map = _glewSearchExtension("GL_ARB_seamless_cube_map", extStart, extEnd);
-#endif /* GL_ARB_seamless_cube_map */
-#ifdef GL_ARB_seamless_cubemap_per_texture
- GLEW_ARB_seamless_cubemap_per_texture = _glewSearchExtension("GL_ARB_seamless_cubemap_per_texture", extStart, extEnd);
-#endif /* GL_ARB_seamless_cubemap_per_texture */
#ifdef GL_ARB_separate_shader_objects
- GLEW_ARB_separate_shader_objects = _glewSearchExtension("GL_ARB_separate_shader_objects", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_separate_shader_objects) GLEW_ARB_separate_shader_objects = !_glewInit_GL_ARB_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_separate_shader_objects) GLEW_ARB_separate_shader_objects = !_glewInit_GL_ARB_separate_shader_objects();
#endif /* GL_ARB_separate_shader_objects */
-#ifdef GL_ARB_shader_atomic_counter_ops
- GLEW_ARB_shader_atomic_counter_ops = _glewSearchExtension("GL_ARB_shader_atomic_counter_ops", extStart, extEnd);
-#endif /* GL_ARB_shader_atomic_counter_ops */
#ifdef GL_ARB_shader_atomic_counters
- GLEW_ARB_shader_atomic_counters = _glewSearchExtension("GL_ARB_shader_atomic_counters", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_shader_atomic_counters) GLEW_ARB_shader_atomic_counters = !_glewInit_GL_ARB_shader_atomic_counters(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_shader_atomic_counters) GLEW_ARB_shader_atomic_counters = !_glewInit_GL_ARB_shader_atomic_counters();
#endif /* GL_ARB_shader_atomic_counters */
-#ifdef GL_ARB_shader_ballot
- GLEW_ARB_shader_ballot = _glewSearchExtension("GL_ARB_shader_ballot", extStart, extEnd);
-#endif /* GL_ARB_shader_ballot */
-#ifdef GL_ARB_shader_bit_encoding
- GLEW_ARB_shader_bit_encoding = _glewSearchExtension("GL_ARB_shader_bit_encoding", extStart, extEnd);
-#endif /* GL_ARB_shader_bit_encoding */
-#ifdef GL_ARB_shader_clock
- GLEW_ARB_shader_clock = _glewSearchExtension("GL_ARB_shader_clock", extStart, extEnd);
-#endif /* GL_ARB_shader_clock */
-#ifdef GL_ARB_shader_draw_parameters
- GLEW_ARB_shader_draw_parameters = _glewSearchExtension("GL_ARB_shader_draw_parameters", extStart, extEnd);
-#endif /* GL_ARB_shader_draw_parameters */
-#ifdef GL_ARB_shader_group_vote
- GLEW_ARB_shader_group_vote = _glewSearchExtension("GL_ARB_shader_group_vote", extStart, extEnd);
-#endif /* GL_ARB_shader_group_vote */
#ifdef GL_ARB_shader_image_load_store
- GLEW_ARB_shader_image_load_store = _glewSearchExtension("GL_ARB_shader_image_load_store", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_shader_image_load_store) GLEW_ARB_shader_image_load_store = !_glewInit_GL_ARB_shader_image_load_store(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_shader_image_load_store) GLEW_ARB_shader_image_load_store = !_glewInit_GL_ARB_shader_image_load_store();
#endif /* GL_ARB_shader_image_load_store */
-#ifdef GL_ARB_shader_image_size
- GLEW_ARB_shader_image_size = _glewSearchExtension("GL_ARB_shader_image_size", extStart, extEnd);
-#endif /* GL_ARB_shader_image_size */
#ifdef GL_ARB_shader_objects
- GLEW_ARB_shader_objects = _glewSearchExtension("GL_ARB_shader_objects", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_shader_objects) GLEW_ARB_shader_objects = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_shader_objects) GLEW_ARB_shader_objects = !_glewInit_GL_ARB_shader_objects();
#endif /* GL_ARB_shader_objects */
-#ifdef GL_ARB_shader_precision
- GLEW_ARB_shader_precision = _glewSearchExtension("GL_ARB_shader_precision", extStart, extEnd);
-#endif /* GL_ARB_shader_precision */
-#ifdef GL_ARB_shader_stencil_export
- GLEW_ARB_shader_stencil_export = _glewSearchExtension("GL_ARB_shader_stencil_export", extStart, extEnd);
-#endif /* GL_ARB_shader_stencil_export */
#ifdef GL_ARB_shader_storage_buffer_object
- GLEW_ARB_shader_storage_buffer_object = _glewSearchExtension("GL_ARB_shader_storage_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_shader_storage_buffer_object) GLEW_ARB_shader_storage_buffer_object = !_glewInit_GL_ARB_shader_storage_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_shader_storage_buffer_object) GLEW_ARB_shader_storage_buffer_object = !_glewInit_GL_ARB_shader_storage_buffer_object();
#endif /* GL_ARB_shader_storage_buffer_object */
#ifdef GL_ARB_shader_subroutine
- GLEW_ARB_shader_subroutine = _glewSearchExtension("GL_ARB_shader_subroutine", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_shader_subroutine) GLEW_ARB_shader_subroutine = !_glewInit_GL_ARB_shader_subroutine(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_shader_subroutine) GLEW_ARB_shader_subroutine = !_glewInit_GL_ARB_shader_subroutine();
#endif /* GL_ARB_shader_subroutine */
-#ifdef GL_ARB_shader_texture_image_samples
- GLEW_ARB_shader_texture_image_samples = _glewSearchExtension("GL_ARB_shader_texture_image_samples", extStart, extEnd);
-#endif /* GL_ARB_shader_texture_image_samples */
-#ifdef GL_ARB_shader_texture_lod
- GLEW_ARB_shader_texture_lod = _glewSearchExtension("GL_ARB_shader_texture_lod", extStart, extEnd);
-#endif /* GL_ARB_shader_texture_lod */
-#ifdef GL_ARB_shader_viewport_layer_array
- GLEW_ARB_shader_viewport_layer_array = _glewSearchExtension("GL_ARB_shader_viewport_layer_array", extStart, extEnd);
-#endif /* GL_ARB_shader_viewport_layer_array */
-#ifdef GL_ARB_shading_language_100
- GLEW_ARB_shading_language_100 = _glewSearchExtension("GL_ARB_shading_language_100", extStart, extEnd);
-#endif /* GL_ARB_shading_language_100 */
-#ifdef GL_ARB_shading_language_420pack
- GLEW_ARB_shading_language_420pack = _glewSearchExtension("GL_ARB_shading_language_420pack", extStart, extEnd);
-#endif /* GL_ARB_shading_language_420pack */
#ifdef GL_ARB_shading_language_include
- GLEW_ARB_shading_language_include = _glewSearchExtension("GL_ARB_shading_language_include", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_shading_language_include) GLEW_ARB_shading_language_include = !_glewInit_GL_ARB_shading_language_include(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_shading_language_include) GLEW_ARB_shading_language_include = !_glewInit_GL_ARB_shading_language_include();
#endif /* GL_ARB_shading_language_include */
-#ifdef GL_ARB_shading_language_packing
- GLEW_ARB_shading_language_packing = _glewSearchExtension("GL_ARB_shading_language_packing", extStart, extEnd);
-#endif /* GL_ARB_shading_language_packing */
-#ifdef GL_ARB_shadow
- GLEW_ARB_shadow = _glewSearchExtension("GL_ARB_shadow", extStart, extEnd);
-#endif /* GL_ARB_shadow */
-#ifdef GL_ARB_shadow_ambient
- GLEW_ARB_shadow_ambient = _glewSearchExtension("GL_ARB_shadow_ambient", extStart, extEnd);
-#endif /* GL_ARB_shadow_ambient */
#ifdef GL_ARB_sparse_buffer
- GLEW_ARB_sparse_buffer = _glewSearchExtension("GL_ARB_sparse_buffer", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_sparse_buffer) GLEW_ARB_sparse_buffer = !_glewInit_GL_ARB_sparse_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_sparse_buffer) GLEW_ARB_sparse_buffer = !_glewInit_GL_ARB_sparse_buffer();
#endif /* GL_ARB_sparse_buffer */
#ifdef GL_ARB_sparse_texture
- GLEW_ARB_sparse_texture = _glewSearchExtension("GL_ARB_sparse_texture", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_sparse_texture) GLEW_ARB_sparse_texture = !_glewInit_GL_ARB_sparse_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_sparse_texture) GLEW_ARB_sparse_texture = !_glewInit_GL_ARB_sparse_texture();
#endif /* GL_ARB_sparse_texture */
-#ifdef GL_ARB_sparse_texture2
- GLEW_ARB_sparse_texture2 = _glewSearchExtension("GL_ARB_sparse_texture2", extStart, extEnd);
-#endif /* GL_ARB_sparse_texture2 */
-#ifdef GL_ARB_sparse_texture_clamp
- GLEW_ARB_sparse_texture_clamp = _glewSearchExtension("GL_ARB_sparse_texture_clamp", extStart, extEnd);
-#endif /* GL_ARB_sparse_texture_clamp */
-#ifdef GL_ARB_stencil_texturing
- GLEW_ARB_stencil_texturing = _glewSearchExtension("GL_ARB_stencil_texturing", extStart, extEnd);
-#endif /* GL_ARB_stencil_texturing */
#ifdef GL_ARB_sync
- GLEW_ARB_sync = _glewSearchExtension("GL_ARB_sync", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_sync) GLEW_ARB_sync = !_glewInit_GL_ARB_sync(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_sync) GLEW_ARB_sync = !_glewInit_GL_ARB_sync();
#endif /* GL_ARB_sync */
#ifdef GL_ARB_tessellation_shader
- GLEW_ARB_tessellation_shader = _glewSearchExtension("GL_ARB_tessellation_shader", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_tessellation_shader) GLEW_ARB_tessellation_shader = !_glewInit_GL_ARB_tessellation_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_tessellation_shader) GLEW_ARB_tessellation_shader = !_glewInit_GL_ARB_tessellation_shader();
#endif /* GL_ARB_tessellation_shader */
#ifdef GL_ARB_texture_barrier
- GLEW_ARB_texture_barrier = _glewSearchExtension("GL_ARB_texture_barrier", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_barrier) GLEW_ARB_texture_barrier = !_glewInit_GL_ARB_texture_barrier(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_barrier) GLEW_ARB_texture_barrier = !_glewInit_GL_ARB_texture_barrier();
#endif /* GL_ARB_texture_barrier */
-#ifdef GL_ARB_texture_border_clamp
- GLEW_ARB_texture_border_clamp = _glewSearchExtension("GL_ARB_texture_border_clamp", extStart, extEnd);
-#endif /* GL_ARB_texture_border_clamp */
#ifdef GL_ARB_texture_buffer_object
- GLEW_ARB_texture_buffer_object = _glewSearchExtension("GL_ARB_texture_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_buffer_object) GLEW_ARB_texture_buffer_object = !_glewInit_GL_ARB_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_buffer_object) GLEW_ARB_texture_buffer_object = !_glewInit_GL_ARB_texture_buffer_object();
#endif /* GL_ARB_texture_buffer_object */
-#ifdef GL_ARB_texture_buffer_object_rgb32
- GLEW_ARB_texture_buffer_object_rgb32 = _glewSearchExtension("GL_ARB_texture_buffer_object_rgb32", extStart, extEnd);
-#endif /* GL_ARB_texture_buffer_object_rgb32 */
#ifdef GL_ARB_texture_buffer_range
- GLEW_ARB_texture_buffer_range = _glewSearchExtension("GL_ARB_texture_buffer_range", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_buffer_range) GLEW_ARB_texture_buffer_range = !_glewInit_GL_ARB_texture_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_buffer_range) GLEW_ARB_texture_buffer_range = !_glewInit_GL_ARB_texture_buffer_range();
#endif /* GL_ARB_texture_buffer_range */
#ifdef GL_ARB_texture_compression
- GLEW_ARB_texture_compression = _glewSearchExtension("GL_ARB_texture_compression", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_compression) GLEW_ARB_texture_compression = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_compression) GLEW_ARB_texture_compression = !_glewInit_GL_ARB_texture_compression();
#endif /* GL_ARB_texture_compression */
-#ifdef GL_ARB_texture_compression_bptc
- GLEW_ARB_texture_compression_bptc = _glewSearchExtension("GL_ARB_texture_compression_bptc", extStart, extEnd);
-#endif /* GL_ARB_texture_compression_bptc */
-#ifdef GL_ARB_texture_compression_rgtc
- GLEW_ARB_texture_compression_rgtc = _glewSearchExtension("GL_ARB_texture_compression_rgtc", extStart, extEnd);
-#endif /* GL_ARB_texture_compression_rgtc */
-#ifdef GL_ARB_texture_cube_map
- GLEW_ARB_texture_cube_map = _glewSearchExtension("GL_ARB_texture_cube_map", extStart, extEnd);
-#endif /* GL_ARB_texture_cube_map */
-#ifdef GL_ARB_texture_cube_map_array
- GLEW_ARB_texture_cube_map_array = _glewSearchExtension("GL_ARB_texture_cube_map_array", extStart, extEnd);
-#endif /* GL_ARB_texture_cube_map_array */
-#ifdef GL_ARB_texture_env_add
- GLEW_ARB_texture_env_add = _glewSearchExtension("GL_ARB_texture_env_add", extStart, extEnd);
-#endif /* GL_ARB_texture_env_add */
-#ifdef GL_ARB_texture_env_combine
- GLEW_ARB_texture_env_combine = _glewSearchExtension("GL_ARB_texture_env_combine", extStart, extEnd);
-#endif /* GL_ARB_texture_env_combine */
-#ifdef GL_ARB_texture_env_crossbar
- GLEW_ARB_texture_env_crossbar = _glewSearchExtension("GL_ARB_texture_env_crossbar", extStart, extEnd);
-#endif /* GL_ARB_texture_env_crossbar */
-#ifdef GL_ARB_texture_env_dot3
- GLEW_ARB_texture_env_dot3 = _glewSearchExtension("GL_ARB_texture_env_dot3", extStart, extEnd);
-#endif /* GL_ARB_texture_env_dot3 */
-#ifdef GL_ARB_texture_filter_minmax
- GLEW_ARB_texture_filter_minmax = _glewSearchExtension("GL_ARB_texture_filter_minmax", extStart, extEnd);
-#endif /* GL_ARB_texture_filter_minmax */
-#ifdef GL_ARB_texture_float
- GLEW_ARB_texture_float = _glewSearchExtension("GL_ARB_texture_float", extStart, extEnd);
-#endif /* GL_ARB_texture_float */
-#ifdef GL_ARB_texture_gather
- GLEW_ARB_texture_gather = _glewSearchExtension("GL_ARB_texture_gather", extStart, extEnd);
-#endif /* GL_ARB_texture_gather */
-#ifdef GL_ARB_texture_mirror_clamp_to_edge
- GLEW_ARB_texture_mirror_clamp_to_edge = _glewSearchExtension("GL_ARB_texture_mirror_clamp_to_edge", extStart, extEnd);
-#endif /* GL_ARB_texture_mirror_clamp_to_edge */
-#ifdef GL_ARB_texture_mirrored_repeat
- GLEW_ARB_texture_mirrored_repeat = _glewSearchExtension("GL_ARB_texture_mirrored_repeat", extStart, extEnd);
-#endif /* GL_ARB_texture_mirrored_repeat */
#ifdef GL_ARB_texture_multisample
- GLEW_ARB_texture_multisample = _glewSearchExtension("GL_ARB_texture_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_multisample) GLEW_ARB_texture_multisample = !_glewInit_GL_ARB_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_multisample) GLEW_ARB_texture_multisample = !_glewInit_GL_ARB_texture_multisample();
#endif /* GL_ARB_texture_multisample */
-#ifdef GL_ARB_texture_non_power_of_two
- GLEW_ARB_texture_non_power_of_two = _glewSearchExtension("GL_ARB_texture_non_power_of_two", extStart, extEnd);
-#endif /* GL_ARB_texture_non_power_of_two */
-#ifdef GL_ARB_texture_query_levels
- GLEW_ARB_texture_query_levels = _glewSearchExtension("GL_ARB_texture_query_levels", extStart, extEnd);
-#endif /* GL_ARB_texture_query_levels */
-#ifdef GL_ARB_texture_query_lod
- GLEW_ARB_texture_query_lod = _glewSearchExtension("GL_ARB_texture_query_lod", extStart, extEnd);
-#endif /* GL_ARB_texture_query_lod */
-#ifdef GL_ARB_texture_rectangle
- GLEW_ARB_texture_rectangle = _glewSearchExtension("GL_ARB_texture_rectangle", extStart, extEnd);
-#endif /* GL_ARB_texture_rectangle */
-#ifdef GL_ARB_texture_rg
- GLEW_ARB_texture_rg = _glewSearchExtension("GL_ARB_texture_rg", extStart, extEnd);
-#endif /* GL_ARB_texture_rg */
-#ifdef GL_ARB_texture_rgb10_a2ui
- GLEW_ARB_texture_rgb10_a2ui = _glewSearchExtension("GL_ARB_texture_rgb10_a2ui", extStart, extEnd);
-#endif /* GL_ARB_texture_rgb10_a2ui */
-#ifdef GL_ARB_texture_stencil8
- GLEW_ARB_texture_stencil8 = _glewSearchExtension("GL_ARB_texture_stencil8", extStart, extEnd);
-#endif /* GL_ARB_texture_stencil8 */
#ifdef GL_ARB_texture_storage
- GLEW_ARB_texture_storage = _glewSearchExtension("GL_ARB_texture_storage", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_storage) GLEW_ARB_texture_storage = !_glewInit_GL_ARB_texture_storage(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_storage) GLEW_ARB_texture_storage = !_glewInit_GL_ARB_texture_storage();
#endif /* GL_ARB_texture_storage */
#ifdef GL_ARB_texture_storage_multisample
- GLEW_ARB_texture_storage_multisample = _glewSearchExtension("GL_ARB_texture_storage_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_storage_multisample) GLEW_ARB_texture_storage_multisample = !_glewInit_GL_ARB_texture_storage_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_storage_multisample) GLEW_ARB_texture_storage_multisample = !_glewInit_GL_ARB_texture_storage_multisample();
#endif /* GL_ARB_texture_storage_multisample */
-#ifdef GL_ARB_texture_swizzle
- GLEW_ARB_texture_swizzle = _glewSearchExtension("GL_ARB_texture_swizzle", extStart, extEnd);
-#endif /* GL_ARB_texture_swizzle */
#ifdef GL_ARB_texture_view
- GLEW_ARB_texture_view = _glewSearchExtension("GL_ARB_texture_view", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_texture_view) GLEW_ARB_texture_view = !_glewInit_GL_ARB_texture_view(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_texture_view) GLEW_ARB_texture_view = !_glewInit_GL_ARB_texture_view();
#endif /* GL_ARB_texture_view */
#ifdef GL_ARB_timer_query
- GLEW_ARB_timer_query = _glewSearchExtension("GL_ARB_timer_query", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_timer_query) GLEW_ARB_timer_query = !_glewInit_GL_ARB_timer_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_timer_query) GLEW_ARB_timer_query = !_glewInit_GL_ARB_timer_query();
#endif /* GL_ARB_timer_query */
#ifdef GL_ARB_transform_feedback2
- GLEW_ARB_transform_feedback2 = _glewSearchExtension("GL_ARB_transform_feedback2", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_transform_feedback2) GLEW_ARB_transform_feedback2 = !_glewInit_GL_ARB_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_transform_feedback2) GLEW_ARB_transform_feedback2 = !_glewInit_GL_ARB_transform_feedback2();
#endif /* GL_ARB_transform_feedback2 */
#ifdef GL_ARB_transform_feedback3
- GLEW_ARB_transform_feedback3 = _glewSearchExtension("GL_ARB_transform_feedback3", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_transform_feedback3) GLEW_ARB_transform_feedback3 = !_glewInit_GL_ARB_transform_feedback3(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_transform_feedback3) GLEW_ARB_transform_feedback3 = !_glewInit_GL_ARB_transform_feedback3();
#endif /* GL_ARB_transform_feedback3 */
#ifdef GL_ARB_transform_feedback_instanced
- GLEW_ARB_transform_feedback_instanced = _glewSearchExtension("GL_ARB_transform_feedback_instanced", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_transform_feedback_instanced) GLEW_ARB_transform_feedback_instanced = !_glewInit_GL_ARB_transform_feedback_instanced(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_transform_feedback_instanced) GLEW_ARB_transform_feedback_instanced = !_glewInit_GL_ARB_transform_feedback_instanced();
#endif /* GL_ARB_transform_feedback_instanced */
-#ifdef GL_ARB_transform_feedback_overflow_query
- GLEW_ARB_transform_feedback_overflow_query = _glewSearchExtension("GL_ARB_transform_feedback_overflow_query", extStart, extEnd);
-#endif /* GL_ARB_transform_feedback_overflow_query */
#ifdef GL_ARB_transpose_matrix
- GLEW_ARB_transpose_matrix = _glewSearchExtension("GL_ARB_transpose_matrix", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_transpose_matrix) GLEW_ARB_transpose_matrix = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_transpose_matrix) GLEW_ARB_transpose_matrix = !_glewInit_GL_ARB_transpose_matrix();
#endif /* GL_ARB_transpose_matrix */
#ifdef GL_ARB_uniform_buffer_object
- GLEW_ARB_uniform_buffer_object = _glewSearchExtension("GL_ARB_uniform_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_uniform_buffer_object) GLEW_ARB_uniform_buffer_object = !_glewInit_GL_ARB_uniform_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_uniform_buffer_object) GLEW_ARB_uniform_buffer_object = !_glewInit_GL_ARB_uniform_buffer_object();
#endif /* GL_ARB_uniform_buffer_object */
-#ifdef GL_ARB_vertex_array_bgra
- GLEW_ARB_vertex_array_bgra = _glewSearchExtension("GL_ARB_vertex_array_bgra", extStart, extEnd);
-#endif /* GL_ARB_vertex_array_bgra */
#ifdef GL_ARB_vertex_array_object
- GLEW_ARB_vertex_array_object = _glewSearchExtension("GL_ARB_vertex_array_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_array_object) GLEW_ARB_vertex_array_object = !_glewInit_GL_ARB_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_array_object) GLEW_ARB_vertex_array_object = !_glewInit_GL_ARB_vertex_array_object();
#endif /* GL_ARB_vertex_array_object */
#ifdef GL_ARB_vertex_attrib_64bit
- GLEW_ARB_vertex_attrib_64bit = _glewSearchExtension("GL_ARB_vertex_attrib_64bit", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_attrib_64bit) GLEW_ARB_vertex_attrib_64bit = !_glewInit_GL_ARB_vertex_attrib_64bit(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_attrib_64bit) GLEW_ARB_vertex_attrib_64bit = !_glewInit_GL_ARB_vertex_attrib_64bit();
#endif /* GL_ARB_vertex_attrib_64bit */
#ifdef GL_ARB_vertex_attrib_binding
- GLEW_ARB_vertex_attrib_binding = _glewSearchExtension("GL_ARB_vertex_attrib_binding", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_attrib_binding) GLEW_ARB_vertex_attrib_binding = !_glewInit_GL_ARB_vertex_attrib_binding(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_attrib_binding) GLEW_ARB_vertex_attrib_binding = !_glewInit_GL_ARB_vertex_attrib_binding();
#endif /* GL_ARB_vertex_attrib_binding */
#ifdef GL_ARB_vertex_blend
- GLEW_ARB_vertex_blend = _glewSearchExtension("GL_ARB_vertex_blend", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_blend) GLEW_ARB_vertex_blend = !_glewInit_GL_ARB_vertex_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_blend) GLEW_ARB_vertex_blend = !_glewInit_GL_ARB_vertex_blend();
#endif /* GL_ARB_vertex_blend */
#ifdef GL_ARB_vertex_buffer_object
- GLEW_ARB_vertex_buffer_object = _glewSearchExtension("GL_ARB_vertex_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_buffer_object) GLEW_ARB_vertex_buffer_object = !_glewInit_GL_ARB_vertex_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_buffer_object) GLEW_ARB_vertex_buffer_object = !_glewInit_GL_ARB_vertex_buffer_object();
#endif /* GL_ARB_vertex_buffer_object */
#ifdef GL_ARB_vertex_program
- GLEW_ARB_vertex_program = _glewSearchExtension("GL_ARB_vertex_program", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_program) GLEW_ARB_vertex_program = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_program) GLEW_ARB_vertex_program = !_glewInit_GL_ARB_vertex_program();
#endif /* GL_ARB_vertex_program */
#ifdef GL_ARB_vertex_shader
- GLEW_ARB_vertex_shader = _glewSearchExtension("GL_ARB_vertex_shader", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_shader) { GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); _glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); }
+ if (glewExperimental || GLEW_ARB_vertex_shader) { GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(); _glewInit_GL_ARB_vertex_program(); }
#endif /* GL_ARB_vertex_shader */
-#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
- GLEW_ARB_vertex_type_10f_11f_11f_rev = _glewSearchExtension("GL_ARB_vertex_type_10f_11f_11f_rev", extStart, extEnd);
-#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */
#ifdef GL_ARB_vertex_type_2_10_10_10_rev
- GLEW_ARB_vertex_type_2_10_10_10_rev = _glewSearchExtension("GL_ARB_vertex_type_2_10_10_10_rev", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_vertex_type_2_10_10_10_rev) GLEW_ARB_vertex_type_2_10_10_10_rev = !_glewInit_GL_ARB_vertex_type_2_10_10_10_rev(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_vertex_type_2_10_10_10_rev) GLEW_ARB_vertex_type_2_10_10_10_rev = !_glewInit_GL_ARB_vertex_type_2_10_10_10_rev();
#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
#ifdef GL_ARB_viewport_array
- GLEW_ARB_viewport_array = _glewSearchExtension("GL_ARB_viewport_array", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_viewport_array) GLEW_ARB_viewport_array = !_glewInit_GL_ARB_viewport_array(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_viewport_array) GLEW_ARB_viewport_array = !_glewInit_GL_ARB_viewport_array();
#endif /* GL_ARB_viewport_array */
#ifdef GL_ARB_window_pos
- GLEW_ARB_window_pos = _glewSearchExtension("GL_ARB_window_pos", extStart, extEnd);
- if (glewExperimental || GLEW_ARB_window_pos) GLEW_ARB_window_pos = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ARB_window_pos) GLEW_ARB_window_pos = !_glewInit_GL_ARB_window_pos();
#endif /* GL_ARB_window_pos */
-#ifdef GL_ATIX_point_sprites
- GLEW_ATIX_point_sprites = _glewSearchExtension("GL_ATIX_point_sprites", extStart, extEnd);
-#endif /* GL_ATIX_point_sprites */
-#ifdef GL_ATIX_texture_env_combine3
- GLEW_ATIX_texture_env_combine3 = _glewSearchExtension("GL_ATIX_texture_env_combine3", extStart, extEnd);
-#endif /* GL_ATIX_texture_env_combine3 */
-#ifdef GL_ATIX_texture_env_route
- GLEW_ATIX_texture_env_route = _glewSearchExtension("GL_ATIX_texture_env_route", extStart, extEnd);
-#endif /* GL_ATIX_texture_env_route */
-#ifdef GL_ATIX_vertex_shader_output_point_size
- GLEW_ATIX_vertex_shader_output_point_size = _glewSearchExtension("GL_ATIX_vertex_shader_output_point_size", extStart, extEnd);
-#endif /* GL_ATIX_vertex_shader_output_point_size */
#ifdef GL_ATI_draw_buffers
- GLEW_ATI_draw_buffers = _glewSearchExtension("GL_ATI_draw_buffers", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_draw_buffers) GLEW_ATI_draw_buffers = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_draw_buffers) GLEW_ATI_draw_buffers = !_glewInit_GL_ATI_draw_buffers();
#endif /* GL_ATI_draw_buffers */
#ifdef GL_ATI_element_array
- GLEW_ATI_element_array = _glewSearchExtension("GL_ATI_element_array", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_element_array) GLEW_ATI_element_array = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_element_array) GLEW_ATI_element_array = !_glewInit_GL_ATI_element_array();
#endif /* GL_ATI_element_array */
#ifdef GL_ATI_envmap_bumpmap
- GLEW_ATI_envmap_bumpmap = _glewSearchExtension("GL_ATI_envmap_bumpmap", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_envmap_bumpmap) GLEW_ATI_envmap_bumpmap = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_envmap_bumpmap) GLEW_ATI_envmap_bumpmap = !_glewInit_GL_ATI_envmap_bumpmap();
#endif /* GL_ATI_envmap_bumpmap */
#ifdef GL_ATI_fragment_shader
- GLEW_ATI_fragment_shader = _glewSearchExtension("GL_ATI_fragment_shader", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_fragment_shader) GLEW_ATI_fragment_shader = !_glewInit_GL_ATI_fragment_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_fragment_shader) GLEW_ATI_fragment_shader = !_glewInit_GL_ATI_fragment_shader();
#endif /* GL_ATI_fragment_shader */
#ifdef GL_ATI_map_object_buffer
- GLEW_ATI_map_object_buffer = _glewSearchExtension("GL_ATI_map_object_buffer", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_map_object_buffer) GLEW_ATI_map_object_buffer = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_map_object_buffer) GLEW_ATI_map_object_buffer = !_glewInit_GL_ATI_map_object_buffer();
#endif /* GL_ATI_map_object_buffer */
-#ifdef GL_ATI_meminfo
- GLEW_ATI_meminfo = _glewSearchExtension("GL_ATI_meminfo", extStart, extEnd);
-#endif /* GL_ATI_meminfo */
#ifdef GL_ATI_pn_triangles
- GLEW_ATI_pn_triangles = _glewSearchExtension("GL_ATI_pn_triangles", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_pn_triangles) GLEW_ATI_pn_triangles = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_pn_triangles) GLEW_ATI_pn_triangles = !_glewInit_GL_ATI_pn_triangles();
#endif /* GL_ATI_pn_triangles */
#ifdef GL_ATI_separate_stencil
- GLEW_ATI_separate_stencil = _glewSearchExtension("GL_ATI_separate_stencil", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_separate_stencil) GLEW_ATI_separate_stencil = !_glewInit_GL_ATI_separate_stencil(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_separate_stencil) GLEW_ATI_separate_stencil = !_glewInit_GL_ATI_separate_stencil();
#endif /* GL_ATI_separate_stencil */
-#ifdef GL_ATI_shader_texture_lod
- GLEW_ATI_shader_texture_lod = _glewSearchExtension("GL_ATI_shader_texture_lod", extStart, extEnd);
-#endif /* GL_ATI_shader_texture_lod */
-#ifdef GL_ATI_text_fragment_shader
- GLEW_ATI_text_fragment_shader = _glewSearchExtension("GL_ATI_text_fragment_shader", extStart, extEnd);
-#endif /* GL_ATI_text_fragment_shader */
-#ifdef GL_ATI_texture_compression_3dc
- GLEW_ATI_texture_compression_3dc = _glewSearchExtension("GL_ATI_texture_compression_3dc", extStart, extEnd);
-#endif /* GL_ATI_texture_compression_3dc */
-#ifdef GL_ATI_texture_env_combine3
- GLEW_ATI_texture_env_combine3 = _glewSearchExtension("GL_ATI_texture_env_combine3", extStart, extEnd);
-#endif /* GL_ATI_texture_env_combine3 */
-#ifdef GL_ATI_texture_float
- GLEW_ATI_texture_float = _glewSearchExtension("GL_ATI_texture_float", extStart, extEnd);
-#endif /* GL_ATI_texture_float */
-#ifdef GL_ATI_texture_mirror_once
- GLEW_ATI_texture_mirror_once = _glewSearchExtension("GL_ATI_texture_mirror_once", extStart, extEnd);
-#endif /* GL_ATI_texture_mirror_once */
#ifdef GL_ATI_vertex_array_object
- GLEW_ATI_vertex_array_object = _glewSearchExtension("GL_ATI_vertex_array_object", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_vertex_array_object) GLEW_ATI_vertex_array_object = !_glewInit_GL_ATI_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_vertex_array_object) GLEW_ATI_vertex_array_object = !_glewInit_GL_ATI_vertex_array_object();
#endif /* GL_ATI_vertex_array_object */
#ifdef GL_ATI_vertex_attrib_array_object
- GLEW_ATI_vertex_attrib_array_object = _glewSearchExtension("GL_ATI_vertex_attrib_array_object", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) GLEW_ATI_vertex_attrib_array_object = !_glewInit_GL_ATI_vertex_attrib_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) GLEW_ATI_vertex_attrib_array_object = !_glewInit_GL_ATI_vertex_attrib_array_object();
#endif /* GL_ATI_vertex_attrib_array_object */
#ifdef GL_ATI_vertex_streams
- GLEW_ATI_vertex_streams = _glewSearchExtension("GL_ATI_vertex_streams", extStart, extEnd);
- if (glewExperimental || GLEW_ATI_vertex_streams) GLEW_ATI_vertex_streams = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_ATI_vertex_streams) GLEW_ATI_vertex_streams = !_glewInit_GL_ATI_vertex_streams();
#endif /* GL_ATI_vertex_streams */
-#ifdef GL_EXT_422_pixels
- GLEW_EXT_422_pixels = _glewSearchExtension("GL_EXT_422_pixels", extStart, extEnd);
-#endif /* GL_EXT_422_pixels */
-#ifdef GL_EXT_Cg_shader
- GLEW_EXT_Cg_shader = _glewSearchExtension("GL_EXT_Cg_shader", extStart, extEnd);
-#endif /* GL_EXT_Cg_shader */
-#ifdef GL_EXT_abgr
- GLEW_EXT_abgr = _glewSearchExtension("GL_EXT_abgr", extStart, extEnd);
-#endif /* GL_EXT_abgr */
-#ifdef GL_EXT_bgra
- GLEW_EXT_bgra = _glewSearchExtension("GL_EXT_bgra", extStart, extEnd);
-#endif /* GL_EXT_bgra */
#ifdef GL_EXT_bindable_uniform
- GLEW_EXT_bindable_uniform = _glewSearchExtension("GL_EXT_bindable_uniform", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_bindable_uniform) GLEW_EXT_bindable_uniform = !_glewInit_GL_EXT_bindable_uniform(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_bindable_uniform) GLEW_EXT_bindable_uniform = !_glewInit_GL_EXT_bindable_uniform();
#endif /* GL_EXT_bindable_uniform */
#ifdef GL_EXT_blend_color
- GLEW_EXT_blend_color = _glewSearchExtension("GL_EXT_blend_color", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_blend_color) GLEW_EXT_blend_color = !_glewInit_GL_EXT_blend_color(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_blend_color) GLEW_EXT_blend_color = !_glewInit_GL_EXT_blend_color();
#endif /* GL_EXT_blend_color */
#ifdef GL_EXT_blend_equation_separate
- GLEW_EXT_blend_equation_separate = _glewSearchExtension("GL_EXT_blend_equation_separate", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_blend_equation_separate) GLEW_EXT_blend_equation_separate = !_glewInit_GL_EXT_blend_equation_separate(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_blend_equation_separate) GLEW_EXT_blend_equation_separate = !_glewInit_GL_EXT_blend_equation_separate();
#endif /* GL_EXT_blend_equation_separate */
#ifdef GL_EXT_blend_func_separate
- GLEW_EXT_blend_func_separate = _glewSearchExtension("GL_EXT_blend_func_separate", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_blend_func_separate) GLEW_EXT_blend_func_separate = !_glewInit_GL_EXT_blend_func_separate(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_blend_func_separate) GLEW_EXT_blend_func_separate = !_glewInit_GL_EXT_blend_func_separate();
#endif /* GL_EXT_blend_func_separate */
-#ifdef GL_EXT_blend_logic_op
- GLEW_EXT_blend_logic_op = _glewSearchExtension("GL_EXT_blend_logic_op", extStart, extEnd);
-#endif /* GL_EXT_blend_logic_op */
#ifdef GL_EXT_blend_minmax
- GLEW_EXT_blend_minmax = _glewSearchExtension("GL_EXT_blend_minmax", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_blend_minmax) GLEW_EXT_blend_minmax = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_blend_minmax) GLEW_EXT_blend_minmax = !_glewInit_GL_EXT_blend_minmax();
#endif /* GL_EXT_blend_minmax */
-#ifdef GL_EXT_blend_subtract
- GLEW_EXT_blend_subtract = _glewSearchExtension("GL_EXT_blend_subtract", extStart, extEnd);
-#endif /* GL_EXT_blend_subtract */
-#ifdef GL_EXT_clip_volume_hint
- GLEW_EXT_clip_volume_hint = _glewSearchExtension("GL_EXT_clip_volume_hint", extStart, extEnd);
-#endif /* GL_EXT_clip_volume_hint */
-#ifdef GL_EXT_cmyka
- GLEW_EXT_cmyka = _glewSearchExtension("GL_EXT_cmyka", extStart, extEnd);
-#endif /* GL_EXT_cmyka */
#ifdef GL_EXT_color_subtable
- GLEW_EXT_color_subtable = _glewSearchExtension("GL_EXT_color_subtable", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_color_subtable) GLEW_EXT_color_subtable = !_glewInit_GL_EXT_color_subtable(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_color_subtable) GLEW_EXT_color_subtable = !_glewInit_GL_EXT_color_subtable();
#endif /* GL_EXT_color_subtable */
#ifdef GL_EXT_compiled_vertex_array
- GLEW_EXT_compiled_vertex_array = _glewSearchExtension("GL_EXT_compiled_vertex_array", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_compiled_vertex_array) GLEW_EXT_compiled_vertex_array = !_glewInit_GL_EXT_compiled_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_compiled_vertex_array) GLEW_EXT_compiled_vertex_array = !_glewInit_GL_EXT_compiled_vertex_array();
#endif /* GL_EXT_compiled_vertex_array */
#ifdef GL_EXT_convolution
- GLEW_EXT_convolution = _glewSearchExtension("GL_EXT_convolution", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_convolution) GLEW_EXT_convolution = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_convolution) GLEW_EXT_convolution = !_glewInit_GL_EXT_convolution();
#endif /* GL_EXT_convolution */
#ifdef GL_EXT_coordinate_frame
- GLEW_EXT_coordinate_frame = _glewSearchExtension("GL_EXT_coordinate_frame", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_coordinate_frame) GLEW_EXT_coordinate_frame = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_coordinate_frame) GLEW_EXT_coordinate_frame = !_glewInit_GL_EXT_coordinate_frame();
#endif /* GL_EXT_coordinate_frame */
#ifdef GL_EXT_copy_texture
- GLEW_EXT_copy_texture = _glewSearchExtension("GL_EXT_copy_texture", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_copy_texture) GLEW_EXT_copy_texture = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_copy_texture) GLEW_EXT_copy_texture = !_glewInit_GL_EXT_copy_texture();
#endif /* GL_EXT_copy_texture */
#ifdef GL_EXT_cull_vertex
- GLEW_EXT_cull_vertex = _glewSearchExtension("GL_EXT_cull_vertex", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_cull_vertex) GLEW_EXT_cull_vertex = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_cull_vertex) GLEW_EXT_cull_vertex = !_glewInit_GL_EXT_cull_vertex();
#endif /* GL_EXT_cull_vertex */
#ifdef GL_EXT_debug_label
- GLEW_EXT_debug_label = _glewSearchExtension("GL_EXT_debug_label", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_debug_label) GLEW_EXT_debug_label = !_glewInit_GL_EXT_debug_label(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_debug_label) GLEW_EXT_debug_label = !_glewInit_GL_EXT_debug_label();
#endif /* GL_EXT_debug_label */
#ifdef GL_EXT_debug_marker
- GLEW_EXT_debug_marker = _glewSearchExtension("GL_EXT_debug_marker", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_debug_marker) GLEW_EXT_debug_marker = !_glewInit_GL_EXT_debug_marker(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_debug_marker) GLEW_EXT_debug_marker = !_glewInit_GL_EXT_debug_marker();
#endif /* GL_EXT_debug_marker */
#ifdef GL_EXT_depth_bounds_test
- GLEW_EXT_depth_bounds_test = _glewSearchExtension("GL_EXT_depth_bounds_test", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_depth_bounds_test) GLEW_EXT_depth_bounds_test = !_glewInit_GL_EXT_depth_bounds_test(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_depth_bounds_test) GLEW_EXT_depth_bounds_test = !_glewInit_GL_EXT_depth_bounds_test();
#endif /* GL_EXT_depth_bounds_test */
#ifdef GL_EXT_direct_state_access
- GLEW_EXT_direct_state_access = _glewSearchExtension("GL_EXT_direct_state_access", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_direct_state_access) GLEW_EXT_direct_state_access = !_glewInit_GL_EXT_direct_state_access(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_direct_state_access) GLEW_EXT_direct_state_access = !_glewInit_GL_EXT_direct_state_access();
#endif /* GL_EXT_direct_state_access */
#ifdef GL_EXT_draw_buffers2
- GLEW_EXT_draw_buffers2 = _glewSearchExtension("GL_EXT_draw_buffers2", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_draw_buffers2) GLEW_EXT_draw_buffers2 = !_glewInit_GL_EXT_draw_buffers2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_draw_buffers2) GLEW_EXT_draw_buffers2 = !_glewInit_GL_EXT_draw_buffers2();
#endif /* GL_EXT_draw_buffers2 */
#ifdef GL_EXT_draw_instanced
- GLEW_EXT_draw_instanced = _glewSearchExtension("GL_EXT_draw_instanced", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_draw_instanced) GLEW_EXT_draw_instanced = !_glewInit_GL_EXT_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_draw_instanced) GLEW_EXT_draw_instanced = !_glewInit_GL_EXT_draw_instanced();
#endif /* GL_EXT_draw_instanced */
#ifdef GL_EXT_draw_range_elements
- GLEW_EXT_draw_range_elements = _glewSearchExtension("GL_EXT_draw_range_elements", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_draw_range_elements) GLEW_EXT_draw_range_elements = !_glewInit_GL_EXT_draw_range_elements(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_draw_range_elements) GLEW_EXT_draw_range_elements = !_glewInit_GL_EXT_draw_range_elements();
#endif /* GL_EXT_draw_range_elements */
#ifdef GL_EXT_fog_coord
- GLEW_EXT_fog_coord = _glewSearchExtension("GL_EXT_fog_coord", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_fog_coord) GLEW_EXT_fog_coord = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_fog_coord) GLEW_EXT_fog_coord = !_glewInit_GL_EXT_fog_coord();
#endif /* GL_EXT_fog_coord */
#ifdef GL_EXT_fragment_lighting
- GLEW_EXT_fragment_lighting = _glewSearchExtension("GL_EXT_fragment_lighting", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_fragment_lighting) GLEW_EXT_fragment_lighting = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_fragment_lighting) GLEW_EXT_fragment_lighting = !_glewInit_GL_EXT_fragment_lighting();
#endif /* GL_EXT_fragment_lighting */
#ifdef GL_EXT_framebuffer_blit
- GLEW_EXT_framebuffer_blit = _glewSearchExtension("GL_EXT_framebuffer_blit", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_framebuffer_blit) GLEW_EXT_framebuffer_blit = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_framebuffer_blit) GLEW_EXT_framebuffer_blit = !_glewInit_GL_EXT_framebuffer_blit();
#endif /* GL_EXT_framebuffer_blit */
#ifdef GL_EXT_framebuffer_multisample
- GLEW_EXT_framebuffer_multisample = _glewSearchExtension("GL_EXT_framebuffer_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_framebuffer_multisample) GLEW_EXT_framebuffer_multisample = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_framebuffer_multisample) GLEW_EXT_framebuffer_multisample = !_glewInit_GL_EXT_framebuffer_multisample();
#endif /* GL_EXT_framebuffer_multisample */
-#ifdef GL_EXT_framebuffer_multisample_blit_scaled
- GLEW_EXT_framebuffer_multisample_blit_scaled = _glewSearchExtension("GL_EXT_framebuffer_multisample_blit_scaled", extStart, extEnd);
-#endif /* GL_EXT_framebuffer_multisample_blit_scaled */
#ifdef GL_EXT_framebuffer_object
- GLEW_EXT_framebuffer_object = _glewSearchExtension("GL_EXT_framebuffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_framebuffer_object) GLEW_EXT_framebuffer_object = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_framebuffer_object) GLEW_EXT_framebuffer_object = !_glewInit_GL_EXT_framebuffer_object();
#endif /* GL_EXT_framebuffer_object */
-#ifdef GL_EXT_framebuffer_sRGB
- GLEW_EXT_framebuffer_sRGB = _glewSearchExtension("GL_EXT_framebuffer_sRGB", extStart, extEnd);
-#endif /* GL_EXT_framebuffer_sRGB */
#ifdef GL_EXT_geometry_shader4
- GLEW_EXT_geometry_shader4 = _glewSearchExtension("GL_EXT_geometry_shader4", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_geometry_shader4) GLEW_EXT_geometry_shader4 = !_glewInit_GL_EXT_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_geometry_shader4) GLEW_EXT_geometry_shader4 = !_glewInit_GL_EXT_geometry_shader4();
#endif /* GL_EXT_geometry_shader4 */
#ifdef GL_EXT_gpu_program_parameters
- GLEW_EXT_gpu_program_parameters = _glewSearchExtension("GL_EXT_gpu_program_parameters", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_gpu_program_parameters) GLEW_EXT_gpu_program_parameters = !_glewInit_GL_EXT_gpu_program_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_gpu_program_parameters) GLEW_EXT_gpu_program_parameters = !_glewInit_GL_EXT_gpu_program_parameters();
#endif /* GL_EXT_gpu_program_parameters */
#ifdef GL_EXT_gpu_shader4
- GLEW_EXT_gpu_shader4 = _glewSearchExtension("GL_EXT_gpu_shader4", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_gpu_shader4) GLEW_EXT_gpu_shader4 = !_glewInit_GL_EXT_gpu_shader4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_gpu_shader4) GLEW_EXT_gpu_shader4 = !_glewInit_GL_EXT_gpu_shader4();
#endif /* GL_EXT_gpu_shader4 */
#ifdef GL_EXT_histogram
- GLEW_EXT_histogram = _glewSearchExtension("GL_EXT_histogram", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_histogram) GLEW_EXT_histogram = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_histogram) GLEW_EXT_histogram = !_glewInit_GL_EXT_histogram();
#endif /* GL_EXT_histogram */
-#ifdef GL_EXT_index_array_formats
- GLEW_EXT_index_array_formats = _glewSearchExtension("GL_EXT_index_array_formats", extStart, extEnd);
-#endif /* GL_EXT_index_array_formats */
#ifdef GL_EXT_index_func
- GLEW_EXT_index_func = _glewSearchExtension("GL_EXT_index_func", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_index_func) GLEW_EXT_index_func = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_index_func) GLEW_EXT_index_func = !_glewInit_GL_EXT_index_func();
#endif /* GL_EXT_index_func */
#ifdef GL_EXT_index_material
- GLEW_EXT_index_material = _glewSearchExtension("GL_EXT_index_material", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_index_material) GLEW_EXT_index_material = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_index_material) GLEW_EXT_index_material = !_glewInit_GL_EXT_index_material();
#endif /* GL_EXT_index_material */
-#ifdef GL_EXT_index_texture
- GLEW_EXT_index_texture = _glewSearchExtension("GL_EXT_index_texture", extStart, extEnd);
-#endif /* GL_EXT_index_texture */
#ifdef GL_EXT_light_texture
- GLEW_EXT_light_texture = _glewSearchExtension("GL_EXT_light_texture", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_light_texture) GLEW_EXT_light_texture = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_light_texture) GLEW_EXT_light_texture = !_glewInit_GL_EXT_light_texture();
#endif /* GL_EXT_light_texture */
-#ifdef GL_EXT_misc_attribute
- GLEW_EXT_misc_attribute = _glewSearchExtension("GL_EXT_misc_attribute", extStart, extEnd);
-#endif /* GL_EXT_misc_attribute */
#ifdef GL_EXT_multi_draw_arrays
- GLEW_EXT_multi_draw_arrays = _glewSearchExtension("GL_EXT_multi_draw_arrays", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_multi_draw_arrays) GLEW_EXT_multi_draw_arrays = !_glewInit_GL_EXT_multi_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_multi_draw_arrays) GLEW_EXT_multi_draw_arrays = !_glewInit_GL_EXT_multi_draw_arrays();
#endif /* GL_EXT_multi_draw_arrays */
#ifdef GL_EXT_multisample
- GLEW_EXT_multisample = _glewSearchExtension("GL_EXT_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_multisample) GLEW_EXT_multisample = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_multisample) GLEW_EXT_multisample = !_glewInit_GL_EXT_multisample();
#endif /* GL_EXT_multisample */
-#ifdef GL_EXT_packed_depth_stencil
- GLEW_EXT_packed_depth_stencil = _glewSearchExtension("GL_EXT_packed_depth_stencil", extStart, extEnd);
-#endif /* GL_EXT_packed_depth_stencil */
-#ifdef GL_EXT_packed_float
- GLEW_EXT_packed_float = _glewSearchExtension("GL_EXT_packed_float", extStart, extEnd);
-#endif /* GL_EXT_packed_float */
-#ifdef GL_EXT_packed_pixels
- GLEW_EXT_packed_pixels = _glewSearchExtension("GL_EXT_packed_pixels", extStart, extEnd);
-#endif /* GL_EXT_packed_pixels */
#ifdef GL_EXT_paletted_texture
- GLEW_EXT_paletted_texture = _glewSearchExtension("GL_EXT_paletted_texture", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_paletted_texture) GLEW_EXT_paletted_texture = !_glewInit_GL_EXT_paletted_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_paletted_texture) GLEW_EXT_paletted_texture = !_glewInit_GL_EXT_paletted_texture();
#endif /* GL_EXT_paletted_texture */
-#ifdef GL_EXT_pixel_buffer_object
- GLEW_EXT_pixel_buffer_object = _glewSearchExtension("GL_EXT_pixel_buffer_object", extStart, extEnd);
-#endif /* GL_EXT_pixel_buffer_object */
#ifdef GL_EXT_pixel_transform
- GLEW_EXT_pixel_transform = _glewSearchExtension("GL_EXT_pixel_transform", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_pixel_transform) GLEW_EXT_pixel_transform = !_glewInit_GL_EXT_pixel_transform(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_pixel_transform) GLEW_EXT_pixel_transform = !_glewInit_GL_EXT_pixel_transform();
#endif /* GL_EXT_pixel_transform */
-#ifdef GL_EXT_pixel_transform_color_table
- GLEW_EXT_pixel_transform_color_table = _glewSearchExtension("GL_EXT_pixel_transform_color_table", extStart, extEnd);
-#endif /* GL_EXT_pixel_transform_color_table */
#ifdef GL_EXT_point_parameters
- GLEW_EXT_point_parameters = _glewSearchExtension("GL_EXT_point_parameters", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters();
#endif /* GL_EXT_point_parameters */
#ifdef GL_EXT_polygon_offset
- GLEW_EXT_polygon_offset = _glewSearchExtension("GL_EXT_polygon_offset", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_polygon_offset) GLEW_EXT_polygon_offset = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_polygon_offset) GLEW_EXT_polygon_offset = !_glewInit_GL_EXT_polygon_offset();
#endif /* GL_EXT_polygon_offset */
#ifdef GL_EXT_polygon_offset_clamp
- GLEW_EXT_polygon_offset_clamp = _glewSearchExtension("GL_EXT_polygon_offset_clamp", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_polygon_offset_clamp) GLEW_EXT_polygon_offset_clamp = !_glewInit_GL_EXT_polygon_offset_clamp(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_polygon_offset_clamp) GLEW_EXT_polygon_offset_clamp = !_glewInit_GL_EXT_polygon_offset_clamp();
#endif /* GL_EXT_polygon_offset_clamp */
-#ifdef GL_EXT_post_depth_coverage
- GLEW_EXT_post_depth_coverage = _glewSearchExtension("GL_EXT_post_depth_coverage", extStart, extEnd);
-#endif /* GL_EXT_post_depth_coverage */
#ifdef GL_EXT_provoking_vertex
- GLEW_EXT_provoking_vertex = _glewSearchExtension("GL_EXT_provoking_vertex", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_provoking_vertex) GLEW_EXT_provoking_vertex = !_glewInit_GL_EXT_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_provoking_vertex) GLEW_EXT_provoking_vertex = !_glewInit_GL_EXT_provoking_vertex();
#endif /* GL_EXT_provoking_vertex */
#ifdef GL_EXT_raster_multisample
- GLEW_EXT_raster_multisample = _glewSearchExtension("GL_EXT_raster_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_raster_multisample) GLEW_EXT_raster_multisample = !_glewInit_GL_EXT_raster_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_raster_multisample) GLEW_EXT_raster_multisample = !_glewInit_GL_EXT_raster_multisample();
#endif /* GL_EXT_raster_multisample */
-#ifdef GL_EXT_rescale_normal
- GLEW_EXT_rescale_normal = _glewSearchExtension("GL_EXT_rescale_normal", extStart, extEnd);
-#endif /* GL_EXT_rescale_normal */
#ifdef GL_EXT_scene_marker
- GLEW_EXT_scene_marker = _glewSearchExtension("GL_EXT_scene_marker", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_scene_marker) GLEW_EXT_scene_marker = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_scene_marker) GLEW_EXT_scene_marker = !_glewInit_GL_EXT_scene_marker();
#endif /* GL_EXT_scene_marker */
#ifdef GL_EXT_secondary_color
- GLEW_EXT_secondary_color = _glewSearchExtension("GL_EXT_secondary_color", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_secondary_color) GLEW_EXT_secondary_color = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_secondary_color) GLEW_EXT_secondary_color = !_glewInit_GL_EXT_secondary_color();
#endif /* GL_EXT_secondary_color */
#ifdef GL_EXT_separate_shader_objects
- GLEW_EXT_separate_shader_objects = _glewSearchExtension("GL_EXT_separate_shader_objects", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_separate_shader_objects) GLEW_EXT_separate_shader_objects = !_glewInit_GL_EXT_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_separate_shader_objects) GLEW_EXT_separate_shader_objects = !_glewInit_GL_EXT_separate_shader_objects();
#endif /* GL_EXT_separate_shader_objects */
-#ifdef GL_EXT_separate_specular_color
- GLEW_EXT_separate_specular_color = _glewSearchExtension("GL_EXT_separate_specular_color", extStart, extEnd);
-#endif /* GL_EXT_separate_specular_color */
-#ifdef GL_EXT_shader_image_load_formatted
- GLEW_EXT_shader_image_load_formatted = _glewSearchExtension("GL_EXT_shader_image_load_formatted", extStart, extEnd);
-#endif /* GL_EXT_shader_image_load_formatted */
#ifdef GL_EXT_shader_image_load_store
- GLEW_EXT_shader_image_load_store = _glewSearchExtension("GL_EXT_shader_image_load_store", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_shader_image_load_store) GLEW_EXT_shader_image_load_store = !_glewInit_GL_EXT_shader_image_load_store(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_shader_image_load_store) GLEW_EXT_shader_image_load_store = !_glewInit_GL_EXT_shader_image_load_store();
#endif /* GL_EXT_shader_image_load_store */
-#ifdef GL_EXT_shader_integer_mix
- GLEW_EXT_shader_integer_mix = _glewSearchExtension("GL_EXT_shader_integer_mix", extStart, extEnd);
-#endif /* GL_EXT_shader_integer_mix */
-#ifdef GL_EXT_shadow_funcs
- GLEW_EXT_shadow_funcs = _glewSearchExtension("GL_EXT_shadow_funcs", extStart, extEnd);
-#endif /* GL_EXT_shadow_funcs */
-#ifdef GL_EXT_shared_texture_palette
- GLEW_EXT_shared_texture_palette = _glewSearchExtension("GL_EXT_shared_texture_palette", extStart, extEnd);
-#endif /* GL_EXT_shared_texture_palette */
-#ifdef GL_EXT_sparse_texture2
- GLEW_EXT_sparse_texture2 = _glewSearchExtension("GL_EXT_sparse_texture2", extStart, extEnd);
-#endif /* GL_EXT_sparse_texture2 */
-#ifdef GL_EXT_stencil_clear_tag
- GLEW_EXT_stencil_clear_tag = _glewSearchExtension("GL_EXT_stencil_clear_tag", extStart, extEnd);
-#endif /* GL_EXT_stencil_clear_tag */
#ifdef GL_EXT_stencil_two_side
- GLEW_EXT_stencil_two_side = _glewSearchExtension("GL_EXT_stencil_two_side", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_stencil_two_side) GLEW_EXT_stencil_two_side = !_glewInit_GL_EXT_stencil_two_side(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_stencil_two_side) GLEW_EXT_stencil_two_side = !_glewInit_GL_EXT_stencil_two_side();
#endif /* GL_EXT_stencil_two_side */
-#ifdef GL_EXT_stencil_wrap
- GLEW_EXT_stencil_wrap = _glewSearchExtension("GL_EXT_stencil_wrap", extStart, extEnd);
-#endif /* GL_EXT_stencil_wrap */
#ifdef GL_EXT_subtexture
- GLEW_EXT_subtexture = _glewSearchExtension("GL_EXT_subtexture", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_subtexture) GLEW_EXT_subtexture = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_subtexture) GLEW_EXT_subtexture = !_glewInit_GL_EXT_subtexture();
#endif /* GL_EXT_subtexture */
-#ifdef GL_EXT_texture
- GLEW_EXT_texture = _glewSearchExtension("GL_EXT_texture", extStart, extEnd);
-#endif /* GL_EXT_texture */
#ifdef GL_EXT_texture3D
- GLEW_EXT_texture3D = _glewSearchExtension("GL_EXT_texture3D", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_texture3D) GLEW_EXT_texture3D = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_texture3D) GLEW_EXT_texture3D = !_glewInit_GL_EXT_texture3D();
#endif /* GL_EXT_texture3D */
#ifdef GL_EXT_texture_array
- GLEW_EXT_texture_array = _glewSearchExtension("GL_EXT_texture_array", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_texture_array) GLEW_EXT_texture_array = !_glewInit_GL_EXT_texture_array(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_texture_array) GLEW_EXT_texture_array = !_glewInit_GL_EXT_texture_array();
#endif /* GL_EXT_texture_array */
#ifdef GL_EXT_texture_buffer_object
- GLEW_EXT_texture_buffer_object = _glewSearchExtension("GL_EXT_texture_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_texture_buffer_object) GLEW_EXT_texture_buffer_object = !_glewInit_GL_EXT_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_texture_buffer_object) GLEW_EXT_texture_buffer_object = !_glewInit_GL_EXT_texture_buffer_object();
#endif /* GL_EXT_texture_buffer_object */
-#ifdef GL_EXT_texture_compression_dxt1
- GLEW_EXT_texture_compression_dxt1 = _glewSearchExtension("GL_EXT_texture_compression_dxt1", extStart, extEnd);
-#endif /* GL_EXT_texture_compression_dxt1 */
-#ifdef GL_EXT_texture_compression_latc
- GLEW_EXT_texture_compression_latc = _glewSearchExtension("GL_EXT_texture_compression_latc", extStart, extEnd);
-#endif /* GL_EXT_texture_compression_latc */
-#ifdef GL_EXT_texture_compression_rgtc
- GLEW_EXT_texture_compression_rgtc = _glewSearchExtension("GL_EXT_texture_compression_rgtc", extStart, extEnd);
-#endif /* GL_EXT_texture_compression_rgtc */
-#ifdef GL_EXT_texture_compression_s3tc
- GLEW_EXT_texture_compression_s3tc = _glewSearchExtension("GL_EXT_texture_compression_s3tc", extStart, extEnd);
-#endif /* GL_EXT_texture_compression_s3tc */
-#ifdef GL_EXT_texture_cube_map
- GLEW_EXT_texture_cube_map = _glewSearchExtension("GL_EXT_texture_cube_map", extStart, extEnd);
-#endif /* GL_EXT_texture_cube_map */
-#ifdef GL_EXT_texture_edge_clamp
- GLEW_EXT_texture_edge_clamp = _glewSearchExtension("GL_EXT_texture_edge_clamp", extStart, extEnd);
-#endif /* GL_EXT_texture_edge_clamp */
-#ifdef GL_EXT_texture_env
- GLEW_EXT_texture_env = _glewSearchExtension("GL_EXT_texture_env", extStart, extEnd);
-#endif /* GL_EXT_texture_env */
-#ifdef GL_EXT_texture_env_add
- GLEW_EXT_texture_env_add = _glewSearchExtension("GL_EXT_texture_env_add", extStart, extEnd);
-#endif /* GL_EXT_texture_env_add */
-#ifdef GL_EXT_texture_env_combine
- GLEW_EXT_texture_env_combine = _glewSearchExtension("GL_EXT_texture_env_combine", extStart, extEnd);
-#endif /* GL_EXT_texture_env_combine */
-#ifdef GL_EXT_texture_env_dot3
- GLEW_EXT_texture_env_dot3 = _glewSearchExtension("GL_EXT_texture_env_dot3", extStart, extEnd);
-#endif /* GL_EXT_texture_env_dot3 */
-#ifdef GL_EXT_texture_filter_anisotropic
- GLEW_EXT_texture_filter_anisotropic = _glewSearchExtension("GL_EXT_texture_filter_anisotropic", extStart, extEnd);
-#endif /* GL_EXT_texture_filter_anisotropic */
-#ifdef GL_EXT_texture_filter_minmax
- GLEW_EXT_texture_filter_minmax = _glewSearchExtension("GL_EXT_texture_filter_minmax", extStart, extEnd);
-#endif /* GL_EXT_texture_filter_minmax */
#ifdef GL_EXT_texture_integer
- GLEW_EXT_texture_integer = _glewSearchExtension("GL_EXT_texture_integer", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_texture_integer) GLEW_EXT_texture_integer = !_glewInit_GL_EXT_texture_integer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_texture_integer) GLEW_EXT_texture_integer = !_glewInit_GL_EXT_texture_integer();
#endif /* GL_EXT_texture_integer */
-#ifdef GL_EXT_texture_lod_bias
- GLEW_EXT_texture_lod_bias = _glewSearchExtension("GL_EXT_texture_lod_bias", extStart, extEnd);
-#endif /* GL_EXT_texture_lod_bias */
-#ifdef GL_EXT_texture_mirror_clamp
- GLEW_EXT_texture_mirror_clamp = _glewSearchExtension("GL_EXT_texture_mirror_clamp", extStart, extEnd);
-#endif /* GL_EXT_texture_mirror_clamp */
#ifdef GL_EXT_texture_object
- GLEW_EXT_texture_object = _glewSearchExtension("GL_EXT_texture_object", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_texture_object) GLEW_EXT_texture_object = !_glewInit_GL_EXT_texture_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_texture_object) GLEW_EXT_texture_object = !_glewInit_GL_EXT_texture_object();
#endif /* GL_EXT_texture_object */
#ifdef GL_EXT_texture_perturb_normal
- GLEW_EXT_texture_perturb_normal = _glewSearchExtension("GL_EXT_texture_perturb_normal", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_texture_perturb_normal) GLEW_EXT_texture_perturb_normal = !_glewInit_GL_EXT_texture_perturb_normal(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_texture_perturb_normal) GLEW_EXT_texture_perturb_normal = !_glewInit_GL_EXT_texture_perturb_normal();
#endif /* GL_EXT_texture_perturb_normal */
-#ifdef GL_EXT_texture_rectangle
- GLEW_EXT_texture_rectangle = _glewSearchExtension("GL_EXT_texture_rectangle", extStart, extEnd);
-#endif /* GL_EXT_texture_rectangle */
-#ifdef GL_EXT_texture_sRGB
- GLEW_EXT_texture_sRGB = _glewSearchExtension("GL_EXT_texture_sRGB", extStart, extEnd);
-#endif /* GL_EXT_texture_sRGB */
-#ifdef GL_EXT_texture_sRGB_decode
- GLEW_EXT_texture_sRGB_decode = _glewSearchExtension("GL_EXT_texture_sRGB_decode", extStart, extEnd);
-#endif /* GL_EXT_texture_sRGB_decode */
-#ifdef GL_EXT_texture_shared_exponent
- GLEW_EXT_texture_shared_exponent = _glewSearchExtension("GL_EXT_texture_shared_exponent", extStart, extEnd);
-#endif /* GL_EXT_texture_shared_exponent */
-#ifdef GL_EXT_texture_snorm
- GLEW_EXT_texture_snorm = _glewSearchExtension("GL_EXT_texture_snorm", extStart, extEnd);
-#endif /* GL_EXT_texture_snorm */
-#ifdef GL_EXT_texture_swizzle
- GLEW_EXT_texture_swizzle = _glewSearchExtension("GL_EXT_texture_swizzle", extStart, extEnd);
-#endif /* GL_EXT_texture_swizzle */
#ifdef GL_EXT_timer_query
- GLEW_EXT_timer_query = _glewSearchExtension("GL_EXT_timer_query", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_timer_query) GLEW_EXT_timer_query = !_glewInit_GL_EXT_timer_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_timer_query) GLEW_EXT_timer_query = !_glewInit_GL_EXT_timer_query();
#endif /* GL_EXT_timer_query */
#ifdef GL_EXT_transform_feedback
- GLEW_EXT_transform_feedback = _glewSearchExtension("GL_EXT_transform_feedback", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_transform_feedback) GLEW_EXT_transform_feedback = !_glewInit_GL_EXT_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_transform_feedback) GLEW_EXT_transform_feedback = !_glewInit_GL_EXT_transform_feedback();
#endif /* GL_EXT_transform_feedback */
#ifdef GL_EXT_vertex_array
- GLEW_EXT_vertex_array = _glewSearchExtension("GL_EXT_vertex_array", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_vertex_array) GLEW_EXT_vertex_array = !_glewInit_GL_EXT_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_vertex_array) GLEW_EXT_vertex_array = !_glewInit_GL_EXT_vertex_array();
#endif /* GL_EXT_vertex_array */
-#ifdef GL_EXT_vertex_array_bgra
- GLEW_EXT_vertex_array_bgra = _glewSearchExtension("GL_EXT_vertex_array_bgra", extStart, extEnd);
-#endif /* GL_EXT_vertex_array_bgra */
#ifdef GL_EXT_vertex_attrib_64bit
- GLEW_EXT_vertex_attrib_64bit = _glewSearchExtension("GL_EXT_vertex_attrib_64bit", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_vertex_attrib_64bit) GLEW_EXT_vertex_attrib_64bit = !_glewInit_GL_EXT_vertex_attrib_64bit(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_vertex_attrib_64bit) GLEW_EXT_vertex_attrib_64bit = !_glewInit_GL_EXT_vertex_attrib_64bit();
#endif /* GL_EXT_vertex_attrib_64bit */
#ifdef GL_EXT_vertex_shader
- GLEW_EXT_vertex_shader = _glewSearchExtension("GL_EXT_vertex_shader", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_vertex_shader) GLEW_EXT_vertex_shader = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_vertex_shader) GLEW_EXT_vertex_shader = !_glewInit_GL_EXT_vertex_shader();
#endif /* GL_EXT_vertex_shader */
#ifdef GL_EXT_vertex_weighting
- GLEW_EXT_vertex_weighting = _glewSearchExtension("GL_EXT_vertex_weighting", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_vertex_weighting) GLEW_EXT_vertex_weighting = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_vertex_weighting) GLEW_EXT_vertex_weighting = !_glewInit_GL_EXT_vertex_weighting();
#endif /* GL_EXT_vertex_weighting */
+#ifdef GL_EXT_window_rectangles
+ if (glewExperimental || GLEW_EXT_window_rectangles) GLEW_EXT_window_rectangles = !_glewInit_GL_EXT_window_rectangles();
+#endif /* GL_EXT_window_rectangles */
#ifdef GL_EXT_x11_sync_object
- GLEW_EXT_x11_sync_object = _glewSearchExtension("GL_EXT_x11_sync_object", extStart, extEnd);
- if (glewExperimental || GLEW_EXT_x11_sync_object) GLEW_EXT_x11_sync_object = !_glewInit_GL_EXT_x11_sync_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_EXT_x11_sync_object) GLEW_EXT_x11_sync_object = !_glewInit_GL_EXT_x11_sync_object();
#endif /* GL_EXT_x11_sync_object */
#ifdef GL_GREMEDY_frame_terminator
- GLEW_GREMEDY_frame_terminator = _glewSearchExtension("GL_GREMEDY_frame_terminator", extStart, extEnd);
- if (glewExperimental || GLEW_GREMEDY_frame_terminator) GLEW_GREMEDY_frame_terminator = !_glewInit_GL_GREMEDY_frame_terminator(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_GREMEDY_frame_terminator) GLEW_GREMEDY_frame_terminator = !_glewInit_GL_GREMEDY_frame_terminator();
#endif /* GL_GREMEDY_frame_terminator */
#ifdef GL_GREMEDY_string_marker
- GLEW_GREMEDY_string_marker = _glewSearchExtension("GL_GREMEDY_string_marker", extStart, extEnd);
- if (glewExperimental || GLEW_GREMEDY_string_marker) GLEW_GREMEDY_string_marker = !_glewInit_GL_GREMEDY_string_marker(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_GREMEDY_string_marker) GLEW_GREMEDY_string_marker = !_glewInit_GL_GREMEDY_string_marker();
#endif /* GL_GREMEDY_string_marker */
-#ifdef GL_HP_convolution_border_modes
- GLEW_HP_convolution_border_modes = _glewSearchExtension("GL_HP_convolution_border_modes", extStart, extEnd);
-#endif /* GL_HP_convolution_border_modes */
#ifdef GL_HP_image_transform
- GLEW_HP_image_transform = _glewSearchExtension("GL_HP_image_transform", extStart, extEnd);
- if (glewExperimental || GLEW_HP_image_transform) GLEW_HP_image_transform = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_HP_image_transform) GLEW_HP_image_transform = !_glewInit_GL_HP_image_transform();
#endif /* GL_HP_image_transform */
-#ifdef GL_HP_occlusion_test
- GLEW_HP_occlusion_test = _glewSearchExtension("GL_HP_occlusion_test", extStart, extEnd);
-#endif /* GL_HP_occlusion_test */
-#ifdef GL_HP_texture_lighting
- GLEW_HP_texture_lighting = _glewSearchExtension("GL_HP_texture_lighting", extStart, extEnd);
-#endif /* GL_HP_texture_lighting */
-#ifdef GL_IBM_cull_vertex
- GLEW_IBM_cull_vertex = _glewSearchExtension("GL_IBM_cull_vertex", extStart, extEnd);
-#endif /* GL_IBM_cull_vertex */
#ifdef GL_IBM_multimode_draw_arrays
- GLEW_IBM_multimode_draw_arrays = _glewSearchExtension("GL_IBM_multimode_draw_arrays", extStart, extEnd);
- if (glewExperimental || GLEW_IBM_multimode_draw_arrays) GLEW_IBM_multimode_draw_arrays = !_glewInit_GL_IBM_multimode_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_IBM_multimode_draw_arrays) GLEW_IBM_multimode_draw_arrays = !_glewInit_GL_IBM_multimode_draw_arrays();
#endif /* GL_IBM_multimode_draw_arrays */
-#ifdef GL_IBM_rasterpos_clip
- GLEW_IBM_rasterpos_clip = _glewSearchExtension("GL_IBM_rasterpos_clip", extStart, extEnd);
-#endif /* GL_IBM_rasterpos_clip */
-#ifdef GL_IBM_static_data
- GLEW_IBM_static_data = _glewSearchExtension("GL_IBM_static_data", extStart, extEnd);
-#endif /* GL_IBM_static_data */
-#ifdef GL_IBM_texture_mirrored_repeat
- GLEW_IBM_texture_mirrored_repeat = _glewSearchExtension("GL_IBM_texture_mirrored_repeat", extStart, extEnd);
-#endif /* GL_IBM_texture_mirrored_repeat */
#ifdef GL_IBM_vertex_array_lists
- GLEW_IBM_vertex_array_lists = _glewSearchExtension("GL_IBM_vertex_array_lists", extStart, extEnd);
- if (glewExperimental || GLEW_IBM_vertex_array_lists) GLEW_IBM_vertex_array_lists = !_glewInit_GL_IBM_vertex_array_lists(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_IBM_vertex_array_lists) GLEW_IBM_vertex_array_lists = !_glewInit_GL_IBM_vertex_array_lists();
#endif /* GL_IBM_vertex_array_lists */
-#ifdef GL_INGR_color_clamp
- GLEW_INGR_color_clamp = _glewSearchExtension("GL_INGR_color_clamp", extStart, extEnd);
-#endif /* GL_INGR_color_clamp */
-#ifdef GL_INGR_interlace_read
- GLEW_INGR_interlace_read = _glewSearchExtension("GL_INGR_interlace_read", extStart, extEnd);
-#endif /* GL_INGR_interlace_read */
-#ifdef GL_INTEL_fragment_shader_ordering
- GLEW_INTEL_fragment_shader_ordering = _glewSearchExtension("GL_INTEL_fragment_shader_ordering", extStart, extEnd);
-#endif /* GL_INTEL_fragment_shader_ordering */
-#ifdef GL_INTEL_framebuffer_CMAA
- GLEW_INTEL_framebuffer_CMAA = _glewSearchExtension("GL_INTEL_framebuffer_CMAA", extStart, extEnd);
-#endif /* GL_INTEL_framebuffer_CMAA */
#ifdef GL_INTEL_map_texture
- GLEW_INTEL_map_texture = _glewSearchExtension("GL_INTEL_map_texture", extStart, extEnd);
- if (glewExperimental || GLEW_INTEL_map_texture) GLEW_INTEL_map_texture = !_glewInit_GL_INTEL_map_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_INTEL_map_texture) GLEW_INTEL_map_texture = !_glewInit_GL_INTEL_map_texture();
#endif /* GL_INTEL_map_texture */
#ifdef GL_INTEL_parallel_arrays
- GLEW_INTEL_parallel_arrays = _glewSearchExtension("GL_INTEL_parallel_arrays", extStart, extEnd);
- if (glewExperimental || GLEW_INTEL_parallel_arrays) GLEW_INTEL_parallel_arrays = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_INTEL_parallel_arrays) GLEW_INTEL_parallel_arrays = !_glewInit_GL_INTEL_parallel_arrays();
#endif /* GL_INTEL_parallel_arrays */
#ifdef GL_INTEL_performance_query
- GLEW_INTEL_performance_query = _glewSearchExtension("GL_INTEL_performance_query", extStart, extEnd);
- if (glewExperimental || GLEW_INTEL_performance_query) GLEW_INTEL_performance_query = !_glewInit_GL_INTEL_performance_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_INTEL_performance_query) GLEW_INTEL_performance_query = !_glewInit_GL_INTEL_performance_query();
#endif /* GL_INTEL_performance_query */
#ifdef GL_INTEL_texture_scissor
- GLEW_INTEL_texture_scissor = _glewSearchExtension("GL_INTEL_texture_scissor", extStart, extEnd);
- if (glewExperimental || GLEW_INTEL_texture_scissor) GLEW_INTEL_texture_scissor = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_INTEL_texture_scissor) GLEW_INTEL_texture_scissor = !_glewInit_GL_INTEL_texture_scissor();
#endif /* GL_INTEL_texture_scissor */
#ifdef GL_KHR_blend_equation_advanced
- GLEW_KHR_blend_equation_advanced = _glewSearchExtension("GL_KHR_blend_equation_advanced", extStart, extEnd);
- if (glewExperimental || GLEW_KHR_blend_equation_advanced) GLEW_KHR_blend_equation_advanced = !_glewInit_GL_KHR_blend_equation_advanced(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_KHR_blend_equation_advanced) GLEW_KHR_blend_equation_advanced = !_glewInit_GL_KHR_blend_equation_advanced();
#endif /* GL_KHR_blend_equation_advanced */
-#ifdef GL_KHR_blend_equation_advanced_coherent
- GLEW_KHR_blend_equation_advanced_coherent = _glewSearchExtension("GL_KHR_blend_equation_advanced_coherent", extStart, extEnd);
-#endif /* GL_KHR_blend_equation_advanced_coherent */
-#ifdef GL_KHR_context_flush_control
- GLEW_KHR_context_flush_control = _glewSearchExtension("GL_KHR_context_flush_control", extStart, extEnd);
-#endif /* GL_KHR_context_flush_control */
#ifdef GL_KHR_debug
- GLEW_KHR_debug = _glewSearchExtension("GL_KHR_debug", extStart, extEnd);
- if (glewExperimental || GLEW_KHR_debug) GLEW_KHR_debug = !_glewInit_GL_KHR_debug(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_KHR_debug) GLEW_KHR_debug = !_glewInit_GL_KHR_debug();
#endif /* GL_KHR_debug */
-#ifdef GL_KHR_no_error
- GLEW_KHR_no_error = _glewSearchExtension("GL_KHR_no_error", extStart, extEnd);
-#endif /* GL_KHR_no_error */
-#ifdef GL_KHR_robust_buffer_access_behavior
- GLEW_KHR_robust_buffer_access_behavior = _glewSearchExtension("GL_KHR_robust_buffer_access_behavior", extStart, extEnd);
-#endif /* GL_KHR_robust_buffer_access_behavior */
#ifdef GL_KHR_robustness
- GLEW_KHR_robustness = _glewSearchExtension("GL_KHR_robustness", extStart, extEnd);
- if (glewExperimental || GLEW_KHR_robustness) GLEW_KHR_robustness = !_glewInit_GL_KHR_robustness(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_KHR_robustness) GLEW_KHR_robustness = !_glewInit_GL_KHR_robustness();
#endif /* GL_KHR_robustness */
-#ifdef GL_KHR_texture_compression_astc_hdr
- GLEW_KHR_texture_compression_astc_hdr = _glewSearchExtension("GL_KHR_texture_compression_astc_hdr", extStart, extEnd);
-#endif /* GL_KHR_texture_compression_astc_hdr */
-#ifdef GL_KHR_texture_compression_astc_ldr
- GLEW_KHR_texture_compression_astc_ldr = _glewSearchExtension("GL_KHR_texture_compression_astc_ldr", extStart, extEnd);
-#endif /* GL_KHR_texture_compression_astc_ldr */
#ifdef GL_KTX_buffer_region
- GLEW_KTX_buffer_region = _glewSearchExtension("GL_KTX_buffer_region", extStart, extEnd);
- if (glewExperimental || GLEW_KTX_buffer_region) GLEW_KTX_buffer_region = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_KTX_buffer_region) GLEW_KTX_buffer_region = !_glewInit_GL_KTX_buffer_region();
#endif /* GL_KTX_buffer_region */
-#ifdef GL_MESAX_texture_stack
- GLEW_MESAX_texture_stack = _glewSearchExtension("GL_MESAX_texture_stack", extStart, extEnd);
-#endif /* GL_MESAX_texture_stack */
-#ifdef GL_MESA_pack_invert
- GLEW_MESA_pack_invert = _glewSearchExtension("GL_MESA_pack_invert", extStart, extEnd);
-#endif /* GL_MESA_pack_invert */
#ifdef GL_MESA_resize_buffers
- GLEW_MESA_resize_buffers = _glewSearchExtension("GL_MESA_resize_buffers", extStart, extEnd);
- if (glewExperimental || GLEW_MESA_resize_buffers) GLEW_MESA_resize_buffers = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_MESA_resize_buffers) GLEW_MESA_resize_buffers = !_glewInit_GL_MESA_resize_buffers();
#endif /* GL_MESA_resize_buffers */
#ifdef GL_MESA_window_pos
- GLEW_MESA_window_pos = _glewSearchExtension("GL_MESA_window_pos", extStart, extEnd);
- if (glewExperimental || GLEW_MESA_window_pos) GLEW_MESA_window_pos = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_MESA_window_pos) GLEW_MESA_window_pos = !_glewInit_GL_MESA_window_pos();
#endif /* GL_MESA_window_pos */
-#ifdef GL_MESA_ycbcr_texture
- GLEW_MESA_ycbcr_texture = _glewSearchExtension("GL_MESA_ycbcr_texture", extStart, extEnd);
-#endif /* GL_MESA_ycbcr_texture */
#ifdef GL_NVX_conditional_render
- GLEW_NVX_conditional_render = _glewSearchExtension("GL_NVX_conditional_render", extStart, extEnd);
- if (glewExperimental || GLEW_NVX_conditional_render) GLEW_NVX_conditional_render = !_glewInit_GL_NVX_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NVX_conditional_render) GLEW_NVX_conditional_render = !_glewInit_GL_NVX_conditional_render();
#endif /* GL_NVX_conditional_render */
-#ifdef GL_NVX_gpu_memory_info
- GLEW_NVX_gpu_memory_info = _glewSearchExtension("GL_NVX_gpu_memory_info", extStart, extEnd);
-#endif /* GL_NVX_gpu_memory_info */
+#ifdef GL_NVX_linked_gpu_multicast
+ if (glewExperimental || GLEW_NVX_linked_gpu_multicast) GLEW_NVX_linked_gpu_multicast = !_glewInit_GL_NVX_linked_gpu_multicast();
+#endif /* GL_NVX_linked_gpu_multicast */
#ifdef GL_NV_bindless_multi_draw_indirect
- GLEW_NV_bindless_multi_draw_indirect = _glewSearchExtension("GL_NV_bindless_multi_draw_indirect", extStart, extEnd);
- if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect) GLEW_NV_bindless_multi_draw_indirect = !_glewInit_GL_NV_bindless_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect) GLEW_NV_bindless_multi_draw_indirect = !_glewInit_GL_NV_bindless_multi_draw_indirect();
#endif /* GL_NV_bindless_multi_draw_indirect */
#ifdef GL_NV_bindless_multi_draw_indirect_count
- GLEW_NV_bindless_multi_draw_indirect_count = _glewSearchExtension("GL_NV_bindless_multi_draw_indirect_count", extStart, extEnd);
- if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect_count) GLEW_NV_bindless_multi_draw_indirect_count = !_glewInit_GL_NV_bindless_multi_draw_indirect_count(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect_count) GLEW_NV_bindless_multi_draw_indirect_count = !_glewInit_GL_NV_bindless_multi_draw_indirect_count();
#endif /* GL_NV_bindless_multi_draw_indirect_count */
#ifdef GL_NV_bindless_texture
- GLEW_NV_bindless_texture = _glewSearchExtension("GL_NV_bindless_texture", extStart, extEnd);
- if (glewExperimental || GLEW_NV_bindless_texture) GLEW_NV_bindless_texture = !_glewInit_GL_NV_bindless_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_bindless_texture) GLEW_NV_bindless_texture = !_glewInit_GL_NV_bindless_texture();
#endif /* GL_NV_bindless_texture */
#ifdef GL_NV_blend_equation_advanced
- GLEW_NV_blend_equation_advanced = _glewSearchExtension("GL_NV_blend_equation_advanced", extStart, extEnd);
- if (glewExperimental || GLEW_NV_blend_equation_advanced) GLEW_NV_blend_equation_advanced = !_glewInit_GL_NV_blend_equation_advanced(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_blend_equation_advanced) GLEW_NV_blend_equation_advanced = !_glewInit_GL_NV_blend_equation_advanced();
#endif /* GL_NV_blend_equation_advanced */
-#ifdef GL_NV_blend_equation_advanced_coherent
- GLEW_NV_blend_equation_advanced_coherent = _glewSearchExtension("GL_NV_blend_equation_advanced_coherent", extStart, extEnd);
-#endif /* GL_NV_blend_equation_advanced_coherent */
-#ifdef GL_NV_blend_square
- GLEW_NV_blend_square = _glewSearchExtension("GL_NV_blend_square", extStart, extEnd);
-#endif /* GL_NV_blend_square */
-#ifdef GL_NV_compute_program5
- GLEW_NV_compute_program5 = _glewSearchExtension("GL_NV_compute_program5", extStart, extEnd);
-#endif /* GL_NV_compute_program5 */
+#ifdef GL_NV_clip_space_w_scaling
+ if (glewExperimental || GLEW_NV_clip_space_w_scaling) GLEW_NV_clip_space_w_scaling = !_glewInit_GL_NV_clip_space_w_scaling();
+#endif /* GL_NV_clip_space_w_scaling */
+#ifdef GL_NV_command_list
+ if (glewExperimental || GLEW_NV_command_list) GLEW_NV_command_list = !_glewInit_GL_NV_command_list();
+#endif /* GL_NV_command_list */
#ifdef GL_NV_conditional_render
- GLEW_NV_conditional_render = _glewSearchExtension("GL_NV_conditional_render", extStart, extEnd);
- if (glewExperimental || GLEW_NV_conditional_render) GLEW_NV_conditional_render = !_glewInit_GL_NV_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_conditional_render) GLEW_NV_conditional_render = !_glewInit_GL_NV_conditional_render();
#endif /* GL_NV_conditional_render */
#ifdef GL_NV_conservative_raster
- GLEW_NV_conservative_raster = _glewSearchExtension("GL_NV_conservative_raster", extStart, extEnd);
- if (glewExperimental || GLEW_NV_conservative_raster) GLEW_NV_conservative_raster = !_glewInit_GL_NV_conservative_raster(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_conservative_raster) GLEW_NV_conservative_raster = !_glewInit_GL_NV_conservative_raster();
#endif /* GL_NV_conservative_raster */
#ifdef GL_NV_conservative_raster_dilate
- GLEW_NV_conservative_raster_dilate = _glewSearchExtension("GL_NV_conservative_raster_dilate", extStart, extEnd);
- if (glewExperimental || GLEW_NV_conservative_raster_dilate) GLEW_NV_conservative_raster_dilate = !_glewInit_GL_NV_conservative_raster_dilate(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_conservative_raster_dilate) GLEW_NV_conservative_raster_dilate = !_glewInit_GL_NV_conservative_raster_dilate();
#endif /* GL_NV_conservative_raster_dilate */
-#ifdef GL_NV_copy_depth_to_color
- GLEW_NV_copy_depth_to_color = _glewSearchExtension("GL_NV_copy_depth_to_color", extStart, extEnd);
-#endif /* GL_NV_copy_depth_to_color */
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ if (glewExperimental || GLEW_NV_conservative_raster_pre_snap_triangles) GLEW_NV_conservative_raster_pre_snap_triangles = !_glewInit_GL_NV_conservative_raster_pre_snap_triangles();
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
#ifdef GL_NV_copy_image
- GLEW_NV_copy_image = _glewSearchExtension("GL_NV_copy_image", extStart, extEnd);
- if (glewExperimental || GLEW_NV_copy_image) GLEW_NV_copy_image = !_glewInit_GL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_copy_image) GLEW_NV_copy_image = !_glewInit_GL_NV_copy_image();
#endif /* GL_NV_copy_image */
-#ifdef GL_NV_deep_texture3D
- GLEW_NV_deep_texture3D = _glewSearchExtension("GL_NV_deep_texture3D", extStart, extEnd);
-#endif /* GL_NV_deep_texture3D */
#ifdef GL_NV_depth_buffer_float
- GLEW_NV_depth_buffer_float = _glewSearchExtension("GL_NV_depth_buffer_float", extStart, extEnd);
- if (glewExperimental || GLEW_NV_depth_buffer_float) GLEW_NV_depth_buffer_float = !_glewInit_GL_NV_depth_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_depth_buffer_float) GLEW_NV_depth_buffer_float = !_glewInit_GL_NV_depth_buffer_float();
#endif /* GL_NV_depth_buffer_float */
-#ifdef GL_NV_depth_clamp
- GLEW_NV_depth_clamp = _glewSearchExtension("GL_NV_depth_clamp", extStart, extEnd);
-#endif /* GL_NV_depth_clamp */
-#ifdef GL_NV_depth_range_unclamped
- GLEW_NV_depth_range_unclamped = _glewSearchExtension("GL_NV_depth_range_unclamped", extStart, extEnd);
-#endif /* GL_NV_depth_range_unclamped */
#ifdef GL_NV_draw_texture
- GLEW_NV_draw_texture = _glewSearchExtension("GL_NV_draw_texture", extStart, extEnd);
- if (glewExperimental || GLEW_NV_draw_texture) GLEW_NV_draw_texture = !_glewInit_GL_NV_draw_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_draw_texture) GLEW_NV_draw_texture = !_glewInit_GL_NV_draw_texture();
#endif /* GL_NV_draw_texture */
+#ifdef GL_NV_draw_vulkan_image
+ if (glewExperimental || GLEW_NV_draw_vulkan_image) GLEW_NV_draw_vulkan_image = !_glewInit_GL_NV_draw_vulkan_image();
+#endif /* GL_NV_draw_vulkan_image */
#ifdef GL_NV_evaluators
- GLEW_NV_evaluators = _glewSearchExtension("GL_NV_evaluators", extStart, extEnd);
- if (glewExperimental || GLEW_NV_evaluators) GLEW_NV_evaluators = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_evaluators) GLEW_NV_evaluators = !_glewInit_GL_NV_evaluators();
#endif /* GL_NV_evaluators */
#ifdef GL_NV_explicit_multisample
- GLEW_NV_explicit_multisample = _glewSearchExtension("GL_NV_explicit_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_NV_explicit_multisample) GLEW_NV_explicit_multisample = !_glewInit_GL_NV_explicit_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_explicit_multisample) GLEW_NV_explicit_multisample = !_glewInit_GL_NV_explicit_multisample();
#endif /* GL_NV_explicit_multisample */
#ifdef GL_NV_fence
- GLEW_NV_fence = _glewSearchExtension("GL_NV_fence", extStart, extEnd);
- if (glewExperimental || GLEW_NV_fence) GLEW_NV_fence = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_fence) GLEW_NV_fence = !_glewInit_GL_NV_fence();
#endif /* GL_NV_fence */
-#ifdef GL_NV_fill_rectangle
- GLEW_NV_fill_rectangle = _glewSearchExtension("GL_NV_fill_rectangle", extStart, extEnd);
-#endif /* GL_NV_fill_rectangle */
-#ifdef GL_NV_float_buffer
- GLEW_NV_float_buffer = _glewSearchExtension("GL_NV_float_buffer", extStart, extEnd);
-#endif /* GL_NV_float_buffer */
-#ifdef GL_NV_fog_distance
- GLEW_NV_fog_distance = _glewSearchExtension("GL_NV_fog_distance", extStart, extEnd);
-#endif /* GL_NV_fog_distance */
#ifdef GL_NV_fragment_coverage_to_color
- GLEW_NV_fragment_coverage_to_color = _glewSearchExtension("GL_NV_fragment_coverage_to_color", extStart, extEnd);
- if (glewExperimental || GLEW_NV_fragment_coverage_to_color) GLEW_NV_fragment_coverage_to_color = !_glewInit_GL_NV_fragment_coverage_to_color(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_fragment_coverage_to_color) GLEW_NV_fragment_coverage_to_color = !_glewInit_GL_NV_fragment_coverage_to_color();
#endif /* GL_NV_fragment_coverage_to_color */
#ifdef GL_NV_fragment_program
- GLEW_NV_fragment_program = _glewSearchExtension("GL_NV_fragment_program", extStart, extEnd);
- if (glewExperimental || GLEW_NV_fragment_program) GLEW_NV_fragment_program = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_fragment_program) GLEW_NV_fragment_program = !_glewInit_GL_NV_fragment_program();
#endif /* GL_NV_fragment_program */
-#ifdef GL_NV_fragment_program2
- GLEW_NV_fragment_program2 = _glewSearchExtension("GL_NV_fragment_program2", extStart, extEnd);
-#endif /* GL_NV_fragment_program2 */
-#ifdef GL_NV_fragment_program4
- GLEW_NV_fragment_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
-#endif /* GL_NV_fragment_program4 */
-#ifdef GL_NV_fragment_program_option
- GLEW_NV_fragment_program_option = _glewSearchExtension("GL_NV_fragment_program_option", extStart, extEnd);
-#endif /* GL_NV_fragment_program_option */
-#ifdef GL_NV_fragment_shader_interlock
- GLEW_NV_fragment_shader_interlock = _glewSearchExtension("GL_NV_fragment_shader_interlock", extStart, extEnd);
-#endif /* GL_NV_fragment_shader_interlock */
-#ifdef GL_NV_framebuffer_mixed_samples
- GLEW_NV_framebuffer_mixed_samples = _glewSearchExtension("GL_NV_framebuffer_mixed_samples", extStart, extEnd);
-#endif /* GL_NV_framebuffer_mixed_samples */
#ifdef GL_NV_framebuffer_multisample_coverage
- GLEW_NV_framebuffer_multisample_coverage = _glewSearchExtension("GL_NV_framebuffer_multisample_coverage", extStart, extEnd);
- if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) GLEW_NV_framebuffer_multisample_coverage = !_glewInit_GL_NV_framebuffer_multisample_coverage(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) GLEW_NV_framebuffer_multisample_coverage = !_glewInit_GL_NV_framebuffer_multisample_coverage();
#endif /* GL_NV_framebuffer_multisample_coverage */
#ifdef GL_NV_geometry_program4
- GLEW_NV_geometry_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
- if (glewExperimental || GLEW_NV_geometry_program4) GLEW_NV_geometry_program4 = !_glewInit_GL_NV_geometry_program4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_geometry_program4) GLEW_NV_geometry_program4 = !_glewInit_GL_NV_geometry_program4();
#endif /* GL_NV_geometry_program4 */
-#ifdef GL_NV_geometry_shader4
- GLEW_NV_geometry_shader4 = _glewSearchExtension("GL_NV_geometry_shader4", extStart, extEnd);
-#endif /* GL_NV_geometry_shader4 */
-#ifdef GL_NV_geometry_shader_passthrough
- GLEW_NV_geometry_shader_passthrough = _glewSearchExtension("GL_NV_geometry_shader_passthrough", extStart, extEnd);
-#endif /* GL_NV_geometry_shader_passthrough */
+#ifdef GL_NV_gpu_multicast
+ if (glewExperimental || GLEW_NV_gpu_multicast) GLEW_NV_gpu_multicast = !_glewInit_GL_NV_gpu_multicast();
+#endif /* GL_NV_gpu_multicast */
#ifdef GL_NV_gpu_program4
- GLEW_NV_gpu_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
- if (glewExperimental || GLEW_NV_gpu_program4) GLEW_NV_gpu_program4 = !_glewInit_GL_NV_gpu_program4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_gpu_program4) GLEW_NV_gpu_program4 = !_glewInit_GL_NV_gpu_program4();
#endif /* GL_NV_gpu_program4 */
-#ifdef GL_NV_gpu_program5
- GLEW_NV_gpu_program5 = _glewSearchExtension("GL_NV_gpu_program5", extStart, extEnd);
-#endif /* GL_NV_gpu_program5 */
-#ifdef GL_NV_gpu_program5_mem_extended
- GLEW_NV_gpu_program5_mem_extended = _glewSearchExtension("GL_NV_gpu_program5_mem_extended", extStart, extEnd);
-#endif /* GL_NV_gpu_program5_mem_extended */
-#ifdef GL_NV_gpu_program_fp64
- GLEW_NV_gpu_program_fp64 = _glewSearchExtension("GL_NV_gpu_program_fp64", extStart, extEnd);
-#endif /* GL_NV_gpu_program_fp64 */
#ifdef GL_NV_gpu_shader5
- GLEW_NV_gpu_shader5 = _glewSearchExtension("GL_NV_gpu_shader5", extStart, extEnd);
- if (glewExperimental || GLEW_NV_gpu_shader5) GLEW_NV_gpu_shader5 = !_glewInit_GL_NV_gpu_shader5(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_gpu_shader5) GLEW_NV_gpu_shader5 = !_glewInit_GL_NV_gpu_shader5();
#endif /* GL_NV_gpu_shader5 */
#ifdef GL_NV_half_float
- GLEW_NV_half_float = _glewSearchExtension("GL_NV_half_float", extStart, extEnd);
- if (glewExperimental || GLEW_NV_half_float) GLEW_NV_half_float = !_glewInit_GL_NV_half_float(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_half_float) GLEW_NV_half_float = !_glewInit_GL_NV_half_float();
#endif /* GL_NV_half_float */
#ifdef GL_NV_internalformat_sample_query
- GLEW_NV_internalformat_sample_query = _glewSearchExtension("GL_NV_internalformat_sample_query", extStart, extEnd);
- if (glewExperimental || GLEW_NV_internalformat_sample_query) GLEW_NV_internalformat_sample_query = !_glewInit_GL_NV_internalformat_sample_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_internalformat_sample_query) GLEW_NV_internalformat_sample_query = !_glewInit_GL_NV_internalformat_sample_query();
#endif /* GL_NV_internalformat_sample_query */
-#ifdef GL_NV_light_max_exponent
- GLEW_NV_light_max_exponent = _glewSearchExtension("GL_NV_light_max_exponent", extStart, extEnd);
-#endif /* GL_NV_light_max_exponent */
-#ifdef GL_NV_multisample_coverage
- GLEW_NV_multisample_coverage = _glewSearchExtension("GL_NV_multisample_coverage", extStart, extEnd);
-#endif /* GL_NV_multisample_coverage */
-#ifdef GL_NV_multisample_filter_hint
- GLEW_NV_multisample_filter_hint = _glewSearchExtension("GL_NV_multisample_filter_hint", extStart, extEnd);
-#endif /* GL_NV_multisample_filter_hint */
#ifdef GL_NV_occlusion_query
- GLEW_NV_occlusion_query = _glewSearchExtension("GL_NV_occlusion_query", extStart, extEnd);
- if (glewExperimental || GLEW_NV_occlusion_query) GLEW_NV_occlusion_query = !_glewInit_GL_NV_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_occlusion_query) GLEW_NV_occlusion_query = !_glewInit_GL_NV_occlusion_query();
#endif /* GL_NV_occlusion_query */
-#ifdef GL_NV_packed_depth_stencil
- GLEW_NV_packed_depth_stencil = _glewSearchExtension("GL_NV_packed_depth_stencil", extStart, extEnd);
-#endif /* GL_NV_packed_depth_stencil */
#ifdef GL_NV_parameter_buffer_object
- GLEW_NV_parameter_buffer_object = _glewSearchExtension("GL_NV_parameter_buffer_object", extStart, extEnd);
- if (glewExperimental || GLEW_NV_parameter_buffer_object) GLEW_NV_parameter_buffer_object = !_glewInit_GL_NV_parameter_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_parameter_buffer_object) GLEW_NV_parameter_buffer_object = !_glewInit_GL_NV_parameter_buffer_object();
#endif /* GL_NV_parameter_buffer_object */
-#ifdef GL_NV_parameter_buffer_object2
- GLEW_NV_parameter_buffer_object2 = _glewSearchExtension("GL_NV_parameter_buffer_object2", extStart, extEnd);
-#endif /* GL_NV_parameter_buffer_object2 */
#ifdef GL_NV_path_rendering
- GLEW_NV_path_rendering = _glewSearchExtension("GL_NV_path_rendering", extStart, extEnd);
- if (glewExperimental || GLEW_NV_path_rendering) GLEW_NV_path_rendering = !_glewInit_GL_NV_path_rendering(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_path_rendering) GLEW_NV_path_rendering = !_glewInit_GL_NV_path_rendering();
#endif /* GL_NV_path_rendering */
-#ifdef GL_NV_path_rendering_shared_edge
- GLEW_NV_path_rendering_shared_edge = _glewSearchExtension("GL_NV_path_rendering_shared_edge", extStart, extEnd);
-#endif /* GL_NV_path_rendering_shared_edge */
#ifdef GL_NV_pixel_data_range
- GLEW_NV_pixel_data_range = _glewSearchExtension("GL_NV_pixel_data_range", extStart, extEnd);
- if (glewExperimental || GLEW_NV_pixel_data_range) GLEW_NV_pixel_data_range = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_pixel_data_range) GLEW_NV_pixel_data_range = !_glewInit_GL_NV_pixel_data_range();
#endif /* GL_NV_pixel_data_range */
#ifdef GL_NV_point_sprite
- GLEW_NV_point_sprite = _glewSearchExtension("GL_NV_point_sprite", extStart, extEnd);
- if (glewExperimental || GLEW_NV_point_sprite) GLEW_NV_point_sprite = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_point_sprite) GLEW_NV_point_sprite = !_glewInit_GL_NV_point_sprite();
#endif /* GL_NV_point_sprite */
#ifdef GL_NV_present_video
- GLEW_NV_present_video = _glewSearchExtension("GL_NV_present_video", extStart, extEnd);
- if (glewExperimental || GLEW_NV_present_video) GLEW_NV_present_video = !_glewInit_GL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_present_video) GLEW_NV_present_video = !_glewInit_GL_NV_present_video();
#endif /* GL_NV_present_video */
#ifdef GL_NV_primitive_restart
- GLEW_NV_primitive_restart = _glewSearchExtension("GL_NV_primitive_restart", extStart, extEnd);
- if (glewExperimental || GLEW_NV_primitive_restart) GLEW_NV_primitive_restart = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_primitive_restart) GLEW_NV_primitive_restart = !_glewInit_GL_NV_primitive_restart();
#endif /* GL_NV_primitive_restart */
#ifdef GL_NV_register_combiners
- GLEW_NV_register_combiners = _glewSearchExtension("GL_NV_register_combiners", extStart, extEnd);
- if (glewExperimental || GLEW_NV_register_combiners) GLEW_NV_register_combiners = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_register_combiners) GLEW_NV_register_combiners = !_glewInit_GL_NV_register_combiners();
#endif /* GL_NV_register_combiners */
#ifdef GL_NV_register_combiners2
- GLEW_NV_register_combiners2 = _glewSearchExtension("GL_NV_register_combiners2", extStart, extEnd);
- if (glewExperimental || GLEW_NV_register_combiners2) GLEW_NV_register_combiners2 = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_register_combiners2) GLEW_NV_register_combiners2 = !_glewInit_GL_NV_register_combiners2();
#endif /* GL_NV_register_combiners2 */
#ifdef GL_NV_sample_locations
- GLEW_NV_sample_locations = _glewSearchExtension("GL_NV_sample_locations", extStart, extEnd);
- if (glewExperimental || GLEW_NV_sample_locations) GLEW_NV_sample_locations = !_glewInit_GL_NV_sample_locations(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_sample_locations) GLEW_NV_sample_locations = !_glewInit_GL_NV_sample_locations();
#endif /* GL_NV_sample_locations */
-#ifdef GL_NV_sample_mask_override_coverage
- GLEW_NV_sample_mask_override_coverage = _glewSearchExtension("GL_NV_sample_mask_override_coverage", extStart, extEnd);
-#endif /* GL_NV_sample_mask_override_coverage */
-#ifdef GL_NV_shader_atomic_counters
- GLEW_NV_shader_atomic_counters = _glewSearchExtension("GL_NV_shader_atomic_counters", extStart, extEnd);
-#endif /* GL_NV_shader_atomic_counters */
-#ifdef GL_NV_shader_atomic_float
- GLEW_NV_shader_atomic_float = _glewSearchExtension("GL_NV_shader_atomic_float", extStart, extEnd);
-#endif /* GL_NV_shader_atomic_float */
-#ifdef GL_NV_shader_atomic_fp16_vector
- GLEW_NV_shader_atomic_fp16_vector = _glewSearchExtension("GL_NV_shader_atomic_fp16_vector", extStart, extEnd);
-#endif /* GL_NV_shader_atomic_fp16_vector */
-#ifdef GL_NV_shader_atomic_int64
- GLEW_NV_shader_atomic_int64 = _glewSearchExtension("GL_NV_shader_atomic_int64", extStart, extEnd);
-#endif /* GL_NV_shader_atomic_int64 */
#ifdef GL_NV_shader_buffer_load
- GLEW_NV_shader_buffer_load = _glewSearchExtension("GL_NV_shader_buffer_load", extStart, extEnd);
- if (glewExperimental || GLEW_NV_shader_buffer_load) GLEW_NV_shader_buffer_load = !_glewInit_GL_NV_shader_buffer_load(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_shader_buffer_load) GLEW_NV_shader_buffer_load = !_glewInit_GL_NV_shader_buffer_load();
#endif /* GL_NV_shader_buffer_load */
-#ifdef GL_NV_shader_storage_buffer_object
- GLEW_NV_shader_storage_buffer_object = _glewSearchExtension("GL_NV_shader_storage_buffer_object", extStart, extEnd);
-#endif /* GL_NV_shader_storage_buffer_object */
-#ifdef GL_NV_shader_thread_group
- GLEW_NV_shader_thread_group = _glewSearchExtension("GL_NV_shader_thread_group", extStart, extEnd);
-#endif /* GL_NV_shader_thread_group */
-#ifdef GL_NV_shader_thread_shuffle
- GLEW_NV_shader_thread_shuffle = _glewSearchExtension("GL_NV_shader_thread_shuffle", extStart, extEnd);
-#endif /* GL_NV_shader_thread_shuffle */
-#ifdef GL_NV_tessellation_program5
- GLEW_NV_tessellation_program5 = _glewSearchExtension("GL_NV_gpu_program5", extStart, extEnd);
-#endif /* GL_NV_tessellation_program5 */
-#ifdef GL_NV_texgen_emboss
- GLEW_NV_texgen_emboss = _glewSearchExtension("GL_NV_texgen_emboss", extStart, extEnd);
-#endif /* GL_NV_texgen_emboss */
-#ifdef GL_NV_texgen_reflection
- GLEW_NV_texgen_reflection = _glewSearchExtension("GL_NV_texgen_reflection", extStart, extEnd);
-#endif /* GL_NV_texgen_reflection */
#ifdef GL_NV_texture_barrier
- GLEW_NV_texture_barrier = _glewSearchExtension("GL_NV_texture_barrier", extStart, extEnd);
- if (glewExperimental || GLEW_NV_texture_barrier) GLEW_NV_texture_barrier = !_glewInit_GL_NV_texture_barrier(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_texture_barrier) GLEW_NV_texture_barrier = !_glewInit_GL_NV_texture_barrier();
#endif /* GL_NV_texture_barrier */
-#ifdef GL_NV_texture_compression_vtc
- GLEW_NV_texture_compression_vtc = _glewSearchExtension("GL_NV_texture_compression_vtc", extStart, extEnd);
-#endif /* GL_NV_texture_compression_vtc */
-#ifdef GL_NV_texture_env_combine4
- GLEW_NV_texture_env_combine4 = _glewSearchExtension("GL_NV_texture_env_combine4", extStart, extEnd);
-#endif /* GL_NV_texture_env_combine4 */
-#ifdef GL_NV_texture_expand_normal
- GLEW_NV_texture_expand_normal = _glewSearchExtension("GL_NV_texture_expand_normal", extStart, extEnd);
-#endif /* GL_NV_texture_expand_normal */
#ifdef GL_NV_texture_multisample
- GLEW_NV_texture_multisample = _glewSearchExtension("GL_NV_texture_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_NV_texture_multisample) GLEW_NV_texture_multisample = !_glewInit_GL_NV_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_texture_multisample) GLEW_NV_texture_multisample = !_glewInit_GL_NV_texture_multisample();
#endif /* GL_NV_texture_multisample */
-#ifdef GL_NV_texture_rectangle
- GLEW_NV_texture_rectangle = _glewSearchExtension("GL_NV_texture_rectangle", extStart, extEnd);
-#endif /* GL_NV_texture_rectangle */
-#ifdef GL_NV_texture_shader
- GLEW_NV_texture_shader = _glewSearchExtension("GL_NV_texture_shader", extStart, extEnd);
-#endif /* GL_NV_texture_shader */
-#ifdef GL_NV_texture_shader2
- GLEW_NV_texture_shader2 = _glewSearchExtension("GL_NV_texture_shader2", extStart, extEnd);
-#endif /* GL_NV_texture_shader2 */
-#ifdef GL_NV_texture_shader3
- GLEW_NV_texture_shader3 = _glewSearchExtension("GL_NV_texture_shader3", extStart, extEnd);
-#endif /* GL_NV_texture_shader3 */
#ifdef GL_NV_transform_feedback
- GLEW_NV_transform_feedback = _glewSearchExtension("GL_NV_transform_feedback", extStart, extEnd);
- if (glewExperimental || GLEW_NV_transform_feedback) GLEW_NV_transform_feedback = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_transform_feedback) GLEW_NV_transform_feedback = !_glewInit_GL_NV_transform_feedback();
#endif /* GL_NV_transform_feedback */
#ifdef GL_NV_transform_feedback2
- GLEW_NV_transform_feedback2 = _glewSearchExtension("GL_NV_transform_feedback2", extStart, extEnd);
- if (glewExperimental || GLEW_NV_transform_feedback2) GLEW_NV_transform_feedback2 = !_glewInit_GL_NV_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_transform_feedback2) GLEW_NV_transform_feedback2 = !_glewInit_GL_NV_transform_feedback2();
#endif /* GL_NV_transform_feedback2 */
-#ifdef GL_NV_uniform_buffer_unified_memory
- GLEW_NV_uniform_buffer_unified_memory = _glewSearchExtension("GL_NV_uniform_buffer_unified_memory", extStart, extEnd);
-#endif /* GL_NV_uniform_buffer_unified_memory */
#ifdef GL_NV_vdpau_interop
- GLEW_NV_vdpau_interop = _glewSearchExtension("GL_NV_vdpau_interop", extStart, extEnd);
- if (glewExperimental || GLEW_NV_vdpau_interop) GLEW_NV_vdpau_interop = !_glewInit_GL_NV_vdpau_interop(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_vdpau_interop) GLEW_NV_vdpau_interop = !_glewInit_GL_NV_vdpau_interop();
#endif /* GL_NV_vdpau_interop */
#ifdef GL_NV_vertex_array_range
- GLEW_NV_vertex_array_range = _glewSearchExtension("GL_NV_vertex_array_range", extStart, extEnd);
- if (glewExperimental || GLEW_NV_vertex_array_range) GLEW_NV_vertex_array_range = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_vertex_array_range) GLEW_NV_vertex_array_range = !_glewInit_GL_NV_vertex_array_range();
#endif /* GL_NV_vertex_array_range */
-#ifdef GL_NV_vertex_array_range2
- GLEW_NV_vertex_array_range2 = _glewSearchExtension("GL_NV_vertex_array_range2", extStart, extEnd);
-#endif /* GL_NV_vertex_array_range2 */
#ifdef GL_NV_vertex_attrib_integer_64bit
- GLEW_NV_vertex_attrib_integer_64bit = _glewSearchExtension("GL_NV_vertex_attrib_integer_64bit", extStart, extEnd);
- if (glewExperimental || GLEW_NV_vertex_attrib_integer_64bit) GLEW_NV_vertex_attrib_integer_64bit = !_glewInit_GL_NV_vertex_attrib_integer_64bit(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_vertex_attrib_integer_64bit) GLEW_NV_vertex_attrib_integer_64bit = !_glewInit_GL_NV_vertex_attrib_integer_64bit();
#endif /* GL_NV_vertex_attrib_integer_64bit */
#ifdef GL_NV_vertex_buffer_unified_memory
- GLEW_NV_vertex_buffer_unified_memory = _glewSearchExtension("GL_NV_vertex_buffer_unified_memory", extStart, extEnd);
- if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) GLEW_NV_vertex_buffer_unified_memory = !_glewInit_GL_NV_vertex_buffer_unified_memory(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) GLEW_NV_vertex_buffer_unified_memory = !_glewInit_GL_NV_vertex_buffer_unified_memory();
#endif /* GL_NV_vertex_buffer_unified_memory */
#ifdef GL_NV_vertex_program
- GLEW_NV_vertex_program = _glewSearchExtension("GL_NV_vertex_program", extStart, extEnd);
- if (glewExperimental || GLEW_NV_vertex_program) GLEW_NV_vertex_program = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_vertex_program) GLEW_NV_vertex_program = !_glewInit_GL_NV_vertex_program();
#endif /* GL_NV_vertex_program */
-#ifdef GL_NV_vertex_program1_1
- GLEW_NV_vertex_program1_1 = _glewSearchExtension("GL_NV_vertex_program1_1", extStart, extEnd);
-#endif /* GL_NV_vertex_program1_1 */
-#ifdef GL_NV_vertex_program2
- GLEW_NV_vertex_program2 = _glewSearchExtension("GL_NV_vertex_program2", extStart, extEnd);
-#endif /* GL_NV_vertex_program2 */
-#ifdef GL_NV_vertex_program2_option
- GLEW_NV_vertex_program2_option = _glewSearchExtension("GL_NV_vertex_program2_option", extStart, extEnd);
-#endif /* GL_NV_vertex_program2_option */
-#ifdef GL_NV_vertex_program3
- GLEW_NV_vertex_program3 = _glewSearchExtension("GL_NV_vertex_program3", extStart, extEnd);
-#endif /* GL_NV_vertex_program3 */
-#ifdef GL_NV_vertex_program4
- GLEW_NV_vertex_program4 = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
-#endif /* GL_NV_vertex_program4 */
#ifdef GL_NV_video_capture
- GLEW_NV_video_capture = _glewSearchExtension("GL_NV_video_capture", extStart, extEnd);
- if (glewExperimental || GLEW_NV_video_capture) GLEW_NV_video_capture = !_glewInit_GL_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_NV_video_capture) GLEW_NV_video_capture = !_glewInit_GL_NV_video_capture();
#endif /* GL_NV_video_capture */
-#ifdef GL_NV_viewport_array2
- GLEW_NV_viewport_array2 = _glewSearchExtension("GL_NV_viewport_array2", extStart, extEnd);
-#endif /* GL_NV_viewport_array2 */
-#ifdef GL_OES_byte_coordinates
- GLEW_OES_byte_coordinates = _glewSearchExtension("GL_OES_byte_coordinates", extStart, extEnd);
-#endif /* GL_OES_byte_coordinates */
-#ifdef GL_OES_compressed_paletted_texture
- GLEW_OES_compressed_paletted_texture = _glewSearchExtension("GL_OES_compressed_paletted_texture", extStart, extEnd);
-#endif /* GL_OES_compressed_paletted_texture */
-#ifdef GL_OES_read_format
- GLEW_OES_read_format = _glewSearchExtension("GL_OES_read_format", extStart, extEnd);
-#endif /* GL_OES_read_format */
+#ifdef GL_NV_viewport_swizzle
+ if (glewExperimental || GLEW_NV_viewport_swizzle) GLEW_NV_viewport_swizzle = !_glewInit_GL_NV_viewport_swizzle();
+#endif /* GL_NV_viewport_swizzle */
#ifdef GL_OES_single_precision
- GLEW_OES_single_precision = _glewSearchExtension("GL_OES_single_precision", extStart, extEnd);
- if (glewExperimental || GLEW_OES_single_precision) GLEW_OES_single_precision = !_glewInit_GL_OES_single_precision(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_OES_single_precision) GLEW_OES_single_precision = !_glewInit_GL_OES_single_precision();
#endif /* GL_OES_single_precision */
-#ifdef GL_OML_interlace
- GLEW_OML_interlace = _glewSearchExtension("GL_OML_interlace", extStart, extEnd);
-#endif /* GL_OML_interlace */
-#ifdef GL_OML_resample
- GLEW_OML_resample = _glewSearchExtension("GL_OML_resample", extStart, extEnd);
-#endif /* GL_OML_resample */
-#ifdef GL_OML_subsample
- GLEW_OML_subsample = _glewSearchExtension("GL_OML_subsample", extStart, extEnd);
-#endif /* GL_OML_subsample */
#ifdef GL_OVR_multiview
- GLEW_OVR_multiview = _glewSearchExtension("GL_OVR_multiview", extStart, extEnd);
- if (glewExperimental || GLEW_OVR_multiview) GLEW_OVR_multiview = !_glewInit_GL_OVR_multiview(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_OVR_multiview) GLEW_OVR_multiview = !_glewInit_GL_OVR_multiview();
#endif /* GL_OVR_multiview */
-#ifdef GL_OVR_multiview2
- GLEW_OVR_multiview2 = _glewSearchExtension("GL_OVR_multiview2", extStart, extEnd);
-#endif /* GL_OVR_multiview2 */
-#ifdef GL_PGI_misc_hints
- GLEW_PGI_misc_hints = _glewSearchExtension("GL_PGI_misc_hints", extStart, extEnd);
-#endif /* GL_PGI_misc_hints */
-#ifdef GL_PGI_vertex_hints
- GLEW_PGI_vertex_hints = _glewSearchExtension("GL_PGI_vertex_hints", extStart, extEnd);
-#endif /* GL_PGI_vertex_hints */
#ifdef GL_REGAL_ES1_0_compatibility
- GLEW_REGAL_ES1_0_compatibility = _glewSearchExtension("GL_REGAL_ES1_0_compatibility", extStart, extEnd);
- if (glewExperimental || GLEW_REGAL_ES1_0_compatibility) GLEW_REGAL_ES1_0_compatibility = !_glewInit_GL_REGAL_ES1_0_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_REGAL_ES1_0_compatibility) GLEW_REGAL_ES1_0_compatibility = !_glewInit_GL_REGAL_ES1_0_compatibility();
#endif /* GL_REGAL_ES1_0_compatibility */
#ifdef GL_REGAL_ES1_1_compatibility
- GLEW_REGAL_ES1_1_compatibility = _glewSearchExtension("GL_REGAL_ES1_1_compatibility", extStart, extEnd);
- if (glewExperimental || GLEW_REGAL_ES1_1_compatibility) GLEW_REGAL_ES1_1_compatibility = !_glewInit_GL_REGAL_ES1_1_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_REGAL_ES1_1_compatibility) GLEW_REGAL_ES1_1_compatibility = !_glewInit_GL_REGAL_ES1_1_compatibility();
#endif /* GL_REGAL_ES1_1_compatibility */
-#ifdef GL_REGAL_enable
- GLEW_REGAL_enable = _glewSearchExtension("GL_REGAL_enable", extStart, extEnd);
-#endif /* GL_REGAL_enable */
#ifdef GL_REGAL_error_string
- GLEW_REGAL_error_string = _glewSearchExtension("GL_REGAL_error_string", extStart, extEnd);
- if (glewExperimental || GLEW_REGAL_error_string) GLEW_REGAL_error_string = !_glewInit_GL_REGAL_error_string(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_REGAL_error_string) GLEW_REGAL_error_string = !_glewInit_GL_REGAL_error_string();
#endif /* GL_REGAL_error_string */
#ifdef GL_REGAL_extension_query
- GLEW_REGAL_extension_query = _glewSearchExtension("GL_REGAL_extension_query", extStart, extEnd);
- if (glewExperimental || GLEW_REGAL_extension_query) GLEW_REGAL_extension_query = !_glewInit_GL_REGAL_extension_query(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_REGAL_extension_query) GLEW_REGAL_extension_query = !_glewInit_GL_REGAL_extension_query();
#endif /* GL_REGAL_extension_query */
#ifdef GL_REGAL_log
- GLEW_REGAL_log = _glewSearchExtension("GL_REGAL_log", extStart, extEnd);
- if (glewExperimental || GLEW_REGAL_log) GLEW_REGAL_log = !_glewInit_GL_REGAL_log(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_REGAL_log) GLEW_REGAL_log = !_glewInit_GL_REGAL_log();
#endif /* GL_REGAL_log */
#ifdef GL_REGAL_proc_address
- GLEW_REGAL_proc_address = _glewSearchExtension("GL_REGAL_proc_address", extStart, extEnd);
- if (glewExperimental || GLEW_REGAL_proc_address) GLEW_REGAL_proc_address = !_glewInit_GL_REGAL_proc_address(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_REGAL_proc_address) GLEW_REGAL_proc_address = !_glewInit_GL_REGAL_proc_address();
#endif /* GL_REGAL_proc_address */
-#ifdef GL_REND_screen_coordinates
- GLEW_REND_screen_coordinates = _glewSearchExtension("GL_REND_screen_coordinates", extStart, extEnd);
-#endif /* GL_REND_screen_coordinates */
-#ifdef GL_S3_s3tc
- GLEW_S3_s3tc = _glewSearchExtension("GL_S3_s3tc", extStart, extEnd);
-#endif /* GL_S3_s3tc */
-#ifdef GL_SGIS_color_range
- GLEW_SGIS_color_range = _glewSearchExtension("GL_SGIS_color_range", extStart, extEnd);
-#endif /* GL_SGIS_color_range */
#ifdef GL_SGIS_detail_texture
- GLEW_SGIS_detail_texture = _glewSearchExtension("GL_SGIS_detail_texture", extStart, extEnd);
- if (glewExperimental || GLEW_SGIS_detail_texture) GLEW_SGIS_detail_texture = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIS_detail_texture) GLEW_SGIS_detail_texture = !_glewInit_GL_SGIS_detail_texture();
#endif /* GL_SGIS_detail_texture */
#ifdef GL_SGIS_fog_function
- GLEW_SGIS_fog_function = _glewSearchExtension("GL_SGIS_fog_function", extStart, extEnd);
- if (glewExperimental || GLEW_SGIS_fog_function) GLEW_SGIS_fog_function = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIS_fog_function) GLEW_SGIS_fog_function = !_glewInit_GL_SGIS_fog_function();
#endif /* GL_SGIS_fog_function */
-#ifdef GL_SGIS_generate_mipmap
- GLEW_SGIS_generate_mipmap = _glewSearchExtension("GL_SGIS_generate_mipmap", extStart, extEnd);
-#endif /* GL_SGIS_generate_mipmap */
#ifdef GL_SGIS_multisample
- GLEW_SGIS_multisample = _glewSearchExtension("GL_SGIS_multisample", extStart, extEnd);
- if (glewExperimental || GLEW_SGIS_multisample) GLEW_SGIS_multisample = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIS_multisample) GLEW_SGIS_multisample = !_glewInit_GL_SGIS_multisample();
#endif /* GL_SGIS_multisample */
-#ifdef GL_SGIS_pixel_texture
- GLEW_SGIS_pixel_texture = _glewSearchExtension("GL_SGIS_pixel_texture", extStart, extEnd);
-#endif /* GL_SGIS_pixel_texture */
-#ifdef GL_SGIS_point_line_texgen
- GLEW_SGIS_point_line_texgen = _glewSearchExtension("GL_SGIS_point_line_texgen", extStart, extEnd);
-#endif /* GL_SGIS_point_line_texgen */
#ifdef GL_SGIS_sharpen_texture
- GLEW_SGIS_sharpen_texture = _glewSearchExtension("GL_SGIS_sharpen_texture", extStart, extEnd);
- if (glewExperimental || GLEW_SGIS_sharpen_texture) GLEW_SGIS_sharpen_texture = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIS_sharpen_texture) GLEW_SGIS_sharpen_texture = !_glewInit_GL_SGIS_sharpen_texture();
#endif /* GL_SGIS_sharpen_texture */
#ifdef GL_SGIS_texture4D
- GLEW_SGIS_texture4D = _glewSearchExtension("GL_SGIS_texture4D", extStart, extEnd);
- if (glewExperimental || GLEW_SGIS_texture4D) GLEW_SGIS_texture4D = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIS_texture4D) GLEW_SGIS_texture4D = !_glewInit_GL_SGIS_texture4D();
#endif /* GL_SGIS_texture4D */
-#ifdef GL_SGIS_texture_border_clamp
- GLEW_SGIS_texture_border_clamp = _glewSearchExtension("GL_SGIS_texture_border_clamp", extStart, extEnd);
-#endif /* GL_SGIS_texture_border_clamp */
-#ifdef GL_SGIS_texture_edge_clamp
- GLEW_SGIS_texture_edge_clamp = _glewSearchExtension("GL_SGIS_texture_edge_clamp", extStart, extEnd);
-#endif /* GL_SGIS_texture_edge_clamp */
#ifdef GL_SGIS_texture_filter4
- GLEW_SGIS_texture_filter4 = _glewSearchExtension("GL_SGIS_texture_filter4", extStart, extEnd);
- if (glewExperimental || GLEW_SGIS_texture_filter4) GLEW_SGIS_texture_filter4 = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIS_texture_filter4) GLEW_SGIS_texture_filter4 = !_glewInit_GL_SGIS_texture_filter4();
#endif /* GL_SGIS_texture_filter4 */
-#ifdef GL_SGIS_texture_lod
- GLEW_SGIS_texture_lod = _glewSearchExtension("GL_SGIS_texture_lod", extStart, extEnd);
-#endif /* GL_SGIS_texture_lod */
-#ifdef GL_SGIS_texture_select
- GLEW_SGIS_texture_select = _glewSearchExtension("GL_SGIS_texture_select", extStart, extEnd);
-#endif /* GL_SGIS_texture_select */
#ifdef GL_SGIX_async
- GLEW_SGIX_async = _glewSearchExtension("GL_SGIX_async", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_async) GLEW_SGIX_async = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_async) GLEW_SGIX_async = !_glewInit_GL_SGIX_async();
#endif /* GL_SGIX_async */
-#ifdef GL_SGIX_async_histogram
- GLEW_SGIX_async_histogram = _glewSearchExtension("GL_SGIX_async_histogram", extStart, extEnd);
-#endif /* GL_SGIX_async_histogram */
-#ifdef GL_SGIX_async_pixel
- GLEW_SGIX_async_pixel = _glewSearchExtension("GL_SGIX_async_pixel", extStart, extEnd);
-#endif /* GL_SGIX_async_pixel */
-#ifdef GL_SGIX_blend_alpha_minmax
- GLEW_SGIX_blend_alpha_minmax = _glewSearchExtension("GL_SGIX_blend_alpha_minmax", extStart, extEnd);
-#endif /* GL_SGIX_blend_alpha_minmax */
-#ifdef GL_SGIX_clipmap
- GLEW_SGIX_clipmap = _glewSearchExtension("GL_SGIX_clipmap", extStart, extEnd);
-#endif /* GL_SGIX_clipmap */
-#ifdef GL_SGIX_convolution_accuracy
- GLEW_SGIX_convolution_accuracy = _glewSearchExtension("GL_SGIX_convolution_accuracy", extStart, extEnd);
-#endif /* GL_SGIX_convolution_accuracy */
-#ifdef GL_SGIX_depth_texture
- GLEW_SGIX_depth_texture = _glewSearchExtension("GL_SGIX_depth_texture", extStart, extEnd);
-#endif /* GL_SGIX_depth_texture */
#ifdef GL_SGIX_flush_raster
- GLEW_SGIX_flush_raster = _glewSearchExtension("GL_SGIX_flush_raster", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_flush_raster) GLEW_SGIX_flush_raster = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_flush_raster) GLEW_SGIX_flush_raster = !_glewInit_GL_SGIX_flush_raster();
#endif /* GL_SGIX_flush_raster */
-#ifdef GL_SGIX_fog_offset
- GLEW_SGIX_fog_offset = _glewSearchExtension("GL_SGIX_fog_offset", extStart, extEnd);
-#endif /* GL_SGIX_fog_offset */
#ifdef GL_SGIX_fog_texture
- GLEW_SGIX_fog_texture = _glewSearchExtension("GL_SGIX_fog_texture", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_fog_texture) GLEW_SGIX_fog_texture = !_glewInit_GL_SGIX_fog_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_fog_texture) GLEW_SGIX_fog_texture = !_glewInit_GL_SGIX_fog_texture();
#endif /* GL_SGIX_fog_texture */
#ifdef GL_SGIX_fragment_specular_lighting
- GLEW_SGIX_fragment_specular_lighting = _glewSearchExtension("GL_SGIX_fragment_specular_lighting", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) GLEW_SGIX_fragment_specular_lighting = !_glewInit_GL_SGIX_fragment_specular_lighting(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) GLEW_SGIX_fragment_specular_lighting = !_glewInit_GL_SGIX_fragment_specular_lighting();
#endif /* GL_SGIX_fragment_specular_lighting */
#ifdef GL_SGIX_framezoom
- GLEW_SGIX_framezoom = _glewSearchExtension("GL_SGIX_framezoom", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_framezoom) GLEW_SGIX_framezoom = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_framezoom) GLEW_SGIX_framezoom = !_glewInit_GL_SGIX_framezoom();
#endif /* GL_SGIX_framezoom */
-#ifdef GL_SGIX_interlace
- GLEW_SGIX_interlace = _glewSearchExtension("GL_SGIX_interlace", extStart, extEnd);
-#endif /* GL_SGIX_interlace */
-#ifdef GL_SGIX_ir_instrument1
- GLEW_SGIX_ir_instrument1 = _glewSearchExtension("GL_SGIX_ir_instrument1", extStart, extEnd);
-#endif /* GL_SGIX_ir_instrument1 */
-#ifdef GL_SGIX_list_priority
- GLEW_SGIX_list_priority = _glewSearchExtension("GL_SGIX_list_priority", extStart, extEnd);
-#endif /* GL_SGIX_list_priority */
#ifdef GL_SGIX_pixel_texture
- GLEW_SGIX_pixel_texture = _glewSearchExtension("GL_SGIX_pixel_texture", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_pixel_texture) GLEW_SGIX_pixel_texture = !_glewInit_GL_SGIX_pixel_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_pixel_texture) GLEW_SGIX_pixel_texture = !_glewInit_GL_SGIX_pixel_texture();
#endif /* GL_SGIX_pixel_texture */
-#ifdef GL_SGIX_pixel_texture_bits
- GLEW_SGIX_pixel_texture_bits = _glewSearchExtension("GL_SGIX_pixel_texture_bits", extStart, extEnd);
-#endif /* GL_SGIX_pixel_texture_bits */
#ifdef GL_SGIX_reference_plane
- GLEW_SGIX_reference_plane = _glewSearchExtension("GL_SGIX_reference_plane", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_reference_plane) GLEW_SGIX_reference_plane = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_reference_plane) GLEW_SGIX_reference_plane = !_glewInit_GL_SGIX_reference_plane();
#endif /* GL_SGIX_reference_plane */
-#ifdef GL_SGIX_resample
- GLEW_SGIX_resample = _glewSearchExtension("GL_SGIX_resample", extStart, extEnd);
-#endif /* GL_SGIX_resample */
-#ifdef GL_SGIX_shadow
- GLEW_SGIX_shadow = _glewSearchExtension("GL_SGIX_shadow", extStart, extEnd);
-#endif /* GL_SGIX_shadow */
-#ifdef GL_SGIX_shadow_ambient
- GLEW_SGIX_shadow_ambient = _glewSearchExtension("GL_SGIX_shadow_ambient", extStart, extEnd);
-#endif /* GL_SGIX_shadow_ambient */
#ifdef GL_SGIX_sprite
- GLEW_SGIX_sprite = _glewSearchExtension("GL_SGIX_sprite", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_sprite) GLEW_SGIX_sprite = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_sprite) GLEW_SGIX_sprite = !_glewInit_GL_SGIX_sprite();
#endif /* GL_SGIX_sprite */
#ifdef GL_SGIX_tag_sample_buffer
- GLEW_SGIX_tag_sample_buffer = _glewSearchExtension("GL_SGIX_tag_sample_buffer", extStart, extEnd);
- if (glewExperimental || GLEW_SGIX_tag_sample_buffer) GLEW_SGIX_tag_sample_buffer = !_glewInit_GL_SGIX_tag_sample_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGIX_tag_sample_buffer) GLEW_SGIX_tag_sample_buffer = !_glewInit_GL_SGIX_tag_sample_buffer();
#endif /* GL_SGIX_tag_sample_buffer */
-#ifdef GL_SGIX_texture_add_env
- GLEW_SGIX_texture_add_env = _glewSearchExtension("GL_SGIX_texture_add_env", extStart, extEnd);
-#endif /* GL_SGIX_texture_add_env */
-#ifdef GL_SGIX_texture_coordinate_clamp
- GLEW_SGIX_texture_coordinate_clamp = _glewSearchExtension("GL_SGIX_texture_coordinate_clamp", extStart, extEnd);
-#endif /* GL_SGIX_texture_coordinate_clamp */
-#ifdef GL_SGIX_texture_lod_bias
- GLEW_SGIX_texture_lod_bias = _glewSearchExtension("GL_SGIX_texture_lod_bias", extStart, extEnd);
-#endif /* GL_SGIX_texture_lod_bias */
-#ifdef GL_SGIX_texture_multi_buffer
- GLEW_SGIX_texture_multi_buffer = _glewSearchExtension("GL_SGIX_texture_multi_buffer", extStart, extEnd);
-#endif /* GL_SGIX_texture_multi_buffer */
-#ifdef GL_SGIX_texture_range
- GLEW_SGIX_texture_range = _glewSearchExtension("GL_SGIX_texture_range", extStart, extEnd);
-#endif /* GL_SGIX_texture_range */
-#ifdef GL_SGIX_texture_scale_bias
- GLEW_SGIX_texture_scale_bias = _glewSearchExtension("GL_SGIX_texture_scale_bias", extStart, extEnd);
-#endif /* GL_SGIX_texture_scale_bias */
-#ifdef GL_SGIX_vertex_preclip
- GLEW_SGIX_vertex_preclip = _glewSearchExtension("GL_SGIX_vertex_preclip", extStart, extEnd);
-#endif /* GL_SGIX_vertex_preclip */
-#ifdef GL_SGIX_vertex_preclip_hint
- GLEW_SGIX_vertex_preclip_hint = _glewSearchExtension("GL_SGIX_vertex_preclip_hint", extStart, extEnd);
-#endif /* GL_SGIX_vertex_preclip_hint */
-#ifdef GL_SGIX_ycrcb
- GLEW_SGIX_ycrcb = _glewSearchExtension("GL_SGIX_ycrcb", extStart, extEnd);
-#endif /* GL_SGIX_ycrcb */
-#ifdef GL_SGI_color_matrix
- GLEW_SGI_color_matrix = _glewSearchExtension("GL_SGI_color_matrix", extStart, extEnd);
-#endif /* GL_SGI_color_matrix */
#ifdef GL_SGI_color_table
- GLEW_SGI_color_table = _glewSearchExtension("GL_SGI_color_table", extStart, extEnd);
- if (glewExperimental || GLEW_SGI_color_table) GLEW_SGI_color_table = !_glewInit_GL_SGI_color_table(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SGI_color_table) GLEW_SGI_color_table = !_glewInit_GL_SGI_color_table();
#endif /* GL_SGI_color_table */
-#ifdef GL_SGI_texture_color_table
- GLEW_SGI_texture_color_table = _glewSearchExtension("GL_SGI_texture_color_table", extStart, extEnd);
-#endif /* GL_SGI_texture_color_table */
#ifdef GL_SUNX_constant_data
- GLEW_SUNX_constant_data = _glewSearchExtension("GL_SUNX_constant_data", extStart, extEnd);
- if (glewExperimental || GLEW_SUNX_constant_data) GLEW_SUNX_constant_data = !_glewInit_GL_SUNX_constant_data(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SUNX_constant_data) GLEW_SUNX_constant_data = !_glewInit_GL_SUNX_constant_data();
#endif /* GL_SUNX_constant_data */
-#ifdef GL_SUN_convolution_border_modes
- GLEW_SUN_convolution_border_modes = _glewSearchExtension("GL_SUN_convolution_border_modes", extStart, extEnd);
-#endif /* GL_SUN_convolution_border_modes */
#ifdef GL_SUN_global_alpha
- GLEW_SUN_global_alpha = _glewSearchExtension("GL_SUN_global_alpha", extStart, extEnd);
- if (glewExperimental || GLEW_SUN_global_alpha) GLEW_SUN_global_alpha = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SUN_global_alpha) GLEW_SUN_global_alpha = !_glewInit_GL_SUN_global_alpha();
#endif /* GL_SUN_global_alpha */
-#ifdef GL_SUN_mesh_array
- GLEW_SUN_mesh_array = _glewSearchExtension("GL_SUN_mesh_array", extStart, extEnd);
-#endif /* GL_SUN_mesh_array */
#ifdef GL_SUN_read_video_pixels
- GLEW_SUN_read_video_pixels = _glewSearchExtension("GL_SUN_read_video_pixels", extStart, extEnd);
- if (glewExperimental || GLEW_SUN_read_video_pixels) GLEW_SUN_read_video_pixels = !_glewInit_GL_SUN_read_video_pixels(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SUN_read_video_pixels) GLEW_SUN_read_video_pixels = !_glewInit_GL_SUN_read_video_pixels();
#endif /* GL_SUN_read_video_pixels */
-#ifdef GL_SUN_slice_accum
- GLEW_SUN_slice_accum = _glewSearchExtension("GL_SUN_slice_accum", extStart, extEnd);
-#endif /* GL_SUN_slice_accum */
#ifdef GL_SUN_triangle_list
- GLEW_SUN_triangle_list = _glewSearchExtension("GL_SUN_triangle_list", extStart, extEnd);
- if (glewExperimental || GLEW_SUN_triangle_list) GLEW_SUN_triangle_list = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SUN_triangle_list) GLEW_SUN_triangle_list = !_glewInit_GL_SUN_triangle_list();
#endif /* GL_SUN_triangle_list */
#ifdef GL_SUN_vertex
- GLEW_SUN_vertex = _glewSearchExtension("GL_SUN_vertex", extStart, extEnd);
- if (glewExperimental || GLEW_SUN_vertex) GLEW_SUN_vertex = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_SUN_vertex) GLEW_SUN_vertex = !_glewInit_GL_SUN_vertex();
#endif /* GL_SUN_vertex */
-#ifdef GL_WIN_phong_shading
- GLEW_WIN_phong_shading = _glewSearchExtension("GL_WIN_phong_shading", extStart, extEnd);
-#endif /* GL_WIN_phong_shading */
-#ifdef GL_WIN_specular_fog
- GLEW_WIN_specular_fog = _glewSearchExtension("GL_WIN_specular_fog", extStart, extEnd);
-#endif /* GL_WIN_specular_fog */
#ifdef GL_WIN_swap_hint
- GLEW_WIN_swap_hint = _glewSearchExtension("GL_WIN_swap_hint", extStart, extEnd);
- if (glewExperimental || GLEW_WIN_swap_hint) GLEW_WIN_swap_hint = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLEW_WIN_swap_hint) GLEW_WIN_swap_hint = !_glewInit_GL_WIN_swap_hint();
#endif /* GL_WIN_swap_hint */
+#ifdef GL_NV_fragment_program4
+ GLEW_NV_fragment_program4 = GLEW_NV_gpu_program4;
+#endif /* GL_NV_fragment_program4 */
+#ifdef GL_NV_geometry_program4
+ GLEW_NV_geometry_program4 = GLEW_NV_gpu_program4;
+#endif /* GL_NV_geometry_program4 */
+#ifdef GL_NV_tessellation_program5
+ GLEW_NV_tessellation_program5 = GLEW_NV_gpu_program5;
+#endif /* GL_NV_tessellation_program5 */
+#ifdef GL_NV_vertex_program4
+ GLEW_NV_vertex_program4 = GLEW_NV_gpu_program4;
+#endif /* GL_NV_vertex_program4 */
return GLEW_OK;
}
-#if defined(_WIN32)
+#if defined(GLEW_OSMESA)
+
+#elif defined(GLEW_EGL)
+
+PFNEGLCHOOSECONFIGPROC __eglewChooseConfig = NULL;
+PFNEGLCOPYBUFFERSPROC __eglewCopyBuffers = NULL;
+PFNEGLCREATECONTEXTPROC __eglewCreateContext = NULL;
+PFNEGLCREATEPBUFFERSURFACEPROC __eglewCreatePbufferSurface = NULL;
+PFNEGLCREATEPIXMAPSURFACEPROC __eglewCreatePixmapSurface = NULL;
+PFNEGLCREATEWINDOWSURFACEPROC __eglewCreateWindowSurface = NULL;
+PFNEGLDESTROYCONTEXTPROC __eglewDestroyContext = NULL;
+PFNEGLDESTROYSURFACEPROC __eglewDestroySurface = NULL;
+PFNEGLGETCONFIGATTRIBPROC __eglewGetConfigAttrib = NULL;
+PFNEGLGETCONFIGSPROC __eglewGetConfigs = NULL;
+PFNEGLGETCURRENTDISPLAYPROC __eglewGetCurrentDisplay = NULL;
+PFNEGLGETCURRENTSURFACEPROC __eglewGetCurrentSurface = NULL;
+PFNEGLGETDISPLAYPROC __eglewGetDisplay = NULL;
+PFNEGLGETERRORPROC __eglewGetError = NULL;
+PFNEGLINITIALIZEPROC __eglewInitialize = NULL;
+PFNEGLMAKECURRENTPROC __eglewMakeCurrent = NULL;
+PFNEGLQUERYCONTEXTPROC __eglewQueryContext = NULL;
+PFNEGLQUERYSTRINGPROC __eglewQueryString = NULL;
+PFNEGLQUERYSURFACEPROC __eglewQuerySurface = NULL;
+PFNEGLSWAPBUFFERSPROC __eglewSwapBuffers = NULL;
+PFNEGLTERMINATEPROC __eglewTerminate = NULL;
+PFNEGLWAITGLPROC __eglewWaitGL = NULL;
+PFNEGLWAITNATIVEPROC __eglewWaitNative = NULL;
+
+PFNEGLBINDTEXIMAGEPROC __eglewBindTexImage = NULL;
+PFNEGLRELEASETEXIMAGEPROC __eglewReleaseTexImage = NULL;
+PFNEGLSURFACEATTRIBPROC __eglewSurfaceAttrib = NULL;
+PFNEGLSWAPINTERVALPROC __eglewSwapInterval = NULL;
+
+PFNEGLBINDAPIPROC __eglewBindAPI = NULL;
+PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC __eglewCreatePbufferFromClientBuffer = NULL;
+PFNEGLQUERYAPIPROC __eglewQueryAPI = NULL;
+PFNEGLRELEASETHREADPROC __eglewReleaseThread = NULL;
+PFNEGLWAITCLIENTPROC __eglewWaitClient = NULL;
+
+PFNEGLGETCURRENTCONTEXTPROC __eglewGetCurrentContext = NULL;
+
+PFNEGLCLIENTWAITSYNCPROC __eglewClientWaitSync = NULL;
+PFNEGLCREATEIMAGEPROC __eglewCreateImage = NULL;
+PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC __eglewCreatePlatformPixmapSurface = NULL;
+PFNEGLCREATEPLATFORMWINDOWSURFACEPROC __eglewCreatePlatformWindowSurface = NULL;
+PFNEGLCREATESYNCPROC __eglewCreateSync = NULL;
+PFNEGLDESTROYIMAGEPROC __eglewDestroyImage = NULL;
+PFNEGLDESTROYSYNCPROC __eglewDestroySync = NULL;
+PFNEGLGETPLATFORMDISPLAYPROC __eglewGetPlatformDisplay = NULL;
+PFNEGLGETSYNCATTRIBPROC __eglewGetSyncAttrib = NULL;
+PFNEGLWAITSYNCPROC __eglewWaitSync = NULL;
+
+PFNEGLSETBLOBCACHEFUNCSANDROIDPROC __eglewSetBlobCacheFuncsANDROID = NULL;
+
+PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC __eglewCreateNativeClientBufferANDROID = NULL;
+
+PFNEGLDUPNATIVEFENCEFDANDROIDPROC __eglewDupNativeFenceFDANDROID = NULL;
+
+PFNEGLPRESENTATIONTIMEANDROIDPROC __eglewPresentationTimeANDROID = NULL;
+
+PFNEGLQUERYSURFACEPOINTERANGLEPROC __eglewQuerySurfacePointerANGLE = NULL;
+
+PFNEGLQUERYDEVICESEXTPROC __eglewQueryDevicesEXT = NULL;
+
+PFNEGLQUERYDEVICEATTRIBEXTPROC __eglewQueryDeviceAttribEXT = NULL;
+PFNEGLQUERYDEVICESTRINGEXTPROC __eglewQueryDeviceStringEXT = NULL;
+PFNEGLQUERYDISPLAYATTRIBEXTPROC __eglewQueryDisplayAttribEXT = NULL;
+
+PFNEGLGETOUTPUTLAYERSEXTPROC __eglewGetOutputLayersEXT = NULL;
+PFNEGLGETOUTPUTPORTSEXTPROC __eglewGetOutputPortsEXT = NULL;
+PFNEGLOUTPUTLAYERATTRIBEXTPROC __eglewOutputLayerAttribEXT = NULL;
+PFNEGLOUTPUTPORTATTRIBEXTPROC __eglewOutputPortAttribEXT = NULL;
+PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC __eglewQueryOutputLayerAttribEXT = NULL;
+PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC __eglewQueryOutputLayerStringEXT = NULL;
+PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC __eglewQueryOutputPortAttribEXT = NULL;
+PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC __eglewQueryOutputPortStringEXT = NULL;
+
+PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC __eglewCreatePlatformPixmapSurfaceEXT = NULL;
+PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC __eglewCreatePlatformWindowSurfaceEXT = NULL;
+PFNEGLGETPLATFORMDISPLAYEXTPROC __eglewGetPlatformDisplayEXT = NULL;
+
+PFNEGLSTREAMCONSUMEROUTPUTEXTPROC __eglewStreamConsumerOutputEXT = NULL;
+
+PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC __eglewSwapBuffersWithDamageEXT = NULL;
+
+PFNEGLCREATEPIXMAPSURFACEHIPROC __eglewCreatePixmapSurfaceHI = NULL;
+
+PFNEGLCREATESYNC64KHRPROC __eglewCreateSync64KHR = NULL;
+
+PFNEGLDEBUGMESSAGECONTROLKHRPROC __eglewDebugMessageControlKHR = NULL;
+PFNEGLLABELOBJECTKHRPROC __eglewLabelObjectKHR = NULL;
+PFNEGLQUERYDEBUGKHRPROC __eglewQueryDebugKHR = NULL;
+
+PFNEGLCREATEIMAGEKHRPROC __eglewCreateImageKHR = NULL;
+PFNEGLDESTROYIMAGEKHRPROC __eglewDestroyImageKHR = NULL;
+
+PFNEGLLOCKSURFACEKHRPROC __eglewLockSurfaceKHR = NULL;
+PFNEGLUNLOCKSURFACEKHRPROC __eglewUnlockSurfaceKHR = NULL;
+
+PFNEGLQUERYSURFACE64KHRPROC __eglewQuerySurface64KHR = NULL;
+
+PFNEGLSETDAMAGEREGIONKHRPROC __eglewSetDamageRegionKHR = NULL;
+
+PFNEGLCLIENTWAITSYNCKHRPROC __eglewClientWaitSyncKHR = NULL;
+PFNEGLCREATESYNCKHRPROC __eglewCreateSyncKHR = NULL;
+PFNEGLDESTROYSYNCKHRPROC __eglewDestroySyncKHR = NULL;
+PFNEGLGETSYNCATTRIBKHRPROC __eglewGetSyncAttribKHR = NULL;
+PFNEGLSIGNALSYNCKHRPROC __eglewSignalSyncKHR = NULL;
+
+PFNEGLCREATESTREAMKHRPROC __eglewCreateStreamKHR = NULL;
+PFNEGLDESTROYSTREAMKHRPROC __eglewDestroyStreamKHR = NULL;
+PFNEGLQUERYSTREAMKHRPROC __eglewQueryStreamKHR = NULL;
+PFNEGLQUERYSTREAMU64KHRPROC __eglewQueryStreamu64KHR = NULL;
+PFNEGLSTREAMATTRIBKHRPROC __eglewStreamAttribKHR = NULL;
+
+PFNEGLSTREAMCONSUMERACQUIREKHRPROC __eglewStreamConsumerAcquireKHR = NULL;
+PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC __eglewStreamConsumerGLTextureExternalKHR = NULL;
+PFNEGLSTREAMCONSUMERRELEASEKHRPROC __eglewStreamConsumerReleaseKHR = NULL;
+
+PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC __eglewCreateStreamFromFileDescriptorKHR = NULL;
+PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC __eglewGetStreamFileDescriptorKHR = NULL;
+
+PFNEGLQUERYSTREAMTIMEKHRPROC __eglewQueryStreamTimeKHR = NULL;
+
+PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC __eglewCreateStreamProducerSurfaceKHR = NULL;
+
+PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC __eglewSwapBuffersWithDamageKHR = NULL;
+
+PFNEGLWAITSYNCKHRPROC __eglewWaitSyncKHR = NULL;
+
+PFNEGLCREATEDRMIMAGEMESAPROC __eglewCreateDRMImageMESA = NULL;
+PFNEGLEXPORTDRMIMAGEMESAPROC __eglewExportDRMImageMESA = NULL;
+
+PFNEGLEXPORTDMABUFIMAGEMESAPROC __eglewExportDMABUFImageMESA = NULL;
+PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC __eglewExportDMABUFImageQueryMESA = NULL;
+
+PFNEGLSWAPBUFFERSREGIONNOKPROC __eglewSwapBuffersRegionNOK = NULL;
+
+PFNEGLSWAPBUFFERSREGION2NOKPROC __eglewSwapBuffersRegion2NOK = NULL;
+
+PFNEGLQUERYNATIVEDISPLAYNVPROC __eglewQueryNativeDisplayNV = NULL;
+PFNEGLQUERYNATIVEPIXMAPNVPROC __eglewQueryNativePixmapNV = NULL;
+PFNEGLQUERYNATIVEWINDOWNVPROC __eglewQueryNativeWindowNV = NULL;
+
+PFNEGLPOSTSUBBUFFERNVPROC __eglewPostSubBufferNV = NULL;
+
+PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC __eglewStreamConsumerGLTextureExternalAttribsNV = NULL;
+
+PFNEGLQUERYDISPLAYATTRIBNVPROC __eglewQueryDisplayAttribNV = NULL;
+PFNEGLQUERYSTREAMMETADATANVPROC __eglewQueryStreamMetadataNV = NULL;
+PFNEGLSETSTREAMMETADATANVPROC __eglewSetStreamMetadataNV = NULL;
+
+PFNEGLCREATESTREAMSYNCNVPROC __eglewCreateStreamSyncNV = NULL;
+
+PFNEGLCLIENTWAITSYNCNVPROC __eglewClientWaitSyncNV = NULL;
+PFNEGLCREATEFENCESYNCNVPROC __eglewCreateFenceSyncNV = NULL;
+PFNEGLDESTROYSYNCNVPROC __eglewDestroySyncNV = NULL;
+PFNEGLFENCENVPROC __eglewFenceNV = NULL;
+PFNEGLGETSYNCATTRIBNVPROC __eglewGetSyncAttribNV = NULL;
+PFNEGLSIGNALSYNCNVPROC __eglewSignalSyncNV = NULL;
+
+PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC __eglewGetSystemTimeFrequencyNV = NULL;
+PFNEGLGETSYSTEMTIMENVPROC __eglewGetSystemTimeNV = NULL;
+GLboolean __EGLEW_VERSION_1_0 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_1 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_2 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_3 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_4 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_5 = GL_FALSE;
+GLboolean __EGLEW_ANDROID_blob_cache = GL_FALSE;
+GLboolean __EGLEW_ANDROID_create_native_client_buffer = GL_FALSE;
+GLboolean __EGLEW_ANDROID_framebuffer_target = GL_FALSE;
+GLboolean __EGLEW_ANDROID_front_buffer_auto_refresh = GL_FALSE;
+GLboolean __EGLEW_ANDROID_image_native_buffer = GL_FALSE;
+GLboolean __EGLEW_ANDROID_native_fence_sync = GL_FALSE;
+GLboolean __EGLEW_ANDROID_presentation_time = GL_FALSE;
+GLboolean __EGLEW_ANDROID_recordable = GL_FALSE;
+GLboolean __EGLEW_ANGLE_d3d_share_handle_client_buffer = GL_FALSE;
+GLboolean __EGLEW_ANGLE_device_d3d = GL_FALSE;
+GLboolean __EGLEW_ANGLE_query_surface_pointer = GL_FALSE;
+GLboolean __EGLEW_ANGLE_surface_d3d_texture_2d_share_handle = GL_FALSE;
+GLboolean __EGLEW_ANGLE_window_fixed_size = GL_FALSE;
+GLboolean __EGLEW_ARM_pixmap_multisample_discard = GL_FALSE;
+GLboolean __EGLEW_EXT_buffer_age = GL_FALSE;
+GLboolean __EGLEW_EXT_client_extensions = GL_FALSE;
+GLboolean __EGLEW_EXT_create_context_robustness = GL_FALSE;
+GLboolean __EGLEW_EXT_device_base = GL_FALSE;
+GLboolean __EGLEW_EXT_device_drm = GL_FALSE;
+GLboolean __EGLEW_EXT_device_enumeration = GL_FALSE;
+GLboolean __EGLEW_EXT_device_openwf = GL_FALSE;
+GLboolean __EGLEW_EXT_device_query = GL_FALSE;
+GLboolean __EGLEW_EXT_image_dma_buf_import = GL_FALSE;
+GLboolean __EGLEW_EXT_multiview_window = GL_FALSE;
+GLboolean __EGLEW_EXT_output_base = GL_FALSE;
+GLboolean __EGLEW_EXT_output_drm = GL_FALSE;
+GLboolean __EGLEW_EXT_output_openwf = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_base = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_device = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_wayland = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_x11 = GL_FALSE;
+GLboolean __EGLEW_EXT_protected_content = GL_FALSE;
+GLboolean __EGLEW_EXT_protected_surface = GL_FALSE;
+GLboolean __EGLEW_EXT_stream_consumer_egloutput = GL_FALSE;
+GLboolean __EGLEW_EXT_swap_buffers_with_damage = GL_FALSE;
+GLboolean __EGLEW_EXT_yuv_surface = GL_FALSE;
+GLboolean __EGLEW_HI_clientpixmap = GL_FALSE;
+GLboolean __EGLEW_HI_colorformats = GL_FALSE;
+GLboolean __EGLEW_IMG_context_priority = GL_FALSE;
+GLboolean __EGLEW_IMG_image_plane_attribs = GL_FALSE;
+GLboolean __EGLEW_KHR_cl_event = GL_FALSE;
+GLboolean __EGLEW_KHR_cl_event2 = GL_FALSE;
+GLboolean __EGLEW_KHR_client_get_all_proc_addresses = GL_FALSE;
+GLboolean __EGLEW_KHR_config_attribs = GL_FALSE;
+GLboolean __EGLEW_KHR_create_context = GL_FALSE;
+GLboolean __EGLEW_KHR_create_context_no_error = GL_FALSE;
+GLboolean __EGLEW_KHR_debug = GL_FALSE;
+GLboolean __EGLEW_KHR_fence_sync = GL_FALSE;
+GLboolean __EGLEW_KHR_get_all_proc_addresses = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_colorspace = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_renderbuffer_image = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_texture_2D_image = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_texture_3D_image = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_texture_cubemap_image = GL_FALSE;
+GLboolean __EGLEW_KHR_image = GL_FALSE;
+GLboolean __EGLEW_KHR_image_base = GL_FALSE;
+GLboolean __EGLEW_KHR_image_pixmap = GL_FALSE;
+GLboolean __EGLEW_KHR_lock_surface = GL_FALSE;
+GLboolean __EGLEW_KHR_lock_surface2 = GL_FALSE;
+GLboolean __EGLEW_KHR_lock_surface3 = GL_FALSE;
+GLboolean __EGLEW_KHR_mutable_render_buffer = GL_FALSE;
+GLboolean __EGLEW_KHR_partial_update = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_android = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_gbm = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_wayland = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_x11 = GL_FALSE;
+GLboolean __EGLEW_KHR_reusable_sync = GL_FALSE;
+GLboolean __EGLEW_KHR_stream = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_consumer_gltexture = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_cross_process_fd = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_fifo = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_producer_aldatalocator = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_producer_eglsurface = GL_FALSE;
+GLboolean __EGLEW_KHR_surfaceless_context = GL_FALSE;
+GLboolean __EGLEW_KHR_swap_buffers_with_damage = GL_FALSE;
+GLboolean __EGLEW_KHR_vg_parent_image = GL_FALSE;
+GLboolean __EGLEW_KHR_wait_sync = GL_FALSE;
+GLboolean __EGLEW_MESA_drm_image = GL_FALSE;
+GLboolean __EGLEW_MESA_image_dma_buf_export = GL_FALSE;
+GLboolean __EGLEW_MESA_platform_gbm = GL_FALSE;
+GLboolean __EGLEW_NOK_swap_region = GL_FALSE;
+GLboolean __EGLEW_NOK_swap_region2 = GL_FALSE;
+GLboolean __EGLEW_NOK_texture_from_pixmap = GL_FALSE;
+GLboolean __EGLEW_NV_3dvision_surface = GL_FALSE;
+GLboolean __EGLEW_NV_coverage_sample = GL_FALSE;
+GLboolean __EGLEW_NV_coverage_sample_resolve = GL_FALSE;
+GLboolean __EGLEW_NV_cuda_event = GL_FALSE;
+GLboolean __EGLEW_NV_depth_nonlinear = GL_FALSE;
+GLboolean __EGLEW_NV_device_cuda = GL_FALSE;
+GLboolean __EGLEW_NV_native_query = GL_FALSE;
+GLboolean __EGLEW_NV_post_convert_rounding = GL_FALSE;
+GLboolean __EGLEW_NV_post_sub_buffer = GL_FALSE;
+GLboolean __EGLEW_NV_robustness_video_memory_purge = GL_FALSE;
+GLboolean __EGLEW_NV_stream_consumer_gltexture_yuv = GL_FALSE;
+GLboolean __EGLEW_NV_stream_metadata = GL_FALSE;
+GLboolean __EGLEW_NV_stream_sync = GL_FALSE;
+GLboolean __EGLEW_NV_sync = GL_FALSE;
+GLboolean __EGLEW_NV_system_time = GL_FALSE;
+GLboolean __EGLEW_TIZEN_image_native_buffer = GL_FALSE;
+GLboolean __EGLEW_TIZEN_image_native_surface = GL_FALSE;
+#ifdef EGL_VERSION_1_0
+
+static GLboolean _glewInit_EGL_VERSION_1_0 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglChooseConfig = (PFNEGLCHOOSECONFIGPROC)glewGetProcAddress((const GLubyte*)"eglChooseConfig")) == NULL) || r;
+ r = ((eglCopyBuffers = (PFNEGLCOPYBUFFERSPROC)glewGetProcAddress((const GLubyte*)"eglCopyBuffers")) == NULL) || r;
+ r = ((eglCreateContext = (PFNEGLCREATECONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglCreateContext")) == NULL) || r;
+ r = ((eglCreatePbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePbufferSurface")) == NULL) || r;
+ r = ((eglCreatePixmapSurface = (PFNEGLCREATEPIXMAPSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePixmapSurface")) == NULL) || r;
+ r = ((eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreateWindowSurface")) == NULL) || r;
+ r = ((eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglDestroyContext")) == NULL) || r;
+ r = ((eglDestroySurface = (PFNEGLDESTROYSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglDestroySurface")) == NULL) || r;
+ r = ((eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"eglGetConfigAttrib")) == NULL) || r;
+ r = ((eglGetConfigs = (PFNEGLGETCONFIGSPROC)glewGetProcAddress((const GLubyte*)"eglGetConfigs")) == NULL) || r;
+ r = ((eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"eglGetCurrentDisplay")) == NULL) || r;
+ r = ((eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglGetCurrentSurface")) == NULL) || r;
+ r = ((eglGetDisplay = (PFNEGLGETDISPLAYPROC)glewGetProcAddress((const GLubyte*)"eglGetDisplay")) == NULL) || r;
+ r = ((eglGetError = (PFNEGLGETERRORPROC)glewGetProcAddress((const GLubyte*)"eglGetError")) == NULL) || r;
+ r = ((eglInitialize = (PFNEGLINITIALIZEPROC)glewGetProcAddress((const GLubyte*)"eglInitialize")) == NULL) || r;
+ r = ((eglMakeCurrent = (PFNEGLMAKECURRENTPROC)glewGetProcAddress((const GLubyte*)"eglMakeCurrent")) == NULL) || r;
+ r = ((eglQueryContext = (PFNEGLQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryContext")) == NULL) || r;
+ r = ((eglQueryString = (PFNEGLQUERYSTRINGPROC)glewGetProcAddress((const GLubyte*)"eglQueryString")) == NULL) || r;
+ r = ((eglQuerySurface = (PFNEGLQUERYSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglQuerySurface")) == NULL) || r;
+ r = ((eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffers")) == NULL) || r;
+ r = ((eglTerminate = (PFNEGLTERMINATEPROC)glewGetProcAddress((const GLubyte*)"eglTerminate")) == NULL) || r;
+ r = ((eglWaitGL = (PFNEGLWAITGLPROC)glewGetProcAddress((const GLubyte*)"eglWaitGL")) == NULL) || r;
+ r = ((eglWaitNative = (PFNEGLWAITNATIVEPROC)glewGetProcAddress((const GLubyte*)"eglWaitNative")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_0 */
+
+#ifdef EGL_VERSION_1_1
+
+static GLboolean _glewInit_EGL_VERSION_1_1 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglBindTexImage = (PFNEGLBINDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglBindTexImage")) == NULL) || r;
+ r = ((eglReleaseTexImage = (PFNEGLRELEASETEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglReleaseTexImage")) == NULL) || r;
+ r = ((eglSurfaceAttrib = (PFNEGLSURFACEATTRIBPROC)glewGetProcAddress((const GLubyte*)"eglSurfaceAttrib")) == NULL) || r;
+ r = ((eglSwapInterval = (PFNEGLSWAPINTERVALPROC)glewGetProcAddress((const GLubyte*)"eglSwapInterval")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_1 */
+
+#ifdef EGL_VERSION_1_2
+
+static GLboolean _glewInit_EGL_VERSION_1_2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglBindAPI = (PFNEGLBINDAPIPROC)glewGetProcAddress((const GLubyte*)"eglBindAPI")) == NULL) || r;
+ r = ((eglCreatePbufferFromClientBuffer = (PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)glewGetProcAddress((const GLubyte*)"eglCreatePbufferFromClientBuffer")) == NULL) || r;
+ r = ((eglQueryAPI = (PFNEGLQUERYAPIPROC)glewGetProcAddress((const GLubyte*)"eglQueryAPI")) == NULL) || r;
+ r = ((eglReleaseThread = (PFNEGLRELEASETHREADPROC)glewGetProcAddress((const GLubyte*)"eglReleaseThread")) == NULL) || r;
+ r = ((eglWaitClient = (PFNEGLWAITCLIENTPROC)glewGetProcAddress((const GLubyte*)"eglWaitClient")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_2 */
+
+#ifdef EGL_VERSION_1_4
+
+static GLboolean _glewInit_EGL_VERSION_1_4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetCurrentContext")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_4 */
+
+#ifdef EGL_VERSION_1_5
+
+static GLboolean _glewInit_EGL_VERSION_1_5 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"eglClientWaitSync")) == NULL) || r;
+ r = ((eglCreateImage = (PFNEGLCREATEIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglCreateImage")) == NULL) || r;
+ r = ((eglCreatePlatformPixmapSurface = (PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformPixmapSurface")) == NULL) || r;
+ r = ((eglCreatePlatformWindowSurface = (PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformWindowSurface")) == NULL) || r;
+ r = ((eglCreateSync = (PFNEGLCREATESYNCPROC)glewGetProcAddress((const GLubyte*)"eglCreateSync")) == NULL) || r;
+ r = ((eglDestroyImage = (PFNEGLDESTROYIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglDestroyImage")) == NULL) || r;
+ r = ((eglDestroySync = (PFNEGLDESTROYSYNCPROC)glewGetProcAddress((const GLubyte*)"eglDestroySync")) == NULL) || r;
+ r = ((eglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYPROC)glewGetProcAddress((const GLubyte*)"eglGetPlatformDisplay")) == NULL) || r;
+ r = ((eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC)glewGetProcAddress((const GLubyte*)"eglGetSyncAttrib")) == NULL) || r;
+ r = ((eglWaitSync = (PFNEGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"eglWaitSync")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_5 */
+
+#ifdef EGL_ANDROID_blob_cache
+
+static GLboolean _glewInit_EGL_ANDROID_blob_cache ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSetBlobCacheFuncsANDROID = (PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglSetBlobCacheFuncsANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifdef EGL_ANDROID_create_native_client_buffer
+
+static GLboolean _glewInit_EGL_ANDROID_create_native_client_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateNativeClientBufferANDROID = (PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglCreateNativeClientBufferANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_create_native_client_buffer */
+
+#ifdef EGL_ANDROID_native_fence_sync
+
+static GLboolean _glewInit_EGL_ANDROID_native_fence_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglDupNativeFenceFDANDROID = (PFNEGLDUPNATIVEFENCEFDANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglDupNativeFenceFDANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifdef EGL_ANDROID_presentation_time
+
+static GLboolean _glewInit_EGL_ANDROID_presentation_time ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglPresentationTimeANDROID = (PFNEGLPRESENTATIONTIMEANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglPresentationTimeANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_presentation_time */
+
+#ifdef EGL_ANGLE_query_surface_pointer
+
+static GLboolean _glewInit_EGL_ANGLE_query_surface_pointer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQuerySurfacePointerANGLE = (PFNEGLQUERYSURFACEPOINTERANGLEPROC)glewGetProcAddress((const GLubyte*)"eglQuerySurfacePointerANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifdef EGL_EXT_device_enumeration
+
+static GLboolean _glewInit_EGL_EXT_device_enumeration ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDevicesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_device_enumeration */
+
+#ifdef EGL_EXT_device_query
+
+static GLboolean _glewInit_EGL_EXT_device_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDeviceAttribEXT")) == NULL) || r;
+ r = ((eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDeviceStringEXT")) == NULL) || r;
+ r = ((eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDisplayAttribEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_device_query */
+
+#ifdef EGL_EXT_output_base
+
+static GLboolean _glewInit_EGL_EXT_output_base ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglGetOutputLayersEXT = (PFNEGLGETOUTPUTLAYERSEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetOutputLayersEXT")) == NULL) || r;
+ r = ((eglGetOutputPortsEXT = (PFNEGLGETOUTPUTPORTSEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetOutputPortsEXT")) == NULL) || r;
+ r = ((eglOutputLayerAttribEXT = (PFNEGLOUTPUTLAYERATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglOutputLayerAttribEXT")) == NULL) || r;
+ r = ((eglOutputPortAttribEXT = (PFNEGLOUTPUTPORTATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglOutputPortAttribEXT")) == NULL) || r;
+ r = ((eglQueryOutputLayerAttribEXT = (PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputLayerAttribEXT")) == NULL) || r;
+ r = ((eglQueryOutputLayerStringEXT = (PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputLayerStringEXT")) == NULL) || r;
+ r = ((eglQueryOutputPortAttribEXT = (PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputPortAttribEXT")) == NULL) || r;
+ r = ((eglQueryOutputPortStringEXT = (PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputPortStringEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_output_base */
+
+#ifdef EGL_EXT_platform_base
+
+static GLboolean _glewInit_EGL_EXT_platform_base ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformPixmapSurfaceEXT")) == NULL) || r;
+ r = ((eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformWindowSurfaceEXT")) == NULL) || r;
+ r = ((eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetPlatformDisplayEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_platform_base */
+
+#ifdef EGL_EXT_stream_consumer_egloutput
+
+static GLboolean _glewInit_EGL_EXT_stream_consumer_egloutput ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglStreamConsumerOutputEXT = (PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerOutputEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
+#ifdef EGL_EXT_swap_buffers_with_damage
+
+static GLboolean _glewInit_EGL_EXT_swap_buffers_with_damage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersWithDamageEXT = (PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersWithDamageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifdef EGL_HI_clientpixmap
+
+static GLboolean _glewInit_EGL_HI_clientpixmap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreatePixmapSurfaceHI = (PFNEGLCREATEPIXMAPSURFACEHIPROC)glewGetProcAddress((const GLubyte*)"eglCreatePixmapSurfaceHI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_HI_clientpixmap */
+
+#ifdef EGL_KHR_cl_event2
+
+static GLboolean _glewInit_EGL_KHR_cl_event2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateSync64KHR = (PFNEGLCREATESYNC64KHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateSync64KHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_cl_event2 */
+
+#ifdef EGL_KHR_debug
+
+static GLboolean _glewInit_EGL_KHR_debug ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglDebugMessageControlKHR = (PFNEGLDEBUGMESSAGECONTROLKHRPROC)glewGetProcAddress((const GLubyte*)"eglDebugMessageControlKHR")) == NULL) || r;
+ r = ((eglLabelObjectKHR = (PFNEGLLABELOBJECTKHRPROC)glewGetProcAddress((const GLubyte*)"eglLabelObjectKHR")) == NULL) || r;
+ r = ((eglQueryDebugKHR = (PFNEGLQUERYDEBUGKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryDebugKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_debug */
+
+#ifdef EGL_KHR_image
+
+static GLboolean _glewInit_EGL_KHR_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateImageKHR")) == NULL) || r;
+ r = ((eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)glewGetProcAddress((const GLubyte*)"eglDestroyImageKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_image */
+
+#ifdef EGL_KHR_lock_surface
+
+static GLboolean _glewInit_EGL_KHR_lock_surface ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglLockSurfaceKHR = (PFNEGLLOCKSURFACEKHRPROC)glewGetProcAddress((const GLubyte*)"eglLockSurfaceKHR")) == NULL) || r;
+ r = ((eglUnlockSurfaceKHR = (PFNEGLUNLOCKSURFACEKHRPROC)glewGetProcAddress((const GLubyte*)"eglUnlockSurfaceKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_lock_surface */
+
+#ifdef EGL_KHR_lock_surface3
+
+static GLboolean _glewInit_EGL_KHR_lock_surface3 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQuerySurface64KHR = (PFNEGLQUERYSURFACE64KHRPROC)glewGetProcAddress((const GLubyte*)"eglQuerySurface64KHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifdef EGL_KHR_partial_update
+
+static GLboolean _glewInit_EGL_KHR_partial_update ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSetDamageRegionKHR = (PFNEGLSETDAMAGEREGIONKHRPROC)glewGetProcAddress((const GLubyte*)"eglSetDamageRegionKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_partial_update */
+
+#ifdef EGL_KHR_reusable_sync
+
+static GLboolean _glewInit_EGL_KHR_reusable_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglClientWaitSyncKHR")) == NULL) || r;
+ r = ((eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateSyncKHR")) == NULL) || r;
+ r = ((eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglDestroySyncKHR")) == NULL) || r;
+ r = ((eglGetSyncAttribKHR = (PFNEGLGETSYNCATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglGetSyncAttribKHR")) == NULL) || r;
+ r = ((eglSignalSyncKHR = (PFNEGLSIGNALSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglSignalSyncKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_reusable_sync */
+
+#ifdef EGL_KHR_stream
+
+static GLboolean _glewInit_EGL_KHR_stream ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamKHR = (PFNEGLCREATESTREAMKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamKHR")) == NULL) || r;
+ r = ((eglDestroyStreamKHR = (PFNEGLDESTROYSTREAMKHRPROC)glewGetProcAddress((const GLubyte*)"eglDestroyStreamKHR")) == NULL) || r;
+ r = ((eglQueryStreamKHR = (PFNEGLQUERYSTREAMKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamKHR")) == NULL) || r;
+ r = ((eglQueryStreamu64KHR = (PFNEGLQUERYSTREAMU64KHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamu64KHR")) == NULL) || r;
+ r = ((eglStreamAttribKHR = (PFNEGLSTREAMATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamAttribKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream */
+
+#ifdef EGL_KHR_stream_consumer_gltexture
+
+static GLboolean _glewInit_EGL_KHR_stream_consumer_gltexture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglStreamConsumerAcquireKHR = (PFNEGLSTREAMCONSUMERACQUIREKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerAcquireKHR")) == NULL) || r;
+ r = ((eglStreamConsumerGLTextureExternalKHR = (PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerGLTextureExternalKHR")) == NULL) || r;
+ r = ((eglStreamConsumerReleaseKHR = (PFNEGLSTREAMCONSUMERRELEASEKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerReleaseKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifdef EGL_KHR_stream_cross_process_fd
+
+static GLboolean _glewInit_EGL_KHR_stream_cross_process_fd ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamFromFileDescriptorKHR = (PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamFromFileDescriptorKHR")) == NULL) || r;
+ r = ((eglGetStreamFileDescriptorKHR = (PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)glewGetProcAddress((const GLubyte*)"eglGetStreamFileDescriptorKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifdef EGL_KHR_stream_fifo
+
+static GLboolean _glewInit_EGL_KHR_stream_fifo ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryStreamTimeKHR = (PFNEGLQUERYSTREAMTIMEKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamTimeKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_fifo */
+
+#ifdef EGL_KHR_stream_producer_eglsurface
+
+static GLboolean _glewInit_EGL_KHR_stream_producer_eglsurface ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamProducerSurfaceKHR = (PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamProducerSurfaceKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifdef EGL_KHR_swap_buffers_with_damage
+
+static GLboolean _glewInit_EGL_KHR_swap_buffers_with_damage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersWithDamageKHR = (PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersWithDamageKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
+#ifdef EGL_KHR_wait_sync
+
+static GLboolean _glewInit_EGL_KHR_wait_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglWaitSyncKHR = (PFNEGLWAITSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglWaitSyncKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_wait_sync */
+
+#ifdef EGL_MESA_drm_image
+
+static GLboolean _glewInit_EGL_MESA_drm_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateDRMImageMESA = (PFNEGLCREATEDRMIMAGEMESAPROC)glewGetProcAddress((const GLubyte*)"eglCreateDRMImageMESA")) == NULL) || r;
+ r = ((eglExportDRMImageMESA = (PFNEGLEXPORTDRMIMAGEMESAPROC)glewGetProcAddress((const GLubyte*)"eglExportDRMImageMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_MESA_drm_image */
+
+#ifdef EGL_MESA_image_dma_buf_export
+
+static GLboolean _glewInit_EGL_MESA_image_dma_buf_export ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglExportDMABUFImageMESA = (PFNEGLEXPORTDMABUFIMAGEMESAPROC)glewGetProcAddress((const GLubyte*)"eglExportDMABUFImageMESA")) == NULL) || r;
+ r = ((eglExportDMABUFImageQueryMESA = (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC)glewGetProcAddress((const GLubyte*)"eglExportDMABUFImageQueryMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_MESA_image_dma_buf_export */
+
+#ifdef EGL_NOK_swap_region
+
+static GLboolean _glewInit_EGL_NOK_swap_region ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersRegionNOK = (PFNEGLSWAPBUFFERSREGIONNOKPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersRegionNOK")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NOK_swap_region */
+
+#ifdef EGL_NOK_swap_region2
+
+static GLboolean _glewInit_EGL_NOK_swap_region2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersRegion2NOK = (PFNEGLSWAPBUFFERSREGION2NOKPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersRegion2NOK")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NOK_swap_region2 */
+
+#ifdef EGL_NV_native_query
+
+static GLboolean _glewInit_EGL_NV_native_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryNativeDisplayNV = (PFNEGLQUERYNATIVEDISPLAYNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryNativeDisplayNV")) == NULL) || r;
+ r = ((eglQueryNativePixmapNV = (PFNEGLQUERYNATIVEPIXMAPNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryNativePixmapNV")) == NULL) || r;
+ r = ((eglQueryNativeWindowNV = (PFNEGLQUERYNATIVEWINDOWNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryNativeWindowNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_native_query */
+
+#ifdef EGL_NV_post_sub_buffer
+
+static GLboolean _glewInit_EGL_NV_post_sub_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"eglPostSubBufferNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifdef EGL_NV_stream_consumer_gltexture_yuv
+
+static GLboolean _glewInit_EGL_NV_stream_consumer_gltexture_yuv ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglStreamConsumerGLTextureExternalAttribsNV = (PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerGLTextureExternalAttribsNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+#ifdef EGL_NV_stream_metadata
+
+static GLboolean _glewInit_EGL_NV_stream_metadata ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDisplayAttribNV = (PFNEGLQUERYDISPLAYATTRIBNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryDisplayAttribNV")) == NULL) || r;
+ r = ((eglQueryStreamMetadataNV = (PFNEGLQUERYSTREAMMETADATANVPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamMetadataNV")) == NULL) || r;
+ r = ((eglSetStreamMetadataNV = (PFNEGLSETSTREAMMETADATANVPROC)glewGetProcAddress((const GLubyte*)"eglSetStreamMetadataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_metadata */
+
+#ifdef EGL_NV_stream_sync
+
+static GLboolean _glewInit_EGL_NV_stream_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamSyncNV = (PFNEGLCREATESTREAMSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamSyncNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_sync */
+
+#ifdef EGL_NV_sync
+
+static GLboolean _glewInit_EGL_NV_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglClientWaitSyncNV = (PFNEGLCLIENTWAITSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglClientWaitSyncNV")) == NULL) || r;
+ r = ((eglCreateFenceSyncNV = (PFNEGLCREATEFENCESYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglCreateFenceSyncNV")) == NULL) || r;
+ r = ((eglDestroySyncNV = (PFNEGLDESTROYSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglDestroySyncNV")) == NULL) || r;
+ r = ((eglFenceNV = (PFNEGLFENCENVPROC)glewGetProcAddress((const GLubyte*)"eglFenceNV")) == NULL) || r;
+ r = ((eglGetSyncAttribNV = (PFNEGLGETSYNCATTRIBNVPROC)glewGetProcAddress((const GLubyte*)"eglGetSyncAttribNV")) == NULL) || r;
+ r = ((eglSignalSyncNV = (PFNEGLSIGNALSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglSignalSyncNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_sync */
+
+#ifdef EGL_NV_system_time
+
+static GLboolean _glewInit_EGL_NV_system_time ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)glewGetProcAddress((const GLubyte*)"eglGetSystemTimeFrequencyNV")) == NULL) || r;
+ r = ((eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)glewGetProcAddress((const GLubyte*)"eglGetSystemTimeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_system_time */
+
+ /* ------------------------------------------------------------------------ */
+
+GLboolean eglewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+
+ start = (const GLubyte*) eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
+ if (0 == start) return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+GLenum eglewInit (EGLDisplay display)
+{
+ EGLint major, minor;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ PFNEGLINITIALIZEPROC initialize = NULL;
+ PFNEGLQUERYSTRINGPROC queryString = NULL;
+
+ /* Load necessary entry points */
+ initialize = (PFNEGLINITIALIZEPROC) glewGetProcAddress("eglInitialize");
+ queryString = (PFNEGLQUERYSTRINGPROC) glewGetProcAddress("eglQueryString");
+ if (!initialize || !queryString)
+ return 1;
+
+ /* query EGK version */
+ if (initialize(display, &major, &minor) != EGL_TRUE)
+ return 1;
+
+ EGLEW_VERSION_1_5 = ( major > 1 ) || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_4 = EGLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_3 = EGLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_2 = EGLEW_VERSION_1_3 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_1 = EGLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_0 = EGLEW_VERSION_1_1 == GL_TRUE || ( major == 1 && minor >= 0 ) ? GL_TRUE : GL_FALSE;
+
+ /* query EGL extension string */
+ extStart = (const GLubyte*) queryString(display, EGL_EXTENSIONS);
+ if (extStart == 0)
+ extStart = (const GLubyte *)"";
+ extEnd = extStart + _glewStrLen(extStart);
+
+ /* initialize extensions */
+#ifdef EGL_VERSION_1_0
+ if (glewExperimental || EGLEW_VERSION_1_0) EGLEW_VERSION_1_0 = !_glewInit_EGL_VERSION_1_0();
+#endif /* EGL_VERSION_1_0 */
+#ifdef EGL_VERSION_1_1
+ if (glewExperimental || EGLEW_VERSION_1_1) EGLEW_VERSION_1_1 = !_glewInit_EGL_VERSION_1_1();
+#endif /* EGL_VERSION_1_1 */
+#ifdef EGL_VERSION_1_2
+ if (glewExperimental || EGLEW_VERSION_1_2) EGLEW_VERSION_1_2 = !_glewInit_EGL_VERSION_1_2();
+#endif /* EGL_VERSION_1_2 */
+#ifdef EGL_VERSION_1_4
+ if (glewExperimental || EGLEW_VERSION_1_4) EGLEW_VERSION_1_4 = !_glewInit_EGL_VERSION_1_4();
+#endif /* EGL_VERSION_1_4 */
+#ifdef EGL_VERSION_1_5
+ if (glewExperimental || EGLEW_VERSION_1_5) EGLEW_VERSION_1_5 = !_glewInit_EGL_VERSION_1_5();
+#endif /* EGL_VERSION_1_5 */
+#ifdef EGL_ANDROID_blob_cache
+ EGLEW_ANDROID_blob_cache = _glewSearchExtension("EGL_ANDROID_blob_cache", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_blob_cache) EGLEW_ANDROID_blob_cache = !_glewInit_EGL_ANDROID_blob_cache();
+#endif /* EGL_ANDROID_blob_cache */
+#ifdef EGL_ANDROID_create_native_client_buffer
+ EGLEW_ANDROID_create_native_client_buffer = _glewSearchExtension("EGL_ANDROID_create_native_client_buffer", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_create_native_client_buffer) EGLEW_ANDROID_create_native_client_buffer = !_glewInit_EGL_ANDROID_create_native_client_buffer();
+#endif /* EGL_ANDROID_create_native_client_buffer */
+#ifdef EGL_ANDROID_framebuffer_target
+ EGLEW_ANDROID_framebuffer_target = _glewSearchExtension("EGL_ANDROID_framebuffer_target", extStart, extEnd);
+#endif /* EGL_ANDROID_framebuffer_target */
+#ifdef EGL_ANDROID_front_buffer_auto_refresh
+ EGLEW_ANDROID_front_buffer_auto_refresh = _glewSearchExtension("EGL_ANDROID_front_buffer_auto_refresh", extStart, extEnd);
+#endif /* EGL_ANDROID_front_buffer_auto_refresh */
+#ifdef EGL_ANDROID_image_native_buffer
+ EGLEW_ANDROID_image_native_buffer = _glewSearchExtension("EGL_ANDROID_image_native_buffer", extStart, extEnd);
+#endif /* EGL_ANDROID_image_native_buffer */
+#ifdef EGL_ANDROID_native_fence_sync
+ EGLEW_ANDROID_native_fence_sync = _glewSearchExtension("EGL_ANDROID_native_fence_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_native_fence_sync) EGLEW_ANDROID_native_fence_sync = !_glewInit_EGL_ANDROID_native_fence_sync();
+#endif /* EGL_ANDROID_native_fence_sync */
+#ifdef EGL_ANDROID_presentation_time
+ EGLEW_ANDROID_presentation_time = _glewSearchExtension("EGL_ANDROID_presentation_time", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_presentation_time) EGLEW_ANDROID_presentation_time = !_glewInit_EGL_ANDROID_presentation_time();
+#endif /* EGL_ANDROID_presentation_time */
+#ifdef EGL_ANDROID_recordable
+ EGLEW_ANDROID_recordable = _glewSearchExtension("EGL_ANDROID_recordable", extStart, extEnd);
+#endif /* EGL_ANDROID_recordable */
+#ifdef EGL_ANGLE_d3d_share_handle_client_buffer
+ EGLEW_ANGLE_d3d_share_handle_client_buffer = _glewSearchExtension("EGL_ANGLE_d3d_share_handle_client_buffer", extStart, extEnd);
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+#ifdef EGL_ANGLE_device_d3d
+ EGLEW_ANGLE_device_d3d = _glewSearchExtension("EGL_ANGLE_device_d3d", extStart, extEnd);
+#endif /* EGL_ANGLE_device_d3d */
+#ifdef EGL_ANGLE_query_surface_pointer
+ EGLEW_ANGLE_query_surface_pointer = _glewSearchExtension("EGL_ANGLE_query_surface_pointer", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANGLE_query_surface_pointer) EGLEW_ANGLE_query_surface_pointer = !_glewInit_EGL_ANGLE_query_surface_pointer();
+#endif /* EGL_ANGLE_query_surface_pointer */
+#ifdef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+ EGLEW_ANGLE_surface_d3d_texture_2d_share_handle = _glewSearchExtension("EGL_ANGLE_surface_d3d_texture_2d_share_handle", extStart, extEnd);
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+#ifdef EGL_ANGLE_window_fixed_size
+ EGLEW_ANGLE_window_fixed_size = _glewSearchExtension("EGL_ANGLE_window_fixed_size", extStart, extEnd);
+#endif /* EGL_ANGLE_window_fixed_size */
+#ifdef EGL_ARM_pixmap_multisample_discard
+ EGLEW_ARM_pixmap_multisample_discard = _glewSearchExtension("EGL_ARM_pixmap_multisample_discard", extStart, extEnd);
+#endif /* EGL_ARM_pixmap_multisample_discard */
+#ifdef EGL_EXT_buffer_age
+ EGLEW_EXT_buffer_age = _glewSearchExtension("EGL_EXT_buffer_age", extStart, extEnd);
+#endif /* EGL_EXT_buffer_age */
+#ifdef EGL_EXT_client_extensions
+ EGLEW_EXT_client_extensions = _glewSearchExtension("EGL_EXT_client_extensions", extStart, extEnd);
+#endif /* EGL_EXT_client_extensions */
+#ifdef EGL_EXT_create_context_robustness
+ EGLEW_EXT_create_context_robustness = _glewSearchExtension("EGL_EXT_create_context_robustness", extStart, extEnd);
+#endif /* EGL_EXT_create_context_robustness */
+#ifdef EGL_EXT_device_base
+ EGLEW_EXT_device_base = _glewSearchExtension("EGL_EXT_device_base", extStart, extEnd);
+#endif /* EGL_EXT_device_base */
+#ifdef EGL_EXT_device_drm
+ EGLEW_EXT_device_drm = _glewSearchExtension("EGL_EXT_device_drm", extStart, extEnd);
+#endif /* EGL_EXT_device_drm */
+#ifdef EGL_EXT_device_enumeration
+ EGLEW_EXT_device_enumeration = _glewSearchExtension("EGL_EXT_device_enumeration", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_device_enumeration) EGLEW_EXT_device_enumeration = !_glewInit_EGL_EXT_device_enumeration();
+#endif /* EGL_EXT_device_enumeration */
+#ifdef EGL_EXT_device_openwf
+ EGLEW_EXT_device_openwf = _glewSearchExtension("EGL_EXT_device_openwf", extStart, extEnd);
+#endif /* EGL_EXT_device_openwf */
+#ifdef EGL_EXT_device_query
+ EGLEW_EXT_device_query = _glewSearchExtension("EGL_EXT_device_query", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_device_query) EGLEW_EXT_device_query = !_glewInit_EGL_EXT_device_query();
+#endif /* EGL_EXT_device_query */
+#ifdef EGL_EXT_image_dma_buf_import
+ EGLEW_EXT_image_dma_buf_import = _glewSearchExtension("EGL_EXT_image_dma_buf_import", extStart, extEnd);
+#endif /* EGL_EXT_image_dma_buf_import */
+#ifdef EGL_EXT_multiview_window
+ EGLEW_EXT_multiview_window = _glewSearchExtension("EGL_EXT_multiview_window", extStart, extEnd);
+#endif /* EGL_EXT_multiview_window */
+#ifdef EGL_EXT_output_base
+ EGLEW_EXT_output_base = _glewSearchExtension("EGL_EXT_output_base", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_output_base) EGLEW_EXT_output_base = !_glewInit_EGL_EXT_output_base();
+#endif /* EGL_EXT_output_base */
+#ifdef EGL_EXT_output_drm
+ EGLEW_EXT_output_drm = _glewSearchExtension("EGL_EXT_output_drm", extStart, extEnd);
+#endif /* EGL_EXT_output_drm */
+#ifdef EGL_EXT_output_openwf
+ EGLEW_EXT_output_openwf = _glewSearchExtension("EGL_EXT_output_openwf", extStart, extEnd);
+#endif /* EGL_EXT_output_openwf */
+#ifdef EGL_EXT_platform_base
+ EGLEW_EXT_platform_base = _glewSearchExtension("EGL_EXT_platform_base", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_platform_base) EGLEW_EXT_platform_base = !_glewInit_EGL_EXT_platform_base();
+#endif /* EGL_EXT_platform_base */
+#ifdef EGL_EXT_platform_device
+ EGLEW_EXT_platform_device = _glewSearchExtension("EGL_EXT_platform_device", extStart, extEnd);
+#endif /* EGL_EXT_platform_device */
+#ifdef EGL_EXT_platform_wayland
+ EGLEW_EXT_platform_wayland = _glewSearchExtension("EGL_EXT_platform_wayland", extStart, extEnd);
+#endif /* EGL_EXT_platform_wayland */
+#ifdef EGL_EXT_platform_x11
+ EGLEW_EXT_platform_x11 = _glewSearchExtension("EGL_EXT_platform_x11", extStart, extEnd);
+#endif /* EGL_EXT_platform_x11 */
+#ifdef EGL_EXT_protected_content
+ EGLEW_EXT_protected_content = _glewSearchExtension("EGL_EXT_protected_content", extStart, extEnd);
+#endif /* EGL_EXT_protected_content */
+#ifdef EGL_EXT_protected_surface
+ EGLEW_EXT_protected_surface = _glewSearchExtension("EGL_EXT_protected_surface", extStart, extEnd);
+#endif /* EGL_EXT_protected_surface */
+#ifdef EGL_EXT_stream_consumer_egloutput
+ EGLEW_EXT_stream_consumer_egloutput = _glewSearchExtension("EGL_EXT_stream_consumer_egloutput", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_stream_consumer_egloutput) EGLEW_EXT_stream_consumer_egloutput = !_glewInit_EGL_EXT_stream_consumer_egloutput();
+#endif /* EGL_EXT_stream_consumer_egloutput */
+#ifdef EGL_EXT_swap_buffers_with_damage
+ EGLEW_EXT_swap_buffers_with_damage = _glewSearchExtension("EGL_EXT_swap_buffers_with_damage", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_swap_buffers_with_damage) EGLEW_EXT_swap_buffers_with_damage = !_glewInit_EGL_EXT_swap_buffers_with_damage();
+#endif /* EGL_EXT_swap_buffers_with_damage */
+#ifdef EGL_EXT_yuv_surface
+ EGLEW_EXT_yuv_surface = _glewSearchExtension("EGL_EXT_yuv_surface", extStart, extEnd);
+#endif /* EGL_EXT_yuv_surface */
+#ifdef EGL_HI_clientpixmap
+ EGLEW_HI_clientpixmap = _glewSearchExtension("EGL_HI_clientpixmap", extStart, extEnd);
+ if (glewExperimental || EGLEW_HI_clientpixmap) EGLEW_HI_clientpixmap = !_glewInit_EGL_HI_clientpixmap();
+#endif /* EGL_HI_clientpixmap */
+#ifdef EGL_HI_colorformats
+ EGLEW_HI_colorformats = _glewSearchExtension("EGL_HI_colorformats", extStart, extEnd);
+#endif /* EGL_HI_colorformats */
+#ifdef EGL_IMG_context_priority
+ EGLEW_IMG_context_priority = _glewSearchExtension("EGL_IMG_context_priority", extStart, extEnd);
+#endif /* EGL_IMG_context_priority */
+#ifdef EGL_IMG_image_plane_attribs
+ EGLEW_IMG_image_plane_attribs = _glewSearchExtension("EGL_IMG_image_plane_attribs", extStart, extEnd);
+#endif /* EGL_IMG_image_plane_attribs */
+#ifdef EGL_KHR_cl_event
+ EGLEW_KHR_cl_event = _glewSearchExtension("EGL_KHR_cl_event", extStart, extEnd);
+#endif /* EGL_KHR_cl_event */
+#ifdef EGL_KHR_cl_event2
+ EGLEW_KHR_cl_event2 = _glewSearchExtension("EGL_KHR_cl_event2", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_cl_event2) EGLEW_KHR_cl_event2 = !_glewInit_EGL_KHR_cl_event2();
+#endif /* EGL_KHR_cl_event2 */
+#ifdef EGL_KHR_client_get_all_proc_addresses
+ EGLEW_KHR_client_get_all_proc_addresses = _glewSearchExtension("EGL_KHR_client_get_all_proc_addresses", extStart, extEnd);
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+#ifdef EGL_KHR_config_attribs
+ EGLEW_KHR_config_attribs = _glewSearchExtension("EGL_KHR_config_attribs", extStart, extEnd);
+#endif /* EGL_KHR_config_attribs */
+#ifdef EGL_KHR_create_context
+ EGLEW_KHR_create_context = _glewSearchExtension("EGL_KHR_create_context", extStart, extEnd);
+#endif /* EGL_KHR_create_context */
+#ifdef EGL_KHR_create_context_no_error
+ EGLEW_KHR_create_context_no_error = _glewSearchExtension("EGL_KHR_create_context_no_error", extStart, extEnd);
+#endif /* EGL_KHR_create_context_no_error */
+#ifdef EGL_KHR_debug
+ EGLEW_KHR_debug = _glewSearchExtension("EGL_KHR_debug", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_debug) EGLEW_KHR_debug = !_glewInit_EGL_KHR_debug();
+#endif /* EGL_KHR_debug */
+#ifdef EGL_KHR_fence_sync
+ EGLEW_KHR_fence_sync = _glewSearchExtension("EGL_KHR_fence_sync", extStart, extEnd);
+#endif /* EGL_KHR_fence_sync */
+#ifdef EGL_KHR_get_all_proc_addresses
+ EGLEW_KHR_get_all_proc_addresses = _glewSearchExtension("EGL_KHR_get_all_proc_addresses", extStart, extEnd);
+#endif /* EGL_KHR_get_all_proc_addresses */
+#ifdef EGL_KHR_gl_colorspace
+ EGLEW_KHR_gl_colorspace = _glewSearchExtension("EGL_KHR_gl_colorspace", extStart, extEnd);
+#endif /* EGL_KHR_gl_colorspace */
+#ifdef EGL_KHR_gl_renderbuffer_image
+ EGLEW_KHR_gl_renderbuffer_image = _glewSearchExtension("EGL_KHR_gl_renderbuffer_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_renderbuffer_image */
+#ifdef EGL_KHR_gl_texture_2D_image
+ EGLEW_KHR_gl_texture_2D_image = _glewSearchExtension("EGL_KHR_gl_texture_2D_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_texture_2D_image */
+#ifdef EGL_KHR_gl_texture_3D_image
+ EGLEW_KHR_gl_texture_3D_image = _glewSearchExtension("EGL_KHR_gl_texture_3D_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_texture_3D_image */
+#ifdef EGL_KHR_gl_texture_cubemap_image
+ EGLEW_KHR_gl_texture_cubemap_image = _glewSearchExtension("EGL_KHR_gl_texture_cubemap_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+#ifdef EGL_KHR_image
+ EGLEW_KHR_image = _glewSearchExtension("EGL_KHR_image", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_image) EGLEW_KHR_image = !_glewInit_EGL_KHR_image();
+#endif /* EGL_KHR_image */
+#ifdef EGL_KHR_image_base
+ EGLEW_KHR_image_base = _glewSearchExtension("EGL_KHR_image_base", extStart, extEnd);
+#endif /* EGL_KHR_image_base */
+#ifdef EGL_KHR_image_pixmap
+ EGLEW_KHR_image_pixmap = _glewSearchExtension("EGL_KHR_image_pixmap", extStart, extEnd);
+#endif /* EGL_KHR_image_pixmap */
+#ifdef EGL_KHR_lock_surface
+ EGLEW_KHR_lock_surface = _glewSearchExtension("EGL_KHR_lock_surface", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_lock_surface) EGLEW_KHR_lock_surface = !_glewInit_EGL_KHR_lock_surface();
+#endif /* EGL_KHR_lock_surface */
+#ifdef EGL_KHR_lock_surface2
+ EGLEW_KHR_lock_surface2 = _glewSearchExtension("EGL_KHR_lock_surface2", extStart, extEnd);
+#endif /* EGL_KHR_lock_surface2 */
+#ifdef EGL_KHR_lock_surface3
+ EGLEW_KHR_lock_surface3 = _glewSearchExtension("EGL_KHR_lock_surface3", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_lock_surface3) EGLEW_KHR_lock_surface3 = !_glewInit_EGL_KHR_lock_surface3();
+#endif /* EGL_KHR_lock_surface3 */
+#ifdef EGL_KHR_mutable_render_buffer
+ EGLEW_KHR_mutable_render_buffer = _glewSearchExtension("EGL_KHR_mutable_render_buffer", extStart, extEnd);
+#endif /* EGL_KHR_mutable_render_buffer */
+#ifdef EGL_KHR_partial_update
+ EGLEW_KHR_partial_update = _glewSearchExtension("EGL_KHR_partial_update", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_partial_update) EGLEW_KHR_partial_update = !_glewInit_EGL_KHR_partial_update();
+#endif /* EGL_KHR_partial_update */
+#ifdef EGL_KHR_platform_android
+ EGLEW_KHR_platform_android = _glewSearchExtension("EGL_KHR_platform_android", extStart, extEnd);
+#endif /* EGL_KHR_platform_android */
+#ifdef EGL_KHR_platform_gbm
+ EGLEW_KHR_platform_gbm = _glewSearchExtension("EGL_KHR_platform_gbm", extStart, extEnd);
+#endif /* EGL_KHR_platform_gbm */
+#ifdef EGL_KHR_platform_wayland
+ EGLEW_KHR_platform_wayland = _glewSearchExtension("EGL_KHR_platform_wayland", extStart, extEnd);
+#endif /* EGL_KHR_platform_wayland */
+#ifdef EGL_KHR_platform_x11
+ EGLEW_KHR_platform_x11 = _glewSearchExtension("EGL_KHR_platform_x11", extStart, extEnd);
+#endif /* EGL_KHR_platform_x11 */
+#ifdef EGL_KHR_reusable_sync
+ EGLEW_KHR_reusable_sync = _glewSearchExtension("EGL_KHR_reusable_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_reusable_sync) EGLEW_KHR_reusable_sync = !_glewInit_EGL_KHR_reusable_sync();
+#endif /* EGL_KHR_reusable_sync */
+#ifdef EGL_KHR_stream
+ EGLEW_KHR_stream = _glewSearchExtension("EGL_KHR_stream", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream) EGLEW_KHR_stream = !_glewInit_EGL_KHR_stream();
+#endif /* EGL_KHR_stream */
+#ifdef EGL_KHR_stream_consumer_gltexture
+ EGLEW_KHR_stream_consumer_gltexture = _glewSearchExtension("EGL_KHR_stream_consumer_gltexture", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_consumer_gltexture) EGLEW_KHR_stream_consumer_gltexture = !_glewInit_EGL_KHR_stream_consumer_gltexture();
+#endif /* EGL_KHR_stream_consumer_gltexture */
+#ifdef EGL_KHR_stream_cross_process_fd
+ EGLEW_KHR_stream_cross_process_fd = _glewSearchExtension("EGL_KHR_stream_cross_process_fd", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_cross_process_fd) EGLEW_KHR_stream_cross_process_fd = !_glewInit_EGL_KHR_stream_cross_process_fd();
+#endif /* EGL_KHR_stream_cross_process_fd */
+#ifdef EGL_KHR_stream_fifo
+ EGLEW_KHR_stream_fifo = _glewSearchExtension("EGL_KHR_stream_fifo", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_fifo) EGLEW_KHR_stream_fifo = !_glewInit_EGL_KHR_stream_fifo();
+#endif /* EGL_KHR_stream_fifo */
+#ifdef EGL_KHR_stream_producer_aldatalocator
+ EGLEW_KHR_stream_producer_aldatalocator = _glewSearchExtension("EGL_KHR_stream_producer_aldatalocator", extStart, extEnd);
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+#ifdef EGL_KHR_stream_producer_eglsurface
+ EGLEW_KHR_stream_producer_eglsurface = _glewSearchExtension("EGL_KHR_stream_producer_eglsurface", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_producer_eglsurface) EGLEW_KHR_stream_producer_eglsurface = !_glewInit_EGL_KHR_stream_producer_eglsurface();
+#endif /* EGL_KHR_stream_producer_eglsurface */
+#ifdef EGL_KHR_surfaceless_context
+ EGLEW_KHR_surfaceless_context = _glewSearchExtension("EGL_KHR_surfaceless_context", extStart, extEnd);
+#endif /* EGL_KHR_surfaceless_context */
+#ifdef EGL_KHR_swap_buffers_with_damage
+ EGLEW_KHR_swap_buffers_with_damage = _glewSearchExtension("EGL_KHR_swap_buffers_with_damage", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_swap_buffers_with_damage) EGLEW_KHR_swap_buffers_with_damage = !_glewInit_EGL_KHR_swap_buffers_with_damage();
+#endif /* EGL_KHR_swap_buffers_with_damage */
+#ifdef EGL_KHR_vg_parent_image
+ EGLEW_KHR_vg_parent_image = _glewSearchExtension("EGL_KHR_vg_parent_image", extStart, extEnd);
+#endif /* EGL_KHR_vg_parent_image */
+#ifdef EGL_KHR_wait_sync
+ EGLEW_KHR_wait_sync = _glewSearchExtension("EGL_KHR_wait_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_wait_sync) EGLEW_KHR_wait_sync = !_glewInit_EGL_KHR_wait_sync();
+#endif /* EGL_KHR_wait_sync */
+#ifdef EGL_MESA_drm_image
+ EGLEW_MESA_drm_image = _glewSearchExtension("EGL_MESA_drm_image", extStart, extEnd);
+ if (glewExperimental || EGLEW_MESA_drm_image) EGLEW_MESA_drm_image = !_glewInit_EGL_MESA_drm_image();
+#endif /* EGL_MESA_drm_image */
+#ifdef EGL_MESA_image_dma_buf_export
+ EGLEW_MESA_image_dma_buf_export = _glewSearchExtension("EGL_MESA_image_dma_buf_export", extStart, extEnd);
+ if (glewExperimental || EGLEW_MESA_image_dma_buf_export) EGLEW_MESA_image_dma_buf_export = !_glewInit_EGL_MESA_image_dma_buf_export();
+#endif /* EGL_MESA_image_dma_buf_export */
+#ifdef EGL_MESA_platform_gbm
+ EGLEW_MESA_platform_gbm = _glewSearchExtension("EGL_MESA_platform_gbm", extStart, extEnd);
+#endif /* EGL_MESA_platform_gbm */
+#ifdef EGL_NOK_swap_region
+ EGLEW_NOK_swap_region = _glewSearchExtension("EGL_NOK_swap_region", extStart, extEnd);
+ if (glewExperimental || EGLEW_NOK_swap_region) EGLEW_NOK_swap_region = !_glewInit_EGL_NOK_swap_region();
+#endif /* EGL_NOK_swap_region */
+#ifdef EGL_NOK_swap_region2
+ EGLEW_NOK_swap_region2 = _glewSearchExtension("EGL_NOK_swap_region2", extStart, extEnd);
+ if (glewExperimental || EGLEW_NOK_swap_region2) EGLEW_NOK_swap_region2 = !_glewInit_EGL_NOK_swap_region2();
+#endif /* EGL_NOK_swap_region2 */
+#ifdef EGL_NOK_texture_from_pixmap
+ EGLEW_NOK_texture_from_pixmap = _glewSearchExtension("EGL_NOK_texture_from_pixmap", extStart, extEnd);
+#endif /* EGL_NOK_texture_from_pixmap */
+#ifdef EGL_NV_3dvision_surface
+ EGLEW_NV_3dvision_surface = _glewSearchExtension("EGL_NV_3dvision_surface", extStart, extEnd);
+#endif /* EGL_NV_3dvision_surface */
+#ifdef EGL_NV_coverage_sample
+ EGLEW_NV_coverage_sample = _glewSearchExtension("EGL_NV_coverage_sample", extStart, extEnd);
+#endif /* EGL_NV_coverage_sample */
+#ifdef EGL_NV_coverage_sample_resolve
+ EGLEW_NV_coverage_sample_resolve = _glewSearchExtension("EGL_NV_coverage_sample_resolve", extStart, extEnd);
+#endif /* EGL_NV_coverage_sample_resolve */
+#ifdef EGL_NV_cuda_event
+ EGLEW_NV_cuda_event = _glewSearchExtension("EGL_NV_cuda_event", extStart, extEnd);
+#endif /* EGL_NV_cuda_event */
+#ifdef EGL_NV_depth_nonlinear
+ EGLEW_NV_depth_nonlinear = _glewSearchExtension("EGL_NV_depth_nonlinear", extStart, extEnd);
+#endif /* EGL_NV_depth_nonlinear */
+#ifdef EGL_NV_device_cuda
+ EGLEW_NV_device_cuda = _glewSearchExtension("EGL_NV_device_cuda", extStart, extEnd);
+#endif /* EGL_NV_device_cuda */
+#ifdef EGL_NV_native_query
+ EGLEW_NV_native_query = _glewSearchExtension("EGL_NV_native_query", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_native_query) EGLEW_NV_native_query = !_glewInit_EGL_NV_native_query();
+#endif /* EGL_NV_native_query */
+#ifdef EGL_NV_post_convert_rounding
+ EGLEW_NV_post_convert_rounding = _glewSearchExtension("EGL_NV_post_convert_rounding", extStart, extEnd);
+#endif /* EGL_NV_post_convert_rounding */
+#ifdef EGL_NV_post_sub_buffer
+ EGLEW_NV_post_sub_buffer = _glewSearchExtension("EGL_NV_post_sub_buffer", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_post_sub_buffer) EGLEW_NV_post_sub_buffer = !_glewInit_EGL_NV_post_sub_buffer();
+#endif /* EGL_NV_post_sub_buffer */
+#ifdef EGL_NV_robustness_video_memory_purge
+ EGLEW_NV_robustness_video_memory_purge = _glewSearchExtension("EGL_NV_robustness_video_memory_purge", extStart, extEnd);
+#endif /* EGL_NV_robustness_video_memory_purge */
+#ifdef EGL_NV_stream_consumer_gltexture_yuv
+ EGLEW_NV_stream_consumer_gltexture_yuv = _glewSearchExtension("EGL_NV_stream_consumer_gltexture_yuv", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_consumer_gltexture_yuv) EGLEW_NV_stream_consumer_gltexture_yuv = !_glewInit_EGL_NV_stream_consumer_gltexture_yuv();
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+#ifdef EGL_NV_stream_metadata
+ EGLEW_NV_stream_metadata = _glewSearchExtension("EGL_NV_stream_metadata", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_metadata) EGLEW_NV_stream_metadata = !_glewInit_EGL_NV_stream_metadata();
+#endif /* EGL_NV_stream_metadata */
+#ifdef EGL_NV_stream_sync
+ EGLEW_NV_stream_sync = _glewSearchExtension("EGL_NV_stream_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_sync) EGLEW_NV_stream_sync = !_glewInit_EGL_NV_stream_sync();
+#endif /* EGL_NV_stream_sync */
+#ifdef EGL_NV_sync
+ EGLEW_NV_sync = _glewSearchExtension("EGL_NV_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_sync) EGLEW_NV_sync = !_glewInit_EGL_NV_sync();
+#endif /* EGL_NV_sync */
+#ifdef EGL_NV_system_time
+ EGLEW_NV_system_time = _glewSearchExtension("EGL_NV_system_time", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_system_time) EGLEW_NV_system_time = !_glewInit_EGL_NV_system_time();
+#endif /* EGL_NV_system_time */
+#ifdef EGL_TIZEN_image_native_buffer
+ EGLEW_TIZEN_image_native_buffer = _glewSearchExtension("EGL_TIZEN_image_native_buffer", extStart, extEnd);
+#endif /* EGL_TIZEN_image_native_buffer */
+#ifdef EGL_TIZEN_image_native_surface
+ EGLEW_TIZEN_image_native_surface = _glewSearchExtension("EGL_TIZEN_image_native_surface", extStart, extEnd);
+#endif /* EGL_TIZEN_image_native_surface */
+
+ return GLEW_OK;
+}
-#if !defined(GLEW_MX)
+#elif defined(_WIN32)
PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL;
@@ -11569,12 +15980,9 @@ GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE;
GLboolean __WGLEW_NV_video_capture = GL_FALSE;
GLboolean __WGLEW_NV_video_output = GL_FALSE;
GLboolean __WGLEW_OML_sync_control = GL_FALSE;
-
-#endif /* !GLEW_MX */
-
#ifdef WGL_3DL_stereo_control
-static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_3DL_stereo_control ()
{
GLboolean r = GL_FALSE;
@@ -11587,7 +15995,7 @@ static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_AMD_gpu_association
-static GLboolean _glewInit_WGL_AMD_gpu_association (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_AMD_gpu_association ()
{
GLboolean r = GL_FALSE;
@@ -11608,7 +16016,7 @@ static GLboolean _glewInit_WGL_AMD_gpu_association (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_ARB_buffer_region
-static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_buffer_region ()
{
GLboolean r = GL_FALSE;
@@ -11624,7 +16032,7 @@ static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_ARB_create_context
-static GLboolean _glewInit_WGL_ARB_create_context (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_create_context ()
{
GLboolean r = GL_FALSE;
@@ -11637,7 +16045,7 @@ static GLboolean _glewInit_WGL_ARB_create_context (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_ARB_extensions_string
-static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_extensions_string ()
{
GLboolean r = GL_FALSE;
@@ -11650,7 +16058,7 @@ static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT
#ifdef WGL_ARB_make_current_read
-static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_make_current_read ()
{
GLboolean r = GL_FALSE;
@@ -11664,7 +16072,7 @@ static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT
#ifdef WGL_ARB_pbuffer
-static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_pbuffer ()
{
GLboolean r = GL_FALSE;
@@ -11681,7 +16089,7 @@ static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_ARB_pixel_format
-static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_pixel_format ()
{
GLboolean r = GL_FALSE;
@@ -11696,7 +16104,7 @@ static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_ARB_render_texture
-static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_ARB_render_texture ()
{
GLboolean r = GL_FALSE;
@@ -11711,7 +16119,7 @@ static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_EXT_display_color_table
-static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_EXT_display_color_table ()
{
GLboolean r = GL_FALSE;
@@ -11727,7 +16135,7 @@ static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_IN
#ifdef WGL_EXT_extensions_string
-static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_EXT_extensions_string ()
{
GLboolean r = GL_FALSE;
@@ -11740,7 +16148,7 @@ static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT
#ifdef WGL_EXT_make_current_read
-static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_EXT_make_current_read ()
{
GLboolean r = GL_FALSE;
@@ -11754,7 +16162,7 @@ static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT
#ifdef WGL_EXT_pbuffer
-static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_EXT_pbuffer ()
{
GLboolean r = GL_FALSE;
@@ -11771,7 +16179,7 @@ static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_EXT_pixel_format
-static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_EXT_pixel_format ()
{
GLboolean r = GL_FALSE;
@@ -11786,7 +16194,7 @@ static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_EXT_swap_control
-static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_EXT_swap_control ()
{
GLboolean r = GL_FALSE;
@@ -11800,7 +16208,7 @@ static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_I3D_digital_video_control
-static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_I3D_digital_video_control ()
{
GLboolean r = GL_FALSE;
@@ -11814,7 +16222,7 @@ static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_
#ifdef WGL_I3D_gamma
-static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_I3D_gamma ()
{
GLboolean r = GL_FALSE;
@@ -11830,7 +16238,7 @@ static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_I3D_genlock
-static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_I3D_genlock ()
{
GLboolean r = GL_FALSE;
@@ -11854,7 +16262,7 @@ static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_I3D_image_buffer
-static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_I3D_image_buffer ()
{
GLboolean r = GL_FALSE;
@@ -11870,7 +16278,7 @@ static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_I3D_swap_frame_lock
-static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_I3D_swap_frame_lock ()
{
GLboolean r = GL_FALSE;
@@ -11886,7 +16294,7 @@ static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_I3D_swap_frame_usage
-static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_I3D_swap_frame_usage ()
{
GLboolean r = GL_FALSE;
@@ -11902,7 +16310,7 @@ static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_DX_interop
-static GLboolean _glewInit_WGL_NV_DX_interop (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_DX_interop ()
{
GLboolean r = GL_FALSE;
@@ -11922,7 +16330,7 @@ static GLboolean _glewInit_WGL_NV_DX_interop (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_copy_image
-static GLboolean _glewInit_WGL_NV_copy_image (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_copy_image ()
{
GLboolean r = GL_FALSE;
@@ -11935,7 +16343,7 @@ static GLboolean _glewInit_WGL_NV_copy_image (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_delay_before_swap
-static GLboolean _glewInit_WGL_NV_delay_before_swap (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_delay_before_swap ()
{
GLboolean r = GL_FALSE;
@@ -11948,7 +16356,7 @@ static GLboolean _glewInit_WGL_NV_delay_before_swap (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_gpu_affinity
-static GLboolean _glewInit_WGL_NV_gpu_affinity (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_gpu_affinity ()
{
GLboolean r = GL_FALSE;
@@ -11965,7 +16373,7 @@ static GLboolean _glewInit_WGL_NV_gpu_affinity (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_present_video
-static GLboolean _glewInit_WGL_NV_present_video (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_present_video ()
{
GLboolean r = GL_FALSE;
@@ -11980,7 +16388,7 @@ static GLboolean _glewInit_WGL_NV_present_video (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_swap_group
-static GLboolean _glewInit_WGL_NV_swap_group (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_swap_group ()
{
GLboolean r = GL_FALSE;
@@ -11998,7 +16406,7 @@ static GLboolean _glewInit_WGL_NV_swap_group (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_vertex_array_range
-static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_vertex_array_range ()
{
GLboolean r = GL_FALSE;
@@ -12012,7 +16420,7 @@ static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT
#ifdef WGL_NV_video_capture
-static GLboolean _glewInit_WGL_NV_video_capture (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_video_capture ()
{
GLboolean r = GL_FALSE;
@@ -12029,7 +16437,7 @@ static GLboolean _glewInit_WGL_NV_video_capture (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_NV_video_output
-static GLboolean _glewInit_WGL_NV_video_output (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_NV_video_output ()
{
GLboolean r = GL_FALSE;
@@ -12047,7 +16455,7 @@ static GLboolean _glewInit_WGL_NV_video_output (WGLEW_CONTEXT_ARG_DEF_INIT)
#ifdef WGL_OML_sync_control
-static GLboolean _glewInit_WGL_OML_sync_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_WGL_OML_sync_control ()
{
GLboolean r = GL_FALSE;
@@ -12085,11 +16493,7 @@ GLboolean GLEWAPIENTRY wglewGetExtension (const char* name)
return _glewSearchExtension(name, start, end);
}
-#ifdef GLEW_MX
-GLenum GLEWAPIENTRY wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST)
-#else
-GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
-#endif
+GLenum GLEWAPIENTRY wglewInit ()
{
GLboolean crippled;
const GLubyte* extStart;
@@ -12113,22 +16517,22 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
#endif /* WGL_3DFX_multisample */
#ifdef WGL_3DL_stereo_control
WGLEW_3DL_stereo_control = _glewSearchExtension("WGL_3DL_stereo_control", extStart, extEnd);
- if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) WGLEW_3DL_stereo_control= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) WGLEW_3DL_stereo_control= !_glewInit_WGL_3DL_stereo_control();
#endif /* WGL_3DL_stereo_control */
#ifdef WGL_AMD_gpu_association
WGLEW_AMD_gpu_association = _glewSearchExtension("WGL_AMD_gpu_association", extStart, extEnd);
- if (glewExperimental || WGLEW_AMD_gpu_association|| crippled) WGLEW_AMD_gpu_association= !_glewInit_WGL_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_AMD_gpu_association|| crippled) WGLEW_AMD_gpu_association= !_glewInit_WGL_AMD_gpu_association();
#endif /* WGL_AMD_gpu_association */
#ifdef WGL_ARB_buffer_region
WGLEW_ARB_buffer_region = _glewSearchExtension("WGL_ARB_buffer_region", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) WGLEW_ARB_buffer_region= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) WGLEW_ARB_buffer_region= !_glewInit_WGL_ARB_buffer_region();
#endif /* WGL_ARB_buffer_region */
#ifdef WGL_ARB_context_flush_control
WGLEW_ARB_context_flush_control = _glewSearchExtension("WGL_ARB_context_flush_control", extStart, extEnd);
#endif /* WGL_ARB_context_flush_control */
#ifdef WGL_ARB_create_context
WGLEW_ARB_create_context = _glewSearchExtension("WGL_ARB_create_context", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_create_context|| crippled) WGLEW_ARB_create_context= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_create_context|| crippled) WGLEW_ARB_create_context= !_glewInit_WGL_ARB_create_context();
#endif /* WGL_ARB_create_context */
#ifdef WGL_ARB_create_context_profile
WGLEW_ARB_create_context_profile = _glewSearchExtension("WGL_ARB_create_context_profile", extStart, extEnd);
@@ -12138,32 +16542,32 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
#endif /* WGL_ARB_create_context_robustness */
#ifdef WGL_ARB_extensions_string
WGLEW_ARB_extensions_string = _glewSearchExtension("WGL_ARB_extensions_string", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) WGLEW_ARB_extensions_string= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) WGLEW_ARB_extensions_string= !_glewInit_WGL_ARB_extensions_string();
#endif /* WGL_ARB_extensions_string */
#ifdef WGL_ARB_framebuffer_sRGB
WGLEW_ARB_framebuffer_sRGB = _glewSearchExtension("WGL_ARB_framebuffer_sRGB", extStart, extEnd);
#endif /* WGL_ARB_framebuffer_sRGB */
#ifdef WGL_ARB_make_current_read
WGLEW_ARB_make_current_read = _glewSearchExtension("WGL_ARB_make_current_read", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) WGLEW_ARB_make_current_read= !_glewInit_WGL_ARB_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) WGLEW_ARB_make_current_read= !_glewInit_WGL_ARB_make_current_read();
#endif /* WGL_ARB_make_current_read */
#ifdef WGL_ARB_multisample
WGLEW_ARB_multisample = _glewSearchExtension("WGL_ARB_multisample", extStart, extEnd);
#endif /* WGL_ARB_multisample */
#ifdef WGL_ARB_pbuffer
WGLEW_ARB_pbuffer = _glewSearchExtension("WGL_ARB_pbuffer", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) WGLEW_ARB_pbuffer= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) WGLEW_ARB_pbuffer= !_glewInit_WGL_ARB_pbuffer();
#endif /* WGL_ARB_pbuffer */
#ifdef WGL_ARB_pixel_format
WGLEW_ARB_pixel_format = _glewSearchExtension("WGL_ARB_pixel_format", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) WGLEW_ARB_pixel_format= !_glewInit_WGL_ARB_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) WGLEW_ARB_pixel_format= !_glewInit_WGL_ARB_pixel_format();
#endif /* WGL_ARB_pixel_format */
#ifdef WGL_ARB_pixel_format_float
WGLEW_ARB_pixel_format_float = _glewSearchExtension("WGL_ARB_pixel_format_float", extStart, extEnd);
#endif /* WGL_ARB_pixel_format_float */
#ifdef WGL_ARB_render_texture
WGLEW_ARB_render_texture = _glewSearchExtension("WGL_ARB_render_texture", extStart, extEnd);
- if (glewExperimental || WGLEW_ARB_render_texture|| crippled) WGLEW_ARB_render_texture= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_ARB_render_texture|| crippled) WGLEW_ARB_render_texture= !_glewInit_WGL_ARB_render_texture();
#endif /* WGL_ARB_render_texture */
#ifdef WGL_ARB_robustness_application_isolation
WGLEW_ARB_robustness_application_isolation = _glewSearchExtension("WGL_ARB_robustness_application_isolation", extStart, extEnd);
@@ -12188,92 +16592,92 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
#endif /* WGL_EXT_depth_float */
#ifdef WGL_EXT_display_color_table
WGLEW_EXT_display_color_table = _glewSearchExtension("WGL_EXT_display_color_table", extStart, extEnd);
- if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) WGLEW_EXT_display_color_table= !_glewInit_WGL_EXT_display_color_table(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) WGLEW_EXT_display_color_table= !_glewInit_WGL_EXT_display_color_table();
#endif /* WGL_EXT_display_color_table */
#ifdef WGL_EXT_extensions_string
WGLEW_EXT_extensions_string = _glewSearchExtension("WGL_EXT_extensions_string", extStart, extEnd);
- if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) WGLEW_EXT_extensions_string= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) WGLEW_EXT_extensions_string= !_glewInit_WGL_EXT_extensions_string();
#endif /* WGL_EXT_extensions_string */
#ifdef WGL_EXT_framebuffer_sRGB
WGLEW_EXT_framebuffer_sRGB = _glewSearchExtension("WGL_EXT_framebuffer_sRGB", extStart, extEnd);
#endif /* WGL_EXT_framebuffer_sRGB */
#ifdef WGL_EXT_make_current_read
WGLEW_EXT_make_current_read = _glewSearchExtension("WGL_EXT_make_current_read", extStart, extEnd);
- if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) WGLEW_EXT_make_current_read= !_glewInit_WGL_EXT_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) WGLEW_EXT_make_current_read= !_glewInit_WGL_EXT_make_current_read();
#endif /* WGL_EXT_make_current_read */
#ifdef WGL_EXT_multisample
WGLEW_EXT_multisample = _glewSearchExtension("WGL_EXT_multisample", extStart, extEnd);
#endif /* WGL_EXT_multisample */
#ifdef WGL_EXT_pbuffer
WGLEW_EXT_pbuffer = _glewSearchExtension("WGL_EXT_pbuffer", extStart, extEnd);
- if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) WGLEW_EXT_pbuffer= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) WGLEW_EXT_pbuffer= !_glewInit_WGL_EXT_pbuffer();
#endif /* WGL_EXT_pbuffer */
#ifdef WGL_EXT_pixel_format
WGLEW_EXT_pixel_format = _glewSearchExtension("WGL_EXT_pixel_format", extStart, extEnd);
- if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) WGLEW_EXT_pixel_format= !_glewInit_WGL_EXT_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) WGLEW_EXT_pixel_format= !_glewInit_WGL_EXT_pixel_format();
#endif /* WGL_EXT_pixel_format */
#ifdef WGL_EXT_pixel_format_packed_float
WGLEW_EXT_pixel_format_packed_float = _glewSearchExtension("WGL_EXT_pixel_format_packed_float", extStart, extEnd);
#endif /* WGL_EXT_pixel_format_packed_float */
#ifdef WGL_EXT_swap_control
WGLEW_EXT_swap_control = _glewSearchExtension("WGL_EXT_swap_control", extStart, extEnd);
- if (glewExperimental || WGLEW_EXT_swap_control|| crippled) WGLEW_EXT_swap_control= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_EXT_swap_control|| crippled) WGLEW_EXT_swap_control= !_glewInit_WGL_EXT_swap_control();
#endif /* WGL_EXT_swap_control */
#ifdef WGL_EXT_swap_control_tear
WGLEW_EXT_swap_control_tear = _glewSearchExtension("WGL_EXT_swap_control_tear", extStart, extEnd);
#endif /* WGL_EXT_swap_control_tear */
#ifdef WGL_I3D_digital_video_control
WGLEW_I3D_digital_video_control = _glewSearchExtension("WGL_I3D_digital_video_control", extStart, extEnd);
- if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) WGLEW_I3D_digital_video_control= !_glewInit_WGL_I3D_digital_video_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) WGLEW_I3D_digital_video_control= !_glewInit_WGL_I3D_digital_video_control();
#endif /* WGL_I3D_digital_video_control */
#ifdef WGL_I3D_gamma
WGLEW_I3D_gamma = _glewSearchExtension("WGL_I3D_gamma", extStart, extEnd);
- if (glewExperimental || WGLEW_I3D_gamma|| crippled) WGLEW_I3D_gamma= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_I3D_gamma|| crippled) WGLEW_I3D_gamma= !_glewInit_WGL_I3D_gamma();
#endif /* WGL_I3D_gamma */
#ifdef WGL_I3D_genlock
WGLEW_I3D_genlock = _glewSearchExtension("WGL_I3D_genlock", extStart, extEnd);
- if (glewExperimental || WGLEW_I3D_genlock|| crippled) WGLEW_I3D_genlock= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_I3D_genlock|| crippled) WGLEW_I3D_genlock= !_glewInit_WGL_I3D_genlock();
#endif /* WGL_I3D_genlock */
#ifdef WGL_I3D_image_buffer
WGLEW_I3D_image_buffer = _glewSearchExtension("WGL_I3D_image_buffer", extStart, extEnd);
- if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) WGLEW_I3D_image_buffer= !_glewInit_WGL_I3D_image_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) WGLEW_I3D_image_buffer= !_glewInit_WGL_I3D_image_buffer();
#endif /* WGL_I3D_image_buffer */
#ifdef WGL_I3D_swap_frame_lock
WGLEW_I3D_swap_frame_lock = _glewSearchExtension("WGL_I3D_swap_frame_lock", extStart, extEnd);
- if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) WGLEW_I3D_swap_frame_lock= !_glewInit_WGL_I3D_swap_frame_lock(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) WGLEW_I3D_swap_frame_lock= !_glewInit_WGL_I3D_swap_frame_lock();
#endif /* WGL_I3D_swap_frame_lock */
#ifdef WGL_I3D_swap_frame_usage
WGLEW_I3D_swap_frame_usage = _glewSearchExtension("WGL_I3D_swap_frame_usage", extStart, extEnd);
- if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) WGLEW_I3D_swap_frame_usage= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) WGLEW_I3D_swap_frame_usage= !_glewInit_WGL_I3D_swap_frame_usage();
#endif /* WGL_I3D_swap_frame_usage */
#ifdef WGL_NV_DX_interop
WGLEW_NV_DX_interop = _glewSearchExtension("WGL_NV_DX_interop", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_DX_interop|| crippled) WGLEW_NV_DX_interop= !_glewInit_WGL_NV_DX_interop(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_DX_interop|| crippled) WGLEW_NV_DX_interop= !_glewInit_WGL_NV_DX_interop();
#endif /* WGL_NV_DX_interop */
#ifdef WGL_NV_DX_interop2
WGLEW_NV_DX_interop2 = _glewSearchExtension("WGL_NV_DX_interop2", extStart, extEnd);
#endif /* WGL_NV_DX_interop2 */
#ifdef WGL_NV_copy_image
WGLEW_NV_copy_image = _glewSearchExtension("WGL_NV_copy_image", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_copy_image|| crippled) WGLEW_NV_copy_image= !_glewInit_WGL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_copy_image|| crippled) WGLEW_NV_copy_image= !_glewInit_WGL_NV_copy_image();
#endif /* WGL_NV_copy_image */
#ifdef WGL_NV_delay_before_swap
WGLEW_NV_delay_before_swap = _glewSearchExtension("WGL_NV_delay_before_swap", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_delay_before_swap|| crippled) WGLEW_NV_delay_before_swap= !_glewInit_WGL_NV_delay_before_swap(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_delay_before_swap|| crippled) WGLEW_NV_delay_before_swap= !_glewInit_WGL_NV_delay_before_swap();
#endif /* WGL_NV_delay_before_swap */
#ifdef WGL_NV_float_buffer
WGLEW_NV_float_buffer = _glewSearchExtension("WGL_NV_float_buffer", extStart, extEnd);
#endif /* WGL_NV_float_buffer */
#ifdef WGL_NV_gpu_affinity
WGLEW_NV_gpu_affinity = _glewSearchExtension("WGL_NV_gpu_affinity", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) WGLEW_NV_gpu_affinity= !_glewInit_WGL_NV_gpu_affinity(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) WGLEW_NV_gpu_affinity= !_glewInit_WGL_NV_gpu_affinity();
#endif /* WGL_NV_gpu_affinity */
#ifdef WGL_NV_multisample_coverage
WGLEW_NV_multisample_coverage = _glewSearchExtension("WGL_NV_multisample_coverage", extStart, extEnd);
#endif /* WGL_NV_multisample_coverage */
#ifdef WGL_NV_present_video
WGLEW_NV_present_video = _glewSearchExtension("WGL_NV_present_video", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_present_video|| crippled) WGLEW_NV_present_video= !_glewInit_WGL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_present_video|| crippled) WGLEW_NV_present_video= !_glewInit_WGL_NV_present_video();
#endif /* WGL_NV_present_video */
#ifdef WGL_NV_render_depth_texture
WGLEW_NV_render_depth_texture = _glewSearchExtension("WGL_NV_render_depth_texture", extStart, extEnd);
@@ -12283,23 +16687,23 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
#endif /* WGL_NV_render_texture_rectangle */
#ifdef WGL_NV_swap_group
WGLEW_NV_swap_group = _glewSearchExtension("WGL_NV_swap_group", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_swap_group|| crippled) WGLEW_NV_swap_group= !_glewInit_WGL_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_swap_group|| crippled) WGLEW_NV_swap_group= !_glewInit_WGL_NV_swap_group();
#endif /* WGL_NV_swap_group */
#ifdef WGL_NV_vertex_array_range
WGLEW_NV_vertex_array_range = _glewSearchExtension("WGL_NV_vertex_array_range", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) WGLEW_NV_vertex_array_range= !_glewInit_WGL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) WGLEW_NV_vertex_array_range= !_glewInit_WGL_NV_vertex_array_range();
#endif /* WGL_NV_vertex_array_range */
#ifdef WGL_NV_video_capture
WGLEW_NV_video_capture = _glewSearchExtension("WGL_NV_video_capture", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_video_capture|| crippled) WGLEW_NV_video_capture= !_glewInit_WGL_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_video_capture|| crippled) WGLEW_NV_video_capture= !_glewInit_WGL_NV_video_capture();
#endif /* WGL_NV_video_capture */
#ifdef WGL_NV_video_output
WGLEW_NV_video_output = _glewSearchExtension("WGL_NV_video_output", extStart, extEnd);
- if (glewExperimental || WGLEW_NV_video_output|| crippled) WGLEW_NV_video_output= !_glewInit_WGL_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_NV_video_output|| crippled) WGLEW_NV_video_output= !_glewInit_WGL_NV_video_output();
#endif /* WGL_NV_video_output */
#ifdef WGL_OML_sync_control
WGLEW_OML_sync_control = _glewSearchExtension("WGL_OML_sync_control", extStart, extEnd);
- if (glewExperimental || WGLEW_OML_sync_control|| crippled) WGLEW_OML_sync_control= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || WGLEW_OML_sync_control|| crippled) WGLEW_OML_sync_control= !_glewInit_WGL_OML_sync_control();
#endif /* WGL_OML_sync_control */
return GLEW_OK;
@@ -12458,8 +16862,6 @@ PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL;
PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL;
PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL;
-#if !defined(GLEW_MX)
-
GLboolean __GLXEW_VERSION_1_0 = GL_FALSE;
GLboolean __GLXEW_VERSION_1_1 = GL_FALSE;
GLboolean __GLXEW_VERSION_1_2 = GL_FALSE;
@@ -12486,6 +16888,7 @@ GLboolean __GLXEW_EXT_create_context_es_profile = GL_FALSE;
GLboolean __GLXEW_EXT_fbconfig_packed_float = GL_FALSE;
GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE;
GLboolean __GLXEW_EXT_import_context = GL_FALSE;
+GLboolean __GLXEW_EXT_libglvnd = GL_FALSE;
GLboolean __GLXEW_EXT_scene_marker = GL_FALSE;
GLboolean __GLXEW_EXT_stereo_tree = GL_FALSE;
GLboolean __GLXEW_EXT_swap_control = GL_FALSE;
@@ -12507,6 +16910,7 @@ GLboolean __GLXEW_NV_delay_before_swap = GL_FALSE;
GLboolean __GLXEW_NV_float_buffer = GL_FALSE;
GLboolean __GLXEW_NV_multisample_coverage = GL_FALSE;
GLboolean __GLXEW_NV_present_video = GL_FALSE;
+GLboolean __GLXEW_NV_robustness_video_memory_purge = GL_FALSE;
GLboolean __GLXEW_NV_swap_group = GL_FALSE;
GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE;
GLboolean __GLXEW_NV_video_capture = GL_FALSE;
@@ -12530,12 +16934,9 @@ GLboolean __GLXEW_SGI_swap_control = GL_FALSE;
GLboolean __GLXEW_SGI_video_sync = GL_FALSE;
GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE;
GLboolean __GLXEW_SUN_video_resize = GL_FALSE;
-
-#endif /* !GLEW_MX */
-
#ifdef GLX_VERSION_1_2
-static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_VERSION_1_2 ()
{
GLboolean r = GL_FALSE;
@@ -12548,7 +16949,7 @@ static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_VERSION_1_3
-static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_VERSION_1_3 ()
{
GLboolean r = GL_FALSE;
@@ -12577,7 +16978,7 @@ static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_AMD_gpu_association
-static GLboolean _glewInit_GLX_AMD_gpu_association (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_AMD_gpu_association ()
{
GLboolean r = GL_FALSE;
@@ -12598,7 +16999,7 @@ static GLboolean _glewInit_GLX_AMD_gpu_association (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_ARB_create_context
-static GLboolean _glewInit_GLX_ARB_create_context (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_ARB_create_context ()
{
GLboolean r = GL_FALSE;
@@ -12611,7 +17012,7 @@ static GLboolean _glewInit_GLX_ARB_create_context (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_ATI_render_texture
-static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_ATI_render_texture ()
{
GLboolean r = GL_FALSE;
@@ -12626,7 +17027,7 @@ static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_EXT_import_context
-static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_EXT_import_context ()
{
GLboolean r = GL_FALSE;
@@ -12642,7 +17043,7 @@ static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_EXT_swap_control
-static GLboolean _glewInit_GLX_EXT_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_EXT_swap_control ()
{
GLboolean r = GL_FALSE;
@@ -12655,7 +17056,7 @@ static GLboolean _glewInit_GLX_EXT_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_EXT_texture_from_pixmap
-static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_EXT_texture_from_pixmap ()
{
GLboolean r = GL_FALSE;
@@ -12669,7 +17070,7 @@ static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_IN
#ifdef GLX_MESA_agp_offset
-static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_agp_offset ()
{
GLboolean r = GL_FALSE;
@@ -12682,7 +17083,7 @@ static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_MESA_copy_sub_buffer
-static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_copy_sub_buffer ()
{
GLboolean r = GL_FALSE;
@@ -12695,7 +17096,7 @@ static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_MESA_pixmap_colormap
-static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_pixmap_colormap ()
{
GLboolean r = GL_FALSE;
@@ -12708,7 +17109,7 @@ static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_MESA_query_renderer
-static GLboolean _glewInit_GLX_MESA_query_renderer (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_query_renderer ()
{
GLboolean r = GL_FALSE;
@@ -12724,7 +17125,7 @@ static GLboolean _glewInit_GLX_MESA_query_renderer (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_MESA_release_buffers
-static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_release_buffers ()
{
GLboolean r = GL_FALSE;
@@ -12737,7 +17138,7 @@ static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_MESA_set_3dfx_mode
-static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_set_3dfx_mode ()
{
GLboolean r = GL_FALSE;
@@ -12750,7 +17151,7 @@ static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_MESA_swap_control
-static GLboolean _glewInit_GLX_MESA_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_MESA_swap_control ()
{
GLboolean r = GL_FALSE;
@@ -12764,7 +17165,7 @@ static GLboolean _glewInit_GLX_MESA_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_copy_buffer
-static GLboolean _glewInit_GLX_NV_copy_buffer (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_copy_buffer ()
{
GLboolean r = GL_FALSE;
@@ -12778,7 +17179,7 @@ static GLboolean _glewInit_GLX_NV_copy_buffer (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_copy_image
-static GLboolean _glewInit_GLX_NV_copy_image (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_copy_image ()
{
GLboolean r = GL_FALSE;
@@ -12791,7 +17192,7 @@ static GLboolean _glewInit_GLX_NV_copy_image (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_delay_before_swap
-static GLboolean _glewInit_GLX_NV_delay_before_swap (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_delay_before_swap ()
{
GLboolean r = GL_FALSE;
@@ -12804,7 +17205,7 @@ static GLboolean _glewInit_GLX_NV_delay_before_swap (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_present_video
-static GLboolean _glewInit_GLX_NV_present_video (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_present_video ()
{
GLboolean r = GL_FALSE;
@@ -12818,7 +17219,7 @@ static GLboolean _glewInit_GLX_NV_present_video (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_swap_group
-static GLboolean _glewInit_GLX_NV_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_swap_group ()
{
GLboolean r = GL_FALSE;
@@ -12836,7 +17237,7 @@ static GLboolean _glewInit_GLX_NV_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_vertex_array_range
-static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_vertex_array_range ()
{
GLboolean r = GL_FALSE;
@@ -12850,7 +17251,7 @@ static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT
#ifdef GLX_NV_video_capture
-static GLboolean _glewInit_GLX_NV_video_capture (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_video_capture ()
{
GLboolean r = GL_FALSE;
@@ -12867,7 +17268,7 @@ static GLboolean _glewInit_GLX_NV_video_capture (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_NV_video_out
-static GLboolean _glewInit_GLX_NV_video_out (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_NV_video_out ()
{
GLboolean r = GL_FALSE;
@@ -12885,7 +17286,7 @@ static GLboolean _glewInit_GLX_NV_video_out (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_OML_sync_control
-static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_OML_sync_control ()
{
GLboolean r = GL_FALSE;
@@ -12902,7 +17303,7 @@ static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGIX_fbconfig
-static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGIX_fbconfig ()
{
GLboolean r = GL_FALSE;
@@ -12920,7 +17321,7 @@ static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGIX_hyperpipe
-static GLboolean _glewInit_GLX_SGIX_hyperpipe (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGIX_hyperpipe ()
{
GLboolean r = GL_FALSE;
@@ -12940,7 +17341,7 @@ static GLboolean _glewInit_GLX_SGIX_hyperpipe (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGIX_pbuffer
-static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGIX_pbuffer ()
{
GLboolean r = GL_FALSE;
@@ -12957,7 +17358,7 @@ static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGIX_swap_barrier
-static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGIX_swap_barrier ()
{
GLboolean r = GL_FALSE;
@@ -12971,7 +17372,7 @@ static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGIX_swap_group
-static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGIX_swap_group ()
{
GLboolean r = GL_FALSE;
@@ -12984,7 +17385,7 @@ static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGIX_video_resize
-static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGIX_video_resize ()
{
GLboolean r = GL_FALSE;
@@ -13001,7 +17402,7 @@ static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGI_cushion
-static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGI_cushion ()
{
GLboolean r = GL_FALSE;
@@ -13014,7 +17415,7 @@ static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGI_make_current_read
-static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGI_make_current_read ()
{
GLboolean r = GL_FALSE;
@@ -13028,7 +17429,7 @@ static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT
#ifdef GLX_SGI_swap_control
-static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGI_swap_control ()
{
GLboolean r = GL_FALSE;
@@ -13041,7 +17442,7 @@ static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SGI_video_sync
-static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SGI_video_sync ()
{
GLboolean r = GL_FALSE;
@@ -13055,7 +17456,7 @@ static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT)
#ifdef GLX_SUN_get_transparent_index
-static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SUN_get_transparent_index ()
{
GLboolean r = GL_FALSE;
@@ -13068,7 +17469,7 @@ static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_
#ifdef GLX_SUN_video_resize
-static GLboolean _glewInit_GLX_SUN_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT)
+static GLboolean _glewInit_GLX_SUN_video_resize ()
{
GLboolean r = GL_FALSE;
@@ -13094,17 +17495,13 @@ GLboolean glxewGetExtension (const char* name)
return _glewSearchExtension(name, start, end);
}
-#ifdef GLEW_MX
-GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST)
-#else
-GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
-#endif
+GLenum glxewInit ()
{
int major, minor;
const GLubyte* extStart;
const GLubyte* extEnd;
/* initialize core GLX 1.2 */
- if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY;
+ if (_glewInit_GLX_VERSION_1_2()) return GLEW_ERROR_GLX_VERSION_11_ONLY;
/* initialize flags */
GLXEW_VERSION_1_0 = GL_TRUE;
GLXEW_VERSION_1_1 = GL_TRUE;
@@ -13138,21 +17535,21 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
extEnd = extStart + _glewStrLen(extStart);
/* initialize extensions */
#ifdef GLX_VERSION_1_3
- if (glewExperimental || GLXEW_VERSION_1_3) GLXEW_VERSION_1_3 = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_VERSION_1_3) GLXEW_VERSION_1_3 = !_glewInit_GLX_VERSION_1_3();
#endif /* GLX_VERSION_1_3 */
#ifdef GLX_3DFX_multisample
GLXEW_3DFX_multisample = _glewSearchExtension("GLX_3DFX_multisample", extStart, extEnd);
#endif /* GLX_3DFX_multisample */
#ifdef GLX_AMD_gpu_association
GLXEW_AMD_gpu_association = _glewSearchExtension("GLX_AMD_gpu_association", extStart, extEnd);
- if (glewExperimental || GLXEW_AMD_gpu_association) GLXEW_AMD_gpu_association = !_glewInit_GLX_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_AMD_gpu_association) GLXEW_AMD_gpu_association = !_glewInit_GLX_AMD_gpu_association();
#endif /* GLX_AMD_gpu_association */
#ifdef GLX_ARB_context_flush_control
GLXEW_ARB_context_flush_control = _glewSearchExtension("GLX_ARB_context_flush_control", extStart, extEnd);
#endif /* GLX_ARB_context_flush_control */
#ifdef GLX_ARB_create_context
GLXEW_ARB_create_context = _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd);
- if (glewExperimental || GLXEW_ARB_create_context) GLXEW_ARB_create_context = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_ARB_create_context) GLXEW_ARB_create_context = !_glewInit_GLX_ARB_create_context();
#endif /* GLX_ARB_create_context */
#ifdef GLX_ARB_create_context_profile
GLXEW_ARB_create_context_profile = _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd);
@@ -13186,7 +17583,7 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
#endif /* GLX_ATI_pixel_format_float */
#ifdef GLX_ATI_render_texture
GLXEW_ATI_render_texture = _glewSearchExtension("GLX_ATI_render_texture", extStart, extEnd);
- if (glewExperimental || GLXEW_ATI_render_texture) GLXEW_ATI_render_texture = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_ATI_render_texture) GLXEW_ATI_render_texture = !_glewInit_GLX_ATI_render_texture();
#endif /* GLX_ATI_render_texture */
#ifdef GLX_EXT_buffer_age
GLXEW_EXT_buffer_age = _glewSearchExtension("GLX_EXT_buffer_age", extStart, extEnd);
@@ -13205,8 +17602,11 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
#endif /* GLX_EXT_framebuffer_sRGB */
#ifdef GLX_EXT_import_context
GLXEW_EXT_import_context = _glewSearchExtension("GLX_EXT_import_context", extStart, extEnd);
- if (glewExperimental || GLXEW_EXT_import_context) GLXEW_EXT_import_context = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_EXT_import_context) GLXEW_EXT_import_context = !_glewInit_GLX_EXT_import_context();
#endif /* GLX_EXT_import_context */
+#ifdef GLX_EXT_libglvnd
+ GLXEW_EXT_libglvnd = _glewSearchExtension("GLX_EXT_libglvnd", extStart, extEnd);
+#endif /* GLX_EXT_libglvnd */
#ifdef GLX_EXT_scene_marker
GLXEW_EXT_scene_marker = _glewSearchExtension("GLX_EXT_scene_marker", extStart, extEnd);
#endif /* GLX_EXT_scene_marker */
@@ -13215,14 +17615,14 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
#endif /* GLX_EXT_stereo_tree */
#ifdef GLX_EXT_swap_control
GLXEW_EXT_swap_control = _glewSearchExtension("GLX_EXT_swap_control", extStart, extEnd);
- if (glewExperimental || GLXEW_EXT_swap_control) GLXEW_EXT_swap_control = !_glewInit_GLX_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_EXT_swap_control) GLXEW_EXT_swap_control = !_glewInit_GLX_EXT_swap_control();
#endif /* GLX_EXT_swap_control */
#ifdef GLX_EXT_swap_control_tear
GLXEW_EXT_swap_control_tear = _glewSearchExtension("GLX_EXT_swap_control_tear", extStart, extEnd);
#endif /* GLX_EXT_swap_control_tear */
#ifdef GLX_EXT_texture_from_pixmap
GLXEW_EXT_texture_from_pixmap = _glewSearchExtension("GLX_EXT_texture_from_pixmap", extStart, extEnd);
- if (glewExperimental || GLXEW_EXT_texture_from_pixmap) GLXEW_EXT_texture_from_pixmap = !_glewInit_GLX_EXT_texture_from_pixmap(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_EXT_texture_from_pixmap) GLXEW_EXT_texture_from_pixmap = !_glewInit_GLX_EXT_texture_from_pixmap();
#endif /* GLX_EXT_texture_from_pixmap */
#ifdef GLX_EXT_visual_info
GLXEW_EXT_visual_info = _glewSearchExtension("GLX_EXT_visual_info", extStart, extEnd);
@@ -13235,43 +17635,43 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
#endif /* GLX_INTEL_swap_event */
#ifdef GLX_MESA_agp_offset
GLXEW_MESA_agp_offset = _glewSearchExtension("GLX_MESA_agp_offset", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_agp_offset) GLXEW_MESA_agp_offset = !_glewInit_GLX_MESA_agp_offset(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_agp_offset) GLXEW_MESA_agp_offset = !_glewInit_GLX_MESA_agp_offset();
#endif /* GLX_MESA_agp_offset */
#ifdef GLX_MESA_copy_sub_buffer
GLXEW_MESA_copy_sub_buffer = _glewSearchExtension("GLX_MESA_copy_sub_buffer", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_copy_sub_buffer) GLXEW_MESA_copy_sub_buffer = !_glewInit_GLX_MESA_copy_sub_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_copy_sub_buffer) GLXEW_MESA_copy_sub_buffer = !_glewInit_GLX_MESA_copy_sub_buffer();
#endif /* GLX_MESA_copy_sub_buffer */
#ifdef GLX_MESA_pixmap_colormap
GLXEW_MESA_pixmap_colormap = _glewSearchExtension("GLX_MESA_pixmap_colormap", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_pixmap_colormap) GLXEW_MESA_pixmap_colormap = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_pixmap_colormap) GLXEW_MESA_pixmap_colormap = !_glewInit_GLX_MESA_pixmap_colormap();
#endif /* GLX_MESA_pixmap_colormap */
#ifdef GLX_MESA_query_renderer
GLXEW_MESA_query_renderer = _glewSearchExtension("GLX_MESA_query_renderer", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_query_renderer) GLXEW_MESA_query_renderer = !_glewInit_GLX_MESA_query_renderer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_query_renderer) GLXEW_MESA_query_renderer = !_glewInit_GLX_MESA_query_renderer();
#endif /* GLX_MESA_query_renderer */
#ifdef GLX_MESA_release_buffers
GLXEW_MESA_release_buffers = _glewSearchExtension("GLX_MESA_release_buffers", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_release_buffers) GLXEW_MESA_release_buffers = !_glewInit_GLX_MESA_release_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_release_buffers) GLXEW_MESA_release_buffers = !_glewInit_GLX_MESA_release_buffers();
#endif /* GLX_MESA_release_buffers */
#ifdef GLX_MESA_set_3dfx_mode
GLXEW_MESA_set_3dfx_mode = _glewSearchExtension("GLX_MESA_set_3dfx_mode", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_set_3dfx_mode) GLXEW_MESA_set_3dfx_mode = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_set_3dfx_mode) GLXEW_MESA_set_3dfx_mode = !_glewInit_GLX_MESA_set_3dfx_mode();
#endif /* GLX_MESA_set_3dfx_mode */
#ifdef GLX_MESA_swap_control
GLXEW_MESA_swap_control = _glewSearchExtension("GLX_MESA_swap_control", extStart, extEnd);
- if (glewExperimental || GLXEW_MESA_swap_control) GLXEW_MESA_swap_control = !_glewInit_GLX_MESA_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_MESA_swap_control) GLXEW_MESA_swap_control = !_glewInit_GLX_MESA_swap_control();
#endif /* GLX_MESA_swap_control */
#ifdef GLX_NV_copy_buffer
GLXEW_NV_copy_buffer = _glewSearchExtension("GLX_NV_copy_buffer", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_copy_buffer) GLXEW_NV_copy_buffer = !_glewInit_GLX_NV_copy_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_copy_buffer) GLXEW_NV_copy_buffer = !_glewInit_GLX_NV_copy_buffer();
#endif /* GLX_NV_copy_buffer */
#ifdef GLX_NV_copy_image
GLXEW_NV_copy_image = _glewSearchExtension("GLX_NV_copy_image", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_copy_image) GLXEW_NV_copy_image = !_glewInit_GLX_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_copy_image) GLXEW_NV_copy_image = !_glewInit_GLX_NV_copy_image();
#endif /* GLX_NV_copy_image */
#ifdef GLX_NV_delay_before_swap
GLXEW_NV_delay_before_swap = _glewSearchExtension("GLX_NV_delay_before_swap", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_delay_before_swap) GLXEW_NV_delay_before_swap = !_glewInit_GLX_NV_delay_before_swap(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_delay_before_swap) GLXEW_NV_delay_before_swap = !_glewInit_GLX_NV_delay_before_swap();
#endif /* GLX_NV_delay_before_swap */
#ifdef GLX_NV_float_buffer
GLXEW_NV_float_buffer = _glewSearchExtension("GLX_NV_float_buffer", extStart, extEnd);
@@ -13281,30 +17681,33 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
#endif /* GLX_NV_multisample_coverage */
#ifdef GLX_NV_present_video
GLXEW_NV_present_video = _glewSearchExtension("GLX_NV_present_video", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_present_video) GLXEW_NV_present_video = !_glewInit_GLX_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_present_video) GLXEW_NV_present_video = !_glewInit_GLX_NV_present_video();
#endif /* GLX_NV_present_video */
+#ifdef GLX_NV_robustness_video_memory_purge
+ GLXEW_NV_robustness_video_memory_purge = _glewSearchExtension("GLX_NV_robustness_video_memory_purge", extStart, extEnd);
+#endif /* GLX_NV_robustness_video_memory_purge */
#ifdef GLX_NV_swap_group
GLXEW_NV_swap_group = _glewSearchExtension("GLX_NV_swap_group", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_swap_group) GLXEW_NV_swap_group = !_glewInit_GLX_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_swap_group) GLXEW_NV_swap_group = !_glewInit_GLX_NV_swap_group();
#endif /* GLX_NV_swap_group */
#ifdef GLX_NV_vertex_array_range
GLXEW_NV_vertex_array_range = _glewSearchExtension("GLX_NV_vertex_array_range", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_vertex_array_range) GLXEW_NV_vertex_array_range = !_glewInit_GLX_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_vertex_array_range) GLXEW_NV_vertex_array_range = !_glewInit_GLX_NV_vertex_array_range();
#endif /* GLX_NV_vertex_array_range */
#ifdef GLX_NV_video_capture
GLXEW_NV_video_capture = _glewSearchExtension("GLX_NV_video_capture", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_video_capture) GLXEW_NV_video_capture = !_glewInit_GLX_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_video_capture) GLXEW_NV_video_capture = !_glewInit_GLX_NV_video_capture();
#endif /* GLX_NV_video_capture */
#ifdef GLX_NV_video_out
GLXEW_NV_video_out = _glewSearchExtension("GLX_NV_video_out", extStart, extEnd);
- if (glewExperimental || GLXEW_NV_video_out) GLXEW_NV_video_out = !_glewInit_GLX_NV_video_out(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_NV_video_out) GLXEW_NV_video_out = !_glewInit_GLX_NV_video_out();
#endif /* GLX_NV_video_out */
#ifdef GLX_OML_swap_method
GLXEW_OML_swap_method = _glewSearchExtension("GLX_OML_swap_method", extStart, extEnd);
#endif /* GLX_OML_swap_method */
#ifdef GLX_OML_sync_control
GLXEW_OML_sync_control = _glewSearchExtension("GLX_OML_sync_control", extStart, extEnd);
- if (glewExperimental || GLXEW_OML_sync_control) GLXEW_OML_sync_control = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_OML_sync_control) GLXEW_OML_sync_control = !_glewInit_GLX_OML_sync_control();
#endif /* GLX_OML_sync_control */
#ifdef GLX_SGIS_blended_overlay
GLXEW_SGIS_blended_overlay = _glewSearchExtension("GLX_SGIS_blended_overlay", extStart, extEnd);
@@ -13320,54 +17723,54 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
#endif /* GLX_SGIS_shared_multisample */
#ifdef GLX_SGIX_fbconfig
GLXEW_SGIX_fbconfig = _glewSearchExtension("GLX_SGIX_fbconfig", extStart, extEnd);
- if (glewExperimental || GLXEW_SGIX_fbconfig) GLXEW_SGIX_fbconfig = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGIX_fbconfig) GLXEW_SGIX_fbconfig = !_glewInit_GLX_SGIX_fbconfig();
#endif /* GLX_SGIX_fbconfig */
#ifdef GLX_SGIX_hyperpipe
GLXEW_SGIX_hyperpipe = _glewSearchExtension("GLX_SGIX_hyperpipe", extStart, extEnd);
- if (glewExperimental || GLXEW_SGIX_hyperpipe) GLXEW_SGIX_hyperpipe = !_glewInit_GLX_SGIX_hyperpipe(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGIX_hyperpipe) GLXEW_SGIX_hyperpipe = !_glewInit_GLX_SGIX_hyperpipe();
#endif /* GLX_SGIX_hyperpipe */
#ifdef GLX_SGIX_pbuffer
GLXEW_SGIX_pbuffer = _glewSearchExtension("GLX_SGIX_pbuffer", extStart, extEnd);
- if (glewExperimental || GLXEW_SGIX_pbuffer) GLXEW_SGIX_pbuffer = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGIX_pbuffer) GLXEW_SGIX_pbuffer = !_glewInit_GLX_SGIX_pbuffer();
#endif /* GLX_SGIX_pbuffer */
#ifdef GLX_SGIX_swap_barrier
GLXEW_SGIX_swap_barrier = _glewSearchExtension("GLX_SGIX_swap_barrier", extStart, extEnd);
- if (glewExperimental || GLXEW_SGIX_swap_barrier) GLXEW_SGIX_swap_barrier = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGIX_swap_barrier) GLXEW_SGIX_swap_barrier = !_glewInit_GLX_SGIX_swap_barrier();
#endif /* GLX_SGIX_swap_barrier */
#ifdef GLX_SGIX_swap_group
GLXEW_SGIX_swap_group = _glewSearchExtension("GLX_SGIX_swap_group", extStart, extEnd);
- if (glewExperimental || GLXEW_SGIX_swap_group) GLXEW_SGIX_swap_group = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGIX_swap_group) GLXEW_SGIX_swap_group = !_glewInit_GLX_SGIX_swap_group();
#endif /* GLX_SGIX_swap_group */
#ifdef GLX_SGIX_video_resize
GLXEW_SGIX_video_resize = _glewSearchExtension("GLX_SGIX_video_resize", extStart, extEnd);
- if (glewExperimental || GLXEW_SGIX_video_resize) GLXEW_SGIX_video_resize = !_glewInit_GLX_SGIX_video_resize(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGIX_video_resize) GLXEW_SGIX_video_resize = !_glewInit_GLX_SGIX_video_resize();
#endif /* GLX_SGIX_video_resize */
#ifdef GLX_SGIX_visual_select_group
GLXEW_SGIX_visual_select_group = _glewSearchExtension("GLX_SGIX_visual_select_group", extStart, extEnd);
#endif /* GLX_SGIX_visual_select_group */
#ifdef GLX_SGI_cushion
GLXEW_SGI_cushion = _glewSearchExtension("GLX_SGI_cushion", extStart, extEnd);
- if (glewExperimental || GLXEW_SGI_cushion) GLXEW_SGI_cushion = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGI_cushion) GLXEW_SGI_cushion = !_glewInit_GLX_SGI_cushion();
#endif /* GLX_SGI_cushion */
#ifdef GLX_SGI_make_current_read
GLXEW_SGI_make_current_read = _glewSearchExtension("GLX_SGI_make_current_read", extStart, extEnd);
- if (glewExperimental || GLXEW_SGI_make_current_read) GLXEW_SGI_make_current_read = !_glewInit_GLX_SGI_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGI_make_current_read) GLXEW_SGI_make_current_read = !_glewInit_GLX_SGI_make_current_read();
#endif /* GLX_SGI_make_current_read */
#ifdef GLX_SGI_swap_control
GLXEW_SGI_swap_control = _glewSearchExtension("GLX_SGI_swap_control", extStart, extEnd);
- if (glewExperimental || GLXEW_SGI_swap_control) GLXEW_SGI_swap_control = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGI_swap_control) GLXEW_SGI_swap_control = !_glewInit_GLX_SGI_swap_control();
#endif /* GLX_SGI_swap_control */
#ifdef GLX_SGI_video_sync
GLXEW_SGI_video_sync = _glewSearchExtension("GLX_SGI_video_sync", extStart, extEnd);
- if (glewExperimental || GLXEW_SGI_video_sync) GLXEW_SGI_video_sync = !_glewInit_GLX_SGI_video_sync(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SGI_video_sync) GLXEW_SGI_video_sync = !_glewInit_GLX_SGI_video_sync();
#endif /* GLX_SGI_video_sync */
#ifdef GLX_SUN_get_transparent_index
GLXEW_SUN_get_transparent_index = _glewSearchExtension("GLX_SUN_get_transparent_index", extStart, extEnd);
- if (glewExperimental || GLXEW_SUN_get_transparent_index) GLXEW_SUN_get_transparent_index = !_glewInit_GLX_SUN_get_transparent_index(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SUN_get_transparent_index) GLXEW_SUN_get_transparent_index = !_glewInit_GLX_SUN_get_transparent_index();
#endif /* GLX_SUN_get_transparent_index */
#ifdef GLX_SUN_video_resize
GLXEW_SUN_video_resize = _glewSearchExtension("GLX_SUN_video_resize", extStart, extEnd);
- if (glewExperimental || GLXEW_SUN_video_resize) GLXEW_SUN_video_resize = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT);
+ if (glewExperimental || GLXEW_SUN_video_resize) GLXEW_SUN_video_resize = !_glewInit_GLX_SUN_video_resize();
#endif /* GLX_SUN_video_resize */
return GLEW_OK;
@@ -13396,9 +17799,9 @@ const GLubyte * GLEWAPIENTRY glewGetString (GLenum name)
static const GLubyte* _glewString[] =
{
(const GLubyte*)NULL,
- (const GLubyte*)"1.13.0",
- (const GLubyte*)"1",
- (const GLubyte*)"13",
+ (const GLubyte*)"2.0.0",
+ (const GLubyte*)"2",
+ (const GLubyte*)"0",
(const GLubyte*)"0"
};
const size_t max_string = sizeof(_glewString)/sizeof(*_glewString) - 1;
@@ -13409,28 +17812,40 @@ const GLubyte * GLEWAPIENTRY glewGetString (GLenum name)
GLboolean glewExperimental = GL_FALSE;
-#if !defined(GLEW_MX)
-
GLenum GLEWAPIENTRY glewInit (void)
{
GLenum r;
+#if defined(GLEW_EGL)
+ PFNEGLGETCURRENTDISPLAYPROC getCurrentDisplay = NULL;
+#endif
r = glewContextInit();
if ( r != 0 ) return r;
-#if defined(_WIN32)
+#if defined(GLEW_EGL)
+ getCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) glewGetProcAddress("eglGetCurrentDisplay");
+ return eglewInit(getCurrentDisplay());
+#elif defined(GLEW_OSMESA) || defined(__ANDROID__) || defined(__native_client__) || defined(__HAIKU__)
+ return r;
+#elif defined(_WIN32)
return wglewInit();
-#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) /* _UNIX */
+#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */
return glxewInit();
#else
return r;
#endif /* _WIN32 */
}
-#endif /* !GLEW_MX */
-#ifdef GLEW_MX
-GLboolean GLEWAPIENTRY glewContextIsSupported (const GLEWContext* ctx, const char* name)
-#else
-GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
+#if defined(_WIN32) && defined(GLEW_BUILD) && defined(__GNUC__)
+/* GCC requires a DLL entry point even without any standard library included. */
+/* Types extracted from windows.h to avoid polluting the rest of the file. */
+int __stdcall DllMainCRTStartup(void* instance, unsigned reason, void* reserved)
+{
+ (void) instance;
+ (void) reason;
+ (void) reserved;
+ return 1;
+}
#endif
+GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
{
const GLubyte* pos = (const GLubyte*)name;
GLuint len = _glewStrLen(pos);
@@ -13706,6 +18121,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_AMD_shader_explicit_vertex_parameter
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_explicit_vertex_parameter", 32))
+ {
+ ret = GLEW_AMD_shader_explicit_vertex_parameter;
+ continue;
+ }
+#endif
#ifdef GL_AMD_shader_stencil_export
if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21))
{
@@ -14338,6 +18760,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_ARB_gl_spirv
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_spirv", 8))
+ {
+ ret = GLEW_ARB_gl_spirv;
+ continue;
+ }
+#endif
#ifdef GL_ARB_gpu_shader5
if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11))
{
@@ -15325,6 +19754,16 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
}
#endif
}
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EGL_", 4))
+ {
+#ifdef GL_EGL_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"NV_robustness_video_memory_purge", 32))
+ {
+ ret = GLEW_EGL_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
+ }
if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
{
#ifdef GL_EXT_422_pixels
@@ -16076,6 +20515,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_EXT_window_rectangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_rectangles", 17))
+ {
+ ret = GLEW_EXT_window_rectangles;
+ continue;
+ }
+#endif
#ifdef GL_EXT_x11_sync_object
if (_glewStrSame3(&pos, &len, (const GLubyte*)"x11_sync_object", 15))
{
@@ -16196,6 +20642,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
}
if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6))
{
+#ifdef GL_INTEL_conservative_rasterization
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_rasterization", 26))
+ {
+ ret = GLEW_INTEL_conservative_rasterization;
+ continue;
+ }
+#endif
#ifdef GL_INTEL_fragment_shader_ordering
if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_ordering", 24))
{
@@ -16304,6 +20757,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_KHR_texture_compression_astc_sliced_3d
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_sliced_3d", 34))
+ {
+ ret = GLEW_KHR_texture_compression_astc_sliced_3d;
+ continue;
+ }
+#endif
}
if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4))
{
@@ -16341,6 +20801,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_MESA_shader_integer_functions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_integer_functions", 24))
+ {
+ ret = GLEW_MESA_shader_integer_functions;
+ continue;
+ }
+#endif
#ifdef GL_MESA_window_pos
if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10))
{
@@ -16358,6 +20825,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
}
if (_glewStrSame2(&pos, &len, (const GLubyte*)"NVX_", 4))
{
+#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_multi_draw_buffers", 42))
+ {
+ ret = GLEW_NVX_blend_equation_advanced_multi_draw_buffers;
+ continue;
+ }
+#endif
#ifdef GL_NVX_conditional_render
if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18))
{
@@ -16372,6 +20846,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NVX_linked_gpu_multicast
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"linked_gpu_multicast", 20))
+ {
+ ret = GLEW_NVX_linked_gpu_multicast;
+ continue;
+ }
+#endif
}
if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
{
@@ -16417,6 +20898,20 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_clip_space_w_scaling
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_space_w_scaling", 20))
+ {
+ ret = GLEW_NV_clip_space_w_scaling;
+ continue;
+ }
+#endif
+#ifdef GL_NV_command_list
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"command_list", 12))
+ {
+ ret = GLEW_NV_command_list;
+ continue;
+ }
+#endif
#ifdef GL_NV_compute_program5
if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_program5", 16))
{
@@ -16445,6 +20940,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster_pre_snap_triangles", 38))
+ {
+ ret = GLEW_NV_conservative_raster_pre_snap_triangles;
+ continue;
+ }
+#endif
#ifdef GL_NV_copy_depth_to_color
if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19))
{
@@ -16494,6 +20996,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_draw_vulkan_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_vulkan_image", 17))
+ {
+ ret = GLEW_NV_draw_vulkan_image;
+ continue;
+ }
+#endif
#ifdef GL_NV_evaluators
if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10))
{
@@ -16613,6 +21122,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_gpu_multicast
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_multicast", 13))
+ {
+ ret = GLEW_NV_gpu_multicast;
+ continue;
+ }
+#endif
#ifdef GL_NV_gpu_program4
if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12))
{
@@ -16767,6 +21283,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29))
+ {
+ ret = GLEW_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
#ifdef GL_NV_sample_locations
if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_locations", 16))
{
@@ -16795,6 +21318,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_shader_atomic_float64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float64", 21))
+ {
+ ret = GLEW_NV_shader_atomic_float64;
+ continue;
+ }
+#endif
#ifdef GL_NV_shader_atomic_fp16_vector
if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_fp16_vector", 25))
{
@@ -16837,6 +21367,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_stereo_view_rendering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_view_rendering", 21))
+ {
+ ret = GLEW_NV_stereo_view_rendering;
+ continue;
+ }
+#endif
#ifdef GL_NV_tessellation_program5
if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_program5", 21))
{
@@ -17033,6 +21570,13 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GL_NV_viewport_swizzle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_swizzle", 16))
+ {
+ ret = GLEW_NV_viewport_swizzle;
+ continue;
+ }
+#endif
}
if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4))
{
@@ -17639,13 +22183,9 @@ GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
return ret;
}
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(GLEW_EGL) && !defined(GLEW_OSMESA)
-#if defined(GLEW_MX)
-GLboolean GLEWAPIENTRY wglewContextIsSupported (const WGLEWContext* ctx, const char* name)
-#else
GLboolean GLEWAPIENTRY wglewIsSupported (const char* name)
-#endif
{
const GLubyte* pos = (const GLubyte*)name;
GLuint len = _glewStrLen(pos);
@@ -18065,13 +22605,9 @@ GLboolean GLEWAPIENTRY wglewIsSupported (const char* name)
return ret;
}
-#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
+#elif !defined(GLEW_OSMESA) && !defined(GLEW_EGL) && !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
-#if defined(GLEW_MX)
-GLboolean glxewContextIsSupported (const GLXEWContext* ctx, const char* name)
-#else
GLboolean glxewIsSupported (const char* name)
-#endif
{
const GLubyte* pos = (const GLubyte*)name;
GLuint len = _glewStrLen(pos);
@@ -18265,6 +22801,13 @@ GLboolean glxewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GLX_EXT_libglvnd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"libglvnd", 8))
+ {
+ ret = GLXEW_EXT_libglvnd;
+ continue;
+ }
+#endif
#ifdef GLX_EXT_scene_marker
if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12))
{
@@ -18421,6 +22964,13 @@ GLboolean glxewIsSupported (const char* name)
continue;
}
#endif
+#ifdef GLX_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29))
+ {
+ ret = GLXEW_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
#ifdef GLX_NV_swap_group
if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
{
@@ -18604,4 +23154,799 @@ GLboolean glxewIsSupported (const char* name)
return ret;
}
+#elif defined(GLEW_EGL)
+
+GLboolean eglewIsSupported (const char* name)
+{
+ const GLubyte* pos = (const GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if(_glewStrSame1(&pos, &len, (const GLubyte*)"EGL_", 4))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8))
+ {
+#ifdef EGL_VERSION_1_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_0", 3))
+ {
+ ret = EGLEW_VERSION_1_0;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_1", 3))
+ {
+ ret = EGLEW_VERSION_1_1;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3))
+ {
+ ret = EGLEW_VERSION_1_2;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3))
+ {
+ ret = EGLEW_VERSION_1_3;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3))
+ {
+ ret = EGLEW_VERSION_1_4;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3))
+ {
+ ret = EGLEW_VERSION_1_5;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANDROID_", 8))
+ {
+#ifdef EGL_ANDROID_blob_cache
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blob_cache", 10))
+ {
+ ret = EGLEW_ANDROID_blob_cache;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_create_native_client_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_native_client_buffer", 27))
+ {
+ ret = EGLEW_ANDROID_create_native_client_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_framebuffer_target
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_target", 18))
+ {
+ ret = EGLEW_ANDROID_framebuffer_target;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_front_buffer_auto_refresh
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"front_buffer_auto_refresh", 25))
+ {
+ ret = EGLEW_ANDROID_front_buffer_auto_refresh;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_image_native_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_native_buffer", 19))
+ {
+ ret = EGLEW_ANDROID_image_native_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_native_fence_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"native_fence_sync", 17))
+ {
+ ret = EGLEW_ANDROID_native_fence_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_presentation_time
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"presentation_time", 17))
+ {
+ ret = EGLEW_ANDROID_presentation_time;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_recordable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"recordable", 10))
+ {
+ ret = EGLEW_ANDROID_recordable;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANGLE_", 6))
+ {
+#ifdef EGL_ANGLE_d3d_share_handle_client_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"d3d_share_handle_client_buffer", 30))
+ {
+ ret = EGLEW_ANGLE_d3d_share_handle_client_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_device_d3d
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_d3d", 10))
+ {
+ ret = EGLEW_ANGLE_device_d3d;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_query_surface_pointer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_surface_pointer", 21))
+ {
+ ret = EGLEW_ANGLE_query_surface_pointer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"surface_d3d_texture_2d_share_handle", 35))
+ {
+ ret = EGLEW_ANGLE_surface_d3d_texture_2d_share_handle;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_window_fixed_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_fixed_size", 17))
+ {
+ ret = EGLEW_ANGLE_window_fixed_size;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARM_", 4))
+ {
+#ifdef EGL_ARM_pixmap_multisample_discard
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_multisample_discard", 26))
+ {
+ ret = EGLEW_ARM_pixmap_multisample_discard;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef EGL_EXT_buffer_age
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_age", 10))
+ {
+ ret = EGLEW_EXT_buffer_age;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_client_extensions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_extensions", 17))
+ {
+ ret = EGLEW_EXT_client_extensions;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_create_context_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25))
+ {
+ ret = EGLEW_EXT_create_context_robustness;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_base", 11))
+ {
+ ret = EGLEW_EXT_device_base;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_drm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_drm", 10))
+ {
+ ret = EGLEW_EXT_device_drm;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_enumeration
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_enumeration", 18))
+ {
+ ret = EGLEW_EXT_device_enumeration;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_openwf
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_openwf", 13))
+ {
+ ret = EGLEW_EXT_device_openwf;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_query", 12))
+ {
+ ret = EGLEW_EXT_device_query;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_image_dma_buf_import
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_dma_buf_import", 20))
+ {
+ ret = EGLEW_EXT_image_dma_buf_import;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_multiview_window
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview_window", 16))
+ {
+ ret = EGLEW_EXT_multiview_window;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_output_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"output_base", 11))
+ {
+ ret = EGLEW_EXT_output_base;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_output_drm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"output_drm", 10))
+ {
+ ret = EGLEW_EXT_output_drm;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_output_openwf
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"output_openwf", 13))
+ {
+ ret = EGLEW_EXT_output_openwf;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_base", 13))
+ {
+ ret = EGLEW_EXT_platform_base;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_device
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_device", 15))
+ {
+ ret = EGLEW_EXT_platform_device;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_wayland
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_wayland", 16))
+ {
+ ret = EGLEW_EXT_platform_wayland;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_x11
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_x11", 12))
+ {
+ ret = EGLEW_EXT_platform_x11;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_protected_content
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"protected_content", 17))
+ {
+ ret = EGLEW_EXT_protected_content;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_protected_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"protected_surface", 17))
+ {
+ ret = EGLEW_EXT_protected_surface;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_stream_consumer_egloutput
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_consumer_egloutput", 25))
+ {
+ ret = EGLEW_EXT_stream_consumer_egloutput;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_swap_buffers_with_damage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_buffers_with_damage", 24))
+ {
+ ret = EGLEW_EXT_swap_buffers_with_damage;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_yuv_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"yuv_surface", 11))
+ {
+ ret = EGLEW_EXT_yuv_surface;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"HI_", 3))
+ {
+#ifdef EGL_HI_clientpixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clientpixmap", 12))
+ {
+ ret = EGLEW_HI_clientpixmap;
+ continue;
+ }
+#endif
+#ifdef EGL_HI_colorformats
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"colorformats", 12))
+ {
+ ret = EGLEW_HI_colorformats;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"IMG_", 4))
+ {
+#ifdef EGL_IMG_context_priority
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_priority", 16))
+ {
+ ret = EGLEW_IMG_context_priority;
+ continue;
+ }
+#endif
+#ifdef EGL_IMG_image_plane_attribs
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_plane_attribs", 19))
+ {
+ ret = EGLEW_IMG_image_plane_attribs;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"KHR_", 4))
+ {
+#ifdef EGL_KHR_cl_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event", 8))
+ {
+ ret = EGLEW_KHR_cl_event;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_cl_event2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event2", 9))
+ {
+ ret = EGLEW_KHR_cl_event2;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_client_get_all_proc_addresses
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_get_all_proc_addresses", 29))
+ {
+ ret = EGLEW_KHR_client_get_all_proc_addresses;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_config_attribs
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"config_attribs", 14))
+ {
+ ret = EGLEW_KHR_config_attribs;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_create_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14))
+ {
+ ret = EGLEW_KHR_create_context;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_create_context_no_error
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_no_error", 23))
+ {
+ ret = EGLEW_KHR_create_context_no_error;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_debug
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug", 5))
+ {
+ ret = EGLEW_KHR_debug;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_fence_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence_sync", 10))
+ {
+ ret = EGLEW_KHR_fence_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_get_all_proc_addresses
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_all_proc_addresses", 22))
+ {
+ ret = EGLEW_KHR_get_all_proc_addresses;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_colorspace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_colorspace", 13))
+ {
+ ret = EGLEW_KHR_gl_colorspace;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_renderbuffer_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_renderbuffer_image", 21))
+ {
+ ret = EGLEW_KHR_gl_renderbuffer_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_texture_2D_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_texture_2D_image", 19))
+ {
+ ret = EGLEW_KHR_gl_texture_2D_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_texture_3D_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_texture_3D_image", 19))
+ {
+ ret = EGLEW_KHR_gl_texture_3D_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_texture_cubemap_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_texture_cubemap_image", 24))
+ {
+ ret = EGLEW_KHR_gl_texture_cubemap_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image", 5))
+ {
+ ret = EGLEW_KHR_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_image_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_base", 10))
+ {
+ ret = EGLEW_KHR_image_base;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_image_pixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_pixmap", 12))
+ {
+ ret = EGLEW_KHR_image_pixmap;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_lock_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"lock_surface", 12))
+ {
+ ret = EGLEW_KHR_lock_surface;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_lock_surface2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"lock_surface2", 13))
+ {
+ ret = EGLEW_KHR_lock_surface2;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_lock_surface3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"lock_surface3", 13))
+ {
+ ret = EGLEW_KHR_lock_surface3;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_mutable_render_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mutable_render_buffer", 21))
+ {
+ ret = EGLEW_KHR_mutable_render_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_partial_update
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"partial_update", 14))
+ {
+ ret = EGLEW_KHR_partial_update;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_android
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_android", 16))
+ {
+ ret = EGLEW_KHR_platform_android;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_gbm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_gbm", 12))
+ {
+ ret = EGLEW_KHR_platform_gbm;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_wayland
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_wayland", 16))
+ {
+ ret = EGLEW_KHR_platform_wayland;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_x11
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_x11", 12))
+ {
+ ret = EGLEW_KHR_platform_x11;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_reusable_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"reusable_sync", 13))
+ {
+ ret = EGLEW_KHR_reusable_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream", 6))
+ {
+ ret = EGLEW_KHR_stream;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_consumer_gltexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_consumer_gltexture", 25))
+ {
+ ret = EGLEW_KHR_stream_consumer_gltexture;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_cross_process_fd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_process_fd", 23))
+ {
+ ret = EGLEW_KHR_stream_cross_process_fd;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_fifo
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_fifo", 11))
+ {
+ ret = EGLEW_KHR_stream_fifo;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_producer_aldatalocator
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_producer_aldatalocator", 29))
+ {
+ ret = EGLEW_KHR_stream_producer_aldatalocator;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_producer_eglsurface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_producer_eglsurface", 26))
+ {
+ ret = EGLEW_KHR_stream_producer_eglsurface;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_surfaceless_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"surfaceless_context", 19))
+ {
+ ret = EGLEW_KHR_surfaceless_context;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_swap_buffers_with_damage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_buffers_with_damage", 24))
+ {
+ ret = EGLEW_KHR_swap_buffers_with_damage;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_vg_parent_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vg_parent_image", 15))
+ {
+ ret = EGLEW_KHR_vg_parent_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_wait_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"wait_sync", 9))
+ {
+ ret = EGLEW_KHR_wait_sync;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5))
+ {
+#ifdef EGL_MESA_drm_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"drm_image", 9))
+ {
+ ret = EGLEW_MESA_drm_image;
+ continue;
+ }
+#endif
+#ifdef EGL_MESA_image_dma_buf_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_dma_buf_export", 20))
+ {
+ ret = EGLEW_MESA_image_dma_buf_export;
+ continue;
+ }
+#endif
+#ifdef EGL_MESA_platform_gbm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_gbm", 12))
+ {
+ ret = EGLEW_MESA_platform_gbm;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NOK_", 4))
+ {
+#ifdef EGL_NOK_swap_region
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_region", 11))
+ {
+ ret = EGLEW_NOK_swap_region;
+ continue;
+ }
+#endif
+#ifdef EGL_NOK_swap_region2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_region2", 12))
+ {
+ ret = EGLEW_NOK_swap_region2;
+ continue;
+ }
+#endif
+#ifdef EGL_NOK_texture_from_pixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19))
+ {
+ ret = EGLEW_NOK_texture_from_pixmap;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef EGL_NV_3dvision_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3dvision_surface", 16))
+ {
+ ret = EGLEW_NV_3dvision_surface;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_coverage_sample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"coverage_sample", 15))
+ {
+ ret = EGLEW_NV_coverage_sample;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_coverage_sample_resolve
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"coverage_sample_resolve", 23))
+ {
+ ret = EGLEW_NV_coverage_sample_resolve;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_cuda_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cuda_event", 10))
+ {
+ ret = EGLEW_NV_cuda_event;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_depth_nonlinear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_nonlinear", 15))
+ {
+ ret = EGLEW_NV_depth_nonlinear;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_device_cuda
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_cuda", 11))
+ {
+ ret = EGLEW_NV_device_cuda;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_native_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"native_query", 12))
+ {
+ ret = EGLEW_NV_native_query;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_post_convert_rounding
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_convert_rounding", 21))
+ {
+ ret = EGLEW_NV_post_convert_rounding;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_post_sub_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_sub_buffer", 15))
+ {
+ ret = EGLEW_NV_post_sub_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29))
+ {
+ ret = EGLEW_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_consumer_gltexture_yuv
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_consumer_gltexture_yuv", 29))
+ {
+ ret = EGLEW_NV_stream_consumer_gltexture_yuv;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_metadata
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_metadata", 15))
+ {
+ ret = EGLEW_NV_stream_metadata;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_sync", 11))
+ {
+ ret = EGLEW_NV_stream_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4))
+ {
+ ret = EGLEW_NV_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_system_time
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"system_time", 11))
+ {
+ ret = EGLEW_NV_system_time;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"TIZEN_", 6))
+ {
+#ifdef EGL_TIZEN_image_native_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_native_buffer", 19))
+ {
+ ret = EGLEW_TIZEN_image_native_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_TIZEN_image_native_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_native_surface", 20))
+ {
+ ret = EGLEW_TIZEN_image_native_surface;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
#endif /* _WIN32 */
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index bfe230250ae..af3b9296077 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -33,6 +33,7 @@ add_subdirectory(opencolorio)
add_subdirectory(mikktspace)
add_subdirectory(glew-mx)
add_subdirectory(eigen)
+add_subdirectory(gawain)
if(WITH_GAMEENGINE_DECKLINK)
add_subdirectory(decklink)
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index a2d6262fb20..1cb7835d14d 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -19,7 +19,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 76, 0),
+ "blender": (2, 80, 0),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
@@ -66,21 +66,21 @@ class CyclesRender(bpy.types.RenderEngine):
engine.free(self)
# final render
- def update(self, data, scene):
+ def update(self, data, depsgraph, scene):
if not self.session:
if self.is_preview:
cscene = bpy.context.scene.cycles
use_osl = cscene.shading_system and cscene.device == 'CPU'
- engine.create(self, data, scene,
+ engine.create(self, data, depsgraph, scene,
None, None, None, use_osl)
else:
- engine.create(self, data, scene)
+ engine.create(self, data, depsgraph, scene)
else:
engine.reset(self, data, scene)
- def render(self, scene):
- engine.render(self)
+ def render_to_image(self, depsgraph):
+ engine.render(self, depsgraph)
def bake(self, scene, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
engine.bake(self, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
@@ -88,12 +88,12 @@ class CyclesRender(bpy.types.RenderEngine):
# viewport render
def view_update(self, context):
if not self.session:
- engine.create(self, context.blend_data, context.scene,
+ engine.create(self, context.blend_data, context.depsgraph, context.scene,
context.region, context.space_data, context.region_data)
engine.update(self, context.blend_data, context.scene)
- def view_draw(self, context):
- engine.draw(self, context.region, context.space_data, context.region_data)
+ def render_to_view(self, context):
+ engine.draw(self, context.depsgraph, context.region, context.space_data, context.region_data)
def update_script_node(self, node):
if engine.with_osl():
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index b5149b5082e..9e22ce331d0 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -123,12 +123,13 @@ def exit():
_cycles.exit()
-def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
+def create(engine, data, depsgraph, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
import bpy
import _cycles
data = data.as_pointer()
userpref = bpy.context.user_preferences.as_pointer()
+ depsgraph = depsgraph.as_pointer()
scene = scene.as_pointer()
if region:
region = region.as_pointer()
@@ -142,7 +143,8 @@ def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=Fa
else:
_cycles.debug_flags_reset()
- engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d, preview_osl)
+ engine.session = _cycles.create(
+ engine.as_pointer(), userpref, data, depsgraph, scene, region, v3d, rv3d, preview_osl)
def free(engine):
@@ -153,7 +155,7 @@ def free(engine):
del engine.session
-def render(engine):
+def render(engine, depsgraph):
import _cycles
if hasattr(engine, "session"):
_cycles.render(engine.session)
@@ -178,13 +180,14 @@ def update(engine, data, scene):
_cycles.sync(engine.session)
-def draw(engine, region, v3d, rv3d):
+def draw(engine, depsgraph, region, v3d, rv3d):
import _cycles
+ depsgraph = depsgraph.as_pointer()
v3d = v3d.as_pointer()
rv3d = rv3d.as_pointer()
# draw render image
- _cycles.draw(engine.session, v3d, rv3d)
+ _cycles.draw(engine.session, depsgraph, v3d, rv3d)
def available_devices():
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 8bb25aba13c..28d60671bd8 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -195,12 +195,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Pause all viewport preview renders",
default=False,
)
- cls.preview_active_layer = BoolProperty(
- name="Preview Active Layer",
- description="Preview active render layer in viewport",
- default=False,
- )
-
cls.aa_samples = IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render for each pixel",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 4ed3ccd9a2c..a8018e3824d 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -17,6 +17,7 @@
# <pep8 compliant>
import bpy
+from bpy_extras.node_utils import find_node_input, find_output_node
from bpy.types import (
Panel,
@@ -898,30 +899,6 @@ class CYCLES_OT_use_shading_nodes(Operator):
return {'FINISHED'}
-def find_node(material, nodetype):
- if material and material.node_tree:
- ntree = material.node_tree
-
- active_output_node = None
- for node in ntree.nodes:
- if getattr(node, "type", None) == nodetype:
- if getattr(node, "is_active_output", True):
- return node
- if not active_output_node:
- active_output_node = node
- return active_output_node
-
- return None
-
-
-def find_node_input(node, name):
- for input in node.inputs:
- if input.name == name:
- return input
-
- return None
-
-
def panel_node_draw(layout, id_data, output_type, input_name):
if not id_data.use_nodes:
layout.operator("cycles.use_shading_nodes", icon='NODETREE')
@@ -929,7 +906,7 @@ def panel_node_draw(layout, id_data, output_type, input_name):
ntree = id_data.node_tree
- node = find_node(id_data, output_type)
+ node = find_output_node(ntree, output_type)
if not node:
layout.label(text="No output node")
else:
@@ -1665,6 +1642,7 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
row.prop(rd, "simplify_subdivision", text="Viewport")
row.prop(rd, "simplify_subdivision_render", text="Render")
+
col = layout.column(align=True)
col.label(text="Child Particles")
row = col.row(align=True)
@@ -1727,11 +1705,8 @@ def draw_pause(self, context):
if scene.render.engine == "CYCLES":
view = context.space_data
- if view.viewport_shade == 'RENDERED':
- cscene = scene.cycles
- layername = scene.render.layers.active.name
- layout.prop(cscene, "preview_pause", icon="PAUSE", text="")
- layout.prop(cscene, "preview_active_layer", icon="RENDERLAYERS", text=layername)
+ cscene = scene.cycles
+ layout.prop(cscene, "preview_pause", icon="PAUSE", text="")
def get_panels():
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 3ebe2d8cf34..3dfb2b1913d 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -417,7 +417,7 @@ static void attr_create_uv_map(Scene *scene,
int i = 0;
for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
- bool active_render = b_mesh.uv_textures[i].active_render();
+ bool active_render = b_mesh.uv_layers[i].active_render();
AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring name = ustring(l->name().c_str());
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index a930c439370..4ed9f00e51f 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -469,19 +469,11 @@ static bool object_render_hide(BL::Object& b_ob,
}
}
-static bool object_render_hide_duplis(BL::Object& b_ob)
-{
- BL::Object parent = b_ob.parent();
-
- return (parent && object_render_hide_original(b_ob.type(), parent.dupli_type()));
-}
-
/* Object Loop */
void BlenderSync::sync_objects(float motion_time)
{
/* layer data */
- uint scene_layer = render_layer.scene_layer;
bool motion = motion_time != 0.0f;
if(!motion) {
@@ -500,100 +492,37 @@ void BlenderSync::sync_objects(float motion_time)
BlenderObjectCulling culling(scene, b_scene);
/* object loop */
- BL::Scene::object_bases_iterator b_base;
- BL::Scene b_sce = b_scene;
- /* modifier result type (not exposed as enum in C++ API)
- * 1 : DAG_EVAL_PREVIEW
- * 2 : DAG_EVAL_RENDER
- */
- int dupli_settings = (render_layer.use_viewport_visibility) ? 1 : 2;
-
bool cancel = false;
bool use_portal = false;
- uint layer_override = get_layer(b_engine.layer_override());
- for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
- /* Render layer's scene_layer is affected by local view already,
- * which is not a desired behavior here.
- */
- uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
- for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
- BL::Object b_ob = b_base->object();
- bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
- uint ob_layer = get_layer(b_base->layers(),
- b_base->layers_local_view(),
- object_is_light(b_ob),
- scene_layers);
- hide = hide || !(ob_layer & scene_layer);
-
- if(!hide) {
- progress.set_sync_status("Synchronizing object", b_ob.name());
-
- /* load per-object culling data */
- culling.init_object(scene, b_ob);
-
- if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
- /* dupli objects */
- b_ob.dupli_list_create(b_scene, dupli_settings);
-
- BL::Object::dupli_list_iterator b_dup;
-
- for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) {
- Transform tfm = get_transform(b_dup->matrix());
- BL::Object b_dup_ob = b_dup->object();
- bool dup_hide = (render_layer.use_viewport_visibility)? b_dup_ob.hide(): b_dup_ob.hide_render();
- bool in_dupli_group = (b_dup->type() == BL::DupliObject::type_GROUP);
- bool hide_tris;
-
- if(!(b_dup->hide() || dup_hide || object_render_hide(b_dup_ob, false, in_dupli_group, hide_tris))) {
- /* the persistent_id allows us to match dupli objects
- * between frames and updates */
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
-
- /* sync object and mesh or light data */
- Object *object = sync_object(b_ob,
- persistent_id.data,
- *b_dup,
- tfm,
- ob_layer,
- motion_time,
- hide_tris,
- culling,
- &use_portal);
-
- /* sync possible particle data, note particle_id
- * starts counting at 1, first is dummy particle */
- if(!motion && object) {
- sync_dupli_particle(b_ob, *b_dup, object);
- }
-
- }
- }
-
- b_ob.dupli_list_clear();
- }
-
- /* test if object needs to be hidden */
- bool hide_tris;
-
- if(!object_render_hide(b_ob, true, true, hide_tris)) {
- /* object itself */
- Transform tfm = get_transform(b_ob.matrix_world());
- BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
- sync_object(b_ob,
- NULL,
- b_empty_dupli_ob,
- tfm,
- ob_layer,
- motion_time,
- hide_tris,
- culling,
- &use_portal);
- }
- }
-
- cancel = progress.get_cancel();
- }
+ BL::Depsgraph::objects_iterator b_ob_iter;
+
+ for(b_depsgraph.objects.begin(b_ob_iter); b_ob_iter != b_depsgraph.objects.end() && !cancel; ++b_ob_iter) {
+ BL::Object b_ob = *b_ob_iter;
+ progress.set_sync_status("Synchronizing object", b_ob.name());
+
+ /* load per-object culling data */
+ culling.init_object(scene, b_ob);
+
+ /* test if object needs to be hidden */
+ bool hide_tris;
+
+ if(!object_render_hide(b_ob, true, true, hide_tris)) {
+ /* object itself */
+ Transform tfm = get_transform(b_ob.matrix_world());
+ BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
+ sync_object(b_ob,
+ NULL,
+ b_empty_dupli_ob,
+ tfm,
+ ~(0), /* until we get rid of layers */
+ motion_time,
+ hide_tris,
+ culling,
+ &use_portal);
+ }
+
+ cancel = progress.get_cancel();
}
progress.set_sync_status("");
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 01570b1e3f9..3c769881bb7 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -199,10 +199,10 @@ static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
static PyObject *create_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
+ PyObject *pyengine, *pyuserpref, *pydata, *pygraph, *pyscene, *pyregion, *pyv3d, *pyrv3d;
int preview_osl;
- if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene,
+ if(!PyArg_ParseTuple(args, "OOOOOOOOi", &pyengine, &pyuserpref, &pydata, &pygraph, &pyscene,
&pyregion, &pyv3d, &pyrv3d, &preview_osl))
{
return NULL;
@@ -221,6 +221,10 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData data(dataptr);
+ PointerRNA graphptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pygraph), &graphptr);
+ BL::Depsgraph graph(graphptr);
+
PointerRNA sceneptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
BL::Scene scene(sceneptr);
@@ -245,7 +249,7 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
int width = region.width();
int height = region.height();
- session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
+ session = new BlenderSession(engine, userpref, data, graph, scene, v3d, rv3d, width, height);
}
else {
/* override some settings for preview */
@@ -257,7 +261,7 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
}
/* offline session or preview render */
- session = new BlenderSession(engine, userpref, data, scene);
+ session = new BlenderSession(engine, userpref, data, graph, scene);
}
python_thread_state_save(&session->python_thread_state);
@@ -323,9 +327,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pyv3d, *pyrv3d;
+ PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
- if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
+ if(!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index c6a59577507..46f32fe816d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -52,11 +52,13 @@ int BlenderSession::end_resumable_chunk = 0;
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene)
: b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
b_render(b_engine.render()),
+ b_depsgraph(b_depsgraph),
b_scene(b_scene),
b_v3d(PointerRNA_NULL),
b_rv3d(PointerRNA_NULL),
@@ -76,6 +78,7 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
@@ -84,6 +87,7 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
b_userpref(b_userpref),
b_data(b_data),
b_render(b_scene.render()),
+ b_depsgraph(b_depsgraph),
b_scene(b_scene),
b_v3d(b_v3d),
b_rv3d(b_rv3d),
@@ -141,7 +145,7 @@ void BlenderSession::create_session()
session->set_pause(session_pause);
/* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, is_cpu);
+ sync = new BlenderSync(b_engine, b_data, b_depsgraph, b_scene, scene, !background, session->progress, is_cpu);
BL::Object b_camera_override(b_engine.camera_override());
if(b_v3d) {
if(session_pause == false) {
@@ -211,7 +215,7 @@ void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
session->stats.mem_peak = session->stats.mem_used;
/* sync object should be re-created */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, is_cpu);
+ sync = new BlenderSync(b_engine, b_data, b_depsgraph, b_scene, scene, !background, session->progress, is_cpu);
/* for final render we will do full data sync per render layer, only
* do some basic syncing here, no objects or materials for speed */
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 536808c5b18..254e8a049ff 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -36,11 +36,13 @@ public:
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene);
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
@@ -104,6 +106,7 @@ public:
BL::UserPreferences b_userpref;
BL::BlendData b_data;
BL::RenderSettings b_render;
+ BL::Depsgraph b_depsgraph;
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 41723599874..1604b0039eb 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -44,6 +44,7 @@ CCL_NAMESPACE_BEGIN
BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
Scene *scene,
bool preview,
@@ -51,6 +52,7 @@ BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
bool is_cpu)
: b_engine(b_engine),
b_data(b_data),
+ b_depsgraph(b_depsgraph),
b_scene(b_scene),
shader_map(&scene->shaders),
object_map(&scene->objects),
@@ -385,26 +387,9 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer)
/* 3d view */
if(b_v3d) {
- if(RNA_boolean_get(&cscene, "preview_active_layer")) {
- BL::RenderLayers layers(b_scene.render().ptr);
- layername = layers.active().name();
- layer = layername.c_str();
- }
- else {
- render_layer.scene_layer = get_layer(b_v3d.layers(), b_v3d.layers_local_view());
- render_layer.layer = render_layer.scene_layer;
- render_layer.exclude_layer = 0;
- render_layer.holdout_layer = 0;
- render_layer.material_override = PointerRNA_NULL;
- render_layer.use_background_shader = true;
- render_layer.use_background_ao = true;
- render_layer.use_hair = true;
- render_layer.use_surfaces = true;
- render_layer.use_viewport_visibility = true;
- render_layer.samples = 0;
- render_layer.bound_samples = false;
- return;
- }
+ BL::RenderLayers layers(b_scene.render().ptr);
+ layername = layers.active().name();
+ layer = layername.c_str();
}
/* render layer */
@@ -433,7 +418,6 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer)
render_layer.use_background_ao = b_rlay->use_ao();
render_layer.use_surfaces = b_rlay->use_solid();
render_layer.use_hair = b_rlay->use_strand();
- render_layer.use_viewport_visibility = false;
render_layer.bound_samples = (use_layer_samples == 1);
if(use_layer_samples != 2) {
@@ -836,17 +820,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
params.shadingsystem = SHADINGSYSTEM_OSL;
/* color managagement */
-#ifdef GLEW_MX
- /* When using GLEW MX we need to check whether we've got an OpenGL
- * context for current window. This is because command line rendering
- * doesn't have OpenGL context actually.
- */
- if(glewGetContext() != NULL)
-#endif
- {
- params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
- b_engine.support_display_space_shader(b_scene);
- }
+ params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
+ b_engine.support_display_space_shader(b_scene);
if(b_engine.is_preview()) {
/* For preview rendering we're using same timeout as
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 0950285d976..e509cce3e31 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -51,6 +51,7 @@ class BlenderSync {
public:
BlenderSync(BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_graph,
BL::Scene& b_scene,
Scene *scene,
bool preview,
@@ -160,6 +161,7 @@ private:
/* variables */
BL::RenderEngine b_engine;
BL::BlendData b_data;
+ BL::Depsgraph b_depsgraph;
BL::Scene b_scene;
id_map<void*, Shader> shader_map;
@@ -190,7 +192,6 @@ private:
use_background_ao(true),
use_surfaces(true),
use_hair(true),
- use_viewport_visibility(false),
samples(0), bound_samples(false)
{}
@@ -204,7 +205,6 @@ private:
bool use_background_ao;
bool use_surfaces;
bool use_hair;
- bool use_viewport_visibility;
int samples;
bool bound_samples;
} render_layer;
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 0603ecb3afb..949c5f932a4 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -23,6 +23,7 @@
#include "util/util_debug.h"
#include "util/util_foreach.h"
#include "util/util_half.h"
+#include "util/util_logging.h"
#include "util/util_math.h"
#include "util/util_opengl.h"
#include "util/util_time.h"
@@ -75,8 +76,13 @@ std::ostream& operator <<(std::ostream &os,
Device::~Device()
{
- if(!background && vertex_buffer != 0) {
- glDeleteBuffers(1, &vertex_buffer);
+ if(!background) {
+ if(vertex_buffer != 0) {
+ glDeleteBuffers(1, &vertex_buffer);
+ }
+ if(fallback_shader_program != 0) {
+ glDeleteProgram(fallback_shader_program);
+ }
}
}
@@ -98,125 +104,266 @@ void Device::pixels_free(device_memory& mem)
mem_free(mem);
}
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params)
+/* TODO move shaders to standalone .glsl file. */
+const char *FALLBACK_VERTEX_SHADER =
+"#version 330\n"
+"uniform vec2 fullscreen;\n"
+"in vec2 texCoord;\n"
+"in vec2 pos;\n"
+"out vec2 texCoord_interp;\n"
+"\n"
+"vec2 normalize_coordinates()\n"
+"{\n"
+" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
+" texCoord_interp = texCoord;\n"
+"}\n\0";
+
+const char *FALLBACK_FRAGMENT_SHADER =
+"#version 330\n"
+"uniform sampler2D image_texture;\n"
+"in vec2 texCoord_interp;\n"
+"out vec4 fragColor;\n"
+"\n"
+"void main()\n"
+"{\n"
+" fragColor = texture(image_texture, texCoord_interp);\n"
+"}\n\0";
+
+static void shader_print_errors(const char *task, const char *log, const char *code)
{
- pixels_copy_from(rgba, y, w, h);
+ LOG(ERROR) << "Shader: " << task << " error:";
+ LOG(ERROR) << "===== shader string ====";
- if(transparent) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ stringstream stream(code);
+ string partial;
+
+ int line = 1;
+ while(getline(stream, partial, '\n')) {
+ if(line < 10) {
+ LOG(ERROR) << " " << line << " " << partial;
+ }
+ else {
+ LOG(ERROR) << line << " " << partial;
+ }
+ line++;
}
+ LOG(ERROR) << log;
+}
- glColor3f(1.0f, 1.0f, 1.0f);
+static int bind_fallback_shader(void)
+{
+ GLint status;
+ GLchar log[5000];
+ GLsizei length = 0;
+ GLuint program = 0;
- if(rgba.data_type == TYPE_HALF) {
- /* for multi devices, this assumes the inefficient method that we allocate
- * all pixels on the device even though we only render to a subset */
- GLhalf *data_pointer = (GLhalf*)rgba.data_pointer;
- float vbuffer[16], *basep;
- float *vp = NULL;
+ struct Shader {
+ const char *source;
+ GLenum type;
+ } shaders[2] = {
+ {FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
+ {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}
+ };
- data_pointer += 4*y*w;
+ program = glCreateProgram();
- /* draw half float texture, GLSL shader for display transform assumed to be bound */
- GLuint texid;
- glGenTextures(1, &texid);
- glBindTexture(GL_TEXTURE_2D, texid);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ for(int i = 0; i < 2; i++) {
+ GLuint shader = glCreateShader(shaders[i].type);
+
+ string source_str = shaders[i].source;
+ const char *c_str = source_str.c_str();
- glEnable(GL_TEXTURE_2D);
+ glShaderSource(shader, 1, &c_str, NULL);
+ glCompileShader(shader);
- if(draw_params.bind_display_space_shader_cb) {
- draw_params.bind_display_space_shader_cb();
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+
+ if(!status) {
+ glGetShaderInfoLog(shader, sizeof(log), &length, log);
+ shader_print_errors("compile", log, c_str);
+ return 0;
}
- if(GLEW_VERSION_1_5) {
- if(!vertex_buffer)
- glGenBuffers(1, &vertex_buffer);
+ glAttachShader(program, shader);
+ }
+
+ /* Link output. */
+ glBindFragDataLocation(program, 0, "fragColor");
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
- /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+ /* Link and error check. */
+ glLinkProgram(program);
- vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+ if(!status) {
+ glGetShaderInfoLog(program, sizeof(log), &length, log);
+ shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
+ shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
+ return 0;
+ }
- basep = NULL;
+ return program;
+}
+
+bool Device::bind_fallback_display_space_shader(const float width, const float height)
+{
+ if(fallback_status == FALLBACK_SHADER_STATUS_ERROR) {
+ return false;
+ }
+
+ if(fallback_status == FALLBACK_SHADER_STATUS_NONE) {
+ fallback_shader_program = bind_fallback_shader();
+ fallback_status = FALLBACK_SHADER_STATUS_ERROR;
+
+ if (fallback_shader_program == 0) {
+ return false;
}
- else {
- basep = vbuffer;
- vp = vbuffer;
+
+ glUseProgram(fallback_shader_program);
+ image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture");
+ if(image_texture_location < 0) {
+ LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform.";
+ return false;
}
- if(vp) {
- /* texture coordinate - vertex pair */
- vp[0] = 0.0f;
- vp[1] = 0.0f;
- vp[2] = dx;
- vp[3] = dy;
-
- vp[4] = 1.0f;
- vp[5] = 0.0f;
- vp[6] = (float)width + dx;
- vp[7] = dy;
-
- vp[8] = 1.0f;
- vp[9] = 1.0f;
- vp[10] = (float)width + dx;
- vp[11] = (float)height + dy;
-
- vp[12] = 0.0f;
- vp[13] = 1.0f;
- vp[14] = dx;
- vp[15] = (float)height + dy;
-
- if(vertex_buffer)
- glUnmapBuffer(GL_ARRAY_BUFFER);
+ fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen");
+ if(fullscreen_location < 0) {
+ LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform.";
+ return false;
}
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), basep);
- glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), ((char *)basep) + 2 * sizeof(float));
+ fallback_status = FALLBACK_SHADER_STATUS_SUCCESS;
+ }
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ /* Run this every time. */
+ glUseProgram(fallback_shader_program);
+ glUniform1i(image_texture_location, 0);
+ glUniform2f(fullscreen_location, width, height);
+ return true;
+}
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+void Device::draw_pixels(
+ device_memory& rgba, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params)
+{
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
+ pixels_copy_from(rgba, y, w, h);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ GLuint texid;
+ glGenTextures(1, &texid);
+ glBindTexture(GL_TEXTURE_2D, texid);
- if(vertex_buffer) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
+ if(rgba.data_type == TYPE_HALF) {
+ GLhalf *data_pointer = (GLhalf*)rgba.data_pointer;
+ data_pointer += 4 * y * w;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
+ }
+ else {
+ uint8_t *data_pointer = (uint8_t*)rgba.data_pointer;
+ data_pointer += 4 * y * w;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer);
+ }
- if(draw_params.unbind_display_space_shader_cb) {
- draw_params.unbind_display_space_shader_cb();
- }
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glEnable(GL_TEXTURE_2D);
+
+ if(transparent) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
- glDeleteTextures(1, &texid);
+ GLint shader_program;
+ if(use_fallback_shader) {
+ if (!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
}
else {
- /* fallback for old graphics cards that don't support GLSL, half float,
- * and non-power-of-two textures */
- glPixelZoom((float)width/(float)w, (float)height/(float)h);
- glRasterPos2f(dx, dy);
+ draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
+ }
+
+ if(!vertex_buffer) {
+ glGenBuffers(1, &vertex_buffer);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+ /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+ glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+ float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+ if(vpointer) {
+ /* texture coordinate - vertex pair */
+ vpointer[0] = 0.0f;
+ vpointer[1] = 0.0f;
+ vpointer[2] = dx;
+ vpointer[3] = dy;
- uint8_t *pixels = (uint8_t*)rgba.data_pointer;
+ vpointer[4] = 1.0f;
+ vpointer[5] = 0.0f;
+ vpointer[6] = (float)width + dx;
+ vpointer[7] = dy;
- pixels += 4*y*w;
+ vpointer[8] = 1.0f;
+ vpointer[9] = 1.0f;
+ vpointer[10] = (float)width + dx;
+ vpointer[11] = (float)height + dy;
- glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ vpointer[12] = 0.0f;
+ vpointer[13] = 1.0f;
+ vpointer[14] = dx;
+ vpointer[15] = (float)height + dy;
- glRasterPos2f(0.0f, 0.0f);
- glPixelZoom(1.0f, 1.0f);
+ if(vertex_buffer) {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ }
}
- if(transparent)
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
+
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
+
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
+
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
+
+ glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if(vertex_buffer) {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+
+ if(use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+ glDeleteTextures(1, &texid);
+
+ if(transparent) {
glDisable(GL_BLEND);
+ }
}
Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 527940e8f50..c22969d7dc6 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -230,13 +230,26 @@ struct DeviceDrawParams {
class Device {
friend class device_sub_ptr;
protected:
- Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), vertex_buffer(0), info(info_), stats(stats_) {}
+ enum {
+ FALLBACK_SHADER_STATUS_NONE = 0,
+ FALLBACK_SHADER_STATUS_ERROR,
+ FALLBACK_SHADER_STATUS_SUCCESS,
+ };
+
+ Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background),
+ vertex_buffer(0),
+ fallback_status(FALLBACK_SHADER_STATUS_NONE), fallback_shader_program(0),
+ info(info_), stats(stats_) {}
bool background;
string error_msg;
/* used for real time display */
unsigned int vertex_buffer;
+ int fallback_status, fallback_shader_program;
+ int image_texture_location, fullscreen_location;
+
+ bool bind_fallback_display_space_shader(const float width, const float height);
virtual device_ptr mem_alloc_sub_ptr(device_memory& /*mem*/, int /*offset*/, int /*size*/, MemoryType /*type*/)
{
@@ -311,9 +324,10 @@ public:
virtual void task_cancel() = 0;
/* opengl drawing */
- virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params);
+ virtual void draw_pixels(device_memory& mem, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params);
#ifdef WITH_NETWORK
/* networking */
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 99537e9a983..caa56c012d8 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1635,10 +1635,14 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
+ void draw_pixels(
+ device_memory& mem, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh, bool transparent,
const DeviceDrawParams &draw_params)
{
if(!background) {
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
PixelMem pmem = pixel_mem_map[mem.device_pointer];
float *vpointer;
@@ -1655,10 +1659,12 @@ public:
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
- if(mem.data_type == TYPE_HALF)
+ if(mem.data_type == TYPE_HALF) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_HALF_FLOAT, (void*)offset);
- else
+ }
+ else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)offset);
+ }
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glEnable(GL_TEXTURE_2D);
@@ -1668,14 +1674,21 @@ public:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
- glColor3f(1.0f, 1.0f, 1.0f);
-
- if(draw_params.bind_display_space_shader_cb) {
+ GLint shader_program;
+ if(use_fallback_shader) {
+ if(!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
+ }
+ else {
draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
}
- if(!vertex_buffer)
+ if(!vertex_buffer) {
glGenBuffers(1, &vertex_buffer);
+ }
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
/* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
@@ -1708,25 +1721,33 @@ public:
glUnmapBuffer(GL_ARRAY_BUFFER);
}
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
- glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)NULL + 2 * sizeof(float));
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- if(draw_params.unbind_display_space_shader_cb) {
+ if(use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
draw_params.unbind_display_space_shader_cb();
}
- if(transparent)
+ if(transparent) {
glDisable(GL_BLEND);
+ }
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
@@ -1736,7 +1757,7 @@ public:
return;
}
- Device::draw_pixels(mem, y, w, h, dx, dy, width, height, transparent, draw_params);
+ Device::draw_pixels(mem, y, w, h, width, height, dx, dy, dw, dh, transparent, draw_params);
}
void thread_run(DeviceTask *task)
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index bc505b676fc..35ae0303d6e 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -254,8 +254,11 @@ public:
mem.device_pointer = tmp;
}
- void draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params)
+ void draw_pixels(
+ device_memory& rgba, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params)
{
device_ptr tmp = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -269,7 +272,7 @@ public:
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[tmp];
- sub.device->draw_pixels(rgba, sy, w, sh, dx, sdy, width, sheight, transparent, draw_params);
+ sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, dx, sdy, dw, dh, transparent, draw_params);
i++;
}
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index cf402c3f214..ff6f40c010e 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -428,7 +428,11 @@ void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
if(draw_width != 0 && draw_height != 0) {
device_memory& rgba = rgba_data();
- device->draw_pixels(rgba, 0, draw_width, draw_height, params.full_x, params.full_y, params.width, params.height, transparent, draw_params);
+ device->draw_pixels(
+ rgba, 0,
+ draw_width, draw_height, params.width, params.height,
+ params.full_x, params.full_y, params.full_width, params.full_height,
+ transparent, draw_params);
}
}
diff --git a/intern/cycles/util/util_opengl.h b/intern/cycles/util/util_opengl.h
index 0b5462e0a09..7a8d5eec1f9 100644
--- a/intern/cycles/util/util_opengl.h
+++ b/intern/cycles/util/util_opengl.h
@@ -20,12 +20,6 @@
/* OpenGL header includes, used everywhere we use OpenGL, to deal with
* platform differences in one central place. */
-#ifdef WITH_GLEW_MX
-# include "glew-mx.h"
-#else
-# include <GL/glew.h>
-# define mxCreateContext() glewInit()
-# define mxMakeCurrentContext(x) (x)
-#endif
+#include <GL/glew.h>
#endif /* __UTIL_OPENGL_H__ */
diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp
index 10d86167921..7b453d123b8 100644
--- a/intern/cycles/util/util_view.cpp
+++ b/intern/cycles/util/util_view.cpp
@@ -252,7 +252,7 @@ void view_main_loop(const char *title, int width, int height,
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow(title);
- mxMakeCurrentContext(mxCreateContext());
+ glewInit();
view_reshape(width, height);
diff --git a/intern/elbeem/intern/solver_control.cpp b/intern/elbeem/intern/solver_control.cpp
index c3015b82f0a..d7ed1a5a7ef 100644
--- a/intern/elbeem/intern/solver_control.cpp
+++ b/intern/elbeem/intern/solver_control.cpp
@@ -873,156 +873,4 @@ LbmFsgrSolver::handleCpdata()
// warning, may return before
}
-#if LBM_USE_GUI==1
-
-#define USE_GLUTILITIES
-#include "../gui/gui_utilities.h"
-
-void LbmFsgrSolver::cpDebugDisplay(int dispset)
-{
- for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) {
- ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts;
- //ControlParticles *cpmotion = mpControl->mCons[cpssi]->mCpmotion;
- // display cp parts
- const bool cpCubes = false;
- const bool cpDots = true;
- const bool cpCpdist = true;
- const bool cpHideIna = true;
- glShadeModel(GL_FLAT);
- glDisable( GL_LIGHTING ); // dont light lines
-
- // dot influence
- if((mpControl->mDebugCpscale>0.) && cpDots) {
- glPointSize(mpControl->mDebugCpscale * 8.);
- glBegin(GL_POINTS);
- for(int i=0; i<cparts->getSize(); i++) {
- if((cpHideIna)&&( (cparts->getParticle(i)->influence<=0.) || (cparts->getParticle(i)->size<=0.) )) continue;
- ntlVec3Gfx org( vec2G(cparts->getParticle(i)->pos ) );
- //LbmFloat halfsize = 0.5;
- LbmFloat scale = cparts->getParticle(i)->densityWeight;
- //glColor4f( scale,scale,scale,scale );
- glColor4f( 0.,scale,0.,scale );
- glVertex3f( org[0],org[1],org[2] );
- //errMsg("lbmDebugDisplay","CP "<<i<<" at "<<org); // DEBUG
- }
- glEnd();
- }
-
- // cp positions
- if((mpControl->mDebugCpscale>0.) && cpDots) {
- glPointSize(mpControl->mDebugCpscale * 3.);
- glBegin(GL_POINTS);
- glColor3f( 0,1,0 );
- }
- for(int i=0; i<cparts->getSize(); i++) {
- if((cpHideIna)&&( (cparts->getParticle(i)->influence<=0.) || (cparts->getParticle(i)->size<=0.) )) continue;
- ntlVec3Gfx org( vec2G(cparts->getParticle(i)->pos ) );
- LbmFloat halfsize = 0.5;
- LbmFloat scale = cparts->getRadiusAtt() * cparts->getParticle(i)->densityWeight;
- if(cpCubes){ glLineWidth( 1 );
- glColor3f( 1,1,1 );
- ntlVec3Gfx s = org-(halfsize * (scale));
- ntlVec3Gfx e = org+(halfsize * (scale));
- drawCubeWire( s,e ); }
- if((mpControl->mDebugCpscale>0.) && cpDots) {
- glVertex3f( org[0],org[1],org[2] );
- }
- }
- if(cpDots) glEnd();
-
- if(mpControl->mDebugAvgVelScale>0.) {
- const float scale = mpControl->mDebugAvgVelScale;
-
- glColor3f( 1.0,1.0,1 );
- glBegin(GL_LINES);
- for(int i=0; i<cparts->getSize(); i++) {
- if((cpHideIna)&&( (cparts->getParticle(i)->influence<=0.) || (cparts->getParticle(i)->size<=0.) )) continue;
- ntlVec3Gfx org( vec2G(cparts->getParticle(i)->pos ) );
-
- //errMsg("CPAVGVEL","i"<<i<<" pos"<<org<<" av"<<cparts->getParticle(i)->avgVel);// DEBUG
- float dx = cparts->getParticle(i)->avgVel[0];
- float dy = cparts->getParticle(i)->avgVel[1];
- float dz = cparts->getParticle(i)->avgVel[2];
- dx *= scale; dy *= scale; dz *= scale;
- glVertex3f( org[0],org[1],org[2] );
- glVertex3f( org[0]+dx,org[1]+dy,org[2]+dz );
- }
- glEnd();
- } // */
-
- if( (LBMDIM==2) && (cpCpdist) ) {
-
- // debug, for use of e.g. LBMGET_FORCE LbmControlData *mpControl = this;
-# define TESTGET_FORCE(lev,i,j,k) mpControl->mCpForces[lev][ ((k*mLevel[lev].lSizey)+j)*mLevel[lev].lSizex+i ]
-
- glBegin(GL_LINES);
- //const int lev=0;
- for(int lev=0; lev<=mMaxRefine; lev++) {
- FSGR_FORIJK_BOUNDS(lev) {
- LbmVec pos = LbmVec(
- ((mvGeoEnd[0]-mvGeoStart[0])/(LbmFloat)mLevel[lev].lSizex) * ((LbmFloat)i+0.5) + mvGeoStart[0],
- ((mvGeoEnd[1]-mvGeoStart[1])/(LbmFloat)mLevel[lev].lSizey) * ((LbmFloat)j+0.5) + mvGeoStart[1],
- ((mvGeoEnd[2]-mvGeoStart[2])/(LbmFloat)mLevel[lev].lSizez) * ((LbmFloat)k+0.5) + mvGeoStart[2] );
- if(LBMDIM==2) pos[2] = ((mvGeoEnd[2]-mvGeoStart[2])*0.5 + mvGeoStart[2]);
-
- if((mpControl->mDebugMaxdScale>0.) && (TESTGET_FORCE(lev,i,j,k).weightAtt<=0.) )
- if(TESTGET_FORCE(lev,i,j,k).maxDistance>=0.)
- if(TESTGET_FORCE(lev,i,j,k).maxDistance<CPF_MAXDINIT ) {
- const float scale = mpControl->mDebugMaxdScale*10001.;
- float dx = TESTGET_FORCE(lev,i,j,k).forceMaxd[0];
- float dy = TESTGET_FORCE(lev,i,j,k).forceMaxd[1];
- float dz = TESTGET_FORCE(lev,i,j,k).forceMaxd[2];
- dx *= scale; dy *= scale; dz *= scale;
- glColor3f( 0,1,0 );
- glVertex3f( pos[0],pos[1],pos[2] );
- glVertex3f( pos[0]+dx,pos[1]+dy,pos[2]+dz );
- } // */
- if((mpControl->mDebugAttScale>0.) && (TESTGET_FORCE(lev,i,j,k).weightAtt>0.)) {
- const float scale = mpControl->mDebugAttScale*100011.;
- float dx = TESTGET_FORCE(lev,i,j,k).forceAtt[0];
- float dy = TESTGET_FORCE(lev,i,j,k).forceAtt[1];
- float dz = TESTGET_FORCE(lev,i,j,k).forceAtt[2];
- dx *= scale; dy *= scale; dz *= scale;
- glColor3f( 1,0,0 );
- glVertex3f( pos[0],pos[1],pos[2] );
- glVertex3f( pos[0]+dx,pos[1]+dy,pos[2]+dz );
- } // */
- // why check maxDistance?
- if((mpControl->mDebugVelScale>0.) && (TESTGET_FORCE(lev,i,j,k).maxDistance+TESTGET_FORCE(lev,i,j,k).weightVel>0.)) {
- float scale = mpControl->mDebugVelScale*1.;
- float wvscale = TESTGET_FORCE(lev,i,j,k).weightVel;
- float dx = TESTGET_FORCE(lev,i,j,k).forceVel[0];
- float dy = TESTGET_FORCE(lev,i,j,k).forceVel[1];
- float dz = TESTGET_FORCE(lev,i,j,k).forceVel[2];
- scale *= wvscale;
- dx *= scale; dy *= scale; dz *= scale;
- glColor3f( 0.2,0.2,1 );
- glVertex3f( pos[0],pos[1],pos[2] );
- glVertex3f( pos[0]+dx,pos[1]+dy,pos[2]+dz );
- } // */
- if((mpControl->mDebugCompavScale>0.) && (TESTGET_FORCE(lev,i,j,k).compAvWeight>0.)) {
- const float scale = mpControl->mDebugCompavScale*1.;
- float dx = TESTGET_FORCE(lev,i,j,k).compAv[0];
- float dy = TESTGET_FORCE(lev,i,j,k).compAv[1];
- float dz = TESTGET_FORCE(lev,i,j,k).compAv[2];
- dx *= scale; dy *= scale; dz *= scale;
- glColor3f( 0.2,0.2,1 );
- glVertex3f( pos[0],pos[1],pos[2] );
- glVertex3f( pos[0]+dx,pos[1]+dy,pos[2]+dz );
- } // */
- } // att,maxd
- }
- glEnd();
- }
- } // cpssi
-
- //fprintf(stderr,"BLA\n");
- glEnable( GL_LIGHTING ); // dont light lines
- glShadeModel(GL_SMOOTH);
-}
-
-#else // LBM_USE_GUI==1
void LbmFsgrSolver::cpDebugDisplay(int dispset) { }
-#endif // LBM_USE_GUI==1
-
-
diff --git a/intern/elbeem/intern/solver_util.cpp b/intern/elbeem/intern/solver_util.cpp
index 6eca427c787..5e112eb3f29 100644
--- a/intern/elbeem/intern/solver_util.cpp
+++ b/intern/elbeem/intern/solver_util.cpp
@@ -1673,223 +1673,6 @@ LbmFloat& LbmFsgrSolver::debRAC(LbmFloat* s,int l) {
* GUI&debugging functions
*****************************************************************************/
-
-#if LBM_USE_GUI==1
-#define USE_GLUTILITIES
-#include "../gui/gui_utilities.h"
-
-//! display a single node
-void LbmFsgrSolver::debugDisplayNode(int dispset, CellIdentifierInterface* cell ) {
- //debugOut(" DD: "<<cell->getAsString() , 10);
- ntlVec3Gfx org = this->getCellOrigin( cell );
- ntlVec3Gfx halfsize = this->getCellSize( cell );
- int set = this->getCellSet( cell );
- //debugOut(" DD: "<<cell->getAsString()<<" "<< (dispset->type) , 10);
-
- bool showcell = true;
- int linewidth = 1;
- ntlColor col(0.5);
- LbmFloat cscale = 1.0; //dispset->scale;
-
-#define DRAWDISPCUBE(col,scale) \
- { glLineWidth( linewidth ); \
- glColor3f( (col)[0], (col)[1], (col)[2]); \
- ntlVec3Gfx s = org-(halfsize * (scale)); \
- ntlVec3Gfx e = org+(halfsize * (scale)); \
- drawCubeWire( s,e ); }
-
- CellFlagType flag = this->getCellFlag(cell, set );
- // always check types
- if(flag& CFInvalid ) { if(!guiShowInvalid ) return; }
- if(flag& CFUnused ) { if(!guiShowInvalid ) return; }
- if(flag& CFEmpty ) { if(!guiShowEmpty ) return; }
- if(flag& CFInter ) { if(!guiShowInterface) return; }
- if(flag& CFNoDelete ) { if(!guiShowNoDelete ) return; }
- if(flag& CFBnd ) { if(!guiShowBnd ) return; }
-
- // only dismiss one of these types
- if(flag& CFGrFromCoarse) { if(!guiShowCoarseInner ) return; } // inner not really interesting
- else
- if(flag& CFGrFromFine) { if(!guiShowCoarseBorder ) return; }
- else
- if(flag& CFFluid ) { if(!guiShowFluid ) return; }
-
- switch(dispset) {
- case FLUIDDISPNothing: {
- showcell = false;
- } break;
- case FLUIDDISPCelltypes: {
- cscale = 0.5;
-
- if(flag& CFNoDelete) { // debug, mark nodel cells
- ntlColor ccol(0.7,0.0,0.0);
- DRAWDISPCUBE(ccol, 0.1);
- }
- if(flag& CFPersistMask) { // mark persistent flags
- ntlColor ccol(0.5);
- DRAWDISPCUBE(ccol, 0.125);
- }
- if(flag& CFNoBndFluid) { // mark persistent flags
- ntlColor ccol(0,0,1);
- DRAWDISPCUBE(ccol, 0.075);
- }
-
- if(flag& CFInvalid) {
- cscale = 0.50;
- col = ntlColor(0.0,0,0.0);
- }
- else if(flag& CFBnd) {
- cscale = 0.59;
- col = ntlColor(0.4);
- }
-
- else if(flag& CFInter) {
- cscale = 0.55;
- col = ntlColor(0,1,1);
-
- } else if(flag& CFGrFromCoarse) {
- // draw as - with marker
- ntlColor col2(0.0,1.0,0.3);
- DRAWDISPCUBE(col2, 0.1);
- cscale = 0.5;
- showcell=false; // DEBUG
- }
- else if(flag& CFFluid) {
- cscale = 0.5;
- if(flag& CFGrToFine) {
- ntlColor col2(0.5,0.0,0.5);
- DRAWDISPCUBE(col2, 0.1);
- col = ntlColor(0,0,1);
- }
- if(flag& CFGrFromFine) {
- ntlColor col2(1.0,1.0,0.0);
- DRAWDISPCUBE(col2, 0.1);
- col = ntlColor(0,0,1);
- } else if(flag& CFGrFromCoarse) {
- // draw as fluid with marker
- ntlColor col2(0.0,1.0,0.3);
- DRAWDISPCUBE(col2, 0.1);
- col = ntlColor(0,0,1);
- } else {
- col = ntlColor(0,0,1);
- }
- }
- else if(flag& CFEmpty) {
- showcell=false;
- }
-
- } break;
- case FLUIDDISPVelocities: {
- // dont use cube display
- LbmVec vel = this->getCellVelocity( cell, set );
- glBegin(GL_LINES);
- glColor3f( 0.0,0.0,0.0 );
- glVertex3f( org[0], org[1], org[2] );
- org += vec2G(vel * 10.0 * cscale);
- glColor3f( 1.0,1.0,1.0 );
- glVertex3f( org[0], org[1], org[2] );
- glEnd();
- showcell = false;
- } break;
- case FLUIDDISPCellfills: {
- cscale = 0.5;
- if(flag& CFFluid) {
- cscale = 0.75;
- col = ntlColor(0,0,0.5);
- }
- else if(flag& CFInter) {
- cscale = 0.75 * this->getCellMass(cell,set);
- col = ntlColor(0,1,1);
- }
- else {
- showcell=false;
- }
-
- if( ABS(this->getCellMass(cell,set)) < 10.0 ) {
- cscale = 0.75 * this->getCellMass(cell,set);
- } else {
- showcell = false;
- }
- if(cscale>0.0) {
- col = ntlColor(0,1,1);
- } else {
- col = ntlColor(1,1,0);
- }
- // TODO
- } break;
- case FLUIDDISPDensity: {
- LbmFloat rho = this->getCellDensity(cell,set);
- cscale = rho*rho * 0.25;
- col = ntlColor( MIN(0.5+cscale,1.0) , MIN(0.0+cscale,1.0), MIN(0.0+cscale,1.0) );
- cscale *= 2.0;
- } break;
- case FLUIDDISPGrid: {
- cscale = 0.59;
- col = ntlColor(1.0);
- } break;
- default: {
- cscale = 0.5;
- col = ntlColor(1.0,0.0,0.0);
- } break;
- }
-
- if(!showcell) return;
- if(cscale==0.0) return; // dont draw zero values
- DRAWDISPCUBE(col, cscale);
-}
-
-//! debug display function
-// D has to implement the CellIterator interface
-void LbmFsgrSolver::lbmDebugDisplay(int dispset) {
- // DEBUG always display testdata
-#if LBM_INCLUDE_TESTSOLVERS==1
- if(mUseTestdata){
- cpDebugDisplay(dispset);
- mpTest->testDebugDisplay(dispset);
- }
-#endif // LBM_INCLUDE_TESTSOLVERS==1
- if(dispset<=FLUIDDISPNothing) return;
- //if(!dispset->on) return;
- glDisable( GL_LIGHTING ); // dont light lines
-
-#if LBM_INCLUDE_TESTSOLVERS==1
- if((!mUseTestdata)|| (mUseTestdata)&&(mpTest->mFarfMode<=0)) {
-#endif // LBM_INCLUDE_TESTSOLVERS==1
-
- LbmFsgrSolver::CellIdentifier cid = this->getFirstCell();
- for(; this->noEndCell( cid );
- this->advanceCell( cid ) ) {
- this->debugDisplayNode(dispset, cid );
- }
- delete cid;
-
-#if LBM_INCLUDE_TESTSOLVERS==1
- } // 3d check
-#endif // LBM_INCLUDE_TESTSOLVERS==1
-
- glEnable( GL_LIGHTING ); // dont light lines
-}
-
-//! debug display function
-// D has to implement the CellIterator interface
-void LbmFsgrSolver::lbmMarkedCellDisplay() {
- //fluidDispSettings dispset;
- // trick - display marked cells as grid displa -> white, big
- int dispset = FLUIDDISPGrid;
- glDisable( GL_LIGHTING ); // dont light lines
-
- LbmFsgrSolver::CellIdentifier cid = this->markedGetFirstCell();
- while(cid) {
- this->debugDisplayNode(dispset, cid );
- cid = this->markedAdvanceCell();
- }
- delete cid;
-
- glEnable( GL_LIGHTING ); // dont light lines
-}
-
-#endif // LBM_USE_GUI==1
-
//! display a single node
void LbmFsgrSolver::debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet) {
//string printInfo,
diff --git a/intern/gawain/CMakeLists.txt b/intern/gawain/CMakeLists.txt
new file mode 100644
index 00000000000..ac94cbb55d1
--- /dev/null
+++ b/intern/gawain/CMakeLists.txt
@@ -0,0 +1,33 @@
+
+set(INC gawain)
+
+set(INC_SYS ${GLEW_INCLUDE_PATH})
+
+set(SRC
+ src/attrib_binding.c
+ src/batch.c
+ src/element.c
+ src/buffer_id.cpp
+ src/immediate.c
+ src/imm_util.c
+ src/primitive.c
+ src/shader_interface.c
+ src/vertex_buffer.c
+ src/vertex_format.c
+
+ gawain/attrib_binding.h
+ gawain/batch.h
+ gawain/buffer_id.h
+ gawain/common.h
+ gawain/element.h
+ gawain/immediate.h
+ gawain/imm_util.h
+ gawain/primitive.h
+ gawain/shader_interface.h
+ gawain/vertex_buffer.h
+ gawain/vertex_format.h
+)
+
+add_definitions(${GL_DEFINITIONS})
+
+blender_add_lib(bf_intern_gawain "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/gawain/gawain/attrib_binding.h b/intern/gawain/gawain/attrib_binding.h
new file mode 100644
index 00000000000..8c372c81cc7
--- /dev/null
+++ b/intern/gawain/gawain/attrib_binding.h
@@ -0,0 +1,19 @@
+
+// Gawain vertex attribute binding
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "common.h"
+
+typedef struct {
+ uint64_t loc_bits; // store 4 bits for each of the 16 attribs
+ uint16_t enabled_bits; // 1 bit for each attrib
+} AttribBinding;
diff --git a/intern/gawain/gawain/attrib_binding_private.h b/intern/gawain/gawain/attrib_binding_private.h
new file mode 100644
index 00000000000..c9b7a3f2c01
--- /dev/null
+++ b/intern/gawain/gawain/attrib_binding_private.h
@@ -0,0 +1,20 @@
+
+// Gawain vertex attribute binding
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "vertex_format.h"
+#include "shader_interface.h"
+
+void AttribBinding_clear(AttribBinding*);
+
+void get_attrib_locations(const VertexFormat*, AttribBinding*, const ShaderInterface*);
+unsigned read_attrib_location(const AttribBinding*, unsigned a_idx);
diff --git a/intern/gawain/gawain/batch.h b/intern/gawain/gawain/batch.h
new file mode 100644
index 00000000000..33a1c1b653c
--- /dev/null
+++ b/intern/gawain/gawain/batch.h
@@ -0,0 +1,129 @@
+
+// Gawain geometry batch
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "vertex_buffer.h"
+#include "element.h"
+#include "shader_interface.h"
+
+typedef enum {
+ READY_TO_FORMAT,
+ READY_TO_BUILD,
+ BUILDING,
+ READY_TO_DRAW
+} BatchPhase;
+
+#define BATCH_MAX_VBO_CT 3
+
+typedef struct Batch {
+ // geometry
+ VertexBuffer* verts[BATCH_MAX_VBO_CT]; // verts[0] is required, others can be NULL
+ ElementList* elem; // NULL if element list not needed
+ PrimitiveType prim_type;
+ GLenum gl_prim_type;
+
+ // book-keeping
+ GLuint vao_id; // remembers all geometry state (vertex attrib bindings & element buffer)
+ BatchPhase phase;
+ bool program_dirty;
+ bool program_in_use;
+
+ // state
+ GLuint program;
+ const ShaderInterface* interface;
+} Batch;
+
+Batch* Batch_create(PrimitiveType, VertexBuffer*, ElementList*);
+void Batch_init(Batch*, PrimitiveType, VertexBuffer*, ElementList*);
+
+void Batch_discard(Batch*); // verts & elem are not discarded
+void Batch_discard_all(Batch*); // including verts & elem
+
+int Batch_add_VertexBuffer(Batch*, VertexBuffer*);
+
+void Batch_set_program(Batch*, GLuint program, const ShaderInterface*);
+// Entire batch draws with one shader program, but can be redrawn later with another program.
+// Vertex shader's inputs must be compatible with the batch's vertex format.
+
+void Batch_use_program(Batch*); // call before Batch_Uniform (temp hack?)
+void Batch_done_using_program(Batch*);
+
+void Batch_Uniform1i(Batch*, const char* name, int value);
+void Batch_Uniform1b(Batch*, const char* name, bool value);
+void Batch_Uniform1f(Batch*, const char* name, float value);
+void Batch_Uniform2f(Batch*, const char* name, float x, float y);
+void Batch_Uniform3f(Batch*, const char* name, float x, float y, float z);
+void Batch_Uniform4f(Batch*, const char* name, float x, float y, float z, float w);
+void Batch_Uniform3fv(Batch*, const char* name, const float data[3]);
+void Batch_Uniform4fv(Batch*, const char* name, const float data[4]);
+
+void Batch_draw(Batch*);
+
+
+// clement : temp stuff
+void Batch_draw_stupid(Batch*);
+void Batch_draw_stupid_instanced(Batch*, unsigned int instance_vbo, int instance_count,
+ int attrib_nbr, int attrib_stride, int attrib_loc[16], int attrib_size[16]);
+void Batch_draw_stupid_instanced_with_batch(Batch*, Batch*);
+
+
+
+
+
+#if 0 // future plans
+
+// Can multiple batches share a VertexBuffer? Use ref count?
+
+
+// We often need a batch with its own data, to be created and discarded together.
+// WithOwn variants reduce number of system allocations.
+
+typedef struct {
+ Batch batch;
+ VertexBuffer verts; // link batch.verts to this
+} BatchWithOwnVertexBuffer;
+
+typedef struct {
+ Batch batch;
+ ElementList elem; // link batch.elem to this
+} BatchWithOwnElementList;
+
+typedef struct {
+ Batch batch;
+ ElementList elem; // link batch.elem to this
+ VertexBuffer verts; // link batch.verts to this
+} BatchWithOwnVertexBufferAndElementList;
+
+Batch* create_BatchWithOwnVertexBuffer(PrimitiveType, VertexFormat*, unsigned v_ct, ElementList*);
+Batch* create_BatchWithOwnElementList(PrimitiveType, VertexBuffer*, unsigned prim_ct);
+Batch* create_BatchWithOwnVertexBufferAndElementList(PrimitiveType, VertexFormat*, unsigned v_ct, unsigned prim_ct);
+// verts: shared, own
+// elem: none, shared, own
+Batch* create_BatchInGeneral(PrimitiveType, VertexBufferStuff, ElementListStuff);
+
+#endif // future plans
+
+
+/* Macros */
+
+#define BATCH_DISCARD_SAFE(batch) do { \
+ if (batch != NULL) { \
+ Batch_discard(batch); \
+ batch = NULL; \
+ } \
+} while (0)
+#define BATCH_DISCARD_ALL_SAFE(batch) do { \
+ if (batch != NULL) { \
+ Batch_discard_all(batch); \
+ batch = NULL; \
+ } \
+} while (0)
diff --git a/intern/gawain/gawain/buffer_id.h b/intern/gawain/gawain/buffer_id.h
new file mode 100644
index 00000000000..3f67458d060
--- /dev/null
+++ b/intern/gawain/gawain/buffer_id.h
@@ -0,0 +1,34 @@
+
+// Gawain buffer IDs
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+// Manage GL buffer IDs in a thread-safe way
+// Use these instead of glGenBuffers & its friends
+// - alloc must be called from main thread
+// - free can be called from any thread
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+
+GLuint buffer_id_alloc(void);
+void buffer_id_free(GLuint buffer_id);
+
+GLuint vao_id_alloc(void);
+void vao_id_free(GLuint vao_id);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/gawain/common.h b/intern/gawain/gawain/common.h
new file mode 100644
index 00000000000..e21b241160d
--- /dev/null
+++ b/intern/gawain/gawain/common.h
@@ -0,0 +1,27 @@
+
+// Gawain common #defines and #includes
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#if defined(NDEBUG)
+ #define TRUST_NO_ONE 0
+#else
+ // strict error checking, enabled for debug builds during early development
+ #define TRUST_NO_ONE 1
+#endif
+
+#include <GL/glew.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#if TRUST_NO_ONE
+ #include <assert.h>
+#endif
diff --git a/intern/gawain/gawain/element.h b/intern/gawain/gawain/element.h
new file mode 100644
index 00000000000..0e2ece1d2f1
--- /dev/null
+++ b/intern/gawain/gawain/element.h
@@ -0,0 +1,75 @@
+
+// Gawain element list (AKA index buffer)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "primitive.h"
+
+#define TRACK_INDEX_RANGE 1
+
+typedef enum {
+ INDEX_U8, // GL has this, Vulkan does not
+ INDEX_U16,
+ INDEX_U32
+} IndexType;
+
+typedef struct {
+ unsigned index_ct;
+#if TRACK_INDEX_RANGE
+ IndexType index_type;
+ GLenum gl_index_type;
+ unsigned min_index;
+ unsigned max_index;
+ unsigned base_index;
+#endif
+ void* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
+ GLuint vbo_id; // 0 indicates not yet sent to VRAM
+} ElementList;
+
+void ElementList_use(ElementList*);
+unsigned ElementList_size(const ElementList*);
+
+typedef struct {
+ unsigned max_allowed_index;
+ unsigned max_index_ct;
+ unsigned index_ct;
+ PrimitiveType prim_type;
+ unsigned* data;
+} ElementListBuilder;
+
+// supported primitives:
+// PRIM_POINTS
+// PRIM_LINES
+// PRIM_TRIANGLES
+
+void ElementListBuilder_init(ElementListBuilder*, PrimitiveType, unsigned prim_ct, unsigned vertex_ct);
+//void ElementListBuilder_init_custom(ElementListBuilder*, PrimitiveType, unsigned index_ct, unsigned vertex_ct);
+
+void add_generic_vertex(ElementListBuilder*, unsigned v);
+
+void add_point_vertex(ElementListBuilder*, unsigned v);
+void add_line_vertices(ElementListBuilder*, unsigned v1, unsigned v2);
+void add_triangle_vertices(ElementListBuilder*, unsigned v1, unsigned v2, unsigned v3);
+
+ElementList* ElementList_build(ElementListBuilder*);
+void ElementList_build_in_place(ElementListBuilder*, ElementList*);
+
+void ElementList_discard(ElementList*);
+
+
+/* Macros */
+
+#define ELEMENTLIST_DISCARD_SAFE(elem) do { \
+ if (elem != NULL) { \
+ ElementList_discard(elem); \
+ elem = NULL; \
+ } \
+} while (0)
diff --git a/intern/gawain/gawain/imm_util.h b/intern/gawain/gawain/imm_util.h
new file mode 100644
index 00000000000..730bd7c1a3c
--- /dev/null
+++ b/intern/gawain/gawain/imm_util.h
@@ -0,0 +1,18 @@
+
+// Gawain immediate mode drawing utilities
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+
+// Draw 2D rectangles (replaces glRect functions)
+// caller is reponsible for vertex format & shader
+void immRectf(unsigned pos, float x1, float y1, float x2, float y2);
+void immRecti(unsigned pos, int x1, int y1, int x2, int y2);
diff --git a/intern/gawain/gawain/immediate.h b/intern/gawain/gawain/immediate.h
new file mode 100644
index 00000000000..1f6ccc3a74b
--- /dev/null
+++ b/intern/gawain/gawain/immediate.h
@@ -0,0 +1,119 @@
+
+// Gawain immediate mode work-alike
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "vertex_format.h"
+#include "primitive.h"
+#include "shader_interface.h"
+
+#define IMM_BATCH_COMBO 1
+
+
+VertexFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib
+
+void immBindProgram(GLuint program, const ShaderInterface*); // every immBegin must have a program bound first
+void immUnbindProgram(void); // call after your last immEnd, or before binding another program
+
+void immBegin(PrimitiveType, unsigned vertex_ct); // must supply exactly vertex_ct vertices
+void immBeginAtMost(PrimitiveType, unsigned max_vertex_ct); // can supply fewer vertices
+void immEnd(void); // finishes and draws
+
+#if IMM_BATCH_COMBO
+#include "batch.h"
+// immBegin a batch, then use standard immFunctions as usual.
+// immEnd will finalize the batch instead of drawing.
+// Then you can draw it as many times as you like! Partially replaces the need for display lists.
+Batch* immBeginBatch(PrimitiveType, unsigned vertex_ct);
+Batch* immBeginBatchAtMost(PrimitiveType, unsigned vertex_ct);
+#endif
+
+
+// provide attribute values that can change per vertex
+// first vertex after immBegin must have all its attributes specified
+// skipped attributes will continue using the previous value for that attrib_id
+void immAttrib1f(unsigned attrib_id, float x);
+void immAttrib2f(unsigned attrib_id, float x, float y);
+void immAttrib3f(unsigned attrib_id, float x, float y, float z);
+void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w);
+
+void immAttrib2i(unsigned attrib_id, int x, int y);
+
+void immAttrib1u(unsigned attrib_id, unsigned x);
+
+void immAttrib2s(unsigned attrib_id, short x, short y);
+
+void immAttrib2fv(unsigned attrib_id, const float data[2]);
+void immAttrib3fv(unsigned attrib_id, const float data[3]);
+void immAttrib4fv(unsigned attrib_id, const float data[4]);
+
+void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b);
+void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+
+void immAttrib3ubv(unsigned attrib_id, const unsigned char data[4]);
+void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4]);
+
+// explicitly skip an attribute
+// this advanced option kills automatic value copying for this attrib_id
+void immSkipAttrib(unsigned attrib_id);
+
+
+// provide one last attribute value & end the current vertex
+// this is most often used for 2D or 3D position (similar to glVertex)
+void immVertex2f(unsigned attrib_id, float x, float y);
+void immVertex3f(unsigned attrib_id, float x, float y, float z);
+
+void immVertex2i(unsigned attrib_id, int x, int y);
+
+void immVertex2s(unsigned attrib_id, short x, short y);
+
+void immVertex2fv(unsigned attrib_id, const float data[2]);
+void immVertex3fv(unsigned attrib_id, const float data[3]);
+
+void immVertex2iv(unsigned attrib_id, const int data[2]);
+
+
+// provide uniform values that don't change for the entire draw call
+void immUniform1i(const char* name, int x);
+void immUniform4iv(const char* name, const int data[4]);
+void immUniform1f(const char* name, float x);
+void immUniform2f(const char* name, float x, float y);
+void immUniform2fv(const char* name, const float data[2]);
+void immUniform3f(const char* name, float x, float y, float z);
+void immUniform3fv(const char* name, const float data[3]);
+void immUniformArray3fv(const char* name, const float *data, int count);
+void immUniform4f(const char* name, float x, float y, float z, float w);
+void immUniform4fv(const char* name, const float data[4]);
+void immUniformArray4fv(const char* bare_name, const float *data, int count);
+void immUniformMatrix4fv(const char* name, const float data[4][4]);
+
+
+// convenience functions for setting "uniform vec4 color"
+// the rgb functions have implicit alpha = 1.0
+void immUniformColor4f(float r, float g, float b, float a);
+void immUniformColor4fv(const float rgba[4]);
+void immUniformColor3f(float r, float g, float b);
+void immUniformColor3fv(const float rgb[3]);
+void immUniformColor3fvAlpha(const float rgb[3], float a);
+
+void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b);
+void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+void immUniformColor3ubv(const unsigned char rgb[3]);
+void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a);
+void immUniformColor4ubv(const unsigned char rgba[4]);
+
+
+// these are called by the system -- not part of drawing API
+
+void immInit(void);
+void immActivate(void);
+void immDeactivate(void);
+void immDestroy(void);
diff --git a/intern/gawain/gawain/primitive.h b/intern/gawain/gawain/primitive.h
new file mode 100644
index 00000000000..25e02ab09dd
--- /dev/null
+++ b/intern/gawain/gawain/primitive.h
@@ -0,0 +1,40 @@
+
+// Gawain geometric primitives
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "common.h"
+
+typedef enum {
+ PRIM_POINTS,
+ PRIM_LINES,
+ PRIM_TRIANGLES,
+ PRIM_LINE_STRIP,
+ PRIM_LINE_LOOP, // GL has this, Vulkan does not
+ PRIM_TRIANGLE_STRIP,
+ PRIM_TRIANGLE_FAN,
+
+ PRIM_LINE_STRIP_ADJACENCY,
+
+ PRIM_NONE
+} PrimitiveType;
+
+// what types of primitives does each shader expect?
+typedef enum {
+ PRIM_CLASS_NONE = 0,
+ PRIM_CLASS_POINT = (1 << 0),
+ PRIM_CLASS_LINE = (1 << 1),
+ PRIM_CLASS_SURFACE = (1 << 2),
+ PRIM_CLASS_ANY = PRIM_CLASS_POINT | PRIM_CLASS_LINE | PRIM_CLASS_SURFACE
+} PrimitiveClass;
+
+PrimitiveClass prim_class_of_type(PrimitiveType);
+bool prim_type_belongs_to_class(PrimitiveType, PrimitiveClass);
diff --git a/intern/gawain/gawain/primitive_private.h b/intern/gawain/gawain/primitive_private.h
new file mode 100644
index 00000000000..e78433ef304
--- /dev/null
+++ b/intern/gawain/gawain/primitive_private.h
@@ -0,0 +1,14 @@
+
+// Gawain geometric primitives (private interface for use inside Gawain)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+GLenum convert_prim_type_to_gl(PrimitiveType);
diff --git a/intern/gawain/gawain/shader_interface.h b/intern/gawain/gawain/shader_interface.h
new file mode 100644
index 00000000000..cf10180e3d5
--- /dev/null
+++ b/intern/gawain/gawain/shader_interface.h
@@ -0,0 +1,53 @@
+
+// Gawain shader interface (C --> GLSL)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "common.h"
+
+typedef enum {
+ UNIFORM_NONE, // uninitialized/unknown
+
+ UNIFORM_MODELVIEW, // mat4 ModelViewMatrix
+ UNIFORM_PROJECTION, // mat4 ProjectionMatrix
+ UNIFORM_MVP, // mat4 ModelViewProjectionMatrix
+
+ UNIFORM_MODELVIEW_INV, // mat4 ModelViewInverseMatrix
+ UNIFORM_PROJECTION_INV, // mat4 ProjectionInverseMatrix
+
+ UNIFORM_NORMAL, // mat3 NormalMatrix
+
+ UNIFORM_COLOR, // vec4 color
+
+ UNIFORM_CUSTOM // custom uniform, not one of the above built-ins
+} BuiltinUniform;
+
+typedef struct {
+ const char* name;
+ unsigned name_hash;
+ GLenum gl_type;
+ BuiltinUniform builtin_type; // only for uniform inputs
+ GLint size;
+ GLint location;
+} ShaderInput;
+
+typedef struct {
+ uint16_t uniform_ct;
+ uint16_t attrib_ct;
+ ShaderInput inputs[0]; // dynamic size, uniforms followed by attribs
+} ShaderInterface;
+
+ShaderInterface* ShaderInterface_create(GLint program_id);
+void ShaderInterface_discard(ShaderInterface*);
+
+const ShaderInput* ShaderInterface_uniform(const ShaderInterface*, const char* name);
+const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface*, BuiltinUniform);
+const ShaderInput* ShaderInterface_attrib(const ShaderInterface*, const char* name);
diff --git a/intern/gawain/gawain/vertex_buffer.h b/intern/gawain/gawain/vertex_buffer.h
new file mode 100644
index 00000000000..bc5518cc4fc
--- /dev/null
+++ b/intern/gawain/gawain/vertex_buffer.h
@@ -0,0 +1,78 @@
+
+// Gawain vertex buffer
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "vertex_format.h"
+
+// How to create a VertexBuffer:
+// 1) verts = VertexBuffer_create() or VertexBuffer_init(verts)
+// 2) VertexFormat_add_attrib(verts->format, ...)
+// 3) VertexBuffer_allocate_data(verts, vertex_ct) <-- finalizes/packs vertex format
+// 4) VertexBuffer_fill_attrib(verts, pos, application_pos_buffer)
+
+// Is VertexBuffer always used as part of a Batch?
+
+typedef struct {
+ VertexFormat format;
+ unsigned vertex_ct;
+ GLubyte* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
+ GLuint vbo_id; // 0 indicates not yet sent to VRAM
+} VertexBuffer;
+
+VertexBuffer* VertexBuffer_create(void);
+VertexBuffer* VertexBuffer_create_with_format(const VertexFormat*);
+
+void VertexBuffer_discard(VertexBuffer*);
+
+void VertexBuffer_init(VertexBuffer*);
+void VertexBuffer_init_with_format(VertexBuffer*, const VertexFormat*);
+
+unsigned VertexBuffer_size(const VertexBuffer*);
+void VertexBuffer_allocate_data(VertexBuffer*, unsigned v_ct);
+void VertexBuffer_resize_data(VertexBuffer*, unsigned v_ct);
+
+// The most important set_attrib variant is the untyped one. Get it right first.
+// It takes a void* so the app developer is responsible for matching their app data types
+// to the vertex attribute's type and component count. They're in control of both, so this
+// should not be a problem.
+
+void VertexBuffer_set_attrib(VertexBuffer*, unsigned a_idx, unsigned v_idx, const void* data);
+void VertexBuffer_fill_attrib(VertexBuffer*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data
+void VertexBuffer_fill_attrib_stride(VertexBuffer*, unsigned a_idx, unsigned stride, const void* data);
+
+// TODO: decide whether to keep the functions below
+// doesn't immediate mode satisfy these needs?
+
+// void setAttrib1f(unsigned a_idx, unsigned v_idx, float x);
+// void setAttrib2f(unsigned a_idx, unsigned v_idx, float x, float y);
+// void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z);
+// void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w);
+//
+// void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b);
+// void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+
+void VertexBuffer_use(VertexBuffer*);
+
+
+// Metrics
+
+unsigned VertexBuffer_get_memory_usage(void);
+
+
+// Macros
+
+#define VERTEXBUFFER_DISCARD_SAFE(verts) do { \
+ if (verts != NULL) { \
+ VertexBuffer_discard(verts); \
+ verts = NULL; \
+ } \
+} while (0)
diff --git a/intern/gawain/gawain/vertex_format.h b/intern/gawain/gawain/vertex_format.h
new file mode 100644
index 00000000000..b4cce0b930f
--- /dev/null
+++ b/intern/gawain/gawain/vertex_format.h
@@ -0,0 +1,78 @@
+
+// Gawain vertex format
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "common.h"
+
+#define MAX_VERTEX_ATTRIBS 16
+#define MAX_ATTRIB_NAMES 3
+#define AVG_VERTEX_ATTRIB_NAME_LEN 11
+#define VERTEX_ATTRIB_NAMES_BUFFER_LEN ((AVG_VERTEX_ATTRIB_NAME_LEN + 1) * MAX_VERTEX_ATTRIBS)
+
+typedef enum {
+ COMP_I8,
+ COMP_U8,
+ COMP_I16,
+ COMP_U16,
+ COMP_I32,
+ COMP_U32,
+
+ COMP_F32,
+
+ COMP_I10
+} VertexCompType;
+
+typedef enum {
+ KEEP_FLOAT,
+ KEEP_INT,
+ NORMALIZE_INT_TO_FLOAT, // 127 (ubyte) -> 0.5 (and so on for other int types)
+ CONVERT_INT_TO_FLOAT // 127 (any int type) -> 127.0
+} VertexFetchMode;
+
+typedef struct {
+ VertexCompType comp_type;
+ unsigned gl_comp_type;
+ unsigned comp_ct; // 1 to 4
+ unsigned sz; // size in bytes, 1 to 16
+ unsigned offset; // from beginning of vertex, in bytes
+ VertexFetchMode fetch_mode;
+ const char* name[MAX_ATTRIB_NAMES];
+ unsigned name_ct;
+} Attrib;
+
+typedef struct {
+ unsigned attrib_ct; // 0 to 16 (MAX_VERTEX_ATTRIBS)
+ unsigned name_ct; // total count of active vertex attrib
+ unsigned stride; // stride in bytes, 1 to 256
+ bool packed;
+ Attrib attribs[MAX_VERTEX_ATTRIBS]; // TODO: variable-size attribs array
+ char names[VERTEX_ATTRIB_NAMES_BUFFER_LEN];
+ unsigned name_offset;
+} VertexFormat;
+
+void VertexFormat_clear(VertexFormat*);
+void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src);
+
+unsigned VertexFormat_add_attrib(VertexFormat*, const char* name, VertexCompType, unsigned comp_ct, VertexFetchMode);
+void VertexFormat_add_alias(VertexFormat*, const char* alias);
+
+// format conversion
+
+typedef struct {
+ int x : 10;
+ int y : 10;
+ int z : 10;
+ int w : 2; // 0 by default, can manually set to { -2, -1, 0, 1 }
+} PackedNormal;
+
+PackedNormal convert_i10_v3(const float data[3]);
+PackedNormal convert_i10_s3(const short data[3]);
diff --git a/intern/gawain/gawain/vertex_format_private.h b/intern/gawain/gawain/vertex_format_private.h
new file mode 100644
index 00000000000..c7f6f131339
--- /dev/null
+++ b/intern/gawain/gawain/vertex_format_private.h
@@ -0,0 +1,16 @@
+
+// Gawain vertex format (private interface for use inside Gawain)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016-2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+void VertexFormat_pack(VertexFormat*);
+unsigned padding(unsigned offset, unsigned alignment);
+unsigned vertex_buffer_size(const VertexFormat*, unsigned vertex_ct);
diff --git a/intern/gawain/src/attrib_binding.c b/intern/gawain/src/attrib_binding.c
new file mode 100644
index 00000000000..57894fdc3cc
--- /dev/null
+++ b/intern/gawain/src/attrib_binding.c
@@ -0,0 +1,70 @@
+
+// Gawain vertex attribute binding
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "attrib_binding.h"
+#include "attrib_binding_private.h"
+#include <stddef.h>
+
+#if MAX_VERTEX_ATTRIBS != 16
+ #error "attrib binding code assumes MAX_VERTEX_ATTRIBS = 16"
+#endif
+
+void AttribBinding_clear(AttribBinding* binding)
+ {
+ binding->loc_bits = 0;
+ binding->enabled_bits = 0;
+ }
+
+unsigned read_attrib_location(const AttribBinding* binding, unsigned a_idx)
+ {
+#if TRUST_NO_ONE
+ assert(a_idx < MAX_VERTEX_ATTRIBS);
+ assert(binding->enabled_bits & (1 << a_idx));
+#endif
+
+ return (binding->loc_bits >> (4 * a_idx)) & 0xF;
+ }
+
+static void write_attrib_location(AttribBinding* binding, unsigned a_idx, unsigned location)
+ {
+#if TRUST_NO_ONE
+ assert(a_idx < MAX_VERTEX_ATTRIBS);
+ assert(location < MAX_VERTEX_ATTRIBS);
+#endif
+
+ const unsigned shift = 4 * a_idx;
+ const uint64_t mask = ((uint64_t)0xF) << shift;
+ // overwrite this attrib's previous location
+ binding->loc_bits = (binding->loc_bits & ~mask) | (location << shift);
+ // mark this attrib as enabled
+ binding->enabled_bits |= 1 << a_idx;
+ }
+
+void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, const ShaderInterface* shaderface)
+ {
+ AttribBinding_clear(binding);
+
+ for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx)
+ {
+ const Attrib* a = format->attribs + a_idx;
+ for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
+ {
+ const ShaderInput* input = ShaderInterface_attrib(shaderface, a->name[n_idx]);
+
+#if TRUST_NO_ONE
+ assert(input != NULL);
+ // TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
+#endif
+
+ write_attrib_location(binding, a_idx, input->location);
+ }
+ }
+ }
diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/batch.c
new file mode 100644
index 00000000000..a1e173f6685
--- /dev/null
+++ b/intern/gawain/src/batch.c
@@ -0,0 +1,442 @@
+
+// Gawain geometry batch
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "batch.h"
+#include "buffer_id.h"
+#include "primitive_private.h"
+#include <stdlib.h>
+
+// necessary functions from matrix API
+extern void gpuBindMatrices(const ShaderInterface* shaderface);
+extern bool gpuMatricesDirty(void); // how best to use this here?
+
+Batch* Batch_create(PrimitiveType prim_type, VertexBuffer* verts, ElementList* elem)
+ {
+ Batch* batch = calloc(1, sizeof(Batch));
+
+ Batch_init(batch, prim_type, verts, elem);
+
+ return batch;
+ }
+
+void Batch_init(Batch* batch, PrimitiveType prim_type, VertexBuffer* verts, ElementList* elem)
+ {
+#if TRUST_NO_ONE
+ assert(verts != NULL);
+#endif
+
+ batch->verts[0] = verts;
+ for (int v = 1; v < BATCH_MAX_VBO_CT; ++v)
+ batch->verts[v] = NULL;
+ batch->elem = elem;
+ batch->prim_type = prim_type;
+ batch->gl_prim_type = convert_prim_type_to_gl(prim_type);
+ batch->phase = READY_TO_DRAW;
+ }
+
+void Batch_discard(Batch* batch)
+ {
+ if (batch->vao_id)
+ vao_id_free(batch->vao_id);
+
+ free(batch);
+ }
+
+void Batch_discard_all(Batch* batch)
+ {
+ for (int v = 0; v < BATCH_MAX_VBO_CT; ++v)
+ {
+ if (batch->verts[v] == NULL)
+ break;
+ VertexBuffer_discard(batch->verts[v]);
+ }
+
+ if (batch->elem)
+ ElementList_discard(batch->elem);
+
+ Batch_discard(batch);
+ }
+
+int Batch_add_VertexBuffer(Batch* batch, VertexBuffer* verts)
+ {
+ for (unsigned v = 0; v < BATCH_MAX_VBO_CT; ++v)
+ {
+ if (batch->verts[v] == NULL)
+ {
+#if TRUST_NO_ONE
+ // for now all VertexBuffers must have same vertex_ct
+ assert(verts->vertex_ct == batch->verts[0]->vertex_ct);
+ // in the near future we will enable instanced attribs which have their own vertex_ct
+#endif
+ batch->verts[v] = verts;
+ // TODO: mark dirty so we can keep attrib bindings up-to-date
+ return v;
+ }
+ }
+
+ // we only make it this far if there is no room for another VertexBuffer
+#if TRUST_NO_ONE
+ assert(false);
+#endif
+ return -1;
+ }
+
+void Batch_set_program(Batch* batch, GLuint program, const ShaderInterface* shaderface)
+ {
+#if TRUST_NO_ONE
+ assert(glIsProgram(program));
+#endif
+
+ batch->program = program;
+ batch->interface = shaderface;
+ batch->program_dirty = true;
+
+ Batch_use_program(batch); // hack! to make Batch_Uniform* simpler
+ }
+
+static void Batch_update_program_bindings(Batch* batch)
+ {
+ // disable all as a precaution
+ // why are we not using prev_attrib_enabled_bits?? see immediate.c
+ for (unsigned a_idx = 0; a_idx < MAX_VERTEX_ATTRIBS; ++a_idx)
+ glDisableVertexAttribArray(a_idx);
+
+ for (int v = 0; v < BATCH_MAX_VBO_CT; ++v)
+ {
+ VertexBuffer* verts = batch->verts[v];
+ if (verts == NULL)
+ break;
+
+ const VertexFormat* format = &verts->format;
+
+ const unsigned attrib_ct = format->attrib_ct;
+ const unsigned stride = format->stride;
+
+ VertexBuffer_use(verts);
+
+ for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
+ {
+ const Attrib* a = format->attribs + a_idx;
+
+ const GLvoid* pointer = (const GLubyte*)0 + a->offset;
+
+ for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
+ {
+ const ShaderInput* input = ShaderInterface_attrib(batch->interface, a->name[n_idx]);
+
+ if (input == NULL) continue;
+
+ glEnableVertexAttribArray(input->location);
+
+ switch (a->fetch_mode)
+ {
+ case KEEP_FLOAT:
+ case CONVERT_INT_TO_FLOAT:
+ glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
+ break;
+ case NORMALIZE_INT_TO_FLOAT:
+ glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
+ break;
+ case KEEP_INT:
+ glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
+ }
+ }
+ }
+ }
+
+ batch->program_dirty = false;
+ }
+
+void Batch_use_program(Batch* batch)
+ {
+ // NOTE: use_program & done_using_program are fragile, depend on staying in sync with
+ // the GL context's active program. use_program doesn't mark other programs as "not used".
+ // TODO: make not fragile (somehow)
+
+ if (!batch->program_in_use)
+ {
+ glUseProgram(batch->program);
+ batch->program_in_use = true;
+ }
+ }
+
+void Batch_done_using_program(Batch* batch)
+ {
+ if (batch->program_in_use)
+ {
+ glUseProgram(0);
+ batch->program_in_use = false;
+ }
+ }
+
+#if TRUST_NO_ONE
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(batch->interface, name); assert(uniform);
+#else
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(batch->interface, name);
+#endif
+
+void Batch_Uniform1i(Batch* batch, const char* name, int value)
+ {
+ GET_UNIFORM
+ glUniform1i(uniform->location, value);
+ }
+
+void Batch_Uniform1b(Batch* batch, const char* name, bool value)
+ {
+ GET_UNIFORM
+ glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE);
+ }
+
+void Batch_Uniform2f(Batch* batch, const char* name, float x, float y)
+ {
+ GET_UNIFORM
+ glUniform2f(uniform->location, x, y);
+ }
+
+void Batch_Uniform3f(Batch* batch, const char* name, float x, float y, float z)
+ {
+ GET_UNIFORM
+ glUniform3f(uniform->location, x, y, z);
+ }
+
+void Batch_Uniform4f(Batch* batch, const char* name, float x, float y, float z, float w)
+ {
+ GET_UNIFORM
+ glUniform4f(uniform->location, x, y, z, w);
+ }
+
+void Batch_Uniform1f(Batch* batch, const char* name, float x)
+ {
+ GET_UNIFORM
+ glUniform1f(uniform->location, x);
+ }
+
+void Batch_Uniform3fv(Batch* batch, const char* name, const float data[3])
+ {
+ GET_UNIFORM
+ glUniform3fv(uniform->location, 1, data);
+ }
+
+void Batch_Uniform4fv(Batch* batch, const char* name, const float data[4])
+ {
+ GET_UNIFORM
+ glUniform4fv(uniform->location, 1, data);
+ }
+
+static void Batch_prime(Batch* batch)
+ {
+ batch->vao_id = vao_id_alloc();
+ glBindVertexArray(batch->vao_id);
+
+ for (int v = 0; v < BATCH_MAX_VBO_CT; ++v)
+ {
+ if (batch->verts[v] == NULL)
+ break;
+ VertexBuffer_use(batch->verts[v]);
+ }
+
+ if (batch->elem)
+ ElementList_use(batch->elem);
+
+ // vertex attribs and element list remain bound to this VAO
+ }
+
+void Batch_draw(Batch* batch)
+ {
+#if TRUST_NO_ONE
+ assert(batch->phase == READY_TO_DRAW);
+ assert(glIsProgram(batch->program));
+#endif
+
+ if (batch->vao_id)
+ glBindVertexArray(batch->vao_id);
+ else
+ Batch_prime(batch);
+
+ if (batch->program_dirty)
+ Batch_update_program_bindings(batch);
+
+ Batch_use_program(batch);
+
+ gpuBindMatrices(batch->interface);
+
+ if (batch->elem)
+ {
+ const ElementList* el = batch->elem;
+
+#if TRACK_INDEX_RANGE
+ if (el->base_index)
+ glDrawRangeElementsBaseVertex(batch->gl_prim_type, el->min_index, el->max_index, el->index_ct, el->gl_index_type, 0, el->base_index);
+ else
+ glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, el->index_ct, el->gl_index_type, 0);
+#else
+ glDrawElements(batch->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
+#endif
+ }
+ else
+ glDrawArrays(batch->gl_prim_type, 0, batch->verts[0]->vertex_ct);
+
+ Batch_done_using_program(batch);
+ glBindVertexArray(0);
+ }
+
+
+
+// clement : temp stuff
+void Batch_draw_stupid(Batch* batch)
+ {
+ if (batch->vao_id)
+ glBindVertexArray(batch->vao_id);
+ else
+ Batch_prime(batch);
+
+ if (batch->program_dirty)
+ Batch_update_program_bindings(batch);
+
+ // Batch_use_program(batch);
+
+ //gpuBindMatrices(batch->program);
+
+ if (batch->elem)
+ {
+ const ElementList* el = batch->elem;
+
+#if TRACK_INDEX_RANGE
+ if (el->base_index)
+ glDrawRangeElementsBaseVertex(batch->gl_prim_type, el->min_index, el->max_index, el->index_ct, el->gl_index_type, 0, el->base_index);
+ else
+ glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, el->index_ct, el->gl_index_type, 0);
+#else
+ glDrawElements(batch->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
+#endif
+ }
+ else
+ glDrawArrays(batch->gl_prim_type, 0, batch->verts[0]->vertex_ct);
+
+ // Batch_done_using_program(batch);
+ glBindVertexArray(0);
+ }
+
+// clement : temp stuff
+void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count,
+ int attrib_nbr, int attrib_stride, int attrib_size[16], int attrib_loc[16])
+ {
+ if (batch->vao_id)
+ glBindVertexArray(batch->vao_id);
+ else
+ Batch_prime(batch);
+
+ if (batch->program_dirty)
+ Batch_update_program_bindings(batch);
+
+ glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
+ int ptr_ofs = 0;
+ for (int i = 0; i < attrib_nbr; ++i)
+ {
+ int size = attrib_size[i];
+ int loc = attrib_loc[i];
+ int atr_ofs = 0;
+
+ while (size > 0)
+ {
+ glEnableVertexAttribArray(loc + atr_ofs);
+ glVertexAttribPointer(loc + atr_ofs, (size > 4) ? 4 : size, GL_FLOAT, GL_FALSE,
+ sizeof(float) * attrib_stride, (GLvoid*)(sizeof(float) * ptr_ofs));
+ glVertexAttribDivisor(loc + atr_ofs, 1);
+ atr_ofs++;
+ ptr_ofs += (size > 4) ? 4 : size;
+ size -= 4;
+ }
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ // Batch_use_program(batch);
+
+ //gpuBindMatrices(batch->program);
+
+ if (batch->elem)
+ {
+ const ElementList* el = batch->elem;
+
+ glDrawElementsInstanced(batch->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, instance_count);
+ }
+ else
+ glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_ct, instance_count);
+
+ // Batch_done_using_program(batch);
+ glBindVertexArray(0);
+ }
+
+void Batch_draw_stupid_instanced_with_batch(Batch* batch_instanced, Batch* batch_instancing)
+ {
+ if (batch_instanced->vao_id)
+ glBindVertexArray(batch_instanced->vao_id);
+ else
+ Batch_prime(batch_instanced);
+
+ if (batch_instanced->program_dirty)
+ Batch_update_program_bindings(batch_instanced);
+
+ VertexBuffer* verts = batch_instancing->verts[0];
+
+ const VertexFormat* format = &verts->format;
+
+ const unsigned attrib_ct = format->attrib_ct;
+ const unsigned stride = format->stride;
+
+ VertexBuffer_use(verts);
+
+ for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
+ {
+ const Attrib* a = format->attribs + a_idx;
+
+ const GLvoid* pointer = (const GLubyte*)0 + a->offset;
+
+ for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
+ {
+ const ShaderInput* input = ShaderInterface_attrib(batch_instanced->interface, a->name[n_idx]);
+
+ if (input == NULL) continue;
+
+ glEnableVertexAttribArray(input->location);
+ glVertexAttribDivisor(input->location, 1);
+
+ switch (a->fetch_mode)
+ {
+ case KEEP_FLOAT:
+ case CONVERT_INT_TO_FLOAT:
+ glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
+ break;
+ case NORMALIZE_INT_TO_FLOAT:
+ glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
+ break;
+ case KEEP_INT:
+ glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
+ }
+ }
+ }
+
+ // Batch_use_program(batch);
+
+ //gpuBindMatrices(batch->program);
+
+ if (batch_instanced->elem)
+ {
+ const ElementList* el = batch_instanced->elem;
+
+ glDrawElementsInstanced(batch_instanced->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, verts->vertex_ct);
+ }
+ else
+ glDrawArraysInstanced(batch_instanced->gl_prim_type, 0, batch_instanced->verts[0]->vertex_ct, verts->vertex_ct);
+
+ // Batch_done_using_program(batch);
+ glBindVertexArray(0);
+ } \ No newline at end of file
diff --git a/intern/gawain/src/buffer_id.cpp b/intern/gawain/src/buffer_id.cpp
new file mode 100644
index 00000000000..450656c4ebf
--- /dev/null
+++ b/intern/gawain/src/buffer_id.cpp
@@ -0,0 +1,115 @@
+
+// Gawain buffer IDs
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.#include "buffer_id.h"
+
+#include "buffer_id.h"
+#include <mutex>
+#include <vector>
+
+#define ORPHAN_DEBUG 0
+
+#if ORPHAN_DEBUG
+ #include <cstdio>
+#endif
+
+static std::vector<GLuint> orphaned_buffer_ids;
+static std::vector<GLuint> orphaned_vao_ids;
+
+static std::mutex orphan_mutex;
+
+extern "C" {
+extern int BLI_thread_is_main(void); // Blender-specific function
+}
+
+static bool thread_is_main()
+ {
+ // "main" here means the GL context's thread
+ return BLI_thread_is_main();
+ }
+
+GLuint buffer_id_alloc()
+ {
+#if TRUST_NO_ONE
+ assert(thread_is_main());
+#endif
+
+ // delete orphaned IDs
+ orphan_mutex.lock();
+ if (!orphaned_buffer_ids.empty())
+ {
+ const auto orphaned_buffer_ct = (unsigned)orphaned_buffer_ids.size();
+#if ORPHAN_DEBUG
+ printf("deleting %u orphaned VBO%s\n", orphaned_buffer_ct, orphaned_buffer_ct == 1 ? "" : "s");
+#endif
+ glDeleteBuffers(orphaned_buffer_ct, orphaned_buffer_ids.data());
+ orphaned_buffer_ids.clear();
+ }
+ orphan_mutex.unlock();
+
+ GLuint new_buffer_id = 0;
+ glGenBuffers(1, &new_buffer_id);
+ return new_buffer_id;
+ }
+
+void buffer_id_free(GLuint buffer_id)
+ {
+ if (thread_is_main())
+ glDeleteBuffers(1, &buffer_id);
+ else
+ {
+ // add this ID to the orphaned list
+ orphan_mutex.lock();
+#if ORPHAN_DEBUG
+ printf("orphaning VBO %u\n", buffer_id);
+#endif
+ orphaned_buffer_ids.emplace_back(buffer_id);
+ orphan_mutex.unlock();
+ }
+ }
+
+GLuint vao_id_alloc()
+ {
+#if TRUST_NO_ONE
+ assert(thread_is_main());
+#endif
+
+ // delete orphaned IDs
+ orphan_mutex.lock();
+ if (!orphaned_vao_ids.empty())
+ {
+ const auto orphaned_vao_ct = (unsigned)orphaned_vao_ids.size();
+#if ORPHAN_DEBUG
+ printf("deleting %u orphaned VAO%s\n", orphaned_vao_ct, orphaned_vao_ct == 1 ? "" : "s");
+#endif
+ glDeleteVertexArrays(orphaned_vao_ct, orphaned_vao_ids.data());
+ orphaned_vao_ids.clear();
+ }
+ orphan_mutex.unlock();
+
+ GLuint new_vao_id = 0;
+ glGenVertexArrays(1, &new_vao_id);
+ return new_vao_id;
+ }
+
+void vao_id_free(GLuint vao_id)
+ {
+ if (thread_is_main())
+ glDeleteVertexArrays(1, &vao_id);
+ else
+ {
+ // add this ID to the orphaned list
+ orphan_mutex.lock();
+#if ORPHAN_DEBUG
+ printf("orphaning VAO %u\n", vao_id);
+#endif
+ orphaned_vao_ids.emplace_back(vao_id);
+ orphan_mutex.unlock();
+ }
+ }
diff --git a/intern/gawain/src/element.c b/intern/gawain/src/element.c
new file mode 100644
index 00000000000..425e3705003
--- /dev/null
+++ b/intern/gawain/src/element.c
@@ -0,0 +1,295 @@
+
+// Gawain element list (AKA index buffer)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "element.h"
+#include "buffer_id.h"
+#include <stdlib.h>
+
+#define KEEP_SINGLE_COPY 1
+
+static GLenum convert_index_type_to_gl(IndexType type)
+ {
+ static const GLenum table[] = {
+ [INDEX_U8] = GL_UNSIGNED_BYTE, // GL has this, Vulkan does not
+ [INDEX_U16] = GL_UNSIGNED_SHORT,
+ [INDEX_U32] = GL_UNSIGNED_INT
+ };
+ return table[type];
+ }
+
+unsigned ElementList_size(const ElementList* elem)
+ {
+#if TRACK_INDEX_RANGE
+ static const unsigned table[] = {
+ [INDEX_U8] = sizeof(GLubyte), // GL has this, Vulkan does not
+ [INDEX_U16] = sizeof(GLushort),
+ [INDEX_U32] = sizeof(GLuint)
+ };
+ return elem->index_ct * table[elem->index_type];
+#else
+ return elem->index_ct * sizeof(GLuint);
+#endif
+ }
+
+static void ElementList_prime(ElementList* elem)
+ {
+ elem->vbo_id = buffer_id_alloc();
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
+ // fill with delicious data & send to GPU the first time only
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, ElementList_size(elem), elem->data, GL_STATIC_DRAW);
+
+#if KEEP_SINGLE_COPY
+ // now that GL has a copy, discard original
+ free(elem->data);
+ elem->data = NULL;
+#endif
+ }
+
+void ElementList_use(ElementList* elem)
+ {
+ if (elem->vbo_id)
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
+ else
+ ElementList_prime(elem);
+ }
+
+void ElementListBuilder_init(ElementListBuilder* builder, PrimitiveType prim_type, unsigned prim_ct, unsigned vertex_ct)
+ {
+ unsigned verts_per_prim = 0;
+ switch (prim_type)
+ {
+ case PRIM_POINTS:
+ verts_per_prim = 1;
+ break;
+ case PRIM_LINES:
+ verts_per_prim = 2;
+ break;
+ case PRIM_TRIANGLES:
+ verts_per_prim = 3;
+ break;
+ default:
+#if TRUST_NO_ONE
+ assert(false);
+#endif
+ return;
+ }
+
+ builder->max_allowed_index = vertex_ct - 1;
+ builder->max_index_ct = prim_ct * verts_per_prim;
+ builder->index_ct = 0; // start empty
+ builder->prim_type = prim_type;
+ builder->data = calloc(builder->max_index_ct, sizeof(unsigned));
+ }
+
+void add_generic_vertex(ElementListBuilder* builder, unsigned v)
+ {
+#if TRUST_NO_ONE
+ assert(builder->data != NULL);
+ assert(builder->index_ct < builder->max_index_ct);
+ assert(v <= builder->max_allowed_index);
+#endif
+
+ builder->data[builder->index_ct++] = v;
+ }
+
+void add_point_vertex(ElementListBuilder* builder, unsigned v)
+ {
+#if TRUST_NO_ONE
+ assert(builder->prim_type == PRIM_POINTS);
+#endif
+
+ add_generic_vertex(builder, v);
+ }
+
+void add_line_vertices(ElementListBuilder* builder, unsigned v1, unsigned v2)
+ {
+#if TRUST_NO_ONE
+ assert(builder->prim_type == PRIM_LINES);
+ assert(v1 != v2);
+#endif
+
+ add_generic_vertex(builder, v1);
+ add_generic_vertex(builder, v2);
+ }
+
+void add_triangle_vertices(ElementListBuilder* builder, unsigned v1, unsigned v2, unsigned v3)
+ {
+#if TRUST_NO_ONE
+ assert(builder->prim_type == PRIM_TRIANGLES);
+ assert(v1 != v2 && v2 != v3 && v3 != v1);
+#endif
+
+ add_generic_vertex(builder, v1);
+ add_generic_vertex(builder, v2);
+ add_generic_vertex(builder, v3);
+ }
+
+#if TRACK_INDEX_RANGE
+// Everything remains 32 bit while building to keep things simple.
+// Find min/max after, then convert to smallest index type possible.
+
+static unsigned index_range(const unsigned values[], unsigned value_ct, unsigned* min_out, unsigned* max_out)
+ {
+ if (value_ct == 0)
+ {
+ *min_out = 0;
+ *max_out = 0;
+ return 0;
+ }
+ unsigned min_value = values[0];
+ unsigned max_value = values[0];
+ for (unsigned i = 1; i < value_ct; ++i)
+ {
+ const unsigned value = values[i];
+ if (value < min_value)
+ min_value = value;
+ else if (value > max_value)
+ max_value = value;
+ }
+ *min_out = min_value;
+ *max_out = max_value;
+ return max_value - min_value;
+ }
+
+static void squeeze_indices_byte(const unsigned values[], ElementList* elem)
+ {
+ const unsigned index_ct = elem->index_ct;
+ GLubyte* data = malloc(index_ct * sizeof(GLubyte));
+
+ if (elem->max_index > 0xFF)
+ {
+ const unsigned base = elem->min_index;
+
+ elem->base_index = base;
+ elem->min_index = 0;
+ elem->max_index -= base;
+
+ for (unsigned i = 0; i < index_ct; ++i)
+ data[i] = (GLubyte)(values[i] - base);
+ }
+ else
+ {
+ elem->base_index = 0;
+
+ for (unsigned i = 0; i < index_ct; ++i)
+ data[i] = (GLubyte)(values[i]);
+ }
+
+ elem->data = data;
+ }
+
+static void squeeze_indices_short(const unsigned values[], ElementList* elem)
+ {
+ const unsigned index_ct = elem->index_ct;
+ GLushort* data = malloc(index_ct * sizeof(GLushort));
+
+ if (elem->max_index > 0xFFFF)
+ {
+ const unsigned base = elem->min_index;
+
+ elem->base_index = base;
+ elem->min_index = 0;
+ elem->max_index -= base;
+
+ for (unsigned i = 0; i < index_ct; ++i)
+ data[i] = (GLushort)(values[i] - base);
+ }
+ else
+ {
+ elem->base_index = 0;
+
+ for (unsigned i = 0; i < index_ct; ++i)
+ data[i] = (GLushort)(values[i]);
+ }
+
+ elem->data = data;
+ }
+
+#endif // TRACK_INDEX_RANGE
+
+ElementList* ElementList_build(ElementListBuilder* builder)
+ {
+ ElementList* elem = calloc(1, sizeof(ElementList));
+ ElementList_build_in_place(builder, elem);
+ return elem;
+ }
+
+void ElementList_build_in_place(ElementListBuilder* builder, ElementList* elem)
+ {
+#if TRUST_NO_ONE
+ assert(builder->data != NULL);
+#endif
+
+ elem->index_ct = builder->index_ct;
+
+#if TRACK_INDEX_RANGE
+ const unsigned range = index_range(builder->data, builder->index_ct, &elem->min_index, &elem->max_index);
+
+ if (range <= 0xFF)
+ {
+ elem->index_type = INDEX_U8;
+ squeeze_indices_byte(builder->data, elem);
+ }
+ else if (range <= 0xFFFF)
+ {
+ elem->index_type = INDEX_U16;
+ squeeze_indices_short(builder->data, elem);
+ }
+ else
+ {
+ elem->index_type = INDEX_U32;
+ elem->base_index = 0;
+
+ if (builder->index_ct < builder->max_index_ct)
+ {
+ builder->data = realloc(builder->data, builder->index_ct * sizeof(unsigned));
+ // TODO: realloc only if index_ct is much smaller than max_index_ct
+ }
+
+ elem->data = builder->data;
+ }
+
+ elem->gl_index_type = convert_index_type_to_gl(elem->index_type);
+#else
+ if (builder->index_ct < builder->max_index_ct)
+ {
+ builder->data = realloc(builder->data, builder->index_ct * sizeof(unsigned));
+ // TODO: realloc only if index_ct is much smaller than max_index_ct
+ }
+
+ elem->data = builder->data;
+#endif
+
+ // elem->data will never be *larger* than builder->data... how about converting
+ // in place to avoid extra allocation?
+
+ elem->vbo_id = 0;
+ // TODO: create GL buffer object directly, based on an input flag
+
+ // discard builder (one-time use)
+ if (builder->data != elem->data)
+ free(builder->data);
+ builder->data = NULL;
+ // other fields are safe to leave
+ }
+
+void ElementList_discard(ElementList* elem)
+ {
+ if (elem->vbo_id)
+ buffer_id_free(elem->vbo_id);
+#if KEEP_SINGLE_COPY
+ else
+#endif
+ if (elem->data)
+ free(elem->data);
+
+ free(elem);
+ }
diff --git a/intern/gawain/src/imm_util.c b/intern/gawain/src/imm_util.c
new file mode 100644
index 00000000000..de50ca96907
--- /dev/null
+++ b/intern/gawain/src/imm_util.c
@@ -0,0 +1,46 @@
+
+// Gawain immediate mode drawing utilities
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "imm_util.h"
+#include "immediate.h"
+
+
+void immRectf(unsigned pos, float x1, float y1, float x2, float y2)
+ {
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x1, y2);
+ immEnd();
+ }
+
+void immRecti(unsigned pos, int x1, int y1, int x2, int y2)
+ {
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immVertex2i(pos, x1, y1);
+ immVertex2i(pos, x2, y1);
+ immVertex2i(pos, x2, y2);
+ immVertex2i(pos, x1, y2);
+ immEnd();
+ }
+
+#if 0 // more complete version in case we want that
+void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4])
+ {
+ VertexFormat *format = immVertexFormat();
+ unsigned pos = add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+ immRecti(pos, x1, y1, x2, y2);
+ immUnbindProgram();
+ }
+#endif
diff --git a/intern/gawain/src/immediate.c b/intern/gawain/src/immediate.c
new file mode 100644
index 00000000000..af9a48c2f4d
--- /dev/null
+++ b/intern/gawain/src/immediate.c
@@ -0,0 +1,919 @@
+
+// Gawain immediate mode work-alike
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "immediate.h"
+#include "buffer_id.h"
+#include "attrib_binding.h"
+#include "attrib_binding_private.h"
+#include "vertex_format_private.h"
+#include "primitive_private.h"
+#include <string.h>
+
+// necessary functions from matrix API
+extern void gpuBindMatrices(const ShaderInterface*);
+extern bool gpuMatricesDirty(void);
+
+typedef struct {
+ // TODO: organize this struct by frequency of change (run-time)
+
+#if IMM_BATCH_COMBO
+ Batch* batch;
+#endif
+
+ // current draw call
+ GLubyte* buffer_data;
+ unsigned buffer_offset;
+ unsigned buffer_bytes_mapped;
+ unsigned vertex_ct;
+ bool strict_vertex_ct;
+ PrimitiveType prim_type;
+
+ VertexFormat vertex_format;
+
+ // current vertex
+ unsigned vertex_idx;
+ GLubyte* vertex_data;
+ uint16_t unassigned_attrib_bits; // which attributes of current vertex have not been given values?
+
+ GLuint vbo_id;
+ GLuint vao_id;
+
+ GLuint bound_program;
+ const ShaderInterface* shader_interface;
+ AttribBinding attrib_binding;
+ uint16_t prev_enabled_attrib_bits; // <-- only affects this VAO, so we're ok
+} Immediate;
+
+// size of internal buffer -- make this adjustable?
+#define IMM_BUFFER_SIZE (4 * 1024 * 1024)
+
+static bool initialized = false;
+static Immediate imm;
+
+void immInit(void)
+ {
+#if TRUST_NO_ONE
+ assert(!initialized);
+#endif
+
+ memset(&imm, 0, sizeof(Immediate));
+
+ imm.vbo_id = buffer_id_alloc();
+ glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id);
+ glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
+
+ imm.prim_type = PRIM_NONE;
+ imm.strict_vertex_ct = true;
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ initialized = true;
+
+ immActivate();
+ }
+
+void immActivate(void)
+ {
+#if TRUST_NO_ONE
+ assert(initialized);
+ assert(imm.prim_type == PRIM_NONE); // make sure we're not between a Begin/End pair
+ assert(imm.vao_id == 0);
+#endif
+
+ imm.vao_id = vao_id_alloc();
+ }
+
+void immDeactivate(void)
+ {
+#if TRUST_NO_ONE
+ assert(initialized);
+ assert(imm.prim_type == PRIM_NONE); // make sure we're not between a Begin/End pair
+ assert(imm.vao_id != 0);
+#endif
+
+ vao_id_free(imm.vao_id);
+ imm.vao_id = 0;
+ imm.prev_enabled_attrib_bits = 0;
+ }
+
+void immDestroy(void)
+ {
+ immDeactivate();
+ buffer_id_free(imm.vbo_id);
+ initialized = false;
+ }
+
+VertexFormat* immVertexFormat(void)
+ {
+ VertexFormat_clear(&imm.vertex_format);
+ return &imm.vertex_format;
+ }
+
+void immBindProgram(GLuint program, const ShaderInterface* shaderface)
+ {
+#if TRUST_NO_ONE
+ assert(imm.bound_program == 0);
+ assert(glIsProgram(program));
+#endif
+
+ imm.bound_program = program;
+ imm.shader_interface = shaderface;
+
+ if (!imm.vertex_format.packed)
+ VertexFormat_pack(&imm.vertex_format);
+
+ glUseProgram(program);
+ get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface);
+ gpuBindMatrices(shaderface);
+ }
+
+void immUnbindProgram(void)
+ {
+#if TRUST_NO_ONE
+ assert(imm.bound_program != 0);
+#endif
+
+ glUseProgram(0);
+ imm.bound_program = 0;
+ }
+
+#if TRUST_NO_ONE
+static bool vertex_count_makes_sense_for_primitive(unsigned vertex_ct, PrimitiveType prim_type)
+ {
+ // does vertex_ct make sense for this primitive type?
+ if (vertex_ct == 0)
+ return false;
+
+ switch (prim_type)
+ {
+ case PRIM_POINTS:
+ return true;
+ case PRIM_LINES:
+ return vertex_ct % 2 == 0;
+ case PRIM_LINE_STRIP:
+ case PRIM_LINE_LOOP:
+ return vertex_ct >= 2;
+ case PRIM_LINE_STRIP_ADJACENCY:
+ return vertex_ct >= 4;
+ case PRIM_TRIANGLES:
+ return vertex_ct % 3 == 0;
+ case PRIM_TRIANGLE_STRIP:
+ case PRIM_TRIANGLE_FAN:
+ return vertex_ct >= 3;
+ default:
+ return false;
+ }
+ }
+#endif
+
+void immBegin(PrimitiveType prim_type, unsigned vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(initialized);
+ assert(imm.prim_type == PRIM_NONE); // make sure we haven't already begun
+ assert(vertex_count_makes_sense_for_primitive(vertex_ct, prim_type));
+#endif
+
+ imm.prim_type = prim_type;
+ imm.vertex_ct = vertex_ct;
+ imm.vertex_idx = 0;
+ imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
+
+ // how many bytes do we need for this draw call?
+ const unsigned bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_ct);
+
+#if TRUST_NO_ONE
+ assert(bytes_needed <= IMM_BUFFER_SIZE);
+#endif
+
+ glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id);
+
+ // does the current buffer have enough room?
+ const unsigned available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset;
+ // ensure vertex data is aligned
+ const unsigned pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); // might waste a little space, but it's safe
+ if ((bytes_needed + pre_padding) <= available_bytes)
+ imm.buffer_offset += pre_padding;
+ else
+ {
+ // orphan this buffer & start with a fresh one
+#if 1
+ // this method works on all platforms, old & new
+ glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
+#else
+ // TODO: use other (more recent) methods after thorough testing
+ if (GLEW_VERSION_4_3 || GLEW_ARB_invalidate_subdata)
+ glInvalidateBufferData(imm.vbo_id);
+ else
+ {
+ // glitches!
+// glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE, GL_MAP_INVALIDATE_BUFFER_BIT);
+
+ // works
+// glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE,
+// GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+// glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ // also works
+ glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
+ }
+#endif
+
+ imm.buffer_offset = 0;
+ }
+
+// printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1);
+
+ imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, imm.buffer_offset, bytes_needed,
+ GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | (imm.strict_vertex_ct ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT));
+
+#if TRUST_NO_ONE
+ assert(imm.buffer_data != NULL);
+#endif
+
+ imm.buffer_bytes_mapped = bytes_needed;
+ imm.vertex_data = imm.buffer_data;
+ }
+
+void immBeginAtMost(PrimitiveType prim_type, unsigned vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(vertex_ct > 0);
+#endif
+
+ imm.strict_vertex_ct = false;
+ immBegin(prim_type, vertex_ct);
+ }
+
+#if IMM_BATCH_COMBO
+
+Batch* immBeginBatch(PrimitiveType prim_type, unsigned vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(initialized);
+ assert(imm.prim_type == PRIM_NONE); // make sure we haven't already begun
+ assert(vertex_count_makes_sense_for_primitive(vertex_ct, prim_type));
+#endif
+
+ imm.prim_type = prim_type;
+ imm.vertex_ct = vertex_ct;
+ imm.vertex_idx = 0;
+ imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
+
+ VertexBuffer* verts = VertexBuffer_create_with_format(&imm.vertex_format);
+ VertexBuffer_allocate_data(verts, vertex_ct);
+
+ imm.buffer_bytes_mapped = VertexBuffer_size(verts);
+ imm.vertex_data = verts->data;
+
+ imm.batch = Batch_create(prim_type, verts, NULL);
+ imm.batch->phase = BUILDING;
+
+ Batch_set_program(imm.batch, imm.bound_program, imm.shader_interface);
+
+ return imm.batch;
+ }
+
+Batch* immBeginBatchAtMost(PrimitiveType prim_type, unsigned vertex_ct)
+ {
+ imm.strict_vertex_ct = false;
+ return immBeginBatch(prim_type, vertex_ct);
+ }
+
+#endif // IMM_BATCH_COMBO
+
+static void immDrawSetup(void)
+ {
+ // set up VAO -- can be done during Begin or End really
+ glBindVertexArray(imm.vao_id);
+
+ // enable/disable vertex attribs as needed
+ if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits)
+ {
+ for (unsigned loc = 0; loc < MAX_VERTEX_ATTRIBS; ++loc)
+ {
+ bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc);
+ bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc);
+
+ if (is_enabled && !was_enabled)
+ {
+// printf("enabling attrib %u\n", loc);
+ glEnableVertexAttribArray(loc);
+ }
+ else if (was_enabled && !is_enabled)
+ {
+// printf("disabling attrib %u\n", loc);
+ glDisableVertexAttribArray(loc);
+ }
+ }
+
+ imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits;
+ }
+
+ const unsigned stride = imm.vertex_format.stride;
+
+ for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx)
+ {
+ const Attrib* a = imm.vertex_format.attribs + a_idx;
+
+ const unsigned offset = imm.buffer_offset + a->offset;
+ const GLvoid* pointer = (const GLubyte*)0 + offset;
+
+ const unsigned loc = read_attrib_location(&imm.attrib_binding, a_idx);
+
+// printf("specifying attrib %u '%s' with offset %u, stride %u\n", loc, a->name, offset, stride);
+
+ switch (a->fetch_mode)
+ {
+ case KEEP_FLOAT:
+ case CONVERT_INT_TO_FLOAT:
+ glVertexAttribPointer(loc, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
+ break;
+ case NORMALIZE_INT_TO_FLOAT:
+ glVertexAttribPointer(loc, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
+ break;
+ case KEEP_INT:
+ glVertexAttribIPointer(loc, a->comp_ct, a->gl_comp_type, stride, pointer);
+ }
+ }
+
+ if (gpuMatricesDirty())
+ gpuBindMatrices(imm.shader_interface);
+ }
+
+void immEnd(void)
+ {
+#if TRUST_NO_ONE
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ unsigned buffer_bytes_used;
+ if (imm.strict_vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(imm.vertex_idx == imm.vertex_ct); // with all vertices defined
+#endif
+ buffer_bytes_used = imm.buffer_bytes_mapped;
+ }
+ else
+ {
+#if TRUST_NO_ONE
+ assert(imm.vertex_idx <= imm.vertex_ct);
+#endif
+ // printf("used %u of %u verts,", imm.vertex_idx, imm.vertex_ct);
+ if (imm.vertex_idx == imm.vertex_ct)
+ {
+ buffer_bytes_used = imm.buffer_bytes_mapped;
+ }
+ else
+ {
+#if TRUST_NO_ONE
+ assert(imm.vertex_idx == 0 || vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type));
+#endif
+ imm.vertex_ct = imm.vertex_idx;
+ buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_ct);
+ // unused buffer bytes are available to the next immBegin
+ // printf(" %u of %u bytes\n", buffer_bytes_used, imm.buffer_bytes_mapped);
+ }
+
+ // tell OpenGL what range was modified so it doesn't copy the whole mapped range
+ // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
+ glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used);
+ }
+
+#if IMM_BATCH_COMBO
+ if (imm.batch)
+ {
+ if (buffer_bytes_used != imm.buffer_bytes_mapped)
+ {
+ VertexBuffer_resize_data(imm.batch->verts[0], imm.vertex_ct);
+ // TODO: resize only if vertex count is much smaller
+ }
+
+ imm.batch->phase = READY_TO_DRAW;
+ imm.batch = NULL; // don't free, batch belongs to caller
+ }
+ else
+#endif
+ {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ if (imm.vertex_ct > 0)
+ {
+ immDrawSetup();
+ glDrawArrays(convert_prim_type_to_gl(imm.prim_type), 0, imm.vertex_ct);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+
+ // prep for next immBegin
+ imm.buffer_offset += buffer_bytes_used;
+ }
+
+ // prep for next immBegin
+ imm.prim_type = PRIM_NONE;
+ imm.strict_vertex_ct = true;
+ }
+
+static void setAttribValueBit(unsigned attrib_id)
+ {
+ uint16_t mask = 1 << attrib_id;
+
+#if TRUST_NO_ONE
+ assert(imm.unassigned_attrib_bits & mask); // not already set
+#endif
+
+ imm.unassigned_attrib_bits &= ~mask;
+ }
+
+
+// --- generic attribute functions ---
+
+void immAttrib1f(unsigned attrib_id, float x)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_F32);
+ assert(attrib->comp_ct == 1);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ float* data = (float*)(imm.vertex_data + attrib->offset);
+// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
+
+ data[0] = x;
+ }
+
+void immAttrib2f(unsigned attrib_id, float x, float y)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_F32);
+ assert(attrib->comp_ct == 2);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ float* data = (float*)(imm.vertex_data + attrib->offset);
+// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
+
+ data[0] = x;
+ data[1] = y;
+ }
+
+void immAttrib3f(unsigned attrib_id, float x, float y, float z)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_F32);
+ assert(attrib->comp_ct == 3);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ float* data = (float*)(imm.vertex_data + attrib->offset);
+// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
+
+ data[0] = x;
+ data[1] = y;
+ data[2] = z;
+ }
+
+void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_F32);
+ assert(attrib->comp_ct == 4);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ float* data = (float*)(imm.vertex_data + attrib->offset);
+// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
+
+ data[0] = x;
+ data[1] = y;
+ data[2] = z;
+ data[3] = w;
+ }
+
+void immAttrib1u(unsigned attrib_id, unsigned x)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_U32);
+ assert(attrib->comp_ct == 1);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ unsigned* data = (unsigned*)(imm.vertex_data + attrib->offset);
+
+ data[0] = x;
+ }
+
+void immAttrib2i(unsigned attrib_id, int x, int y)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_I32);
+ assert(attrib->comp_ct == 2);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ int* data = (int*)(imm.vertex_data + attrib->offset);
+
+ data[0] = x;
+ data[1] = y;
+ }
+
+void immAttrib2s(unsigned attrib_id, short x, short y)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_I16);
+ assert(attrib->comp_ct == 2);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ short* data = (short*)(imm.vertex_data + attrib->offset);
+
+ data[0] = x;
+ data[1] = y;
+ }
+
+void immAttrib2fv(unsigned attrib_id, const float data[2])
+ {
+ immAttrib2f(attrib_id, data[0], data[1]);
+ }
+
+void immAttrib3fv(unsigned attrib_id, const float data[3])
+ {
+ immAttrib3f(attrib_id, data[0], data[1], data[2]);
+ }
+
+void immAttrib4fv(unsigned attrib_id, const float data[4])
+ {
+ immAttrib4f(attrib_id, data[0], data[1], data[2], data[3]);
+ }
+
+void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_U8);
+ assert(attrib->comp_ct == 3);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ GLubyte* data = imm.vertex_data + attrib->offset;
+// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data);
+
+ data[0] = r;
+ data[1] = g;
+ data[2] = b;
+ }
+
+void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+ {
+ Attrib* attrib = imm.vertex_format.attribs + attrib_id;
+
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(attrib->comp_type == COMP_U8);
+ assert(attrib->comp_ct == 4);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+
+ GLubyte* data = imm.vertex_data + attrib->offset;
+// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data);
+
+ data[0] = r;
+ data[1] = g;
+ data[2] = b;
+ data[3] = a;
+ }
+
+void immAttrib3ubv(unsigned attrib_id, const unsigned char data[3])
+ {
+ immAttrib3ub(attrib_id, data[0], data[1], data[2]);
+ }
+
+void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4])
+ {
+ immAttrib4ub(attrib_id, data[0], data[1], data[2], data[3]);
+ }
+
+void immSkipAttrib(unsigned attrib_id)
+ {
+#if TRUST_NO_ONE
+ assert(attrib_id < imm.vertex_format.attrib_ct);
+ assert(imm.vertex_idx < imm.vertex_ct);
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+#endif
+
+ setAttribValueBit(attrib_id);
+ }
+
+static void immEndVertex(void) // and move on to the next vertex
+ {
+#if TRUST_NO_ONE
+ assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
+ assert(imm.vertex_idx < imm.vertex_ct);
+#endif
+
+ // have all attribs been assigned values?
+ // if not, copy value from previous vertex
+ if (imm.unassigned_attrib_bits)
+ {
+#if TRUST_NO_ONE
+ assert(imm.vertex_idx > 0); // first vertex must have all attribs specified
+#endif
+
+ for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx)
+ {
+ if ((imm.unassigned_attrib_bits >> a_idx) & 1)
+ {
+ const Attrib* a = imm.vertex_format.attribs + a_idx;
+
+// printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx);
+
+ GLubyte* data = imm.vertex_data + a->offset;
+ memcpy(data, data - imm.vertex_format.stride, a->sz);
+ // TODO: consolidate copy of adjacent attributes
+ }
+ }
+ }
+
+ imm.vertex_idx++;
+ imm.vertex_data += imm.vertex_format.stride;
+ imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
+ }
+
+void immVertex2f(unsigned attrib_id, float x, float y)
+ {
+ immAttrib2f(attrib_id, x, y);
+ immEndVertex();
+ }
+
+void immVertex3f(unsigned attrib_id, float x, float y, float z)
+ {
+ immAttrib3f(attrib_id, x, y, z);
+ immEndVertex();
+ }
+
+void immVertex2i(unsigned attrib_id, int x, int y)
+ {
+ immAttrib2i(attrib_id, x, y);
+ immEndVertex();
+ }
+
+void immVertex2s(unsigned attrib_id, short x, short y)
+ {
+ immAttrib2s(attrib_id, x, y);
+ immEndVertex();
+ }
+
+void immVertex2fv(unsigned attrib_id, const float data[2])
+ {
+ immAttrib2f(attrib_id, data[0], data[1]);
+ immEndVertex();
+ }
+
+void immVertex3fv(unsigned attrib_id, const float data[3])
+ {
+ immAttrib3f(attrib_id, data[0], data[1], data[2]);
+ immEndVertex();
+ }
+
+void immVertex2iv(unsigned attrib_id, const int data[2])
+ {
+ immAttrib2i(attrib_id, data[0], data[1]);
+ immEndVertex();
+ }
+
+
+// --- generic uniform functions ---
+
+#if 0
+ #if TRUST_NO_ONE
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(imm.shader_interface, name); assert(uniform);
+ #else
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(imm.shader_interface, name);
+ #endif
+#else
+ // NOTE: It is possible to have uniform fully optimized out from the shader.
+ // In this case we can't assert failure or allow NULL-pointer dereference.
+ // TODO(sergey): How can we detect existing-but-optimized-out uniform but still
+ // catch typos in uniform names passed to immUniform*() functions?
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(imm.shader_interface, name); if (uniform == NULL) return;
+#endif
+
+void immUniform1f(const char* name, float x)
+ {
+ GET_UNIFORM
+ glUniform1f(uniform->location, x);
+ }
+
+void immUniform2f(const char* name, float x, float y)
+ {
+ GET_UNIFORM
+ glUniform2f(uniform->location, x, y);
+ }
+
+void immUniform2fv(const char* name, const float data[2])
+ {
+ GET_UNIFORM
+ glUniform2fv(uniform->location, 1, data);
+ }
+
+void immUniform3f(const char* name, float x, float y, float z)
+ {
+ GET_UNIFORM
+ glUniform3f(uniform->location, x, y, z);
+ }
+
+void immUniform3fv(const char* name, const float data[3])
+ {
+ GET_UNIFORM
+ glUniform3fv(uniform->location, 1, data);
+ }
+
+// can increase this limit or move to another file
+#define MAX_UNIFORM_NAME_LEN 60
+
+void immUniformArray3fv(const char* bare_name, const float *data, int count)
+ {
+ // look up "name[0]" when given "name"
+ const size_t len = strlen(bare_name);
+#if TRUST_NO_ONE
+ assert(len <= MAX_UNIFORM_NAME_LEN);
+#endif
+ char name[MAX_UNIFORM_NAME_LEN];
+ strcpy(name, bare_name);
+ name[len + 0] = '[';
+ name[len + 1] = '0';
+ name[len + 2] = ']';
+ name[len + 3] = '\0';
+
+ GET_UNIFORM
+ glUniform3fv(uniform->location, count, data);
+ }
+
+void immUniform4f(const char* name, float x, float y, float z, float w)
+ {
+ GET_UNIFORM
+ glUniform4f(uniform->location, x, y, z, w);
+ }
+
+void immUniform4fv(const char* name, const float data[4])
+ {
+ GET_UNIFORM
+ glUniform4fv(uniform->location, 1, data);
+ }
+
+void immUniformArray4fv(const char* bare_name, const float *data, int count)
+ {
+ // look up "name[0]" when given "name"
+ const size_t len = strlen(bare_name);
+#if TRUST_NO_ONE
+ assert(len <= MAX_UNIFORM_NAME_LEN);
+#endif
+ char name[MAX_UNIFORM_NAME_LEN];
+ strcpy(name, bare_name);
+ name[len + 0] = '[';
+ name[len + 1] = '0';
+ name[len + 2] = ']';
+ name[len + 3] = '\0';
+
+ GET_UNIFORM
+ glUniform4fv(uniform->location, count, data);
+ }
+
+void immUniformMatrix4fv(const char* name, const float data[4][4])
+ {
+ GET_UNIFORM
+ glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data);
+ }
+
+void immUniform1i(const char* name, int x)
+ {
+ GET_UNIFORM
+ glUniform1i(uniform->location, x);
+ }
+
+void immUniform4iv(const char* name, const int data[4])
+ {
+ GET_UNIFORM
+ glUniform4iv(uniform->location, 1, data);
+ }
+
+// --- convenience functions for setting "uniform vec4 color" ---
+
+void immUniformColor4f(float r, float g, float b, float a)
+ {
+ const ShaderInput* uniform = ShaderInterface_builtin_uniform(imm.shader_interface, UNIFORM_COLOR);
+
+#if TRUST_NO_ONE
+ assert(uniform != NULL);
+#endif
+
+ glUniform4f(uniform->location, r, g, b, a);
+ }
+
+void immUniformColor4fv(const float rgba[4])
+ {
+ immUniformColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
+
+void immUniformColor3f(float r, float g, float b)
+ {
+ immUniformColor4f(r, g, b, 1.0f);
+ }
+
+void immUniformColor3fv(const float rgb[3])
+ {
+ immUniformColor4f(rgb[0], rgb[1], rgb[2], 1.0f);
+ }
+
+void immUniformColor3fvAlpha(const float rgb[3], float a)
+ {
+ immUniformColor4f(rgb[0], rgb[1], rgb[2], a);
+ }
+
+// TODO: v-- treat as sRGB? --v
+
+void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b)
+ {
+ const float scale = 1.0f / 255.0f;
+ immUniformColor4f(scale * r, scale * g, scale * b, 1.0f);
+ }
+
+void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+ {
+ const float scale = 1.0f / 255.0f;
+ immUniformColor4f(scale * r, scale * g, scale * b, scale * a);
+ }
+
+void immUniformColor3ubv(const unsigned char rgb[3])
+ {
+ immUniformColor3ub(rgb[0], rgb[1], rgb[2]);
+ }
+
+void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char alpha)
+ {
+ immUniformColor4ub(rgb[0], rgb[1], rgb[2], alpha);
+ }
+
+void immUniformColor4ubv(const unsigned char rgba[4])
+ {
+ immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
diff --git a/intern/gawain/src/primitive.c b/intern/gawain/src/primitive.c
new file mode 100644
index 00000000000..da32932c1e5
--- /dev/null
+++ b/intern/gawain/src/primitive.c
@@ -0,0 +1,63 @@
+
+// Gawain geometric primitives
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "primitive.h"
+#include "primitive_private.h"
+
+PrimitiveClass prim_class_of_type(PrimitiveType prim_type)
+ {
+ static const PrimitiveClass classes[] =
+ {
+ [PRIM_POINTS] = PRIM_CLASS_POINT,
+ [PRIM_LINES] = PRIM_CLASS_LINE,
+ [PRIM_LINE_STRIP] = PRIM_CLASS_LINE,
+ [PRIM_LINE_LOOP] = PRIM_CLASS_LINE,
+ [PRIM_TRIANGLES] = PRIM_CLASS_SURFACE,
+ [PRIM_TRIANGLE_STRIP] = PRIM_CLASS_SURFACE,
+ [PRIM_TRIANGLE_FAN] = PRIM_CLASS_SURFACE,
+
+ [PRIM_LINE_STRIP_ADJACENCY] = PRIM_CLASS_LINE,
+
+ [PRIM_NONE] = PRIM_CLASS_NONE
+ };
+
+ return classes[prim_type];
+ }
+
+bool prim_type_belongs_to_class(PrimitiveType prim_type, PrimitiveClass prim_class)
+ {
+ if (prim_class == PRIM_CLASS_NONE && prim_type == PRIM_NONE)
+ return true;
+
+ return prim_class & prim_class_of_type(prim_type);
+ }
+
+GLenum convert_prim_type_to_gl(PrimitiveType prim_type)
+ {
+#if TRUST_NO_ONE
+ assert(prim_type != PRIM_NONE);
+#endif
+
+ static const GLenum table[] =
+ {
+ [PRIM_POINTS] = GL_POINTS,
+ [PRIM_LINES] = GL_LINES,
+ [PRIM_LINE_STRIP] = GL_LINE_STRIP,
+ [PRIM_LINE_LOOP] = GL_LINE_LOOP,
+ [PRIM_TRIANGLES] = PRIM_CLASS_SURFACE,
+ [PRIM_TRIANGLE_STRIP] = GL_TRIANGLE_STRIP,
+ [PRIM_TRIANGLE_FAN] = GL_TRIANGLE_FAN,
+
+ [PRIM_LINE_STRIP_ADJACENCY] = GL_LINE_STRIP_ADJACENCY,
+ };
+
+ return table[prim_type];
+ }
diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/shader_interface.c
new file mode 100644
index 00000000000..f0da342f088
--- /dev/null
+++ b/intern/gawain/src/shader_interface.c
@@ -0,0 +1,303 @@
+
+// Gawain shader interface (C --> GLSL)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "shader_interface.h"
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#define SUPPORT_LEGACY_GLSL 1
+#define DEBUG_SHADER_INTERFACE 0
+
+#if DEBUG_SHADER_INTERFACE
+ #include <stdio.h>
+#endif
+
+static const char* BuiltinUniform_name(BuiltinUniform u)
+ {
+ static const char* names[] =
+ {
+ [UNIFORM_NONE] = NULL,
+
+ [UNIFORM_MODELVIEW] = "ModelViewMatrix",
+ [UNIFORM_PROJECTION] = "ProjectionMatrix",
+ [UNIFORM_MVP] = "ModelViewProjectionMatrix",
+
+ [UNIFORM_MODELVIEW_INV] = "ModelViewInverseMatrix",
+ [UNIFORM_PROJECTION_INV] = "ProjectionInverseMatrix",
+
+ [UNIFORM_NORMAL] = "NormalMatrix",
+
+ [UNIFORM_COLOR] = "color",
+
+ [UNIFORM_CUSTOM] = NULL
+ };
+
+ return names[u];
+ }
+
+static bool match(const char* a, const char* b)
+ {
+ return strcmp(a, b) == 0;
+ }
+
+static unsigned hash_string(const char *str)
+ {
+ unsigned i = 0, c;
+
+ while ((c = *str++))
+ {
+ i = i * 37 + c;
+ }
+
+ return i;
+ }
+
+static inline void set_input_name(ShaderInput* input, const char* name)
+ {
+ input->name = name;
+ input->name_hash = hash_string(name);
+ }
+
+// keep these in sync with BuiltinUniform order
+#define FIRST_MAT4_UNIFORM UNIFORM_MODELVIEW
+#define LAST_MAT4_UNIFORM UNIFORM_PROJECTION_INV
+
+static bool setup_builtin_uniform(ShaderInput* input, const char* name)
+ {
+ // TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
+
+ // detect built-in uniforms (gl_type and name must match)
+ // if a match is found, use BuiltinUniform_name so name buffer space can be reclaimed
+ switch (input->gl_type)
+ {
+ case GL_FLOAT_MAT4:
+ for (BuiltinUniform u = FIRST_MAT4_UNIFORM; u <= LAST_MAT4_UNIFORM; ++u)
+ {
+ const char* builtin_name = BuiltinUniform_name(u);
+ if (match(name, builtin_name))
+ {
+ set_input_name(input, builtin_name);
+ input->builtin_type = u;
+ return true;
+ }
+ }
+ break;
+ case GL_FLOAT_MAT3:
+ {
+ const char* builtin_name = BuiltinUniform_name(UNIFORM_NORMAL);
+ if (match(name, builtin_name))
+ {
+ set_input_name(input, builtin_name);
+ input->builtin_type = UNIFORM_NORMAL;
+ return true;
+ }
+ }
+ break;
+ case GL_FLOAT_VEC4:
+ {
+ const char* builtin_name = BuiltinUniform_name(UNIFORM_COLOR);
+ if (match(name, builtin_name))
+ {
+ set_input_name(input, builtin_name);
+ input->builtin_type = UNIFORM_COLOR;
+ return true;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+
+ input->builtin_type = UNIFORM_CUSTOM;
+ return false;
+ }
+
+ShaderInterface* ShaderInterface_create(GLint program)
+ {
+#if DEBUG_SHADER_INTERFACE
+ printf("%s {\n", __func__); // enter function
+#endif
+
+ GLint uniform_ct, attrib_ct;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniform_ct);
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attrib_ct);
+ const GLint input_ct = uniform_ct + attrib_ct;
+
+ GLint max_uniform_name_len, max_attrib_name_len;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_len);
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attrib_name_len);
+ const uint32_t name_buffer_len = uniform_ct * max_uniform_name_len + attrib_ct * max_attrib_name_len;
+
+ // allocate enough space for input counts, details for each input, and a buffer for name strings
+ ShaderInterface* shaderface = calloc(1, offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput) + name_buffer_len);
+ shaderface->uniform_ct = uniform_ct;
+ shaderface->attrib_ct = attrib_ct;
+
+ char* name_buffer = (char*)shaderface + offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput);
+ uint32_t name_buffer_offset = 0;
+
+ for (uint32_t i = 0; i < uniform_ct; ++i)
+ {
+ ShaderInput* input = shaderface->inputs + i;
+ GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
+ char* name = name_buffer + name_buffer_offset;
+ GLsizei name_len = 0;
+
+ glGetActiveUniform(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
+
+ input->location = glGetUniformLocation(program, name);
+
+#if SUPPORT_LEGACY_GLSL
+ if (input->location != -1)
+ {
+#elif TRUST_NO_ONE
+ assert(input->location != -1);
+#endif
+
+ if (setup_builtin_uniform(input, name))
+ ; // reclaim space from name buffer (don't advance offset)
+ else
+ {
+ set_input_name(input, name);
+ name_buffer_offset += name_len + 1; // include NULL terminator
+ }
+#if SUPPORT_LEGACY_GLSL
+ }
+#endif
+
+#if DEBUG_SHADER_INTERFACE
+ printf("uniform[%u] '%s' at location %d\n", i, name, input->location);
+#endif
+ }
+
+ for (uint32_t i = 0; i < attrib_ct; ++i)
+ {
+ ShaderInput* input = shaderface->inputs + uniform_ct + i;
+ GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
+ char* name = name_buffer + name_buffer_offset;
+ GLsizei name_len = 0;
+
+ glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
+
+ // TODO: reject DOUBLE gl_types
+
+ input->location = glGetAttribLocation(program, name);
+
+#if SUPPORT_LEGACY_GLSL
+ if (input->location != -1)
+ {
+#elif TRUST_NO_ONE
+ assert(input->location != -1);
+#endif
+
+ set_input_name(input, name);
+ name_buffer_offset += name_len + 1; // include NULL terminator
+#if SUPPORT_LEGACY_GLSL
+ }
+#endif
+
+#if DEBUG_SHADER_INTERFACE
+ printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
+#endif
+ }
+
+ const uint32_t name_buffer_used = name_buffer_offset;
+
+#if DEBUG_SHADER_INTERFACE
+ printf("using %u of %u bytes from name buffer\n", name_buffer_used, name_buffer_len);
+ printf("}\n"); // exit function
+#endif
+
+ if (name_buffer_used < name_buffer_len)
+ {
+ // realloc shaderface to shrink name buffer
+ const size_t shaderface_alloc =
+ offsetof(ShaderInterface, inputs) + (input_ct * sizeof(ShaderInput)) + name_buffer_used;
+ const char* shaderface_orig_start = (const char*)shaderface;
+ const char* shaderface_orig_end = &shaderface_orig_start[shaderface_alloc];
+ shaderface = realloc(shaderface, shaderface_alloc);
+ const ptrdiff_t delta = (char*)shaderface - shaderface_orig_start;
+
+ if (delta)
+ {
+ // each input->name will need adjustment (except static built-in names)
+ for (uint32_t i = 0; i < input_ct; ++i)
+ {
+ ShaderInput* input = shaderface->inputs + i;
+
+ if (input->name >= shaderface_orig_start && input->name < shaderface_orig_end)
+ input->name += delta;
+ }
+ }
+ }
+
+ return shaderface;
+ }
+
+void ShaderInterface_discard(ShaderInterface* shaderface)
+ {
+ // allocated as one chunk, so discard is simple
+ free(shaderface);
+ }
+
+const ShaderInput* ShaderInterface_uniform(const ShaderInterface* shaderface, const char* name)
+ {
+ const unsigned name_hash = hash_string(name);
+ for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
+ {
+ const ShaderInput* uniform = shaderface->inputs + i;
+
+#if SUPPORT_LEGACY_GLSL
+ if (uniform->name == NULL) continue;
+#endif
+
+ if (uniform->name_hash != name_hash) continue;
+
+ if (match(uniform->name, name))
+ return uniform;
+
+ // TODO: warn if we find a matching builtin, since these can be looked up much quicker --v
+ }
+
+ return NULL; // not found
+ }
+
+const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface* shaderface, BuiltinUniform builtin)
+ {
+ // look up by enum, not name
+ for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
+ {
+ const ShaderInput* uniform = shaderface->inputs + i;
+
+ if (uniform->builtin_type == builtin)
+ return uniform;
+ }
+ return NULL; // not found
+ }
+
+const ShaderInput* ShaderInterface_attrib(const ShaderInterface* shaderface, const char* name)
+ {
+ // attribs are stored after uniforms
+ const uint32_t input_ct = shaderface->uniform_ct + shaderface->attrib_ct;
+ for (uint32_t i = shaderface->uniform_ct; i < input_ct; ++i)
+ {
+ const ShaderInput* attrib = shaderface->inputs + i;
+
+#if SUPPORT_LEGACY_GLSL
+ if (attrib->name == NULL) continue;
+#endif
+
+ if (match(attrib->name, name))
+ return attrib;
+ }
+ return NULL; // not found
+ }
diff --git a/intern/gawain/src/vertex_buffer.c b/intern/gawain/src/vertex_buffer.c
new file mode 100644
index 00000000000..769a0842a7e
--- /dev/null
+++ b/intern/gawain/src/vertex_buffer.c
@@ -0,0 +1,183 @@
+
+// Gawain vertex buffer
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "vertex_buffer.h"
+#include "buffer_id.h"
+#include "vertex_format_private.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define KEEP_SINGLE_COPY 1
+
+static unsigned vbo_memory_usage;
+
+VertexBuffer* VertexBuffer_create(void)
+ {
+ VertexBuffer* verts = malloc(sizeof(VertexBuffer));
+ VertexBuffer_init(verts);
+ return verts;
+ }
+
+VertexBuffer* VertexBuffer_create_with_format(const VertexFormat* format)
+ {
+ VertexBuffer* verts = VertexBuffer_create();
+ VertexFormat_copy(&verts->format, format);
+ if (!format->packed)
+ VertexFormat_pack(&verts->format);
+ return verts;
+
+ // this function might seem redundant, but there is potential for memory savings here...
+ // TODO: implement those memory savings
+ }
+
+void VertexBuffer_init(VertexBuffer* verts)
+ {
+ memset(verts, 0, sizeof(VertexBuffer));
+ }
+
+void VertexBuffer_init_with_format(VertexBuffer* verts, const VertexFormat* format)
+ {
+ VertexBuffer_init(verts);
+ VertexFormat_copy(&verts->format, format);
+ if (!format->packed)
+ VertexFormat_pack(&verts->format);
+ }
+
+void VertexBuffer_discard(VertexBuffer* verts)
+ {
+ if (verts->vbo_id) {
+ buffer_id_free(verts->vbo_id);
+ vbo_memory_usage -= VertexBuffer_size(verts);
+ }
+#if KEEP_SINGLE_COPY
+ else
+#endif
+ if (verts->data)
+ free(verts->data);
+
+
+ free(verts);
+ }
+
+unsigned VertexBuffer_size(const VertexBuffer* verts)
+ {
+ return vertex_buffer_size(&verts->format, verts->vertex_ct);
+ }
+
+void VertexBuffer_allocate_data(VertexBuffer* verts, unsigned v_ct)
+ {
+ VertexFormat* format = &verts->format;
+ if (!format->packed)
+ VertexFormat_pack(format);
+
+ verts->vertex_ct = v_ct;
+
+ // Data initially lives in main memory. Will be transferred to VRAM when we "prime" it.
+ verts->data = malloc(VertexBuffer_size(verts));
+ }
+
+void VertexBuffer_resize_data(VertexBuffer* verts, unsigned v_ct)
+ {
+#if TRUST_NO_ONE
+ assert(verts->vertex_ct != v_ct); // allow this?
+ assert(verts->data != NULL); // has already been allocated
+ assert(verts->vbo_id == 0); // has not been sent to VRAM
+#endif
+
+ verts->vertex_ct = v_ct;
+ verts->data = realloc(verts->data, VertexBuffer_size(verts));
+ // TODO: skip realloc if v_ct < existing vertex count
+ // extra space will be reclaimed, and never sent to VRAM (see VertexBuffer_prime)
+ }
+
+void VertexBuffer_set_attrib(VertexBuffer* verts, unsigned a_idx, unsigned v_idx, const void* data)
+ {
+ const VertexFormat* format = &verts->format;
+ const Attrib* a = format->attribs + a_idx;
+
+#if TRUST_NO_ONE
+ assert(a_idx < format->attrib_ct);
+ assert(v_idx < verts->vertex_ct);
+ assert(verts->data != NULL); // data must be in main mem
+#endif
+
+ memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz);
+ }
+
+void VertexBuffer_fill_attrib(VertexBuffer* verts, unsigned a_idx, const void* data)
+ {
+ const VertexFormat* format = &verts->format;
+ const Attrib* a = format->attribs + a_idx;
+
+#if TRUST_NO_ONE
+ assert(a_idx < format->attrib_ct);
+#endif
+
+ const unsigned stride = a->sz; // tightly packed input data
+
+ VertexBuffer_fill_attrib_stride(verts, a_idx, stride, data);
+ }
+
+void VertexBuffer_fill_attrib_stride(VertexBuffer* verts, unsigned a_idx, unsigned stride, const void* data)
+ {
+ const VertexFormat* format = &verts->format;
+ const Attrib* a = format->attribs + a_idx;
+
+#if TRUST_NO_ONE
+ assert(a_idx < format->attrib_ct);
+ assert(verts->data != NULL); // data must be in main mem
+#endif
+
+ const unsigned vertex_ct = verts->vertex_ct;
+
+ if (format->attrib_ct == 1 && stride == format->stride)
+ {
+ // we can copy it all at once
+ memcpy(verts->data, data, vertex_ct * a->sz);
+ }
+ else
+ {
+ // we must copy it per vertex
+ for (unsigned v = 0; v < vertex_ct; ++v)
+ memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz);
+ }
+ }
+
+static void VertexBuffer_prime(VertexBuffer* verts)
+ {
+ const unsigned buffer_sz = VertexBuffer_size(verts);
+
+ verts->vbo_id = buffer_id_alloc();
+ glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
+ // fill with delicious data & send to GPU the first time only
+ glBufferData(GL_ARRAY_BUFFER, buffer_sz, verts->data, GL_STATIC_DRAW);
+
+ vbo_memory_usage += buffer_sz;
+
+#if KEEP_SINGLE_COPY
+ // now that GL has a copy, discard original
+ free(verts->data);
+ verts->data = NULL;
+#endif
+ }
+
+void VertexBuffer_use(VertexBuffer* verts)
+ {
+ if (verts->vbo_id)
+ glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
+ else
+ VertexBuffer_prime(verts);
+ }
+
+unsigned VertexBuffer_get_memory_usage(void)
+ {
+ return vbo_memory_usage;
+ }
diff --git a/intern/gawain/src/vertex_format.c b/intern/gawain/src/vertex_format.c
new file mode 100644
index 00000000000..963e660dc3d
--- /dev/null
+++ b/intern/gawain/src/vertex_format.c
@@ -0,0 +1,296 @@
+
+// Gawain vertex format
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "vertex_format.h"
+#include "vertex_format_private.h"
+#include <stddef.h>
+#include <string.h>
+
+#define PACK_DEBUG 0
+
+#if PACK_DEBUG
+ #include <stdio.h>
+#endif
+
+void VertexFormat_clear(VertexFormat* format)
+ {
+#if TRUST_NO_ONE
+ memset(format, 0, sizeof(VertexFormat));
+#else
+ format->attrib_ct = 0;
+ format->packed = false;
+ format->name_offset = 0;
+ format->name_ct = 0;
+
+ for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ format->attribs[i].name_ct = 0;
+ }
+#endif
+ }
+
+void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src)
+ {
+ // copy regular struct fields
+ memcpy(dest, src, sizeof(VertexFormat));
+
+ for (unsigned i = 0; i < dest->attrib_ct; i++)
+ {
+ dest->attribs[i].name_ct = dest->attribs[i].name_ct;
+ for (unsigned j = 0; j < dest->attribs[i].name_ct; j++)
+ {
+ dest->attribs[i].name[j] = (char *)dest + (src->attribs[i].name[j] - ((char *)src));
+ }
+ }
+ }
+
+static GLenum convert_comp_type_to_gl(VertexCompType type)
+ {
+ static const GLenum table[] = {
+ [COMP_I8] = GL_BYTE,
+ [COMP_U8] = GL_UNSIGNED_BYTE,
+ [COMP_I16] = GL_SHORT,
+ [COMP_U16] = GL_UNSIGNED_SHORT,
+ [COMP_I32] = GL_INT,
+ [COMP_U32] = GL_UNSIGNED_INT,
+
+ [COMP_F32] = GL_FLOAT,
+
+ [COMP_I10] = GL_INT_2_10_10_10_REV
+ };
+ return table[type];
+ }
+
+static unsigned comp_sz(VertexCompType type)
+ {
+#if TRUST_NO_ONE
+ assert(type <= COMP_F32); // other types have irregular sizes (not bytes)
+#endif
+
+ const GLubyte sizes[] = {1,1,2,2,4,4,4};
+ return sizes[type];
+ }
+
+static unsigned attrib_sz(const Attrib *a)
+ {
+ if (a->comp_type == COMP_I10)
+ return 4; // always packed as 10_10_10_2
+
+ return a->comp_ct * comp_sz(a->comp_type);
+ }
+
+static unsigned attrib_align(const Attrib *a)
+ {
+ if (a->comp_type == COMP_I10)
+ return 4; // always packed as 10_10_10_2
+
+ unsigned c = comp_sz(a->comp_type);
+ if (a->comp_ct == 3 && c <= 2)
+ return 4 * c; // AMD HW can't fetch these well, so pad it out (other vendors too?)
+ else
+ return c; // most fetches are ok if components are naturally aligned
+ }
+
+unsigned vertex_buffer_size(const VertexFormat* format, unsigned vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(format->packed && format->stride > 0);
+#endif
+
+ return format->stride * vertex_ct;
+ }
+
+static const char* copy_attrib_name(VertexFormat* format, const char* name)
+ {
+ // strncpy does 110% of what we need; let's do exactly 100%
+ char* name_copy = format->names + format->name_offset;
+ unsigned available = VERTEX_ATTRIB_NAMES_BUFFER_LEN - format->name_offset;
+ bool terminated = false;
+
+ for (unsigned i = 0; i < available; ++i)
+ {
+ const char c = name[i];
+ name_copy[i] = c;
+ if (c == '\0')
+ {
+ terminated = true;
+ format->name_offset += (i + 1);
+ break;
+ }
+ }
+
+#if TRUST_NO_ONE
+ assert(terminated);
+ assert(format->name_offset <= VERTEX_ATTRIB_NAMES_BUFFER_LEN);
+#else
+ (void)terminated;
+#endif
+
+ return name_copy;
+ }
+
+unsigned VertexFormat_add_attrib(VertexFormat* format, const char* name, VertexCompType comp_type, unsigned comp_ct, VertexFetchMode fetch_mode)
+ {
+#if TRUST_NO_ONE
+ assert(format->name_ct < MAX_VERTEX_ATTRIBS); // there's room for more
+ assert(format->attrib_ct < MAX_VERTEX_ATTRIBS); // there's room for more
+ assert(!format->packed); // packed means frozen/locked
+ assert(comp_ct >= 1 && comp_ct <= 4);
+ switch (comp_type)
+ {
+ case COMP_F32:
+ // float type can only kept as float
+ assert(fetch_mode == KEEP_FLOAT);
+ break;
+ case COMP_I10:
+ // 10_10_10 format intended for normals (xyz) or colors (rgb)
+ // extra component packed.w can be manually set to { -2, -1, 0, 1 }
+ assert(comp_ct == 3 || comp_ct == 4);
+ assert(fetch_mode == NORMALIZE_INT_TO_FLOAT); // not strictly required, may relax later
+ break;
+ default:
+ // integer types can be kept as int or converted/normalized to float
+ assert(fetch_mode != KEEP_FLOAT);
+ }
+#endif
+ format->name_ct++; // multiname support
+
+ const unsigned attrib_id = format->attrib_ct++;
+ Attrib* attrib = format->attribs + attrib_id;
+
+ attrib->name[attrib->name_ct++] = copy_attrib_name(format, name);
+ attrib->comp_type = comp_type;
+ attrib->gl_comp_type = convert_comp_type_to_gl(comp_type);
+ attrib->comp_ct = (comp_type == COMP_I10) ? 4 : comp_ct; // system needs 10_10_10_2 to be 4 or BGRA
+ attrib->sz = attrib_sz(attrib);
+ attrib->offset = 0; // offsets & stride are calculated later (during pack)
+ attrib->fetch_mode = fetch_mode;
+
+ return attrib_id;
+ }
+
+void VertexFormat_add_alias(VertexFormat* format, const char* alias)
+ {
+ Attrib* attrib = format->attribs + (format->attrib_ct - 1);
+#if TRUST_NO_ONE
+ assert(format->name_ct < MAX_VERTEX_ATTRIBS); // there's room for more
+ assert(attrib->name_ct < MAX_ATTRIB_NAMES);
+#endif
+ format->name_ct++; // multiname support
+ attrib->name[attrib->name_ct++] = copy_attrib_name(format, alias);
+ }
+
+unsigned padding(unsigned offset, unsigned alignment)
+ {
+ const unsigned mod = offset % alignment;
+ return (mod == 0) ? 0 : (alignment - mod);
+ }
+
+#if PACK_DEBUG
+static void show_pack(unsigned a_idx, unsigned sz, unsigned pad)
+ {
+ const char c = 'A' + a_idx;
+ for (unsigned i = 0; i < pad; ++i)
+ putchar('-');
+ for (unsigned i = 0; i < sz; ++i)
+ putchar(c);
+ }
+#endif
+
+void VertexFormat_pack(VertexFormat* format)
+ {
+ // for now, attributes are packed in the order they were added,
+ // making sure each attrib is naturally aligned (add padding where necessary)
+
+ // later we can implement more efficient packing w/ reordering
+ // (keep attrib ID order, adjust their offsets to reorder in buffer)
+
+ // TODO:
+ // realloc just enough to hold the final combo string. And just enough to
+ // hold used attribs, not all 16.
+
+ Attrib* a0 = format->attribs + 0;
+ a0->offset = 0;
+ unsigned offset = a0->sz;
+
+#if PACK_DEBUG
+ show_pack(0, a0->sz, 0);
+#endif
+
+ for (unsigned a_idx = 1; a_idx < format->attrib_ct; ++a_idx)
+ {
+ Attrib* a = format->attribs + a_idx;
+ unsigned mid_padding = padding(offset, attrib_align(a));
+ offset += mid_padding;
+ a->offset = offset;
+ offset += a->sz;
+
+#if PACK_DEBUG
+ show_pack(a_idx, a->sz, mid_padding);
+#endif
+ }
+
+ unsigned end_padding = padding(offset, attrib_align(a0));
+
+#if PACK_DEBUG
+ show_pack(0, 0, end_padding);
+ putchar('\n');
+#endif
+
+ format->stride = offset + end_padding;
+ format->packed = true;
+ }
+
+
+// OpenGL ES packs in a different order as desktop GL but component conversion is the same.
+// Of the code here, only struct PackedNormal needs to change.
+
+#define SIGNED_INT_10_MAX 511
+#define SIGNED_INT_10_MIN -512
+
+static int clampi(int x, int min_allowed, int max_allowed)
+ {
+#if TRUST_NO_ONE
+ assert(min_allowed <= max_allowed);
+#endif
+
+ if (x < min_allowed)
+ return min_allowed;
+ else if (x > max_allowed)
+ return max_allowed;
+ else
+ return x;
+ }
+
+static int quantize(float x)
+ {
+ int qx = x * 511.0f;
+ return clampi(qx, SIGNED_INT_10_MIN, SIGNED_INT_10_MAX);
+ }
+
+static int convert_i16(short x)
+ {
+ // 16-bit signed --> 10-bit signed
+ return x >> 6;
+ // TODO: round?
+ }
+
+PackedNormal convert_i10_v3(const float data[3])
+ {
+ PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) };
+ return n;
+ }
+
+PackedNormal convert_i10_s3(const short data[3])
+ {
+ PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) };
+ return n;
+ }
diff --git a/intern/ghost/intern/GHOST_Context.cpp b/intern/ghost/intern/GHOST_Context.cpp
index 72db17c4f56..823a476d244 100644
--- a/intern/ghost/intern/GHOST_Context.cpp
+++ b/intern/ghost/intern/GHOST_Context.cpp
@@ -143,11 +143,7 @@ bool win32_chk(bool result, const char *file, int line, const char *text)
void GHOST_Context::initContextGLEW()
{
- mxDestroyContext(m_mxContext); // no-op if m_mxContext is NULL
-
- mxMakeCurrentContext(mxCreateContext());
-
- m_mxContext = mxGetCurrentContext();
+ GLEW_CHK(glewInit());
}
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index 18d36c40e9c..8776fa4764f 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -50,15 +50,13 @@ public:
*/
GHOST_Context(bool stereoVisual, GHOST_TUns16 numOfAASamples)
: m_stereoVisual(stereoVisual),
- m_numOfAASamples(numOfAASamples),
- m_mxContext(NULL)
+ m_numOfAASamples(numOfAASamples)
{}
/**
* Destructor.
*/
virtual ~GHOST_Context() {
- mxDestroyContext(m_mxContext);
}
/**
@@ -128,19 +126,12 @@ public:
protected:
void initContextGLEW();
- inline void activateGLEW() const {
- mxMakeCurrentContext(m_mxContext);
- }
-
bool m_stereoVisual;
GHOST_TUns16 m_numOfAASamples;
static void initClearGL();
-private:
- MXContext *m_mxContext;
-
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context")
#endif
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index dd49b81b561..6dcc4da0f0a 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -34,10 +34,6 @@
#include "GHOST_Context.h"
-//#define cglewGetContext() cglewContext
-//#include <GL/cglew.h>
-//extern "C" CGLEWContext *cglewContext;
-
#ifndef GHOST_OPENGL_CGL_CONTEXT_FLAGS
#define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0
#endif
@@ -120,21 +116,14 @@ public:
*/
GHOST_TSuccess updateDrawingContext();
-//protected:
-// inline void activateCGLEW() const {
-// cglewContext = m_cglewContext;
-// }
-
private:
- //void initContextCGLEW()
-
/** The openGL view */
NSOpenGLView *m_openGLView;
/** The OpenGL drawing context */
NSOpenGLContext *m_openGLContext;
- //static CGLEWContext *s_cglewContext;
+ bool m_coreProfile;
const bool m_debug;
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index 03c45f9945b..03af3cc497e 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -63,6 +63,23 @@ GHOST_ContextCGL::GHOST_ContextCGL(
m_debug(contextFlags)
{
assert(openGLView != nil);
+
+ // for now be very strict about OpenGL version requested
+ switch (contextMajorVersion) {
+ case 2:
+ assert(contextMinorVersion == 1);
+ assert(contextProfileMask == 0);
+ m_coreProfile = false;
+ break;
+ case 3:
+ // Apple didn't implement 3.0 or 3.1
+ assert(contextMinorVersion == 2);
+ assert(contextProfileMask == GL_CONTEXT_CORE_PROFILE_BIT);
+ m_coreProfile = true;
+ break;
+ default:
+ assert(false);
+ }
}
@@ -142,9 +159,6 @@ GHOST_TSuccess GHOST_ContextCGL::activateDrawingContext()
if (m_openGLContext != nil) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[m_openGLContext makeCurrentContext];
-
- activateGLEW();
-
[pool drain];
return GHOST_kSuccess;
}
@@ -170,6 +184,7 @@ GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
static void makeAttribList(
std::vector<NSOpenGLPixelFormatAttribute>& attribs,
+ bool coreProfile,
bool stereoVisual,
int numOfAASamples,
bool needAlpha,
@@ -178,6 +193,9 @@ static void makeAttribList(
{
attribs.clear();
+ attribs.push_back(NSOpenGLPFAOpenGLProfile);
+ attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy);
+
// Pixel Format Attributes for the windowed NSOpenGLContext
attribs.push_back(NSOpenGLPFADoubleBuffer);
@@ -190,15 +208,11 @@ static void makeAttribList(
attribs.push_back(NSOpenGLPFANoRecovery);
}
- /* Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway */
- //attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
+ attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching
attribs.push_back(NSOpenGLPFADepthSize);
attribs.push_back((NSOpenGLPixelFormatAttribute) 32);
- attribs.push_back(NSOpenGLPFAAccumSize);
- attribs.push_back((NSOpenGLPixelFormatAttribute) 32);
-
if (stereoVisual)
attribs.push_back(NSOpenGLPFAStereo);
@@ -263,7 +277,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
NSOpenGLPixelFormat *pixelFormat;
// TODO: keep pixel format for subsequent windows/contexts instead of recreating each time
- makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
+ makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
@@ -274,7 +288,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
// (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
attribs.clear();
- makeAttribList(attribs, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
+ makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
}
@@ -316,7 +330,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
[m_openGLContext release];
// create software GL context
- makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
+ makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
[pixelFormat release];
diff --git a/intern/ghost/intern/GHOST_ContextEGL.cpp b/intern/ghost/intern/GHOST_ContextEGL.cpp
index 520aa0fffb2..a591d9b7583 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextEGL.cpp
@@ -42,11 +42,6 @@
#include <cstring>
-#ifdef WITH_GLEW_MX
-EGLEWContext *eglewContext = NULL;
-#endif
-
-
#define CASE_CODE_RETURN_STR(code) case code: return #code;
static const char *get_egl_error_enum_string(EGLenum error)
@@ -168,13 +163,8 @@ static bool egl_chk(bool result, const char *file = NULL, int line = 0, const ch
static inline bool bindAPI(EGLenum api)
{
-#ifdef WITH_GLEW_MX
- if (eglewContext != NULL)
-#endif
- {
- if (EGLEW_VERSION_1_2) {
- return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE);
- }
+ if (EGLEW_VERSION_1_2) {
+ return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE);
}
return false;
@@ -238,9 +228,6 @@ GHOST_ContextEGL::GHOST_ContextEGL(
m_surface(EGL_NO_SURFACE),
m_display(EGL_NO_DISPLAY),
m_swap_interval(1),
-#ifdef WITH_GLEW_MX
- m_eglewContext(NULL),
-#endif
m_sharedContext(choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)),
m_sharedCount (choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
{
@@ -252,7 +239,6 @@ GHOST_ContextEGL::GHOST_ContextEGL(
GHOST_ContextEGL::~GHOST_ContextEGL()
{
if (m_display != EGL_NO_DISPLAY) {
- activateEGLEW();
bindAPI(m_api);
@@ -276,10 +262,6 @@ GHOST_ContextEGL::~GHOST_ContextEGL()
EGL_CHK(::eglDestroySurface(m_display, m_surface));
EGL_CHK(::eglTerminate(m_display));
-
-#ifdef WITH_GLEW_MX
- delete m_eglewContext;
-#endif
}
}
@@ -321,9 +303,6 @@ GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int &intervalOut)
GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext()
{
if (m_display) {
- activateEGLEW();
- activateGLEW();
-
bindAPI(m_api);
return EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)) ? GHOST_kSuccess : GHOST_kFailure;
@@ -336,14 +315,6 @@ GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext()
void GHOST_ContextEGL::initContextEGLEW()
{
-#ifdef WITH_GLEW_MX
- eglewContext = new EGLEWContext;
- memset(eglewContext, 0, sizeof(EGLEWContext));
-
- delete m_eglewContext;
- m_eglewContext = eglewContext;
-#endif
-
if (GLEW_CHK(eglewInit(m_display)) != GLEW_OK)
fprintf(stderr, "Warning! EGLEW failed to initialize properly.\n");
}
diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h
index 70c26c940fc..6dfb177f26d 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.h
+++ b/intern/ghost/intern/GHOST_ContextEGL.h
@@ -34,17 +34,8 @@
#include "GHOST_Context.h"
-#ifdef WITH_GLEW_MX
-# define eglewGetContext() eglewContext
-#endif
-
#include <GL/eglew.h>
-#ifdef WITH_GLEW_MX
-extern "C" EGLEWContext *eglewContext;
-#endif
-
-
#ifndef GHOST_OPENGL_EGL_CONTEXT_FLAGS
#define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0
#endif
@@ -116,13 +107,6 @@ public:
*/
GHOST_TSuccess getSwapInterval(int &intervalOut);
-protected:
- inline void activateEGLEW() const {
-#ifdef WITH_GLEW_MX
- eglewContext = m_eglewContext;
-#endif
- }
-
private:
void initContextEGLEW();
@@ -143,10 +127,6 @@ private:
EGLint m_swap_interval;
-#ifdef WITH_GLEW_MX
- EGLEWContext *m_eglewContext;
-#endif
-
EGLContext &m_sharedContext;
EGLint &m_sharedCount;
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index 9ac61db4041..0a9dc900aed 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -48,10 +48,6 @@ static GLuint _glewStrLen(const GLubyte *s);
static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end);
#endif
-#ifdef WITH_GLEW_MX
-GLXEWContext *glxewContext = NULL;
-#endif
-
GLXContext GHOST_ContextGLX::s_sharedContext = None;
int GHOST_ContextGLX::s_sharedCount = 0;
@@ -79,10 +75,6 @@ GHOST_ContextGLX::GHOST_ContextGLX(
m_contextFlags(contextFlags),
m_contextResetNotificationStrategy(contextResetNotificationStrategy),
m_context(None)
-#ifdef WITH_GLEW_MX
- ,
- m_glxewContext(NULL)
-#endif
{
assert(m_window != 0);
assert(m_display != NULL);
@@ -92,8 +84,6 @@ GHOST_ContextGLX::GHOST_ContextGLX(
GHOST_ContextGLX::~GHOST_ContextGLX()
{
if (m_display != NULL) {
- activateGLXEW();
-
if (m_context != None) {
if (m_window != 0 && m_context == ::glXGetCurrentContext())
::glXMakeCurrent(m_display, None, NULL);
@@ -109,11 +99,6 @@ GHOST_ContextGLX::~GHOST_ContextGLX()
::glXDestroyContext(m_display, m_context);
}
}
-
-#ifdef WITH_GLEW_MX
- if (m_glxewContext)
- delete m_glxewContext;
-#endif
}
}
@@ -129,9 +114,6 @@ GHOST_TSuccess GHOST_ContextGLX::swapBuffers()
GHOST_TSuccess GHOST_ContextGLX::activateDrawingContext()
{
if (m_display) {
- activateGLXEW();
- activateGLEW();
-
return ::glXMakeCurrent(m_display, m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
}
else {
@@ -141,15 +123,6 @@ GHOST_TSuccess GHOST_ContextGLX::activateDrawingContext()
void GHOST_ContextGLX::initContextGLXEW()
{
-#ifdef WITH_GLEW_MX
- glxewContext = new GLXEWContext;
- memset(glxewContext, 0, sizeof(GLXEWContext));
-
- if (m_glxewContext)
- delete m_glxewContext;
- m_glxewContext = glxewContext;
-#endif
-
initContextGLEW();
}
@@ -255,9 +228,6 @@ const bool GLXEW_ARB_create_context_robustness =
if (m_contextMajorVersion != 0) {
attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
attribs[i++] = m_contextMajorVersion;
- }
-
- if (m_contextMinorVersion != 0) {
attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
attribs[i++] = m_contextMinorVersion;
}
@@ -300,8 +270,8 @@ const bool GLXEW_ARB_create_context_robustness =
}
}
else {
- /* Create legacy context */
- m_context = glXCreateContext(m_display, m_visualInfo, s_sharedContext, True);
+ /* Don't create legacy context */
+ fprintf(stderr, "Warning! GLX_ARB_create_context not available.\n");
}
GHOST_TSuccess success;
@@ -328,8 +298,14 @@ const bool GLXEW_ARB_create_context_robustness =
version = glGetString(GL_VERSION);
- if (!version || version[0] < '2' || ((version[0] == '2') && (version[2] < '1'))) {
- fprintf(stderr, "Error! Blender requires OpenGL 2.1 to run. Try updating your drivers.\n");
+#if 0 // enable this when Blender switches to 3.3 core profile
+ if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) {
+ fprintf(stderr, "Error! Blender requires OpenGL 3.3 to run. Try updating your drivers.\n");
+#else
+ // with Mesa, the closest thing to 3.3 compatibility profile is 3.0
+ if (!version || version[0] < '3') {
+ fprintf(stderr, "Error! Blender requires OpenGL 3.0 (soon 3.3) to run. Try updating your drivers.\n");
+#endif
fflush(stderr);
/* ugly, but we get crashes unless a whole bunch of systems are patched. */
exit(0);
diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h
index f0f010d1942..6547a0bd00a 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.h
+++ b/intern/ghost/intern/GHOST_ContextGLX.h
@@ -34,16 +34,8 @@
#include "GHOST_Context.h"
-#ifdef WITH_GLEW_MX
-# define glxewGetContext() glxewContext
-#endif
-
#include <GL/glxew.h>
-#ifdef WITH_GLEW_MX
-extern "C" GLXEWContext *glxewContext;
-#endif
-
#ifndef GHOST_OPENGL_GLX_CONTEXT_FLAGS
/* leave as convenience define for the future */
@@ -117,13 +109,6 @@ public:
*/
GHOST_TSuccess getSwapInterval(int &intervalOut);
-protected:
- inline void activateGLXEW() const {
-#ifdef WITH_GLEW_MX
- glxewContext = m_glxewContext;
-#endif
- }
-
private:
void initContextGLXEW();
@@ -140,10 +125,6 @@ private:
GLXContext m_context;
-#ifdef WITH_GLEW_MX
- GLXEWContext *m_glxewContext;
-#endif
-
/** The first created OpenGL context (for sharing display lists) */
static GLXContext s_sharedContext;
static int s_sharedCount;
diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp
index 39627fac899..7a02e9743c3 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.cpp
+++ b/intern/ghost/intern/GHOST_ContextSDL.cpp
@@ -97,8 +97,6 @@ GHOST_TSuccess GHOST_ContextSDL::swapBuffers()
GHOST_TSuccess GHOST_ContextSDL::activateDrawingContext()
{
if (m_context) {
- activateGLEW();
-
return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
}
else {
diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp
index 64ee692797b..8cf311b9e84 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextWGL.cpp
@@ -40,10 +40,6 @@
#include <vector>
-#ifdef WITH_GLEW_MX
-WGLEWContext *wglewContext = NULL;
-#endif
-
HGLRC GHOST_ContextWGL::s_sharedHGLRC = NULL;
int GHOST_ContextWGL::s_sharedCount = 0;
@@ -82,10 +78,6 @@ GHOST_ContextWGL::GHOST_ContextWGL(
m_alphaBackground(alphaBackground),
m_contextResetNotificationStrategy(contextResetNotificationStrategy),
m_hGLRC(NULL)
-#ifdef WITH_GLEW_MX
- ,
- m_wglewContext(NULL)
-#endif
#ifndef NDEBUG
,
m_dummyVendor(NULL),
@@ -116,10 +108,6 @@ GHOST_ContextWGL::~GHOST_ContextWGL()
}
}
-#ifdef WITH_GLEW_MX
- delete m_wglewContext;
-#endif
-
#ifndef NDEBUG
free((void*)m_dummyRenderer);
free((void*)m_dummyVendor);
@@ -158,7 +146,6 @@ GHOST_TSuccess GHOST_ContextWGL::getSwapInterval(int &intervalOut)
GHOST_TSuccess GHOST_ContextWGL::activateDrawingContext()
{
if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
- activateGLEW();
return GHOST_kSuccess;
}
else {
@@ -338,15 +325,6 @@ void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
int iPixelFormat;
-
-#ifdef WITH_GLEW_MX
- wglewContext = new WGLEWContext;
- memset(wglewContext, 0, sizeof(WGLEWContext));
-
- delete m_wglewContext;
- m_wglewContext = wglewContext;
-#endif
-
SetLastError(NO_ERROR);
prevHDC = ::wglGetCurrentDC();
@@ -385,13 +363,8 @@ void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC)))
goto finalize;
-#ifdef WITH_GLEW_MX
- if (GLEW_CHK(wglewInit()) != GLEW_OK)
- fprintf(stderr, "Warning! WGLEW failed to initialize properly.\n");
-#else
if (GLEW_CHK(glewInit()) != GLEW_OK)
fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n");
-#endif
// the following are not technially WGLEW, but they also require a context to work
@@ -828,8 +801,6 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
return GHOST_kFailure;
}
- activateWGLEW();
-
if (WGLEW_ARB_create_context) {
int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
@@ -907,21 +878,6 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
else
m_hGLRC = s_sharedHGLRC;
}
- else {
- if (m_contextProfileMask != 0)
- fprintf(stderr, "Warning! Legacy WGL is unable to select between OpenGL profiles.");
-
- if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0)
- fprintf(stderr, "Warning! Legacy WGL is unable to select between OpenGL versions.");
-
- if (m_contextFlags != 0)
- fprintf(stderr, "Warning! Legacy WGL is unable to set context flags.");
-
- if (!s_singleContextMode || s_sharedHGLRC == NULL)
- m_hGLRC = ::wglCreateContext(m_hDC);
- else
- m_hGLRC = s_sharedHGLRC;
- }
if (!WIN32_CHK(m_hGLRC != NULL)) {
::wglMakeCurrent(prevHDC, prevHGLRC);
@@ -962,7 +918,7 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
strcmp(renderer, "GDI Generic") == 0) && version[0] == '1' && version[2] == '1')
{
MessageBox(m_hWnd, "Your system does not use 3D hardware acceleration.\n"
- "Blender requires a graphics driver with OpenGL 2.1 support.\n\n"
+ "Blender requires a graphics driver with OpenGL 3.3 support.\n\n"
"This may be caused by:\n"
"* A missing or faulty graphics driver installation.\n"
" Blender needs a graphics card driver to work correctly.\n"
@@ -973,8 +929,8 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
MB_OK | MB_ICONERROR);
exit(0);
}
- else if (version[0] < '2' || (version[0] == '2' && version[2] < '1')) {
- MessageBox(m_hWnd, "Blender requires a graphics driver with OpenGL 2.1 support.\n\n"
+ else if (version[0] < '3' || (version[0] == '3' && version[2] < '3')) {
+ MessageBox(m_hWnd, "Blender requires a graphics driver with OpenGL 3.3 support.\n\n"
"The program will now close.",
"Blender - Unsupported Graphics Driver!",
MB_OK | MB_ICONERROR);
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h
index 580b4dcb82f..a07cc1b6301 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -36,24 +36,8 @@
#include "GHOST_Context.h"
-#ifdef WITH_GLEW_MX
-#define wglewGetContext() wglewContext
-#endif
-
#include <GL/wglew.h>
-#ifdef WITH_GLEW_MX
-extern "C" WGLEWContext *wglewContext;
-#endif
-
-#ifndef GHOST_OPENGL_WGL_CONTEXT_FLAGS
-# ifdef WITH_GPU_DEBUG
-# define GHOST_OPENGL_WGL_CONTEXT_FLAGS WGL_CONTEXT_DEBUG_BIT_ARB
-# else
-# define GHOST_OPENGL_WGL_CONTEXT_FLAGS 0
-# endif
-#endif
-
#ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0
#endif
@@ -121,13 +105,6 @@ public:
*/
GHOST_TSuccess getSwapInterval(int &intervalOut);
-protected:
- inline void activateWGLEW() const {
-#ifdef WITH_GLEW_MX
- wglewContext = m_wglewContext;
-#endif
- }
-
private:
int choose_pixel_format(
bool stereoVisual,
@@ -171,10 +148,6 @@ private:
const int m_contextResetNotificationStrategy;
HGLRC m_hGLRC;
-
-#ifdef WITH_GLEW_MX
- WGLEWContext *m_wglewContext;
-#endif
#ifndef NDEBUG
const char *m_dummyVendor;
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 97615dcea96..b0feb11a6af 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -1086,82 +1086,23 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
{
if (type == GHOST_kDrawingContextTypeOpenGL) {
-#if !defined(WITH_GL_EGL)
-#if defined(WITH_GL_PROFILE_CORE)
- GHOST_Context *context = new GHOST_ContextCGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_openGLView,
- GL_CONTEXT_CORE_PROFILE_BIT,
- 3, 2,
- GHOST_OPENGL_CGL_CONTEXT_FLAGS,
- GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
-#elif defined(WITH_GL_PROFILE_ES20)
GHOST_Context *context = new GHOST_ContextCGL(
m_wantStereoVisual,
m_wantNumOfAASamples,
m_window,
m_openGLView,
- CGL_CONTEXT_ES2_PROFILE_BIT_EXT,
- 2, 0,
- GHOST_OPENGL_CGL_CONTEXT_FLAGS,
- GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
-#elif defined(WITH_GL_PROFILE_COMPAT)
- GHOST_Context *context = new GHOST_ContextCGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_openGLView,
- 0, // profile bit
- 0, 0,
- m_debug_context,
- GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
-#else
-# error
-#endif
-
-#else
#if defined(WITH_GL_PROFILE_CORE)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_openGLView,
- EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ GL_CONTEXT_CORE_PROFILE_BIT,
3, 2,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_API);
-#elif defined(WITH_GL_PROFILE_ES20)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_openGLView,
- 0, // profile bit
- 2, 0,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_ES_API);
-#elif defined(WITH_GL_PROFILE_COMPAT)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_openGLView,
- 0, // profile bit
- 0, 0,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_API);
#else
-# error
+ 0, // no profile bit
+ 2, 1,
#endif
+ GHOST_OPENGL_CGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
-#endif
if (context->initializeDrawingContext())
return context;
else
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index fc46164c135..2a141f8770c 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -611,97 +611,72 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate()
GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type)
{
if (type == GHOST_kDrawingContextTypeOpenGL) {
-#if !defined(WITH_GL_EGL)
+
+ // During development:
+ // ask for 2.1 context, driver gives latest compatibility profile
+ // (we check later to ensure it's >= 3.3 on Windows)
+ //
+ // Final Blender 2.8:
+ // try 4.x core profile
+ // try 3.3 core profile
+ // no fallbacks
+
+ // TODO(merwin): query version of initial dummy context, request that + profile + debug
+
+ GHOST_Context *context;
#if defined(WITH_GL_PROFILE_CORE)
- GHOST_Context *context = new GHOST_ContextWGL(
+ // our minimum requirement is 3.3 core profile
+ // when we request a specific GL version:
+ // - AMD and Intel give us exactly this version
+ // - NVIDIA gives at least this version <-- desired behavior
+ // so we ask for 4.5, 4.4 ... 3.3 in descending order to get the best version on the user's system
+ for (int minor = 5; minor >= 0; --minor) {
+ context = new GHOST_ContextWGL(
+ m_wantStereoVisual,
+ m_wantAlphaBackground,
+ m_wantNumOfAASamples,
+ m_hWnd,
+ m_hDC,
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 4, minor,
+ (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+ }
+
+ context = new GHOST_ContextWGL(
m_wantStereoVisual,
m_wantAlphaBackground,
m_wantNumOfAASamples,
m_hWnd,
m_hDC,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
- 3, 2,
- GHOST_OPENGL_WGL_CONTEXT_FLAGS,
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-#elif defined(WITH_GL_PROFILE_ES20)
- GHOST_Context *context = new GHOST_ContextWGL(
- m_wantStereoVisual,
- m_wantAlphaBackground,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
- WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
- 2, 0,
- GHOST_OPENGL_WGL_CONTEXT_FLAGS,
+ 3, 3,
+ (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
#elif defined(WITH_GL_PROFILE_COMPAT)
- GHOST_Context *context = new GHOST_ContextWGL(
+ // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile)
+ // 2.1 ignores the profile bit & is incompatible with core profile
+ context = new GHOST_ContextWGL(
m_wantStereoVisual,
m_wantAlphaBackground,
m_wantNumOfAASamples,
m_hWnd,
m_hDC,
-#if 1
- 0, // profile bit
- 2, 1, // GL version requested
-#else
- // switch to this for Blender 2.8 development
- WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
- 3, 2,
-#endif
+ 0, // no profile bit
+ 2, 1,
(m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
#else
-# error
-#endif
-
-#else
-
-#if defined(WITH_GL_PROFILE_CORE)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
- EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
- 3, 2,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_API);
-#elif defined(WITH_GL_PROFILE_ES20)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
- 0, // profile bit
- 2, 0,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_ES_API);
-#elif defined(WITH_GL_PROFILE_COMPAT)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
-#if 1
- 0, // profile bit
- 2, 1, // GL version requested
-#else
- // switch to this for Blender 2.8 development
- EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
- 3, 2,
-#endif
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_API);
-#else
-# error
+# error // must specify either core or compat at build time
#endif
-#endif
if (context->initializeDrawingContext())
return context;
else
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 2019f58251f..450fe568814 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -1318,92 +1318,74 @@ GHOST_WindowX11::
GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
{
if (type == GHOST_kDrawingContextTypeOpenGL) {
-#if !defined(WITH_GL_EGL)
+
+ // During development:
+ // try 4.x compatibility profile
+ // try 3.3 compatibility profile
+ // fall back to 3.0 if needed
+ //
+ // Final Blender 2.8:
+ // try 4.x core profile
+ // try 3.3 core profile
+ // no fallbacks
#if defined(WITH_GL_PROFILE_CORE)
- GHOST_Context *context = new GHOST_ContextGLX(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- m_visualInfo,
- (GLXFBConfig)m_fbconfig,
- GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
- 3, 2,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
-#elif defined(WITH_GL_PROFILE_ES20)
- GHOST_Context *context = new GHOST_ContextGLX(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- m_visualInfo,
- (GLXFBConfig)m_fbconfig,
- GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
- 2, 0,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+ {
+ const char *version_major = (char*)glewGetString(GLEW_VERSION_MAJOR);
+ if (version_major != NULL && version_major[0] == '1') {
+ fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
+ abort();
+ }
+ }
+#endif
+
+ const int profile_mask =
+#if defined(WITH_GL_PROFILE_CORE)
+ GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
#elif defined(WITH_GL_PROFILE_COMPAT)
- GHOST_Context *context = new GHOST_ContextGLX(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- m_visualInfo,
- (GLXFBConfig)m_fbconfig,
- 0, // profile bit
- 0, 0,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+ GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
#else
-# error
+# error // must specify either core or compat at build time
#endif
-#else
+ GHOST_Context *context;
+
+ for (int minor = 5; minor >= 0; --minor) {
+ context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ m_visualInfo,
+ (GLXFBConfig)m_fbconfig,
+ profile_mask,
+ 4, minor,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+ }
-#if defined(WITH_GL_PROFILE_CORE)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
- 3, 2,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_API);
-#elif defined(WITH_GL_PROFILE_ES20)
- GHOST_Context *context = new GHOST_ContextEGL(
+ context = new GHOST_ContextGLX(
m_wantStereoVisual,
m_wantNumOfAASamples,
m_window,
m_display,
- 0, // profile bit
- 2, 0,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_ES_API);
-#elif defined(WITH_GL_PROFILE_COMPAT)
- GHOST_Context *context = new GHOST_ContextEGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- 0, // profile bit
- 0, 0,
- GHOST_OPENGL_EGL_CONTEXT_FLAGS,
- GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
- EGL_OPENGL_API);
-#else
-# error
-#endif
+ m_visualInfo,
+ (GLXFBConfig)m_fbconfig,
+ profile_mask,
+ 3, 3,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
-#endif
if (context->initializeDrawingContext())
return context;
else
delete context;
+
}
return NULL;
diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt
index fb9ef621ecf..ef6e8915871 100644
--- a/intern/ghost/test/CMakeLists.txt
+++ b/intern/ghost/test/CMakeLists.txt
@@ -203,7 +203,6 @@ target_link_libraries(gears_c
glewmx_lib
string_lib
${OPENGL_gl_LIBRARY}
- ${OPENGL_glu_LIBRARY}
${PLATFORM_LINKLIBS}
)
@@ -217,7 +216,6 @@ target_link_libraries(gears_cpp
glewmx_lib
string_lib
${OPENGL_gl_LIBRARY}
- ${OPENGL_glu_LIBRARY}
${PLATFORM_LINKLIBS}
)
@@ -248,7 +246,6 @@ target_link_libraries(multitest_c
guardedalloc_lib
wcwidth_lib
${OPENGL_gl_LIBRARY}
- ${OPENGL_glu_LIBRARY}
${FREETYPE_LIBRARY}
${ZLIB_LIBRARIES}
${PLATFORM_LINKLIBS}
diff --git a/intern/glew-mx/glew-mx.h b/intern/glew-mx/glew-mx.h
index ed17ea4a0e6..86f48a1068d 100644
--- a/intern/glew-mx/glew-mx.h
+++ b/intern/glew-mx/glew-mx.h
@@ -49,12 +49,6 @@
#ifndef __GLEW_MX_H__
#define __GLEW_MX_H__
-#ifdef WITH_GLEW_MX
-/* glew itself expects this */
-# define GLEW_MX 1
-# define glewGetContext() (&(_mx_context->glew_context))
-#endif
-
#include <GL/glew.h>
@@ -62,39 +56,16 @@
extern "C" {
#endif
-/* MXContext is used instead of GLEWContext directly so that
- extending what data is held by a context is easier.
- */
-typedef struct MXContext {
-#ifdef WITH_GLEW_MX
- GLEWContext glew_context;
-#endif
-
- int reserved; /* structs need at least one member */
-
-} MXContext;
-
-#ifdef WITH_GLEW_MX
-extern MXContext *_mx_context;
-#endif
-
-
#include "intern/symbol-binding.h"
/* If compiling only for OpenGL 3.2 Core Profile then we should make sure
* no legacy API entries or symbolic constants are used.
*/
-#if defined(WITH_GL_PROFILE_CORE) && !defined(WITH_GL_PROFILE_COMPAT) && !defined(WITH_GL_PROFILE_ES20)
+#if (!defined(WITH_LEGACY_OPENGL)) || defined(WITH_GL_PROFILE_CORE) && !defined(WITH_GL_PROFILE_COMPAT) && !defined(WITH_GL_PROFILE_ES20)
# include "intern/gl-deprecated.h"
#endif
-
-MXContext *mxCreateContext (void);
-MXContext *mxGetCurrentContext (void);
-void mxMakeCurrentContext(MXContext *ctx);
-void mxDestroyContext (MXContext *ctx);
-
GLenum glew_chk(GLenum error, const char *file, int line, const char *text);
#ifndef NDEBUG
diff --git a/intern/glew-mx/intern/gl-deprecated.h b/intern/glew-mx/intern/gl-deprecated.h
index 1a23642fbfc..669fb83a644 100644
--- a/intern/glew-mx/intern/gl-deprecated.h
+++ b/intern/glew-mx/intern/gl-deprecated.h
@@ -841,6 +841,7 @@
#undef GL_SOURCE2_RGB
#define GL_SOURCE2_RGB DO_NOT_USE_GL_SOURCE2_RGB
+#if 0 /* Those are deprecated but still valid */
// Old Token Names 3.0
#undef GL_CLIP_PLANE0
#define GL_CLIP_PLANE0 USE_GL_CLIP_DISTANCE0
@@ -864,9 +865,6 @@
// Old Token Names 3.2
#undef GL_VERTEX_PROGRAM_POINT_SIZE
#define GL_VERTEX_PROGRAM_POINT_SIZE USE_GL_PROGRAM_POINT_SIZE
-
-// Old Token Names 4.1
-#undef GL_CURRENT_PROGRAM
-#define GL_CURRENT_PROGRAM DO_NOT_USE_GL_CURRENT_PROGRAM
+#endif
#endif /* __GL_DEPRECATED_H__ */
diff --git a/intern/glew-mx/intern/glew-mx.c b/intern/glew-mx/intern/glew-mx.c
index 6fbb1a7a2e2..9db2d233085 100644
--- a/intern/glew-mx/intern/glew-mx.c
+++ b/intern/glew-mx/intern/glew-mx.c
@@ -84,61 +84,3 @@ GLenum glew_chk(GLenum error, const char *file, int line, const char *text)
return error;
}
-
-
-#ifdef WITH_GLEW_MX
-MXContext *_mx_context = NULL;
-#endif
-
-
-MXContext *mxCreateContext(void)
-{
-#ifdef WITH_GLEW_MX
- MXContext* new_ctx = calloc(1, sizeof(MXContext));
-
- if (new_ctx != NULL) {
- MXContext* cur_ctx = _mx_context;
- _mx_context = new_ctx;
- GLEW_CHK(glewInit());
- _mx_context = cur_ctx;
- }
-
- return new_ctx;
-#else
- GLEW_CHK(glewInit());
- return NULL;
-#endif
-}
-
-
-MXContext *mxGetCurrentContext(void)
-{
-#ifdef WITH_GLEW_MX
- return _mx_context;
-#else
- return NULL;
-#endif
-}
-
-
-void mxMakeCurrentContext(MXContext *ctx)
-{
-#ifdef WITH_GLEW_MX
- _mx_context = ctx;
-#else
- (void)ctx;
-#endif
-}
-
-
-void mxDestroyContext(MXContext *ctx)
-{
-#ifdef WITH_GLEW_MX
- if (_mx_context == ctx)
- _mx_context = NULL;
-
- free(ctx);
-#else
- (void)ctx;
-#endif
-}
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt
index 75e228933aa..2611477252a 100644
--- a/intern/opencolorio/CMakeLists.txt
+++ b/intern/opencolorio/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
.
../glew-mx
../guardedalloc
+ ../gawain
../../source/blender/blenlib
)
@@ -66,6 +67,7 @@ if(WITH_OPENCOLORIO)
endif()
data_to_c_simple(gpu_shader_display_transform.glsl SRC)
+ data_to_c_simple(gpu_shader_display_transform_vertex.glsl SRC)
endif()
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
index 853bf575582..372d41dfecb 100644
--- a/intern/opencolorio/gpu_shader_display_transform.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -10,6 +10,10 @@ uniform float image_texture_width;
uniform float image_texture_height;
#endif
+in vec2 texCoord_interp;
+out vec4 fragColor;
+#define texture2D texture
+
#ifdef USE_CURVE_MAPPING
/* Curve mapping parameters
*
@@ -143,7 +147,7 @@ vec4 apply_dither(vec2 st, vec4 col)
void main()
{
- vec4 col = texture2D(image_texture, gl_TexCoord[0].st);
+ vec4 col = texture2D(image_texture, texCoord_interp.st);
#ifdef USE_CURVE_MAPPING
col = curvemapping_evaluate_premulRGBF(col);
#endif
@@ -165,8 +169,8 @@ void main()
vec4 result = OCIODisplay(col, lut3d_texture);
#ifdef USE_DITHER
- result = apply_dither(gl_TexCoord[0].st, result);
+ result = apply_dither(texCoord_interp.st, result);
#endif
- gl_FragColor = result;
+ fragColor = result;
}
diff --git a/intern/opencolorio/gpu_shader_display_transform_vertex.glsl b/intern/opencolorio/gpu_shader_display_transform_vertex.glsl
new file mode 100644
index 00000000000..054f7f3ec91
--- /dev/null
+++ b/intern/opencolorio/gpu_shader_display_transform_vertex.glsl
@@ -0,0 +1,12 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 texCoord;
+in vec2 pos;
+out vec2 texCoord_interp;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f);
+ texCoord_interp = texCoord;
+}
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index bf91ea143da..89df3080749 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -48,6 +48,9 @@
# pragma warning(pop)
#endif
+extern "C" {
+#include "gawain/immediate.h"
+}
using namespace OCIO_NAMESPACE;
@@ -58,6 +61,7 @@ using namespace OCIO_NAMESPACE;
static const int LUT3D_EDGE_SIZE = 64;
extern "C" char datatoc_gpu_shader_display_transform_glsl[];
+extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
@@ -89,7 +93,9 @@ typedef struct OCIO_GLSLDrawState {
/* GLSL stuff */
GLuint ocio_shader;
+ GLuint vert_shader;
GLuint program;
+ ShaderInterface *shader_interface;
/* Previous OpenGL state. */
GLint last_texture, last_texture_unit;
@@ -116,14 +122,15 @@ static GLuint compileShaderText(GLenum shaderType, const char *text)
return shader;
}
-static GLuint linkShaders(GLuint ocio_shader)
+static GLuint linkShaders(GLuint ocio_shader, GLuint vert_shader)
{
- if (!ocio_shader)
+ if (!ocio_shader || !vert_shader)
return 0;
GLuint program = glCreateProgram();
glAttachShader(program, ocio_shader);
+ glAttachShader(program, vert_shader);
glLinkProgram(program);
@@ -339,6 +346,25 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
glDeleteShader(state->ocio_shader);
}
+ if (state->vert_shader) {
+ glDeleteShader(state->vert_shader);
+ }
+
+ /* Vertex shader */
+ std::ostringstream osv;
+
+ if (supportGLSL13()) {
+ osv << "#version 130\n";
+ }
+ else {
+ osv << "#version 120\n";
+ }
+
+ osv << datatoc_gpu_shader_display_transform_vertex_glsl;
+
+ state->vert_shader = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
+
+ /* Fragment shader */
std::ostringstream os;
if (supportGLSL13()) {
@@ -366,8 +392,12 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
state->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
- if (state->ocio_shader) {
- state->program = linkShaders(state->ocio_shader);
+ if (state->ocio_shader && state->vert_shader) {
+ state->program = linkShaders(state->ocio_shader, state->vert_shader);
+ }
+
+ if (state->program) {
+ state->shader_interface = ShaderInterface_create(state->program);
}
state->curve_mapping_used = use_curve_mapping;
@@ -386,10 +416,21 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
glActiveTexture(GL_TEXTURE0);
- glUseProgram(state->program);
-
- glUniform1i(glGetUniformLocation(state->program, "image_texture"), 0);
- glUniform1i(glGetUniformLocation(state->program, "lut3d_texture"), 1);
+ /* IMM needs vertex format even if we don't draw with it.
+ *
+ * NOTE: The only reason why it's here is because of Cycles viewport.
+ * All other areas are managing their own vertex formats.
+ * Doing it here is probably harmless, but kind of stupid.
+ *
+ * TODO(sergey): Look into some nicer solution.
+ */
+ VertexFormat *format = immVertexFormat();
+ VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ immBindProgram(state->program, state->shader_interface);
+
+ immUniform1i("image_texture", 0);
+ immUniform1i("lut3d_texture", 1);
if (state->texture_size_used) {
/* we use textureSize() if possible for best performance, if not
@@ -399,30 +440,30 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
- glUniform1f(glGetUniformLocation(state->program, "image_texture_width"), (float)width);
- glUniform1f(glGetUniformLocation(state->program, "image_texture_height"), (float)height);
+ immUniform1f("image_texture_width", (float)width);
+ immUniform1f("image_texture_height", (float)height);
}
if (use_dither) {
- glUniform1f(glGetUniformLocation(state->program, "dither"), dither);
+ immUniform1f("dither", dither);
}
if (use_curve_mapping) {
- glUniform1i(glGetUniformLocation(state->program, "curve_mapping_texture"), 2);
- glUniform1i(glGetUniformLocation(state->program, "curve_mapping_lut_size"), curve_mapping_settings->lut_size);
- glUniform4iv(glGetUniformLocation(state->program, "use_curve_mapping_extend_extrapolate"), 1, curve_mapping_settings->use_extend_extrapolate);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_mintable"), 1, curve_mapping_settings->mintable);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_range"), 1, curve_mapping_settings->range);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_in_x"), 1, curve_mapping_settings->ext_in_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_in_y"), 1, curve_mapping_settings->ext_in_y);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_out_x"), 1, curve_mapping_settings->ext_out_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_out_y"), 1, curve_mapping_settings->ext_out_y);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_first_x"), 1, curve_mapping_settings->first_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_first_y"), 1, curve_mapping_settings->first_y);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_last_x"), 1, curve_mapping_settings->last_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_last_y"), 1, curve_mapping_settings->last_y);
- glUniform3fv(glGetUniformLocation(state->program, "curve_mapping_black"), 1, curve_mapping_settings->black);
- glUniform3fv(glGetUniformLocation(state->program, "curve_mapping_bwmul"), 1, curve_mapping_settings->bwmul);
+ immUniform1i("curve_mapping_texture", 2);
+ immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
+ immUniform4iv("use_curve_mapping_extend_extrapolate", curve_mapping_settings->use_extend_extrapolate);
+ immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
+ immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
+ immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);
+ immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y);
+ immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x);
+ immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y);
+ immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x);
+ immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y);
+ immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x);
+ immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y);
+ immUniform3fv("curve_mapping_black", curve_mapping_settings->black);
+ immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul);
}
return true;
@@ -439,7 +480,7 @@ void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
{
glActiveTexture(state->last_texture_unit);
glBindTexture(GL_TEXTURE_2D, state->last_texture);
- glUseProgram(0);
+ immUnbindProgram();
}
void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
@@ -455,6 +496,9 @@ void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
if (state->program)
glDeleteProgram(state->program);
+ if (state->shader_interface)
+ ShaderInterface_discard(state->shader_interface);
+
if (state->ocio_shader)
glDeleteShader(state->ocio_shader);
diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl
index 3a83d44a8be..b16a5cca733 100644
--- a/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl
@@ -29,22 +29,11 @@ struct VertexData {
vec2 uv;
};
-#if __VERSION__ >= 150
layout(lines_adjacency) in;
- #ifdef WIREFRAME
+#ifdef WIREFRAME
layout(line_strip, max_vertices = 8) out;
- #else
-layout(triangle_strip, max_vertices = 4) out;
- #endif
#else
- #extension GL_EXT_geometry_shader4: require
- /* application provides input/output layout info */
-#endif
-
-#if __VERSION__ < 140
- #extension GL_ARB_uniform_buffer_object: require
- #extension GL_ARB_texture_buffer_object: enable
- #extension GL_EXT_texture_buffer_object: enable
+layout(triangle_strip, max_vertices = 4) out;
#endif
uniform mat4 modelViewMatrix;
diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl
index 6d3c06f59c9..6fcf5ad20cd 100644
--- a/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl
@@ -43,11 +43,4 @@ void main()
{
outpt.v.position = modelViewMatrix * position;
outpt.v.normal = normalize(normalMatrix * normal);
-
-#if __VERSION__ < 140
- /* Some compilers expects gl_Position to be written.
- * It's not needed once we explicitly switch to GLSL 1.40 or above.
- */
- gl_Position = outpt.v.position;
-#endif
}
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index 52ce98fe74b..8337bcb0ce5 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -368,16 +368,3 @@ const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefine
{
return gl_mesh->topology_refiner;
}
-
-int openSubdiv_supportGPUDisplay(void)
-{
- // TODO: simplify extension check once Blender adopts GL 3.2
- return openSubdiv_gpu_legacy_support() &&
- (GLEW_VERSION_3_2 ||
- (GLEW_VERSION_3_1 && GLEW_EXT_geometry_shader4) ||
- (GLEW_VERSION_3_0 &&
- GLEW_EXT_geometry_shader4 &&
- GLEW_ARB_uniform_buffer_object &&
- (GLEW_ARB_texture_buffer_object || GLEW_EXT_texture_buffer_object)));
- /* also ARB_explicit_attrib_location? */
-}
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index c3a194813e6..3fdfefd525f 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -146,11 +146,9 @@ void openSubdiv_osdGLAllocFVar(struct OpenSubdiv_TopologyRefinerDescr *topology_
void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh);
/* ** Utility functions ** */
-int openSubdiv_supportGPUDisplay(void);
int openSubdiv_getAvailableEvaluators(void);
-void openSubdiv_init(bool gpu_legacy_support);
+void openSubdiv_init(void);
void openSubdiv_cleanup(void);
-bool openSubdiv_gpu_legacy_support(void);
#ifdef __cplusplus
}
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index c36eaae1c6e..811cd18745e 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -275,24 +275,6 @@ GLuint linkProgram(const char *version, const char *define)
glBindAttribLocation(program, 0, "position");
glBindAttribLocation(program, 1, "normal");
-
- if (!GLEW_VERSION_3_2) {
- /* provide input/output layout info */
- glProgramParameteriEXT(program,
- GL_GEOMETRY_INPUT_TYPE_EXT,
- GL_LINES_ADJACENCY_EXT);
-
- bool wireframe = strstr(define, "WIREFRAME") != NULL;
-
- glProgramParameteriEXT(program,
- GL_GEOMETRY_OUTPUT_TYPE_EXT,
- wireframe ? GL_LINE_STRIP : GL_TRIANGLE_STRIP);
-
- glProgramParameteriEXT(program,
- GL_GEOMETRY_VERTICES_OUT_EXT,
- 8);
- }
-
glLinkProgram(program);
glDeleteShader(vertexShader);
@@ -314,17 +296,26 @@ GLuint linkProgram(const char *version, const char *define)
glGetUniformBlockIndex(program, "Lighting"),
0);
- glProgramUniform1i(program,
- glGetUniformLocation(program, "texture_buffer"),
- 0); /* GL_TEXTURE0 */
+ if (GLEW_VERSION_4_1) {
+ glProgramUniform1i(program,
+ glGetUniformLocation(program, "texture_buffer"),
+ 0); /* GL_TEXTURE0 */
- glProgramUniform1i(program,
- glGetUniformLocation(program, "FVarDataOffsetBuffer"),
- 30); /* GL_TEXTURE30 */
+ glProgramUniform1i(program,
+ glGetUniformLocation(program, "FVarDataOffsetBuffer"),
+ 30); /* GL_TEXTURE30 */
- glProgramUniform1i(program,
- glGetUniformLocation(program, "FVarDataBuffer"),
- 31); /* GL_TEXTURE31 */
+ glProgramUniform1i(program,
+ glGetUniformLocation(program, "FVarDataBuffer"),
+ 31); /* GL_TEXTURE31 */
+ }
+ else {
+ glUseProgram(program);
+ glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0); /* GL_TEXTURE0 */
+ glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); /* GL_TEXTURE30 */
+ glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */
+ glUseProgram(0);
+ }
return program;
}
@@ -353,10 +344,8 @@ void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program)
glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
/* Color */
- GLboolean use_lighting;
- glGetBooleanv(GL_LIGHTING, &use_lighting);
-
- if (use_lighting) {
+ {
+ /* TODO: stop using glGetMaterial */
float color[4];
glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color);
glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color);
@@ -367,11 +356,6 @@ void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program)
glGetMaterialfv(GL_FRONT, GL_SHININESS, color);
glUniform1f(glGetUniformLocation(program, "shininess"), color[0]);
}
- else {
- float color[4];
- glGetFloatv(GL_CURRENT_COLOR, color);
- glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color);
- }
/* Face-vertex data */
if (gl_mesh->fvar_data != NULL) {
@@ -409,11 +393,10 @@ bool openSubdiv_osdGLDisplayInit(void)
{
static bool need_init = true;
static bool init_success = false;
- if (need_init) {
- if (!openSubdiv_supportGPUDisplay()) {
- return false;
- }
+ if (need_init) {
+ /* TODO: update OSD drawing to OpenGL 3.3 core, then remove following line */
+ return false;
const char *version = "";
if (GLEW_VERSION_3_2) {
@@ -538,6 +521,7 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
g_lighting_data.num_enabled++;
}
+ /* TODO: stop using glGetLight */
glGetLightfv(GL_LIGHT0 + i,
GL_POSITION,
g_lighting_data.lights[i].position);
@@ -635,31 +619,24 @@ static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh,
GLboolean use_texture_2d, use_lighting;
glGetIntegerv(GL_SHADE_MODEL, &model);
glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
- glGetBooleanv(GL_LIGHTING, &use_lighting);
+
if (model == GL_FLAT) {
if (use_texture_2d) {
- program = use_lighting
- ? g_flat_fill_texture2d_program
- : g_flat_fill_texture2d_shadeless_program;
+ program = g_flat_fill_texture2d_program;
}
else {
- program = use_lighting
- ? g_flat_fill_solid_program
- : g_flat_fill_solid_shadeless_program;
+ program = g_flat_fill_solid_program;
}
}
else {
if (use_texture_2d) {
- program = use_lighting
- ? g_smooth_fill_texture2d_program
- : g_smooth_fill_texture2d_shadeless_program;
+ program = g_smooth_fill_texture2d_program;
}
else {
- program = use_lighting
- ? g_smooth_fill_solid_program
- : g_smooth_fill_solid_shadeless_program;
+ program = g_smooth_fill_solid_program;
}
}
+
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
diff --git a/intern/opensubdiv/opensubdiv_utils_capi.cc b/intern/opensubdiv/opensubdiv_utils_capi.cc
index ae5592367dd..72e3751e6b3 100644
--- a/intern/opensubdiv/opensubdiv_utils_capi.cc
+++ b/intern/opensubdiv/opensubdiv_utils_capi.cc
@@ -41,14 +41,8 @@
# include "opensubdiv_device_context_cuda.h"
#endif /* OPENSUBDIV_HAS_CUDA */
-static bool gpu_legacy_support_global = false;
-
int openSubdiv_getAvailableEvaluators(void)
{
- if (!openSubdiv_supportGPUDisplay()) {
- return 0;
- }
-
int flags = OPENSUBDIV_EVALUATOR_CPU;
#ifdef OPENSUBDIV_HAS_OPENMP
@@ -82,19 +76,13 @@ int openSubdiv_getAvailableEvaluators(void)
return flags;
}
-void openSubdiv_init(bool gpu_legacy_support)
+void openSubdiv_init(void)
{
/* Ensure all OpenGL strings are cached. */
(void)openSubdiv_getAvailableEvaluators();
- gpu_legacy_support_global = gpu_legacy_support;
}
void openSubdiv_cleanup(void)
{
openSubdiv_osdGLDisplayDeinit();
}
-
-bool openSubdiv_gpu_legacy_support(void)
-{
- return gpu_legacy_support_global;
-}
diff --git a/make.bat b/make.bat
index 988cb5f4c68..4abcd086cdf 100644
--- a/make.bat
+++ b/make.bat
@@ -98,7 +98,7 @@ if NOT "%1" == "" (
) else if "%1" == "update" (
svn up ../lib/*
git pull --rebase
- git submodule foreach git pull --rebase origin master
+ git submodule update --remote
goto EOF
) else if "%1" == "clean" (
set MUST_CLEAN=1
diff --git a/release/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist
index 0649a2075cd..92e8d8cc761 100644
--- a/release/darwin/blender.app/Contents/Info.plist
+++ b/release/darwin/blender.app/Contents/Info.plist
@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>LSMinimumSystemVersion</key>
+ <string>10.9.0</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
@@ -47,5 +49,7 @@
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<true/>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
</dict>
</plist>
diff --git a/release/datafiles/preview.blend b/release/datafiles/preview.blend
index 7eaa7a63eeb..c22245eacc5 100644
--- a/release/datafiles/preview.blend
+++ b/release/datafiles/preview.blend
Binary files differ
diff --git a/release/datafiles/preview_cycles.blend b/release/datafiles/preview_cycles.blend
index d813e23b4cf..ed32ea530d6 100644
--- a/release/datafiles/preview_cycles.blend
+++ b/release/datafiles/preview_cycles.blend
Binary files differ
diff --git a/release/scripts/modules/bpy_extras/__init__.py b/release/scripts/modules/bpy_extras/__init__.py
index c8d12070de8..cd176e77aed 100644
--- a/release/scripts/modules/bpy_extras/__init__.py
+++ b/release/scripts/modules/bpy_extras/__init__.py
@@ -29,5 +29,6 @@ __all__ = (
"image_utils",
"keyconfig_utils",
"mesh_utils",
+ "node_utils",
"view3d_utils",
)
diff --git a/release/scripts/modules/bpy_extras/node_utils.py b/release/scripts/modules/bpy_extras/node_utils.py
new file mode 100644
index 00000000000..3b8d4ad7c2a
--- /dev/null
+++ b/release/scripts/modules/bpy_extras/node_utils.py
@@ -0,0 +1,47 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# 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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+__all__ = (
+ "find_node_input",
+ "find_output_node",
+ )
+
+
+# XXX Names are not unique. Returns the first match.
+def find_node_input(node, name):
+ for input in node.inputs:
+ if input.name == name:
+ return input
+
+ return None
+
+# Return the output node to display in the UI
+def find_output_node(ntree, nodetype):
+ if ntree:
+ active_output_node = None
+ for node in ntree.nodes:
+ if getattr(node, "type", None) == nodetype:
+ if getattr(node, "is_active_output", True):
+ return node
+ if not active_output_node:
+ active_output_node = node
+ return active_output_node
+
+ return None
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index c48f03c133d..8f2e69313fc 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -103,9 +103,9 @@ def add_object_align_init(context, operator):
return location * rotation
-def object_data_add(context, obdata, operator=None, use_active_layer=True, name=None):
+def object_data_add(context, obdata, operator=None, name=None):
"""
- Add an object using the view context and preference to to initialize the
+ Add an object using the view context and preference to initialize the
location, rotation and layer.
:arg context: The context to use.
@@ -117,53 +117,31 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
:arg name: Optional name
:type name: string
:return: the newly created object in the scene.
- :rtype: :class:`bpy.types.ObjectBase`
+ :rtype: :class:`bpy.types.Object`
"""
scene = context.scene
+ layer = context.render_layer
+ layer_collection = context.layer_collection
- # ugh, could be made nicer
- for ob in scene.objects:
- ob.select = False
+ for ob in layer.objects:
+ ob.select_set(action='DESELECT')
+
+ if not layer_collection:
+ # when there is no collection linked to this render_layer create one
+ scene_collection = scene.master_collection.collections.new("")
+ layer_collection = layer.collections.link(scene_collection)
+ else:
+ scene_collection = layer_collection.collection
if name is None:
name = "Object" if obdata is None else obdata.name
+ obj_act = layer.objects.active
obj_new = bpy.data.objects.new(name, obdata)
-
- base = scene.objects.link(obj_new)
- base.select = True
-
- v3d = None
- if context.space_data and context.space_data.type == 'VIEW_3D':
- v3d = context.space_data
-
- if v3d and v3d.local_view:
- base.layers_from_view(context.space_data)
-
- if operator is not None and any(operator.layers):
- base.layers = operator.layers
- else:
- if use_active_layer:
- if v3d and v3d.local_view:
- base.layers[scene.active_layer] = True
- else:
- if v3d and not v3d.lock_camera_and_layers:
- base.layers = [True if i == v3d.active_layer
- else False for i in range(len(v3d.layers))]
- else:
- base.layers = [True if i == scene.active_layer
- else False for i in range(len(scene.layers))]
- else:
- if v3d:
- base.layers_from_view(context.space_data)
-
- if operator is not None:
- operator.layers = base.layers
-
+ scene_collection.objects.link(obj_new)
+ obj_new.select_set(action='SELECT')
obj_new.matrix_world = add_object_align_init(context, operator)
- obj_act = scene.objects.active
-
# XXX
# caused because entering edit-mode does not add a empty undo slot!
if context.user_preferences.edit.use_enter_edit_mode:
@@ -174,8 +152,8 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
_obdata = bpy.data.meshes.new(name)
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
obj_act.matrix_world = obj_new.matrix_world
- scene.objects.link(obj_act)
- scene.objects.active = obj_act
+ scene_collection.objects.link(obj_act)
+ layer.objects.active = obj_act
bpy.ops.object.mode_set(mode='EDIT')
# need empty undo step
bpy.ops.ed.undo_push(message="Enter Editmode")
@@ -183,9 +161,10 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
bpy.ops.mesh.select_all(action='DESELECT')
+ obj_act.select_set(action='SELECT')
bpy.ops.object.mode_set(mode='OBJECT')
- obj_act.select = True
+ obj_act.select_set(action='SELECT')
scene.update() # apply location
# scene.objects.active = obj_new
@@ -200,16 +179,14 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
bpy.ops.object.join() # join into the active.
if obdata:
bpy.data.meshes.remove(obdata)
- # base is freed, set to active object
- base = scene.object_bases.active
bpy.ops.object.mode_set(mode='EDIT')
else:
- scene.objects.active = obj_new
+ layer.objects.active = obj_new
if context.user_preferences.edit.use_enter_edit_mode:
bpy.ops.object.mode_set(mode='EDIT')
- return base
+ return obj_new
class AddObjectHelper:
@@ -230,12 +207,6 @@ class AddObjectHelper:
name="Rotation",
subtype='EULER',
)
- layers = BoolVectorProperty(
- name="Layers",
- size=20,
- subtype='LAYER',
- options={'HIDDEN', 'SKIP_SAVE'},
- )
@classmethod
def poll(self, context):
diff --git a/release/scripts/presets/keyconfig/3dsmax.py b/release/scripts/presets/keyconfig/3dsmax.py
index 6d05ff6982c..09c6704df1f 100644
--- a/release/scripts/presets/keyconfig/3dsmax.py
+++ b/release/scripts/presets/keyconfig/3dsmax.py
@@ -7,7 +7,7 @@ kc = wm.keyconfigs.new('3dsmax')
# Map Window
km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False)
-kmi = km.keymap_items.new('wm.window_duplicate', 'W', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.window_new', 'W', 'PRESS', ctrl=True, alt=True)
kmi = km.keymap_items.new('wm.read_homefile', 'N', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.save_homefile', 'U', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.call_menu', 'O', 'PRESS', shift=True, ctrl=True)
@@ -330,7 +330,6 @@ kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', shift=True)
kmi.properties.unselected = True
kmi = km.keymap_items.new('object.hide_render_clear', 'H', 'PRESS', ctrl=True, alt=True)
kmi = km.keymap_items.new('object.hide_render_set', 'H', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
kmi = km.keymap_items.new('object.delete', 'X', 'PRESS')
kmi.properties.use_global = False
kmi = km.keymap_items.new('object.delete', 'X', 'PRESS', shift=True)
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py
index 53129593a59..194b9b3c283 100644
--- a/release/scripts/presets/keyconfig/maya.py
+++ b/release/scripts/presets/keyconfig/maya.py
@@ -8,7 +8,7 @@ kc = wm.keyconfigs.new(os.path.splitext(os.path.basename(__file__))[0])
# Map Window
km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False)
-kmi = km.keymap_items.new('wm.window_duplicate', 'W', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.window_new', 'W', 'PRESS', ctrl=True, alt=True)
kmi = km.keymap_items.new('wm.read_homefile', 'N', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.save_homefile', 'U', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.call_menu', 'O', 'PRESS', shift=True, ctrl=True)
@@ -384,7 +384,6 @@ kmi = km.keymap_items.new('object.hide_view_clear', 'H', 'PRESS', shift=True, ct
kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', alt=True)
kmi.properties.unselected = True
-kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
kmi = km.keymap_items.new('object.delete', 'BACK_SPACE', 'PRESS')
kmi = km.keymap_items.new('object.delete', 'DEL', 'PRESS')
kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
diff --git a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py
index 9e2efcaa727..a13ba5c4ccc 100644
--- a/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py
+++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py
@@ -10,7 +10,6 @@ op.include_armatures = False
op.include_shapekeys = False
op.deform_bones_only = False
op.active_uv_only = True
-op.include_uv_textures = True
op.use_texture_copies = True
op.triangulate = True
op.use_object_instantiation = False
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 0e5acea94f9..c7152c8a22f 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -79,7 +79,7 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
def add_uvs(mesh, minor_seg, major_seg):
from math import fmod
- mesh.uv_textures.new()
+ mesh.uv_layers.new()
uv_data = mesh.uv_layers.active.data
polygons = mesh.polygons
u_step = 1.0 / major_seg
@@ -286,4 +286,4 @@ class AddTorus(Operator, object_utils.AddObjectHelper):
classes = (
AddTorus,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index e52d577b900..6747bfec1fb 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -235,7 +235,7 @@ class CLIP_OT_track_to_empty(Operator):
ob = None
ob = bpy.data.objects.new(name=track.name, object_data=None)
- ob.select = True
+ ob.select_set(action='SELECT')
context.scene.objects.link(ob)
context.scene.objects.active = ob
@@ -509,7 +509,7 @@ object's movement caused by this constraint"""
# XXX, should probably use context.selected_editable_objects
# since selected objects can be from a lib or in hidden layer!
for ob in scene.objects:
- if ob.select:
+ if ob.select_set(action='SELECT'):
self._bake_object(scene, ob)
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py
index 2e46160aeeb..4cee1abf15f 100644
--- a/release/scripts/startup/bl_operators/freestyle.py
+++ b/release/scripts/startup/bl_operators/freestyle.py
@@ -104,7 +104,7 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
m.range_max = max_dist
return {'FINISHED'}
# Find selected mesh objects
- selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != ref.name]
+ selection = [ob for ob in scene.objects if ob.select_get() and ob.type == 'MESH' and ob.name != source.name]
if selection:
# Compute the min/max distance from the reference to mesh vertices
min_dist = sys.float_info.max
diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py
index 4edefd7bf9b..9151f800497 100644
--- a/release/scripts/startup/bl_operators/mesh.py
+++ b/release/scripts/startup/bl_operators/mesh.py
@@ -50,7 +50,7 @@ class MeshMirrorUV(Operator):
@classmethod
def poll(cls, context):
obj = context.active_object
- return (obj and obj.type == 'MESH' and obj.data.uv_textures.active)
+ return (obj and obj.type == 'MESH' and obj.data.uv_layers.active)
def execute(self, context):
DIR = (self.direction == 'NEGATIVE')
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 307764205e6..566487d9d0e 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -81,16 +81,18 @@ class SelectPattern(Operator):
# Can be pose bones or objects
for item in items:
if pattern_match(item.name, self.pattern):
- item.select = True
# hrmf, perhaps there should be a utility function for this.
if is_ebone:
+ item.select = True
item.select_head = True
item.select_tail = True
if item.use_connect:
item_parent = item.parent
if item_parent is not None:
item_parent.select_tail = True
+ else:
+ item.select_set(action='SELECT')
return {'FINISHED'}
@@ -136,7 +138,7 @@ class SelectCamera(Operator):
bpy.ops.object.select_all(action='DESELECT')
scene.objects.active = camera
camera.hide = False
- camera.select = True
+ camera.select_set(action='SELECT')
return {'FINISHED'}
return {'CANCELLED'}
@@ -202,7 +204,7 @@ class SelectHierarchy(Operator):
bpy.ops.object.select_all(action='DESELECT')
for obj in select_new:
- obj.select = True
+ obj.select_set(action='SELECT')
scene.objects.active = act_new
return {'FINISHED'}
@@ -513,7 +515,7 @@ class JoinUVs(Operator):
if is_editmode:
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
- if not mesh.uv_textures:
+ if not mesh.uv_layers:
self.report({'WARNING'},
"Object: %s, Mesh: '%s' has no UVs"
% (obj.name, mesh.name))
@@ -551,7 +553,7 @@ class JoinUVs(Operator):
else:
uv_other = mesh_other.uv_layers.active
if not uv_other:
- mesh_other.uv_textures.new()
+ mesh_other.uv_layers.new()
uv_other = mesh_other.uv_layers.active
if not uv_other:
self.report({'ERROR'}, "Could not add "
@@ -644,8 +646,8 @@ class MakeDupliFace(Operator):
ob_new.use_dupli_faces_scale = True
ob_new.dupli_faces_scale = 1.0 / SCALE_FAC
- ob_inst.select = True
- ob_new.select = True
+ ob_inst.select_set(action='SELECT')
+ ob_new.select_set(action='SELECT')
def execute(self, context):
self._main(context)
@@ -664,7 +666,7 @@ class IsolateTypeRender(Operator):
for obj in context.visible_objects:
- if obj.select:
+ if obj.select_get():
obj.hide_render = False
else:
if obj.type == act_type:
@@ -1029,8 +1031,8 @@ class LodGenerate(Operator):
for level in ob.lod_levels[1:]:
level.object.hide = level.object.hide_render = True
- lod.select = False
- ob.select = True
+ lod.select_set(action='DESELECT')
+ ob.select_set(action='SELECT')
scene.objects.active = ob
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 16f29c77bb9..39191a896c9 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -222,7 +222,7 @@ class QuickExplode(Operator):
if self.fade:
explode.show_dead = False
- uv = obj.data.uv_textures.new("Explode fade")
+ uv = obj.data.uv_layers.new("Explode fade")
explode.particle_uv = uv.name
mat = object_ensure_material(obj, "Explode Fade")
diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py
index 6792d525683..e10a2a2915e 100644
--- a/release/scripts/startup/bl_operators/rigidbody.py
+++ b/release/scripts/startup/bl_operators/rigidbody.py
@@ -65,7 +65,7 @@ class CopyRigidbodySettings(Operator):
# deselect all but mesh objects
for o in context.selected_objects:
if o.type != 'MESH':
- o.select = False
+ o.select_set(action='DESELECT')
elif o.rigid_body is None:
# Add rigidbody to object!
scene.objects.active = o
@@ -127,7 +127,7 @@ class BakeToKeyframes(Operator):
# filter objects selection
for obj in context.selected_objects:
if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE':
- obj.select = False
+ obj.select_set(action='DESELECT')
objects = context.selected_objects
@@ -260,7 +260,7 @@ class ConnectRigidBodies(Operator):
ob.location = loc
context.scene.objects.link(ob)
context.scene.objects.active = ob
- ob.select = True
+ ob.select_set(action='SELECT')
bpy.ops.rigidbody.constraint_add()
con_obj = context.active_object
@@ -305,7 +305,7 @@ class ConnectRigidBodies(Operator):
# restore selection
bpy.ops.object.select_all(action='DESELECT')
for obj in objects:
- obj.select = True
+ obj.select_set(action='SELECT')
scene.objects.active = obj_act
return {'FINISHED'}
else:
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index 25ee5cafe81..29cefd83328 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -30,8 +30,8 @@ def extend(obj, operator, EXTEND_MODE):
import bmesh
me = obj.data
# script will fail without UVs
- if not me.uv_textures:
- me.uv_textures.new()
+ if not me.uv_layers:
+ me.uv_layers.new()
bm = bmesh.from_edit_mesh(me)
@@ -252,4 +252,4 @@ class FollowActiveQuads(Operator):
classes = (
FollowActiveQuads,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 8ee29d15d1b..61ceb3c04c4 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -275,12 +275,12 @@ def lightmap_uvpack(meshes,
face_groups.append(faces)
if PREF_NEW_UVLAYER:
- me.uv_textures.new()
+ me.uv_layers.new()
# Add face UV if it does not exist.
# All new faces are selected.
- if not me.uv_textures:
- me.uv_textures.new()
+ if not me.uv_layers:
+ me.uv_layers.new()
for face_sel in face_groups:
print("\nStarting unwrap")
@@ -538,6 +538,9 @@ def lightmap_uvpack(meshes,
print("done")
if PREF_APPLY_IMAGE:
+ pass
+ # removed with texface
+ '''
if not PREF_PACK_IN_ONE:
image = bpy.data.images.new(name="lightmap",
width=PREF_IMG_PX_SIZE,
@@ -545,8 +548,8 @@ def lightmap_uvpack(meshes,
)
for f in face_sel:
- # f.image = image
- f.id_data.uv_textures.active.data[f.index].image = image # XXX25
+ f.image = image
+ '''
for me in meshes:
me.update()
@@ -672,4 +675,4 @@ class LightMapPack(Operator):
classes = (
LightMapPack,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 5581415c083..b7ef6856575 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -810,8 +810,8 @@ def main(context,
# Tag as used
me.tag = True
- if not me.uv_textures: # Mesh has no UV Coords, don't bother.
- me.uv_textures.new()
+ if not me.uv_layers: # Mesh has no UV Coords, don't bother.
+ me.uv_layers.new()
uv_layer = me.uv_layers.active.data
me_verts = list(me.vertices)
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index 5b609605cee..c5772101df8 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -28,6 +28,7 @@ if "bpy" in locals():
_modules = [
"properties_animviz",
+ "properties_collection",
"properties_constraint",
"properties_data_armature",
"properties_data_bone",
diff --git a/release/scripts/startup/bl_ui/properties_collection.py b/release/scripts/startup/bl_ui/properties_collection.py
new file mode 100644
index 00000000000..9e7d29358a9
--- /dev/null
+++ b/release/scripts/startup/bl_ui/properties_collection.py
@@ -0,0 +1,167 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# 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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Panel
+
+
+class CollectionButtonsPanel:
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "collection"
+
+
+class COLLECTION_PT_context_collection(CollectionButtonsPanel, Panel):
+ bl_label = ""
+ bl_options = {'HIDE_HEADER'}
+
+ def draw(self, context):
+ layout = self.layout
+ space = context.space_data
+
+ collection = context.layer_collection
+ name = collection.name
+ if name == 'Master Collection':
+ layout.label(text=name, icon='COLLAPSEMENU')
+ else:
+ layout.prop(collection, "name", text="", icon='COLLAPSEMENU')
+
+
+class COLLECTION_PT_clay_settings(CollectionButtonsPanel, Panel):
+ bl_label = "Render Settings"
+ COMPAT_ENGINES = {'BLENDER_CLAY'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene_props = context.scene.collection_properties['BLENDER_CLAY']
+ collection = context.layer_collection
+ collection_props = collection.engine_overrides['BLENDER_CLAY']
+
+ col = layout.column()
+ col.template_override_property(collection_props, scene_props, "matcap_icon", custom_template="icon_view")
+ col.template_override_property(collection_props, scene_props, "matcap_rotation")
+ col.template_override_property(collection_props, scene_props, "matcap_hue")
+ col.template_override_property(collection_props, scene_props, "matcap_saturation")
+ col.template_override_property(collection_props, scene_props, "matcap_value")
+ col.template_override_property(collection_props, scene_props, "ssao_factor_cavity")
+ col.template_override_property(collection_props, scene_props, "ssao_factor_edge")
+ col.template_override_property(collection_props, scene_props, "ssao_distance")
+ col.template_override_property(collection_props, scene_props, "ssao_attenuation")
+ col.template_override_property(collection_props, scene_props, "hair_brightness_randomness")
+
+
+class COLLECTION_PT_object_mode_settings(CollectionButtonsPanel, Panel):
+ bl_label = "Object Mode Settings"
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.object
+ return ob and (ob.mode == 'OBJECT')
+
+ def draw(self, context):
+ layout = self.layout
+ scene_props = context.scene.collection_properties['ObjectMode']
+ collection = context.layer_collection
+ collection_props = collection.engine_overrides['ObjectMode']
+
+ col = layout.column()
+ col.template_override_property(collection_props, scene_props, "show_wire")
+ col.template_override_property(collection_props, scene_props, "show_backface_culling")
+
+
+class COLLECTION_PT_edit_mode_settings(CollectionButtonsPanel, Panel):
+ bl_label = "Edit Mode Settings"
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.object
+ return ob and (ob.mode == 'EDIT')
+
+ def draw(self, context):
+ layout = self.layout
+ scene_props = context.scene.collection_properties['EditMode']
+ collection = context.layer_collection
+ collection_props = collection.engine_overrides['EditMode']
+
+ col = layout.column()
+ col.template_override_property(collection_props, scene_props, "show_occlude_wire")
+ col.template_override_property(collection_props, scene_props, "backwire_opacity")
+ col.template_override_property(collection_props, scene_props, "face_normals_show")
+ col.template_override_property(collection_props, scene_props, "vert_normals_show")
+ col.template_override_property(collection_props, scene_props, "loop_normals_show")
+ col.template_override_property(collection_props, scene_props, "normals_length")
+ col.template_override_property(collection_props, scene_props, "show_weight")
+
+
+class COLLECTION_PT_paint_weight_mode_settings(CollectionButtonsPanel, Panel):
+ bl_label = "Weight Paint Mode Settings"
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.object
+ return ob and (ob.mode == 'WEIGHT_PAINT')
+
+ def draw(self, context):
+ layout = self.layout
+ scene_props = context.scene.collection_properties['WeightPaintMode']
+ collection = context.layer_collection
+ collection_props = collection.engine_overrides['WeightPaintMode']
+
+ col = layout.column()
+ col.template_override_property(collection_props, scene_props, "use_shading")
+ col.template_override_property(collection_props, scene_props, "use_wire")
+
+
+class COLLECTION_PT_paint_vertex_mode_settings(CollectionButtonsPanel, Panel):
+ bl_label = "Vertex Paint Mode Settings"
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.object
+ return ob and (ob.mode == 'VERTEX_PAINT')
+
+ def draw(self, context):
+ layout = self.layout
+ scene_props = context.scene.collection_properties['VertexPaintMode']
+ collection = context.layer_collection
+ collection_props = collection.engine_overrides['VertexPaintMode']
+
+ col = layout.column()
+ col.template_override_property(collection_props, scene_props, "use_shading")
+ col.template_override_property(collection_props, scene_props, "use_wire")
+
+
+classes = (
+ COLLECTION_PT_context_collection,
+ COLLECTION_PT_clay_settings,
+ COLLECTION_PT_object_mode_settings,
+ COLLECTION_PT_edit_mode_settings,
+ COLLECTION_PT_paint_weight_mode_settings,
+ COLLECTION_PT_paint_vertex_mode_settings,
+)
+
+if __name__ == "__main__": # only for live edit.
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 8d3ab24b4cf..ee159adfcef 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -324,7 +324,7 @@ class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from
class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Armature
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 132c355ed99..e6a2a266e08 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -438,7 +438,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel):
class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone
@property
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 14286045704..e0b92555735 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -37,7 +37,7 @@ class CAMERA_MT_presets(Menu):
bl_label = "Camera Presets"
preset_subdir = "camera"
preset_operator = "script.execute_preset"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
draw = Menu.draw_preset
@@ -45,14 +45,14 @@ class SAFE_AREAS_MT_presets(Menu):
bl_label = "Camera Presets"
preset_subdir = "safe_areas"
preset_operator = "script.execute_preset"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
draw = Menu.draw_preset
class DATA_PT_context_camera(CameraButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -72,7 +72,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel):
class DATA_PT_lens(CameraButtonsPanel, Panel):
bl_label = "Lens"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -114,7 +114,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
sub = row.column(align=True)
sub.prop(ccam, "longitude_min")
sub.prop(ccam, "longitude_max")
- elif engine == 'BLENDER_RENDER':
+ elif engine in {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}:
row = col.row()
if cam.lens_unit == 'MILLIMETERS':
row.prop(cam, "lens")
@@ -137,7 +137,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
bl_label = "Stereoscopy"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -183,7 +183,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
class DATA_PT_camera(CameraButtonsPanel, Panel):
bl_label = "Camera"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -217,7 +217,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
bl_label = "Depth of Field"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -234,20 +234,30 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
sub.active = (cam.dof_object is None)
sub.prop(cam, "dof_distance", text="Distance")
- hq_support = dof_options.is_hq_supported
- col = split.column(align=True)
- col.label("Viewport:")
- sub = col.column()
- sub.active = hq_support
- sub.prop(dof_options, "use_high_quality")
- col.prop(dof_options, "fstop")
- if dof_options.use_high_quality and hq_support:
- col.prop(dof_options, "blades")
+ if context.scene.render.engine == 'BLENDER_EEVEE':
+ col = split.column(align=True)
+ col.label("Aperture:")
+ engine = context.scene.render.engine
+ sub = col.column(align=True)
+ sub.prop(dof_options, "fstop")
+ sub.prop(dof_options, "blades")
+ sub.prop(dof_options, "rotation")
+ sub.prop(dof_options, "ratio")
+ else:
+ hq_support = dof_options.is_hq_supported
+ col = split.column(align=True)
+ col.label("Viewport:")
+ sub = col.column()
+ sub.active = hq_support
+ sub.prop(dof_options, "use_high_quality")
+ col.prop(dof_options, "fstop")
+ if dof_options.use_high_quality and hq_support:
+ col.prop(dof_options, "blades")
class DATA_PT_camera_display(CameraButtonsPanel, Panel):
bl_label = "Display"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -277,7 +287,7 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel):
class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel):
bl_label = "Safe Areas"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw_header(self, context):
cam = context.camera
@@ -293,7 +303,7 @@ class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel):
class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Camera
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 3a3ad31a8ef..6fb147007e6 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -136,7 +136,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel):
bl_label = "Texture Space"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -427,7 +427,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel):
class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Curve
diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index 98aa31ac915..d60354b4bec 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -26,7 +26,7 @@ class LAMP_MT_sunsky_presets(Menu):
bl_label = "Sun & Sky Presets"
preset_subdir = "sunsky"
preset_operator = "script.execute_preset"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
draw = Menu.draw_preset
@@ -44,7 +44,7 @@ class DataButtonsPanel:
class DATA_PT_context_lamp(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -68,7 +68,7 @@ class DATA_PT_context_lamp(DataButtonsPanel, Panel):
class DATA_PT_preview(DataButtonsPanel, Panel):
bl_label = "Preview"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
self.layout.template_preview(context.lamp)
@@ -76,7 +76,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel):
class DATA_PT_lamp(DataButtonsPanel, Panel):
bl_label = "Lamp"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -96,6 +96,7 @@ class DATA_PT_lamp(DataButtonsPanel, Panel):
sub.label(text="Falloff:")
sub.prop(lamp, "falloff_type", text="")
sub.prop(lamp, "distance")
+ sub.prop(lamp, "shadow_soft_size", text="Radius")
if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED':
col.label(text="Attenuation Factors:")
@@ -312,7 +313,7 @@ class DATA_PT_shadow(DataButtonsPanel, Panel):
class DATA_PT_area(DataButtonsPanel, Panel):
bl_label = "Area Shape"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -338,7 +339,7 @@ class DATA_PT_area(DataButtonsPanel, Panel):
class DATA_PT_spot(DataButtonsPanel, Panel):
bl_label = "Spot Shape"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -374,7 +375,7 @@ class DATA_PT_spot(DataButtonsPanel, Panel):
class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
bl_label = "Falloff Curve"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -390,7 +391,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Lamp
diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py
index 4b3fd48c195..34cb323a8cb 100644
--- a/release/scripts/startup/bl_ui/properties_data_lattice.py
+++ b/release/scripts/startup/bl_ui/properties_data_lattice.py
@@ -78,7 +78,7 @@ class DATA_PT_lattice(DataButtonsPanel, Panel):
class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Lattice
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index de55b4152ba..4d00b70a0fa 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -24,7 +24,7 @@ from rna_prop_ui import PropertyPanel
class MESH_MT_vertex_group_specials(Menu):
bl_label = "Vertex Group Specials"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -48,7 +48,7 @@ class MESH_MT_vertex_group_specials(Menu):
class MESH_MT_shape_key_specials(Menu):
bl_label = "Shape Key Specials"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -76,6 +76,17 @@ class MESH_UL_vgroups(UIList):
layout.label(text="", icon_value=icon)
+class MESH_UL_fmaps(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.FaceMap))
+ fmap = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.prop(fmap, "name", text="", emboss=False, icon_value=icon)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
class MESH_UL_shape_keys(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.ShapeKey))
@@ -126,7 +137,7 @@ class MeshButtonsPanel:
class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -143,7 +154,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
class DATA_PT_normals(MeshButtonsPanel, Panel):
bl_label = "Normals"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -164,7 +175,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel):
class DATA_PT_texture_space(MeshButtonsPanel, Panel):
bl_label = "Texture Space"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -183,7 +194,7 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel):
class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
bl_label = "Vertex Groups"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -227,9 +238,50 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
+class DATA_PT_face_maps(MeshButtonsPanel, Panel):
+ bl_label = "Face Maps"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.type == 'MESH')
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ facemap = ob.face_maps.active
+
+ rows = 2
+ if facemap:
+ rows = 4
+
+ row = layout.row()
+ row.template_list("MESH_UL_fmaps", "", ob, "face_maps", ob.face_maps, "active_index", rows=rows)
+
+ col = row.column(align=True)
+ col.operator("object.face_map_add", icon='ZOOMIN', text="")
+ col.operator("object.face_map_remove", icon='ZOOMOUT', text="")
+ if facemap:
+ col.separator()
+ col.operator("object.face_map_move", icon='TRIA_UP', text="").direction = 'UP'
+ col.operator("object.face_map_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+
+ if ob.face_maps and (ob.mode == 'EDIT' and ob.type == 'MESH'):
+ row = layout.row()
+
+ sub = row.row(align=True)
+ sub.operator("object.face_map_assign", text="Assign")
+ sub.operator("object.face_map_remove_from", text="Remove")
+
+ sub = row.row(align=True)
+ sub.operator("object.face_map_select", text="Select")
+ sub.operator("object.face_map_deselect", text="Deselect")
+
class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
bl_label = "Shape Keys"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -322,7 +374,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
bl_label = "UV Maps"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -332,7 +384,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=1)
+ col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_layers", me.uv_layers, "active_index", rows=1)
col = row.column(align=True)
col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
@@ -341,7 +393,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
bl_label = "Vertex Colors"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -361,7 +413,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
class DATA_PT_customdata(MeshButtonsPanel, Panel):
bl_label = "Geometry Data"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -387,7 +439,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Mesh
@@ -396,12 +448,14 @@ classes = (
MESH_MT_vertex_group_specials,
MESH_MT_shape_key_specials,
MESH_UL_vgroups,
+ MESH_UL_fmaps,
MESH_UL_shape_keys,
MESH_UL_uvmaps_vcols,
DATA_PT_context_mesh,
DATA_PT_normals,
DATA_PT_texture_space,
DATA_PT_vertex_groups,
+ DATA_PT_face_maps,
DATA_PT_shape_keys,
DATA_PT_uv_texture,
DATA_PT_vertex_colors,
diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py
index dd62c4523b1..e771caf49e3 100644
--- a/release/scripts/startup/bl_ui/properties_data_metaball.py
+++ b/release/scripts/startup/bl_ui/properties_data_metaball.py
@@ -76,7 +76,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel):
class DATA_PT_mball_texture_space(DataButtonsPanel, Panel):
bl_label = "Texture Space"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -131,7 +131,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel):
class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.MetaBall
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index d72855fab6b..05321ee4486 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -355,7 +355,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "texture_coords_object", text="")
elif md.texture_coords == 'UV' and ob.type == 'MESH':
col.label(text="UV Map:")
- col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
+ col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="")
layout.separator()
@@ -387,7 +387,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
sub.active = bool(md.vertex_group)
sub.prop(md, "protect")
col.label(text="Particle UV")
- col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
+ col.prop_search(md, "particle_uv", ob.data, "uv_layers", text="")
col = split.column()
col.prop(md, "use_edge_cut")
@@ -985,11 +985,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.label(text="UV Map:")
- col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
+ col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="")
split = layout.split()
col = split.column()
- col.prop(md, "use_image_override")
col.prop(md, "projector_count", text="Projectors")
for proj in md.projectors:
col.prop(proj, "object", text="")
@@ -1043,7 +1042,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
if md.texture_coords == 'OBJECT':
layout.prop(md, "texture_coords_object", text="Object")
elif md.texture_coords == 'UV' and ob.type == 'MESH':
- layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
+ layout.prop_search(md, "uv_layer", ob.data, "uv_layers")
def WAVE(self, layout, ob, md):
split = layout.split()
@@ -1089,7 +1088,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.template_ID(md, "texture", new="texture.new")
layout.prop(md, "texture_coords")
if md.texture_coords == 'UV' and ob.type == 'MESH':
- layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
+ layout.prop_search(md, "uv_layer", ob.data, "uv_layers")
elif md.texture_coords == 'OBJECT':
layout.prop(md, "texture_coords_object")
@@ -1156,7 +1155,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
if md.mask_tex_mapping == 'OBJECT':
layout.prop(md, "mask_tex_map_object", text="Object")
elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
- layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
+ layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_layers")
def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
split = layout.split()
@@ -1325,7 +1324,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.label(text="UV Map:")
- col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
+ col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="")
def WIREFRAME(self, layout, ob, md):
has_vgroup = bool(md.vertex_group)
diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py
index eecb2690302..5ed9ce0478c 100644
--- a/release/scripts/startup/bl_ui/properties_data_speaker.py
+++ b/release/scripts/startup/bl_ui/properties_data_speaker.py
@@ -36,7 +36,7 @@ class DataButtonsPanel:
class DATA_PT_context_speaker(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -55,7 +55,7 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel):
class DATA_PT_speaker(DataButtonsPanel, Panel):
bl_label = "Sound"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -74,7 +74,7 @@ class DATA_PT_speaker(DataButtonsPanel, Panel):
class DATA_PT_distance(DataButtonsPanel, Panel):
bl_label = "Distance"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -97,7 +97,7 @@ class DATA_PT_distance(DataButtonsPanel, Panel):
class DATA_PT_cone(DataButtonsPanel, Panel):
bl_label = "Cone"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -117,7 +117,7 @@ class DATA_PT_cone(DataButtonsPanel, Panel):
class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object.data"
_property_type = bpy.types.Speaker
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index 636a9707ab9..7f33041e338 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -422,10 +422,8 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
col = row.column()
col.prop(gs, "use_frame_rate")
col.prop(gs, "use_restrict_animation_updates")
- col.prop(gs, "use_material_caching")
col = row.column()
- col.prop(gs, "use_display_lists")
- col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
+ col.prop(gs, "use_material_caching")
row = layout.row()
row.prop(gs, "vsync")
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index dc82bb0d69b..efdd22c5d0c 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
from bpy.app.translations import pgettext_iface as iface_
-
+from bpy_extras.node_utils import find_node_input, find_output_node
def active_node_mat(mat):
# TODO, 2.4x has a pipeline section, for 2.5 we need to communicate
@@ -745,7 +745,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, Panel):
col.prop(tan, "width_fade")
ob = context.object
if ob and ob.type == 'MESH':
- col.prop_search(tan, "uv_layer", ob.data, "uv_textures", text="")
+ col.prop_search(tan, "uv_layer", ob.data, "uv_layers", text="")
else:
col.prop(tan, "uv_layer", text="")
col.separator()
@@ -794,11 +794,6 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel):
row.prop(mat, "use_light_group_local", text="Local")
col = split.column()
- col.prop(mat, "use_face_texture")
- sub = col.column()
- sub.active = mat.use_face_texture
- sub.prop(mat, "use_face_texture_alpha")
- col.separator()
col.prop(mat, "use_vertex_color_paint")
col.prop(mat, "use_vertex_color_light")
col.prop(mat, "use_object_color")
@@ -806,6 +801,9 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel):
if simple_material(base_mat):
col.prop(mat, "pass_index")
+ col.label("Edit Image")
+ col.template_ID(mat, "edit_image")
+
class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel):
bl_label = "Shadow"
@@ -1054,6 +1052,120 @@ class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel):
_property_type = bpy.types.Material
+class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
+ bl_label = ""
+ bl_context = "material"
+ bl_options = {'HIDE_HEADER'}
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ engine = context.scene.render.engine
+ return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+
+ mat = context.material
+ ob = context.object
+ slot = context.material_slot
+ space = context.space_data
+
+ if ob:
+ is_sortable = len(ob.material_slots) > 1
+ rows = 1
+ if (is_sortable):
+ rows = 4
+
+ row = layout.row()
+
+ row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
+
+ col = row.column(align=True)
+ col.operator("object.material_slot_add", icon='ZOOMIN', text="")
+ col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
+
+ col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
+
+ if is_sortable:
+ col.separator()
+
+ col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
+ col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+
+ if ob.mode == 'EDIT':
+ row = layout.row(align=True)
+ row.operator("object.material_slot_assign", text="Assign")
+ row.operator("object.material_slot_select", text="Select")
+ row.operator("object.material_slot_deselect", text="Deselect")
+
+ split = layout.split(percentage=0.65)
+
+ if ob:
+ split.template_ID(ob, "active_material", new="material.new")
+ row = split.row()
+
+ if slot:
+ row.prop(slot, "link", text="")
+ else:
+ row.label()
+ elif mat:
+ split.template_ID(space, "pin_id")
+ split.separator()
+
+
+def panel_node_draw(layout, ntree, output_type):
+ node = find_output_node(ntree, output_type)
+
+ if node:
+ def display_input(layout, ntree, node, input_name):
+ input = find_node_input(node, input_name)
+ layout.template_node_view(ntree, node, input)
+
+ display_input(layout, ntree, node, 'Base Color')
+ if output_type == 'OUTPUT_METALLIC':
+ display_input(layout, ntree, node, 'Metallic')
+ display_input(layout, ntree, node, 'Specular')
+ display_input(layout, ntree, node, 'Roughness')
+ display_input(layout, ntree, node, 'Emissive Color')
+ display_input(layout, ntree, node, 'Transparency')
+ display_input(layout, ntree, node, 'Normal')
+ display_input(layout, ntree, node, 'Ambient Occlusion')
+ return True
+
+ return False
+
+
+class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
+ bl_label = "Surface"
+ bl_context = "material"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ engine = context.scene.render.engine
+ return context.material and (engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+
+ mat = context.material
+
+ layout.prop(mat, "use_nodes", icon='NODETREE')
+ layout.separator()
+
+ if mat.use_nodes:
+ if not panel_node_draw(layout, mat.node_tree, 'OUTPUT_METALLIC'):
+ if not panel_node_draw(layout, mat.node_tree, 'OUTPUT_SPECULAR'):
+ layout.label(text="No output node")
+ else:
+ raym = mat.raytrace_mirror
+ layout.prop(mat, "diffuse_color", text="Base Color")
+ layout.prop(raym, "reflect_factor", text="Metallic")
+ layout.prop(mat, "specular_intensity", text="Specular")
+ layout.prop(raym, "gloss_factor", text="Roughness")
+
+
classes = (
MATERIAL_MT_sss_presets,
MATERIAL_MT_specials,
@@ -1082,6 +1194,8 @@ classes = (
MATERIAL_PT_volume_integration,
MATERIAL_PT_volume_options,
MATERIAL_PT_custom_props,
+ EEVEE_MATERIAL_PT_context_material,
+ EEVEE_MATERIAL_PT_surface,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 43c8300b558..5311e893773 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -362,7 +362,7 @@ class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit fr
class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "object"
_property_type = bpy.types.Object
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index dfd20d90ec4..91f4239c067 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -96,8 +96,8 @@ class VIEW3D_MT_tools_projectpaint_clone(Menu):
def draw(self, context):
layout = self.layout
- for i, tex in enumerate(context.active_object.data.uv_textures):
- props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
+ for i, uv_layer in enumerate(context.active_object.data.uv_layers):
+ props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False)
props.data_path = "active_object.data.uv_texture_clone_index"
props.value = i
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 23e7c0a6787..c9012e46698 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -66,7 +66,7 @@ def particle_get_settings(context):
class PARTICLE_MT_specials(Menu):
bl_label = "Particle Specials"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -86,7 +86,7 @@ class PARTICLE_MT_hair_dynamics_presets(Menu):
bl_label = "Hair Dynamics Presets"
preset_subdir = "hair_dynamics"
preset_operator = "script.execute_preset"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
draw = Menu.draw_preset
@@ -131,7 +131,7 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList):
class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -238,7 +238,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
bl_label = "Emission"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -314,7 +314,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
bl_label = "Hair Dynamics"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -412,7 +412,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
bl_label = "Cache"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -442,7 +442,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
bl_label = "Velocity"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -493,7 +493,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
bl_label = "Rotation"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -556,7 +556,7 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
bl_label = "Physics"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -796,7 +796,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
bl_label = "Boid Brain"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -899,7 +899,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
bl_label = "Render"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -1058,8 +1058,8 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
if psys:
col = layout.column()
- col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_textures")
- col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_textures")
+ col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_layers")
+ col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_layers")
split = layout.split(percentage=0.33)
split.label(text="Split UVs:")
@@ -1068,7 +1068,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
if psys:
col = layout.column()
col.active = part.billboard_uv_split > 1
- col.prop_search(psys, "billboard_split_uv", ob.data, "uv_textures")
+ col.prop_search(psys, "billboard_split_uv", ob.data, "uv_layers")
row = col.row()
row.label(text="Animate:")
@@ -1098,7 +1098,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
bl_label = "Display"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -1161,7 +1161,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
bl_label = "Children"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -1290,7 +1290,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel):
bl_label = "Field Weights"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -1311,7 +1311,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel):
class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel):
bl_label = "Force Field Settings"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -1345,7 +1345,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel):
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
bl_label = "Vertex Groups"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -1411,7 +1411,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "particle_system.settings"
_property_type = bpy.types.ParticleSettings
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index 0a7890670b2..6ada3c59942 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -64,6 +64,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
split = layout.split(percentage=0.25)
+ col = split.column()
+
split.label(text="Presets:")
sub = split.row(align=True)
sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label)
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
index cf1d4f38038..538022a0fcf 100644
--- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
@@ -276,7 +276,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
# image format outputs
if surface.surface_format == 'IMAGE':
layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
- layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV Map")
+ layout.prop_search(surface, "uv_layer", ob.data, "uv_layers", text="UV Map")
layout.separator()
layout.prop(surface, "image_output_path", text="")
@@ -337,7 +337,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
elif surface.init_color_type == 'TEXTURE':
layout.prop(surface, "init_texture")
- layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map")
+ layout.prop_search(surface, "init_layername", ob.data, "uv_layers", text="UV Map")
elif surface.init_color_type == 'VERTEX_COLOR':
layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer")
diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index 3fd47f0b8ca..bb15ba5e189 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -39,7 +39,7 @@ class PhysicButtonsPanel:
class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
bl_label = "Force Fields"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -177,7 +177,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
bl_label = "Collision"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index 4f0d3680834..bf070bf6acb 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -158,7 +158,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel):
sub.label(text="Mapping:")
sub.prop(flow, "texture_map_type", expand=False, text="")
if flow.texture_map_type == 'UV':
- sub.prop_search(flow, "uv_layer", ob.data, "uv_textures", text="")
+ sub.prop_search(flow, "uv_layer", ob.data, "uv_layers", text="")
if flow.texture_map_type == 'AUTO':
sub.prop(flow, "texture_size")
sub.prop(flow, "texture_offset")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index a7e8d9273ad..ad210498126 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -584,6 +584,91 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
sub.prop(rd, "bake_user_scale", text="User Scale")
+class RENDER_PT_clay_layer_settings(RenderButtonsPanel, Panel):
+ bl_label = "Clay Layer Settings"
+ COMPAT_ENGINES = {'BLENDER_CLAY'}
+
+ def draw(self, context):
+ layout = self.layout
+ props = context.scene.layer_properties['BLENDER_CLAY']
+
+ col = layout.column()
+ col.prop(props, "ssao_samples")
+
+
+class RENDER_PT_clay_collection_settings(RenderButtonsPanel, Panel):
+ bl_label = "Clay Collection Settings"
+ COMPAT_ENGINES = {'BLENDER_CLAY'}
+
+ def draw(self, context):
+ layout = self.layout
+ props = context.scene.collection_properties['BLENDER_CLAY']
+
+ col = layout.column()
+ col.template_icon_view(props, "matcap_icon")
+ col.prop(props, "matcap_rotation")
+ col.prop(props, "matcap_hue")
+ col.prop(props, "matcap_saturation")
+ col.prop(props, "matcap_value")
+ col.prop(props, "ssao_factor_cavity")
+ col.prop(props, "ssao_factor_edge")
+ col.prop(props, "ssao_distance")
+ col.prop(props, "ssao_attenuation")
+ col.prop(props, "hair_brightness_randomness")
+
+class RENDER_PT_eevee_poststack_settings(RenderButtonsPanel, Panel):
+ bl_label = "Post Process Stack"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ props = scene.layer_properties['BLENDER_EEVEE']
+
+ col = layout.column()
+ col.prop(props, "motion_blur_enable")
+ col.prop(props, "dof_enable")
+ col.prop(props, "bloom_enable")
+
+
+class RENDER_PT_eevee_postprocess_settings(RenderButtonsPanel, Panel):
+ bl_label = "Post Process Settings"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ props = scene.layer_properties['BLENDER_EEVEE']
+
+ col = layout.column()
+
+ col.label("Motion Blur:")
+ col.prop(props, "motion_blur_samples")
+ col.prop(props, "motion_blur_shutter")
+ col.separator()
+
+ col.label("Depth of Field:")
+ col.prop(props, "bokeh_max_size")
+ col.prop(props, "bokeh_threshold")
+ col.separator()
+
+ col.label("Bloom:")
+ col.prop(props, "bloom_threshold")
+ col.prop(props, "bloom_knee")
+ col.prop(props, "bloom_radius")
+ col.prop(props, "bloom_intensity")
+
+
classes = (
RENDER_MT_presets,
RENDER_MT_ffmpeg_presets,
@@ -599,6 +684,10 @@ classes = (
RENDER_PT_output,
RENDER_PT_encoding,
RENDER_PT_bake,
+ RENDER_PT_clay_layer_settings,
+ RENDER_PT_clay_collection_settings,
+ RENDER_PT_eevee_poststack_settings,
+ RENDER_PT_eevee_postprocess_settings,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index 084bc387822..fb52fdf5fa0 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -35,7 +35,7 @@ class RenderLayerButtonsPanel:
class RENDERLAYER_UL_renderlayers(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
- # assert(isinstance(item, bpy.types.SceneRenderLayer)
+ # assert(isinstance(item, bpy.types.SceneLayer)
layer = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(layer, "name", text="", icon_value=icon, emboss=False)
@@ -48,7 +48,7 @@ class RENDERLAYER_UL_renderlayers(UIList):
class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
bl_label = "Layer List"
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -62,7 +62,7 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
+ col.template_list("RENDERLAYER_UL_renderlayers", "", scene, "render_layers", scene.render_layers, "active_index", rows=2)
col = row.column()
sub = col.column(align=True)
@@ -71,103 +71,6 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
col.prop(rd, "use_single_layer", icon_only=True)
-class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel):
- bl_label = "Layer"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- rd = scene.render
- rl = rd.layers.active
-
- split = layout.split()
-
- col = split.column()
- col.prop(scene, "layers", text="Scene")
- col.label(text="")
- col.prop(rl, "light_override", text="Lights")
- col.prop(rl, "material_override", text="Material")
-
- col = split.column()
- col.prop(rl, "layers", text="Layer")
- col.prop(rl, "layers_zmask", text="Mask Layer")
-
- layout.separator()
- layout.label(text="Include:")
-
- split = layout.split()
-
- col = split.column()
- col.prop(rl, "use_zmask")
- row = col.row()
- row.prop(rl, "invert_zmask", text="Negate")
- row.active = rl.use_zmask
- col.prop(rl, "use_all_z")
-
- col = split.column()
- col.prop(rl, "use_solid")
- col.prop(rl, "use_halo")
- col.prop(rl, "use_ztransp")
-
- col = split.column()
- col.prop(rl, "use_sky")
- col.prop(rl, "use_edge_enhance")
- col.prop(rl, "use_strand")
- if bpy.app.build_options.freestyle:
- row = col.row()
- row.prop(rl, "use_freestyle")
- row.active = rd.use_freestyle
-
-
-class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel):
- bl_label = "Passes"
- bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- @staticmethod
- def draw_pass_type_buttons(box, rl, pass_type):
- # property names
- use_pass_type = "use_pass_" + pass_type
- exclude_pass_type = "exclude_" + pass_type
- # draw pass type buttons
- row = box.row()
- row.prop(rl, use_pass_type)
- row.prop(rl, exclude_pass_type, text="")
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- rd = scene.render
- rl = rd.layers.active
-
- split = layout.split()
-
- col = split.column()
- col.prop(rl, "use_pass_combined")
- col.prop(rl, "use_pass_z")
- col.prop(rl, "use_pass_vector")
- col.prop(rl, "use_pass_normal")
- col.prop(rl, "use_pass_uv")
- col.prop(rl, "use_pass_mist")
- col.prop(rl, "use_pass_object_index")
- col.prop(rl, "use_pass_material_index")
- col.prop(rl, "use_pass_color")
-
- col = split.column()
- col.prop(rl, "use_pass_diffuse")
- self.draw_pass_type_buttons(col, rl, "specular")
- self.draw_pass_type_buttons(col, rl, "shadow")
- self.draw_pass_type_buttons(col, rl, "emit")
- self.draw_pass_type_buttons(col, rl, "ambient_occlusion")
- self.draw_pass_type_buttons(col, rl, "environment")
- self.draw_pass_type_buttons(col, rl, "indirect")
- self.draw_pass_type_buttons(col, rl, "reflection")
- self.draw_pass_type_buttons(col, rl, "refraction")
-
-
class RENDERLAYER_UL_renderviews(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.SceneRenderView)
@@ -186,7 +89,7 @@ class RENDERLAYER_UL_renderviews(UIList):
class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel):
bl_label = "Views"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
@@ -227,13 +130,90 @@ class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel):
row.prop(rv, "camera_suffix", text="")
+class RENDERLAYER_PT_clay_settings(RenderLayerButtonsPanel, Panel):
+ bl_label = "Render Settings"
+ COMPAT_ENGINES = {'BLENDER_CLAY'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ scene_props = scene.layer_properties['BLENDER_CLAY']
+ layer = bpy.context.render_layer
+ layer_props = layer.engine_overrides['BLENDER_CLAY']
+
+ col = layout.column()
+ col.template_override_property(layer_props, scene_props, "ssao_samples")
+
+
+class RENDERLAYER_PT_eevee_poststack_settings(RenderLayerButtonsPanel, Panel):
+ bl_label = "Post Process Stack"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ scene_props = scene.layer_properties['BLENDER_EEVEE']
+ layer = bpy.context.render_layer
+ layer_props = layer.engine_overrides['BLENDER_EEVEE']
+
+ col = layout.column()
+ col.template_override_property(layer_props, scene_props, "motion_blur_enable")
+ col.template_override_property(layer_props, scene_props, "dof_enable")
+ col.template_override_property(layer_props, scene_props, "bloom_enable")
+
+
+class RENDERLAYER_PT_eevee_postprocess_settings(RenderLayerButtonsPanel, Panel):
+ bl_label = "Post Process Settings"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ scene_props = scene.layer_properties['BLENDER_EEVEE']
+ layer = bpy.context.render_layer
+ layer_props = layer.engine_overrides['BLENDER_EEVEE']
+
+ col = layout.column()
+ col.label("Motion Blur:")
+ col.template_override_property(layer_props, scene_props, "motion_blur_samples")
+ col.template_override_property(layer_props, scene_props, "motion_blur_shutter")
+ col.separator()
+
+ col.label("Depth of Field:")
+ col.template_override_property(layer_props, scene_props, "bokeh_max_size")
+ col.template_override_property(layer_props, scene_props, "bokeh_threshold")
+ col.separator()
+
+ col.label("Bloom:")
+ col.template_override_property(layer_props, scene_props, "bloom_threshold")
+ col.template_override_property(layer_props, scene_props, "bloom_knee")
+ col.template_override_property(layer_props, scene_props, "bloom_radius")
+ col.template_override_property(layer_props, scene_props, "bloom_intensity")
+
+
classes = (
RENDERLAYER_UL_renderlayers,
RENDERLAYER_PT_layers,
- RENDERLAYER_PT_layer_options,
- RENDERLAYER_PT_layer_passes,
RENDERLAYER_UL_renderviews,
RENDERLAYER_PT_views,
+ RENDERLAYER_PT_clay_settings,
+ RENDERLAYER_PT_eevee_poststack_settings,
+ RENDERLAYER_PT_eevee_postprocess_settings,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index fb93c0b56f2..8c65ed2b78a 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -66,7 +66,7 @@ class SceneButtonsPanel:
class SCENE_PT_scene(SceneButtonsPanel, Panel):
bl_label = "Scene"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -81,7 +81,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel):
class SCENE_PT_unit(SceneButtonsPanel, Panel):
bl_label = "Units"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -166,7 +166,7 @@ class SceneKeyingSetsPanel:
class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
bl_label = "Keying Sets"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -199,7 +199,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
bl_label = "Active Keying Set"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
def poll(cls, context):
@@ -256,7 +256,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
class SCENE_PT_color_management(SceneButtonsPanel, Panel):
bl_label = "Color Management"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -281,7 +281,7 @@ class SCENE_PT_color_management(SceneButtonsPanel, Panel):
class SCENE_PT_audio(SceneButtonsPanel, Panel):
bl_label = "Audio"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@@ -409,7 +409,7 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel):
class SCENE_PT_simplify(SceneButtonsPanel, Panel):
bl_label = "Simplify"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw_header(self, context):
rd = context.scene.render
@@ -439,7 +439,7 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel):
class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "scene"
_property_type = bpy.types.Scene
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index 880684997bf..a9857a618c8 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -963,7 +963,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
split.label(text="Map:")
ob = context.object
if ob and ob.type == 'MESH':
- split.prop_search(tex, "uv_layer", ob.data, "uv_textures", text="")
+ split.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="")
else:
split.prop(tex, "uv_layer", text="")
diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py
index 107c31567b3..c7bf318faef 100644
--- a/release/scripts/startup/bl_ui/properties_world.py
+++ b/release/scripts/startup/bl_ui/properties_world.py
@@ -20,6 +20,7 @@
import bpy
from bpy.types import Panel
from rna_prop_ui import PropertyPanel
+from bpy_extras.node_utils import find_node_input, find_output_node
class WorldButtonsPanel:
@@ -249,6 +250,37 @@ class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel):
_property_type = bpy.types.World
+class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel):
+ bl_label = "Surface"
+ bl_context = "world"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ engine = context.scene.render.engine
+ return context.world and (engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+
+ world = context.world
+
+ layout.prop(world, "use_nodes", icon='NODETREE')
+ layout.separator()
+
+ if world.use_nodes:
+ ntree = world.node_tree
+ node = find_output_node(ntree, 'OUTPUT_WORLD')
+
+ if not node:
+ layout.label(text="No output node")
+ else:
+ input = find_node_input(node, 'Surface')
+ layout.template_node_view(ntree, node, input)
+ else:
+ layout.prop(world, "horizon_color", text="Color")
+
+
classes = (
WORLD_PT_context_world,
WORLD_PT_preview,
@@ -259,6 +291,7 @@ classes = (
WORLD_PT_gather,
WORLD_PT_mist,
WORLD_PT_custom_props,
+ EEVEE_WORLD_PT_surface,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index f070161f3da..eeb32a32066 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -481,7 +481,7 @@ class IMAGE_HT_header(Header):
row.prop(toolsettings, "snap_target", text="")
mesh = context.edit_object.data
- layout.prop_search(mesh.uv_textures, "active", mesh, "uv_textures", text="")
+ layout.prop_search(mesh.uv_layers, "active", mesh, "uv_layers", text="")
if ima:
if ima.is_stereo_3d:
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index a7b518dfd2e..90168429724 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -40,7 +40,7 @@ class INFO_HT_header(Header):
layout.operator("screen.back_to_previous", icon='SCREEN_BACK', text="Back to Previous")
layout.separator()
else:
- layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete")
+ layout.template_ID_preview(context.window, "screen", new="screen.new", unlink="screen.delete", rows=2, cols=6)
layout.template_ID(context.screen, "scene", new="scene.new", unlink="scene.delete")
layout.separator()
@@ -69,7 +69,7 @@ class INFO_HT_header(Header):
return
row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
- row.label(text=scene.statistics(), translate=False)
+ row.label(text=scene.statistics(context.render_layer), translate=False)
class INFO_MT_editor_menus(Menu):
@@ -293,7 +293,7 @@ class INFO_MT_window(Menu):
layout = self.layout
- layout.operator("wm.window_duplicate")
+ layout.operator("wm.window_new")
layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER')
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index b37b3c5705a..2021a69059b 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -395,8 +395,7 @@ class NODE_PT_backdrop(Panel):
col = layout.column(align=True)
col.label(text="Offset:")
- col.prop(snode, "backdrop_x", text="X")
- col.prop(snode, "backdrop_y", text="Y")
+ col.prop(snode, "backdrop_offset", text="")
col.operator("node.backimage_move", text="Move")
layout.operator("node.backimage_fit", text="Fit")
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 4eb550bbb35..054a955ab9c 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -60,6 +60,16 @@ class OUTLINER_HT_header(Header):
elif space.display_mode == 'ORPHAN_DATA':
layout.operator("outliner.orphans_purge")
+ elif space.display_mode in {'ACT_LAYER', 'MASTER_COLLECTION'}:
+ row = layout.row(align=True)
+
+ row.operator("outliner.collection_new", text="", icon='NEW')
+ if space.display_mode == 'ACT_LAYER':
+ row.operator("outliner.collection_override_new", text="", icon='LINK_AREA')
+ row.operator("outliner.collection_link", text="", icon='LINKED')
+ row.operator("outliner.collection_unlink", text="", icon='UNLINKED')
+ row.operator("outliner.collections_delete", text="", icon='X')
+
class OUTLINER_MT_editor_menus(Menu):
bl_idname = "OUTLINER_MT_editor_menus"
@@ -88,7 +98,8 @@ class OUTLINER_MT_view(Menu):
space = context.space_data
if space.display_mode not in {'DATABLOCKS', 'USER_PREFERENCES', 'KEYMAPS'}:
- layout.prop(space, "use_sort_alpha")
+ if space.display_mode not in {'ACT_LAYER', 'MASTER_COLLECTION'}:
+ layout.prop(space, "use_sort_alpha")
layout.prop(space, "show_restrict_columns")
layout.separator()
layout.operator("outliner.show_active")
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 47c94cefe16..317d621778a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -635,7 +635,6 @@ class VIEW3D_MT_select_object(Menu):
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
layout.operator("object.select_random", text="Random")
layout.operator("object.select_mirror", text="Mirror")
- layout.operator("object.select_by_layer", text="Select All by Layer")
layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
layout.operator("object.select_camera", text="Select Camera")
@@ -1327,15 +1326,6 @@ class VIEW3D_MT_object(Menu):
layout.separator()
- if is_local_view:
- layout.operator_context = 'EXEC_REGION_WIN'
- layout.operator("object.move_to_layer", text="Move out of Local View")
- layout.operator_context = 'INVOKE_REGION_WIN'
- else:
- layout.operator("object.move_to_layer", text="Move to Layer...")
-
- layout.menu("VIEW3D_MT_object_showhide")
-
layout.operator_menu_enum("object.convert", "target")
@@ -1614,17 +1604,6 @@ class VIEW3D_MT_object_quick_effects(Menu):
layout.operator("object.quick_fluid")
-class VIEW3D_MT_object_showhide(Menu):
- bl_label = "Show/Hide"
-
- def draw(self, context):
- layout = self.layout
-
- layout.operator("object.hide_view_clear", text="Show Hidden")
- layout.operator("object.hide_view_set", text="Hide Selected").unselected = False
- layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
-
-
class VIEW3D_MT_make_single_user(Menu):
bl_label = "Make Single User"
@@ -3149,7 +3128,6 @@ class VIEW3D_MT_edit_gpencil_interpolate(Menu):
# ********** Panel **********
-
class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -3358,56 +3336,6 @@ class VIEW3D_PT_view3d_stereo(Panel):
split.prop(view, "stereo_3d_volume_alpha", text="Alpha")
-class VIEW3D_PT_view3d_shading(Panel):
- bl_space_type = 'VIEW_3D'
- bl_region_type = 'UI'
- bl_label = "Shading"
-
- def draw(self, context):
- layout = self.layout
-
- view = context.space_data
- scene = context.scene
- gs = scene.game_settings
- obj = context.object
-
- col = layout.column()
-
- if not scene.render.use_shading_nodes:
- col.prop(gs, "material_mode", text="")
-
- if view.viewport_shade == 'SOLID':
- col.prop(view, "show_textured_solid")
- col.prop(view, "use_matcap")
- if view.use_matcap:
- col.template_icon_view(view, "matcap_icon")
- if view.viewport_shade == 'TEXTURED' or context.mode == 'PAINT_TEXTURE':
- if scene.render.use_shading_nodes or gs.material_mode != 'GLSL':
- col.prop(view, "show_textured_shadeless")
-
- col.prop(view, "show_backface_culling")
-
- if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
- if obj and obj.mode == 'EDIT':
- col.prop(view, "show_occlude_wire")
-
- fx_settings = view.fx_settings
-
- if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
- sub = col.column()
- sub.active = view.region_3d.view_perspective == 'CAMERA'
- sub.prop(fx_settings, "use_dof")
- col.prop(fx_settings, "use_ssao", text="Ambient Occlusion")
- if fx_settings.use_ssao:
- ssao_settings = fx_settings.ssao
- subcol = col.column(align=True)
- subcol.prop(ssao_settings, "factor")
- subcol.prop(ssao_settings, "distance_max")
- subcol.prop(ssao_settings, "attenuation")
- subcol.prop(ssao_settings, "samples")
- subcol.prop(ssao_settings, "color")
-
-
class VIEW3D_PT_view3d_motion_tracking(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -3859,7 +3787,6 @@ classes = (
VIEW3D_MT_object_group,
VIEW3D_MT_object_constraints,
VIEW3D_MT_object_quick_effects,
- VIEW3D_MT_object_showhide,
VIEW3D_MT_make_single_user,
VIEW3D_MT_make_links,
VIEW3D_MT_object_game,
@@ -3927,7 +3854,6 @@ classes = (
VIEW3D_PT_view3d_name,
VIEW3D_PT_view3d_display,
VIEW3D_PT_view3d_stereo,
- VIEW3D_PT_view3d_shading,
VIEW3D_PT_view3d_motion_tracking,
VIEW3D_PT_view3d_meshdisplay,
VIEW3D_PT_view3d_meshstatvis,
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 2e291d3d471..996e351e715 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1174,9 +1174,9 @@ class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
def draw(self, context):
layout = self.layout
- for i, tex in enumerate(context.active_object.data.uv_textures):
- props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
- props.data_path = "active_object.data.uv_textures.active_index"
+ for i, uv_layer in enumerate(context.active_object.data.uv_layers):
+ props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False)
+ props.data_path = "active_object.data.uv_layers.active_index"
props.value = i
@@ -1234,11 +1234,11 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
if slot and slot.index != -1:
col.label("UV Map")
- col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="")
+ col.prop_search(slot, "uv_layer", ob.data, "uv_layers", text="")
elif settings.mode == 'IMAGE':
mesh = ob.data
- uv_text = mesh.uv_textures.active.name if mesh.uv_textures.active else ""
+ uv_text = mesh.uv_layers.active.name if mesh.uv_layers.active else ""
col.label("Canvas Image")
col.template_ID(settings, "canvas")
col.operator("image.new", text="New").gen_context = 'PAINT_CANVAS'
@@ -1876,8 +1876,8 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu):
def draw(self, context):
layout = self.layout
- for i, tex in enumerate(context.active_object.data.uv_textures):
- props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
+ for i, uv_layer in enumerate(context.active_object.data.uv_layers):
+ props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False)
props.data_path = "active_object.data.uv_texture_stencil_index"
props.value = i
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index bee6ae80590..2e2684a0524 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -216,6 +216,8 @@ shader_node_categories = [
NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[
+ NodeItem("ShaderNodeOutputMetallic", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeOutputSpecular", poll=object_shader_nodes_poll),
NodeItem("ShaderNodeOutputMaterial", poll=object_shader_nodes_poll),
NodeItem("ShaderNodeOutputLamp", poll=object_shader_nodes_poll),
NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
diff --git a/release/scripts/templates_py/batch_export.py b/release/scripts/templates_py/batch_export.py
index 6c77c5d6a1a..8de7a5e2903 100644
--- a/release/scripts/templates_py/batch_export.py
+++ b/release/scripts/templates_py/batch_export.py
@@ -18,7 +18,7 @@ bpy.ops.object.select_all(action='DESELECT')
for obj in selection:
- obj.select = True
+ obj.select_set(action='SELECT')
# some exporters only use the active object
scene.objects.active = obj
@@ -31,7 +31,7 @@ for obj in selection:
## Can be used for multiple formats
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
- obj.select = False
+ obj.select_set(action='DESELECT')
print("written:", fn)
@@ -39,4 +39,4 @@ for obj in selection:
scene.objects.active = obj_active
for obj in selection:
- obj.select = True
+ obj.select_set(action='SELECT')
diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
index c4d661b4c1f..e3b63813fc4 100644
--- a/release/scripts/templates_py/operator_modal_view3d_raycast.py
+++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py
@@ -67,7 +67,7 @@ def main(context, event):
# now we have the object under the mouse cursor,
# we could do lots of stuff but for the example just select.
if best_obj is not None:
- best_obj.select = True
+ best_obj.select_set(action='SELECT')
context.scene.objects.active = best_obj
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index c696719e650..4e4724771f3 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -23,6 +23,10 @@
#
# ***** END GPL LICENSE BLOCK *****
+if(WITH_LEGACY_OPENGL)
+ add_definitions(-DWITH_LEGACY_OPENGL)
+endif()
+
add_subdirectory(blender)
if(WITH_GAMEENGINE)
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index 6f2b78e0845..448e66ec540 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -54,8 +54,10 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_key_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_lamp_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_lattice_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_layer_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_linestyle_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_listBase.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_manipulator_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_material_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_mesh_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_meshdata_types.h
@@ -100,6 +102,7 @@ add_subdirectory(windowmanager)
add_subdirectory(blenkernel)
add_subdirectory(blenlib)
add_subdirectory(bmesh)
+add_subdirectory(draw)
add_subdirectory(render)
add_subdirectory(blenfont)
add_subdirectory(blentranslation)
diff --git a/source/blender/alembic/CMakeLists.txt b/source/blender/alembic/CMakeLists.txt
index a6e0be6a7f3..aa12b726d6b 100644
--- a/source/blender/alembic/CMakeLists.txt
+++ b/source/blender/alembic/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../blenlib
../blenloader
../bmesh
+ ../depsgraph
../editors/include
../makesdna
../makesrna
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index 3da67ac0865..59a4cb082df 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -132,32 +132,32 @@ static bool object_type_is_exportable(Object *ob)
* Returns whether this object should be exported into the Alembic file.
*
* @param settings export settings, used for options like 'selected only'.
- * @param ob the object in question.
+ * @param ob the object's base in question.
* @param is_duplicated normally false; true when the object is instanced
* into the scene by a dupli-object (e.g. part of a
* dupligroup). This ignores selection and layer
* visibility, and assumes that the dupli-object itself
* (e.g. the group-instantiating empty) is exported.
*/
-static bool export_object(const ExportSettings * const settings, Object *ob,
+static bool export_object(const ExportSettings * const settings, const Base * const ob_base,
bool is_duplicated)
{
if (!is_duplicated) {
/* These two tests only make sense when the object isn't being instanced
* into the scene. When it is, its exportability is determined by
* its dupli-object and the DupliObject::no_draw property. */
- if (settings->selected_only && !parent_selected(ob)) {
+ if (settings->selected_only && !object_selected(ob_base)) {
return false;
}
-
- if (settings->visible_layers_only && !(settings->scene->lay & ob->lay)) {
+ // FIXME Sybren: handle these cleanly (maybe just remove code), now using active scene layer instead.
+ if (settings->visible_layers_only && (ob_base->flag & BASE_VISIBLED) == 0) {
return false;
}
}
- if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) {
- return false;
- }
+ // if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) {
+ // return false;
+ // }
return true;
}
@@ -354,32 +354,32 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
{
- Base *base = static_cast<Base *>(m_scene->base.first);
-
- while (base) {
+ for (Base *base = static_cast<Base *>(m_settings.sl->object_bases.first); base; base = base->next) {
Object *ob = base->object;
- switch (ob->type) {
- case OB_LAMP:
- case OB_LATTICE:
- case OB_MBALL:
- case OB_SPEAKER:
- /* We do not export transforms for objects of these classes. */
- break;
-
- default:
- exploreTransform(eval_ctx, ob, ob->parent);
+ if (export_object(&m_settings, base, false)) {
+ switch (ob->type) {
+ case OB_LAMP:
+ case OB_LATTICE:
+ case OB_MBALL:
+ case OB_SPEAKER:
+ /* We do not export transforms for objects of these classes. */
+ break;
+
+ default:
+ exploreTransform(eval_ctx, base, ob->parent, NULL);
+ }
}
-
- base = base->next;
}
}
-void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent)
+void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, Object *parent, Object *dupliObParent)
{
+ Object *ob = ob_base->object;
+
/* If an object isn't exported itself, its duplilist shouldn't be
* exported either. */
- if (!export_object(&m_settings, ob, dupliObParent != NULL)) {
+ if (!export_object(&m_settings, ob_base, dupliObParent != NULL)) {
return;
}
@@ -390,6 +390,9 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje
ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
if (lb) {
+ Base fake_base = *ob_base; // copy flags (like selection state) from the real object.
+ fake_base.next = fake_base.prev = NULL;
+
DupliObject *link = static_cast<DupliObject *>(lb->first);
Object *dupli_ob = NULL;
Object *dupli_parent = NULL;
@@ -404,7 +407,8 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje
dupli_ob = link->ob;
dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob;
- exploreTransform(eval_ctx, dupli_ob, dupli_parent, ob);
+ fake_base.object = dupli_ob;
+ exploreTransform(eval_ctx, &fake_base, dupli_parent, ob);
}
}
}
@@ -483,29 +487,28 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare
void AbcExporter::createShapeWriters(EvaluationContext *eval_ctx)
{
- Base *base = static_cast<Base *>(m_scene->base.first);
-
- while (base) {
- Object *ob = base->object;
- exploreObject(eval_ctx, ob, NULL);
-
- base = base->next;
+ for (Base *base = static_cast<Base *>(m_settings.sl->object_bases.first); base; base = base->next) {
+ exploreObject(eval_ctx, base, NULL);
}
}
-void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object *dupliObParent)
+void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Base *ob_base, Object *dupliObParent)
{
/* If an object isn't exported itself, its duplilist shouldn't be
* exported either. */
- if (!export_object(&m_settings, ob, dupliObParent != NULL)) {
+ if (!export_object(&m_settings, ob_base, dupliObParent != NULL)) {
return;
}
- createShapeWriter(ob, dupliObParent);
+ createShapeWriter(ob_base, dupliObParent);
+ Object *ob = ob_base->object;
ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
if (lb) {
+ Base fake_base = *ob_base; // copy flags (like selection state) from the real object.
+ fake_base.next = fake_base.prev = NULL;
+
DupliObject *link = static_cast<DupliObject *>(lb->first);
for (; link; link = link->next) {
@@ -513,9 +516,9 @@ void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object
if (m_settings.renderable_only && link->no_draw) {
continue;
}
-
if (link->type == OB_DUPLIGROUP) {
- exploreObject(eval_ctx, link->ob, ob);
+ fake_base.object = link->ob;
+ exploreObject(eval_ctx, &fake_base, ob);
}
}
}
@@ -546,8 +549,10 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x
}
}
-void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
+void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
{
+ Object *ob = ob_base->object;
+
if (!object_type_is_exportable(ob)) {
return;
}
@@ -632,5 +637,5 @@ void AbcExporter::setCurrentFrame(Main *bmain, double t)
{
m_scene->r.cfra = static_cast<int>(t);
m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene, m_scene->lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene);
}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index f763922a73b..15158a9ef51 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -38,11 +38,14 @@ struct EvaluationContext;
struct Main;
struct Object;
struct Scene;
+struct SceneLayer;
+struct Base;
struct ExportSettings {
ExportSettings();
Scene *scene;
+ SceneLayer *sl; // Scene layer to export; all its objects will be exported, unless selected_only=true
SimpleLogger logger;
bool selected_only;
@@ -114,10 +117,10 @@ private:
void createTransformWritersHierarchy(EvaluationContext *eval_ctx);
AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent);
- void exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent = NULL);
- void exploreObject(EvaluationContext *eval_ctx, Object *ob, Object *dupliObParent);
+ void exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, Object *parent, Object *dupliObParent);
+ void exploreObject(EvaluationContext *eval_ctx, Base *ob_base, Object *dupliObParent);
void createShapeWriters(EvaluationContext *eval_ctx);
- void createShapeWriter(Object *ob, Object *dupliObParent);
+ void createShapeWriter(Base *ob_base, Object *dupliObParent);
void createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform);
AbcTransformWriter *getXForm(const std::string &name);
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 9a4ca6f99a8..bc62db5702c 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -38,7 +38,6 @@ extern "C" {
#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -918,12 +917,6 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type)
numloops = dm->getNumLoops(dm);
cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT,
NULL, numloops, name);
- if (cd_data_type == CD_MLOOPUV) {
- CustomData_add_layer_named(dm->getPolyDataLayout(dm),
- CD_MTEXPOLY, CD_DEFAULT,
- NULL, numloops, name);
- }
-
return cd_ptr;
}
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 04f6da48711..8b169988096 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -32,7 +32,6 @@ extern "C" {
#include "DNA_space_types.h" /* for FILE_MAX */
#include "BKE_constraint.h"
-#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 67d2d3b1eb2..24f77ad3a05 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -35,6 +35,7 @@
extern "C" {
#include "DNA_object_types.h"
+#include "DNA_layer_types.h"
#include "BLI_math.h"
@@ -60,6 +61,15 @@ std::string get_id_name(const ID * const id)
return name;
}
+/**
+ * @brief get_object_dag_path_name returns the name under which the object
+ * will be exported in the Alembic file. It is of the form
+ * "[../grandparent/]parent/object" if dupli_parent is NULL, or
+ * "dupli_parent/[../grandparent/]parent/object" otherwise.
+ * @param ob
+ * @param dupli_parent
+ * @return
+ */
std::string get_object_dag_path_name(const Object * const ob, Object *dupli_parent)
{
std::string name = get_id_name(ob);
@@ -78,31 +88,9 @@ std::string get_object_dag_path_name(const Object * const ob, Object *dupli_pare
return name;
}
-bool object_selected(Object *ob)
-{
- return ob->flag & SELECT;
-}
-
-bool parent_selected(Object *ob)
+bool object_selected(const Base * const ob_base)
{
- if (object_selected(ob)) {
- return true;
- }
-
- bool do_export = false;
-
- Object *parent = ob->parent;
-
- while (parent != NULL) {
- if (object_selected(parent)) {
- do_export = true;
- break;
- }
-
- parent = parent->parent;
- }
-
- return do_export;
+ return ob_base->flag & SELECT;
}
Imath::M44d convert_matrix(float mat[4][4])
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index 74d0faf97d3..4c6bd7d5412 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -48,13 +48,13 @@ struct ImportSettings;
struct ID;
struct Object;
+struct Base;
std::string get_id_name(const ID * const id);
std::string get_id_name(const Object * const ob);
std::string get_object_dag_path_name(const Object * const ob, Object *dupli_parent);
-bool object_selected(Object *ob);
-bool parent_selected(Object *ob);
+bool object_selected(const Base * const ob_base);
Imath::M44d convert_matrix(float mat[4][4]);
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 5ac73175e5b..3cad132b7be 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -48,12 +48,15 @@ extern "C" {
#include "BKE_cdderivedmesh.h"
#include "BKE_context.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
/* SpaceType struct has a member called 'new' which obviously conflicts with C++
* so temporarily redefining the new keyword to make it compile. */
#define new extern_new
@@ -269,8 +272,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
if (CFRA != orig_frame) {
CFRA = orig_frame;
- BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain,
- scene, scene->lay);
+ BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain, scene);
}
data->export_ok = !data->was_canceled;
@@ -330,13 +332,24 @@ bool ABC_export(
* hardcore refactoring. */
new (&job->settings) ExportSettings();
job->settings.scene = job->scene;
+
+ /* Sybren: for now we only export the active scene layer.
+ * Later in the 2.8 development process this may be replaced by using
+ * a specific collection for Alembic I/O, which can then be toggled
+ * between "real" objects and cached Alembic files. */
+ job->settings.sl = CTX_data_scene_layer(C);
+
job->settings.frame_start = params->frame_start;
job->settings.frame_end = params->frame_end;
job->settings.frame_samples_xform = params->frame_samples_xform;
job->settings.frame_samples_shape = params->frame_samples_shape;
job->settings.shutter_open = params->shutter_open;
job->settings.shutter_close = params->shutter_close;
+
+ /* Sybren: For now this is ignored, until we can get selection
+ * detection working through Base pointers (instead of ob->flags). */
job->settings.selected_only = params->selected_only;
+
job->settings.export_face_sets = params->face_sets;
job->settings.export_normals = params->normals;
job->settings.export_uvs = params->uvs;
@@ -345,8 +358,13 @@ bool ABC_export(
job->settings.export_particles = params->export_particles;
job->settings.apply_subdiv = params->apply_subdiv;
job->settings.flatten_hierarchy = params->flatten_hierarchy;
+
+ /* Sybren: visible_layer & renderable only is ignored for now,
+ * to be replaced with collections later in the 2.8 dev process
+ * (also see note above). */
job->settings.visible_layers_only = params->visible_layers_only;
job->settings.renderable_only = params->renderable_only;
+
job->settings.use_subdiv_schema = params->use_subdiv_schema;
job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
job->settings.pack_uv = params->packuv;
@@ -605,6 +623,7 @@ enum {
struct ImportJobData {
Main *bmain;
Scene *scene;
+ SceneLayer *scene_layer;
char filename[1024];
ImportSettings settings;
@@ -806,20 +825,32 @@ static void import_endjob(void *user_data)
else {
/* Add object to scene. */
Base *base;
+ LayerCollection *lc;
+ SceneLayer *sl = data->scene_layer;
- BKE_scene_base_deselect_all(data->scene);
+ BKE_scene_layer_base_deselect_all(sl);
+
+ lc = BKE_layer_collection_get_active(sl);
+ if (lc == NULL) {
+ BLI_assert(BLI_listbase_count_ex(&sl->layer_collections, 1) == 0);
+ /* when there is no collection linked to this SceneLayer, create one */
+ SceneCollection *sc = BKE_collection_add(data->scene, NULL, NULL);
+ lc = BKE_collection_link(sl, sc);
+ }
for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
Object *ob = (*iter)->object();
ob->lay = data->scene->lay;
- base = BKE_scene_base_add(data->scene, ob);
- BKE_scene_base_select(data->scene, base);
+ BKE_collection_object_add(data->scene, lc->scene_collection, ob);
+
+ base = BKE_scene_layer_base_find(sl, ob);
+ BKE_scene_layer_base_select(sl, base);
- DAG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
- DAG_relations_tag_update(data->bmain);
+ DEG_relations_tag_update(data->bmain);
}
for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
@@ -862,6 +893,7 @@ bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence
ImportJobData *job = new ImportJobData();
job->bmain = CTX_data_main(C);
job->scene = CTX_data_scene(C);
+ job->scene_layer = CTX_data_scene_layer(C);
job->import_ok = false;
BLI_strncpy(job->filename, filepath, 1024);
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 1f38d64924c..1b967f889c0 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -34,6 +34,9 @@
#include "BLI_compiler_attrs.h"
+/* enable this only if needed (unused circa 2016) */
+#define BLF_BLUR_ENABLE 0
+
struct rctf;
struct ColorManagedDisplay;
struct ResultBLF;
@@ -42,6 +45,7 @@ int BLF_init(int points, int dpi);
void BLF_exit(void);
void BLF_default_dpi(int dpi);
void BLF_default_set(int fontid);
+int BLF_default(void); /* get default font ID so we can pass it to other functions */
void BLF_cache_clear(void);
@@ -61,6 +65,17 @@ void BLF_aspect(int fontid, float x, float y, float z);
void BLF_position(int fontid, float x, float y, float z);
void BLF_size(int fontid, int size, int dpi);
+/* goal: small but useful color API */
+void BLF_color4ubv(int fontid, const unsigned char rgba[4]);
+void BLF_color3ubv(int fontid, const unsigned char rgb[3]);
+void BLF_color3ubv_alpha(int fontid, const unsigned char rgb[3], unsigned char alpha);
+void BLF_color3ub(int fontid, unsigned char r, unsigned char g, unsigned char b);
+void BLF_color4f(int fontid, float r, float g, float b, float a);
+void BLF_color4fv(int fontid, const float rgba[4]);
+void BLF_color3f(int fontid, float r, float g, float b);
+void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha);
+/* also available: UI_FontThemeColor(fontid, colorid) */
+
/* Set a 4x4 matrix to be multiplied before draw the text.
* Remember that you need call BLF_enable(BLF_MATRIX)
* to enable this.
@@ -122,29 +137,16 @@ void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_widt
*/
float BLF_fixed_width(int fontid) ATTR_WARN_UNUSED_RESULT;
-/* and this two function return the width and height
- * of the string, using the default font and both value
- * are multiplied by the aspect of the font.
- */
-void BLF_width_and_height_default(const char *str, size_t len, float *r_width, float *r_height) ATTR_NONNULL();
-float BLF_width_default(const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BLF_height_default(const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-/* Set rotation for default font. */
-void BLF_rotation_default(float angle);
-
-/* Enable/disable options to the default font. */
-void BLF_enable_default(int option);
-void BLF_disable_default(int option);
-
/* By default, rotation and clipping are disable and
* have to be enable/disable using BLF_enable/disable.
*/
void BLF_rotation(int fontid, float angle);
void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax);
-void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax);
void BLF_wordwrap(int fontid, int wrap_width);
+
+#if BLF_BLUR_ENABLE
void BLF_blur(int fontid, int size);
+#endif
void BLF_enable(int fontid, int option);
void BLF_disable(int fontid, int option);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 132a0ec3808..43060870449 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -50,13 +50,14 @@
#include "BLI_math.h"
#include "BLI_threads.h"
-#include "BIF_gl.h"
#include "BLF_api.h"
#include "IMB_colormanagement.h"
#ifndef BLF_STANDALONE
-#include "GPU_basic_shader.h"
+#include "GPU_shader.h"
+#include "GPU_matrix.h"
+#include "GPU_immediate.h"
#endif
#include "blf_internal_types.h"
@@ -174,6 +175,12 @@ void BLF_default_set(int fontid)
}
}
+int BLF_default(void)
+{
+ ASSERT_DEFAULT_SET;
+ return global_font_default;
+}
+
int BLF_load(const char *name)
{
FontBLF *font;
@@ -357,24 +364,6 @@ void BLF_disable(int fontid, int option)
}
}
-void BLF_enable_default(int option)
-{
- FontBLF *font = blf_get(global_font_default);
-
- if (font) {
- font->flags |= option;
- }
-}
-
-void BLF_disable_default(int option)
-{
- FontBLF *font = blf_get(global_font_default);
-
- if (font) {
- font->flags &= ~option;
- }
-}
-
void BLF_aspect(int fontid, float x, float y, float z)
{
FontBLF *font = blf_get(fontid);
@@ -453,6 +442,7 @@ void BLF_size(int fontid, int size, int dpi)
}
}
+#if BLF_BLUR_ENABLE
void BLF_blur(int fontid, int size)
{
FontBLF *font = blf_get(fontid);
@@ -461,6 +451,77 @@ void BLF_blur(int fontid, int size)
font->blur = size;
}
}
+#endif
+
+void BLF_color4ubv(int fontid, const unsigned char rgba[4])
+{
+ FontBLF *font = blf_get(fontid);
+
+ if (font) {
+ font->color[0] = rgba[0];
+ font->color[1] = rgba[1];
+ font->color[2] = rgba[2];
+ font->color[3] = rgba[3];
+ }
+}
+
+void BLF_color3ubv_alpha(int fontid, const unsigned char rgb[3], unsigned char alpha)
+{
+ FontBLF *font = blf_get(fontid);
+
+ if (font) {
+ font->color[0] = rgb[0];
+ font->color[1] = rgb[1];
+ font->color[2] = rgb[2];
+ font->color[3] = alpha;
+ }
+}
+
+void BLF_color3ubv(int fontid, const unsigned char rgb[3])
+{
+ BLF_color3ubv_alpha(fontid, rgb, 255);
+}
+
+void BLF_color3ub(int fontid, unsigned char r, unsigned char g, unsigned char b)
+{
+ FontBLF *font = blf_get(fontid);
+
+ if (font) {
+ font->color[0] = r;
+ font->color[1] = g;
+ font->color[2] = b;
+ font->color[3] = 255;
+ }
+}
+
+void BLF_color4fv(int fontid, const float rgba[4])
+{
+ FontBLF *font = blf_get(fontid);
+
+ if (font) {
+ rgba_float_to_uchar(font->color, rgba);
+ }
+}
+
+void BLF_color4f(int fontid, float r, float g, float b, float a)
+{
+ float rgba[4] = { r, g, b, a };
+ BLF_color4fv(fontid, rgba);
+}
+
+void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
+{
+ float rgba[4];
+ copy_v3_v3(rgba, rgb);
+ rgba[3] = alpha;
+ BLF_color4fv(fontid, rgba);
+}
+
+void BLF_color3f(int fontid, float r, float g, float b)
+{
+ float rgba[4] = { r, g, b, 1.0f };
+ BLF_color4fv(fontid, rgba);
+}
void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
{
@@ -481,16 +542,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l
BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */
}
-void BLF_rotation_default(float angle)
-{
- FontBLF *font = blf_get(global_font_default);
-
- if (font) {
- font->angle = angle;
- }
-}
-
-static void blf_draw_gl__start(FontBLF *font, GLint *mode)
+static void blf_draw_gl__start(FontBLF *font)
{
/*
* The pixmap alignment hack is handle
@@ -500,52 +552,46 @@ static void blf_draw_gl__start(FontBLF *font, GLint *mode)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-#ifndef BLF_STANDALONE
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
-#endif
+ gpuPushMatrix();
- /* Save the current matrix mode. */
- glGetIntegerv(GL_MATRIX_MODE, mode);
+ if (font->flags & BLF_MATRIX)
+ gpuMultMatrix(font->m);
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glLoadIdentity();
+ gpuTranslate3fv(font->pos);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ if (font->flags & BLF_ASPECT)
+ gpuScale3fv(font->aspect);
- if (font->flags & BLF_MATRIX)
- glMultMatrixf(font->m);
+ if (font->flags & BLF_ROTATION)
+ gpuRotate2D(RAD2DEG(font->angle));
- glTranslate3fv(font->pos);
+#ifndef BLF_STANDALONE
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
- if (font->flags & BLF_ASPECT)
- glScalef(font->aspect[0], font->aspect[1], font->aspect[2]);
+ BLI_assert(pos == BLF_POS_ID);
+ BLI_assert(texCoord == BLF_COORD_ID);
+ BLI_assert(color == BLF_COLOR_ID);
- if (font->flags & BLF_ROTATION) /* radians -> degrees */
- glRotatef(font->angle * (float)(180.0 / M_PI), 0.0f, 0.0f, 1.0f);
+ UNUSED_VARS_NDEBUG(pos, texCoord, color);
- if (font->shadow || font->blur)
- glGetFloatv(GL_CURRENT_COLOR, font->orig_col);
+ immBindBuiltinProgram(GPU_SHADER_TEXT);
+#endif
/* always bind the texture for the first glyph */
font->tex_bind_state = -1;
}
-static void blf_draw_gl__end(GLint mode)
+static void blf_draw_gl__end(void)
{
- glMatrixMode(GL_TEXTURE);
- glPopMatrix();
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- if (mode != GL_MODELVIEW)
- glMatrixMode(mode);
+ gpuPopMatrix();
#ifndef BLF_STANDALONE
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immUnbindProgram();
#endif
+
glDisable(GL_BLEND);
}
@@ -554,23 +600,26 @@ void BLF_draw_ex(
struct ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
- GLint mode;
BLF_RESULT_CHECK_INIT(r_info);
if (font && font->glyph_cache) {
- blf_draw_gl__start(font, &mode);
+ blf_draw_gl__start(font);
if (font->flags & BLF_WORD_WRAP) {
blf_font_draw__wrap(font, str, len, r_info);
}
else {
blf_font_draw(font, str, len, r_info);
}
- blf_draw_gl__end(mode);
+ blf_draw_gl__end();
}
}
void BLF_draw(int fontid, const char *str, size_t len)
{
+ if (len == 0 || str[0] == '\0') {
+ return;
+ }
+
BLF_draw_ex(fontid, str, len, NULL);
}
@@ -579,12 +628,11 @@ void BLF_draw_ascii_ex(
struct ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
- GLint mode;
BLF_RESULT_CHECK_INIT(r_info);
if (font && font->glyph_cache) {
- blf_draw_gl__start(font, &mode);
+ blf_draw_gl__start(font);
if (font->flags & BLF_WORD_WRAP) {
/* use non-ascii draw function for word-wrap */
blf_font_draw__wrap(font, str, len, r_info);
@@ -592,24 +640,31 @@ void BLF_draw_ascii_ex(
else {
blf_font_draw_ascii(font, str, len, r_info);
}
- blf_draw_gl__end(mode);
+ blf_draw_gl__end();
}
}
void BLF_draw_ascii(int fontid, const char *str, size_t len)
{
+ if (len == 0 || str[0] == '\0') {
+ return;
+ }
+
BLF_draw_ascii_ex(fontid, str, len, NULL);
}
int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
{
+ if (len == 0 || str[0] == '\0') {
+ return 0;
+ }
+
FontBLF *font = blf_get(fontid);
- GLint mode;
int columns = 0;
if (font && font->glyph_cache) {
- blf_draw_gl__start(font, &mode);
+ blf_draw_gl__start(font);
columns = blf_font_draw_mono(font, str, len, cwidth);
- blf_draw_gl__end(mode);
+ blf_draw_gl__end();
}
return columns;
@@ -689,14 +744,6 @@ void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_widt
}
}
-void BLF_width_and_height_default(const char *str, size_t len, float *r_width, float *r_height)
-{
- ASSERT_DEFAULT_SET;
-
- BLF_size(global_font_default, global_font_points, global_font_dpi);
- BLF_width_and_height(global_font_default, str, len, r_width, r_height);
-}
-
float BLF_width_ex(
int fontid, const char *str, size_t len,
struct ResultBLF *r_info)
@@ -727,14 +774,6 @@ float BLF_fixed_width(int fontid)
return 0.0f;
}
-float BLF_width_default(const char *str, size_t len)
-{
- ASSERT_DEFAULT_SET;
-
- BLF_size(global_font_default, global_font_points, global_font_dpi);
- return BLF_width(global_font_default, str, len);
-}
-
float BLF_height_ex(
int fontid, const char *str, size_t len,
struct ResultBLF *r_info)
@@ -798,15 +837,6 @@ float BLF_ascender(int fontid)
return 0.0f;
}
-float BLF_height_default(const char *str, size_t len)
-{
- ASSERT_DEFAULT_SET;
-
- BLF_size(global_font_default, global_font_points, global_font_dpi);
-
- return BLF_height(global_font_default, str, len);
-}
-
void BLF_rotation(int fontid, float angle)
{
FontBLF *font = blf_get(fontid);
@@ -828,18 +858,6 @@ void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax)
}
}
-void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax)
-{
- FontBLF *font = blf_get(global_font_default);
-
- if (font) {
- font->clip_rec.xmin = xmin;
- font->clip_rec.ymin = ymin;
- font->clip_rec.xmax = xmax;
- font->clip_rec.ymax = ymax;
- }
-}
-
void BLF_wordwrap(int fontid, int wrap_width)
{
FontBLF *font = blf_get(fontid);
@@ -855,7 +873,7 @@ void BLF_shadow(int fontid, int level, const float rgba[4])
if (font) {
font->shadow = level;
- copy_v4_v4(font->shadow_col, rgba);
+ rgba_float_to_uchar(font->shadow_color, rgba);
}
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 44a1d08f1fd..3ba75517581 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -58,6 +58,8 @@
#include "BIF_gl.h"
#include "BLF_api.h"
+#include "GPU_immediate.h"
+
#include "blf_internal_types.h"
#include "blf_internal.h"
@@ -172,6 +174,23 @@ static void blf_font_ensure_ascii_table(FontBLF *font)
} \
} (void)0
+static unsigned int verts_needed(const FontBLF *font, const char *str, size_t len)
+{
+ unsigned int length = (unsigned int)((len == INT_MAX) ? strlen(str) : len);
+ unsigned int quad_ct = 1;
+
+ if (font->flags & BLF_SHADOW) {
+ if (font->shadow == 0)
+ quad_ct += 1;
+ if (font->shadow <= 4)
+ quad_ct += 9; /* 3x3 kernel */
+ else
+ quad_ct += 25; /* 5x5 kernel */
+ }
+
+ return length * quad_ct * 6;
+}
+
static void blf_font_draw_ex(
FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info,
int pen_y)
@@ -187,6 +206,9 @@ static void blf_font_draw_ex(
blf_font_ensure_ascii_table(font);
+ immBeginAtMost(PRIM_TRIANGLES, verts_needed(font, str, len));
+ /* at most because some glyphs might be clipped & not drawn */
+
while ((i < len) && str[i]) {
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
@@ -204,6 +226,8 @@ static void blf_font_draw_ex(
g_prev = g;
}
+ immEnd();
+
if (r_info) {
r_info->lines = 1;
r_info->width = pen_x;
@@ -229,6 +253,8 @@ static void blf_font_draw_ascii_ex(
blf_font_ensure_ascii_table(font);
+ immBeginAtMost(PRIM_TRIANGLES, verts_needed(font, str, len));
+
while ((c = *(str++)) && len--) {
BLI_assert(c < 128);
if ((g = glyph_ascii_table[c]) == NULL)
@@ -243,6 +269,8 @@ static void blf_font_draw_ascii_ex(
g_prev = g;
}
+ immEnd();
+
if (r_info) {
r_info->lines = 1;
r_info->width = pen_x;
@@ -265,6 +293,8 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
blf_font_ensure_ascii_table(font);
+ immBeginAtMost(PRIM_TRIANGLES, verts_needed(font, str, len));
+
while ((i < len) && str[i]) {
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
@@ -284,6 +314,8 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
pen_x += cwidth * col;
}
+ immEnd();
+
return columns;
}
@@ -901,8 +933,6 @@ void blf_font_free(FontBLF *font)
static void blf_font_fill(FontBLF *font)
{
- unsigned int i;
-
font->aspect[0] = 1.0f;
font->aspect[1] = 1.0f;
font->aspect[2] = 1.0f;
@@ -910,9 +940,15 @@ static void blf_font_fill(FontBLF *font)
font->pos[1] = 0.0f;
font->angle = 0.0f;
- for (i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++)
font->m[i] = 0;
+ /* annoying bright color so we can see where to add BLF_color calls */
+ font->color[0] = 255;
+ font->color[1] = 255;
+ font->color[2] = 0;
+ font->color[3] = 255;
+
font->clip_rec.xmin = 0.0f;
font->clip_rec.xmax = 0.0f;
font->clip_rec.ymin = 0.0f;
@@ -922,7 +958,9 @@ static void blf_font_fill(FontBLF *font)
font->size = 0;
BLI_listbase_clear(&font->cache);
font->glyph_cache = NULL;
+#if BLF_BLUR_ENABLE
font->blur = 0;
+#endif
font->max_tex_size = -1;
font->buf_info.fbuf = NULL;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index bbbabfb8ba2..a7d52e96800 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -56,7 +56,7 @@
#include "BLF_api.h"
#ifndef BLF_STANDALONE
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
#endif
#include "blf_internal_types.h"
@@ -183,18 +183,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-#ifndef BLF_STANDALONE
- /* needed since basic shader doesn't support alpha-only textures,
- * while we could add support this is only used in a few places
- * (an alternative could be to have a simple shader for BLF). */
- if (GLEW_ARB_texture_swizzle && GPU_basic_shader_use_glsl_get()) {
- GLint swizzle_mask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA};
- glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle_mask);
- }
-#endif
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, gc->p2_width, gc->p2_height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
}
GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
@@ -327,73 +316,83 @@ void blf_glyph_free(GlyphBLF *g)
MEM_freeN(g);
}
-static void blf_texture_draw(float uv[2][2], float dx, float y1, float dx1, float y2)
+static void blf_texture_draw(const unsigned char color[4], float uv[2][2], float dx, float y1, float dx1, float y2)
{
- glBegin(GL_QUADS);
- glTexCoord2f(uv[0][0], uv[0][1]);
- glVertex2f(dx, y1);
-
- glTexCoord2f(uv[0][0], uv[1][1]);
- glVertex2f(dx, y2);
-
- glTexCoord2f(uv[1][0], uv[1][1]);
- glVertex2f(dx1, y2);
-
- glTexCoord2f(uv[1][0], uv[0][1]);
- glVertex2f(dx1, y1);
- glEnd();
+ /* First triangle. */
+ immAttrib2f(BLF_COORD_ID, uv[0][0], uv[0][1]);
+ immSkipAttrib(BLF_COLOR_ID); /* skip color of most vertices */
+ immVertex2f(BLF_POS_ID, dx, y1);
+
+ immAttrib2f(BLF_COORD_ID, uv[0][0], uv[1][1]);
+ immSkipAttrib(BLF_COLOR_ID);
+ immVertex2f(BLF_POS_ID, dx, y2);
+
+ immAttrib2f(BLF_COORD_ID, uv[1][0], uv[1][1]);
+ immAttrib4ubv(BLF_COLOR_ID, color); /* set color of provoking vertex */
+ immVertex2f(BLF_POS_ID, dx1, y2);
+
+ /* Second triangle. */
+ immAttrib2f(BLF_COORD_ID, uv[0][0], uv[0][1]);
+ immSkipAttrib(BLF_COLOR_ID); /* skip color of most vertices */
+ immVertex2f(BLF_POS_ID, dx, y1);
+
+ immAttrib2f(BLF_COORD_ID, uv[1][0], uv[1][1]);
+ immSkipAttrib(BLF_COLOR_ID);
+ immVertex2f(BLF_POS_ID, dx1, y2);
+
+ immAttrib2f(BLF_COORD_ID, uv[1][0], uv[0][1]);
+ immAttrib4ubv(BLF_COLOR_ID, color); /* set color of provoking vertex */
+ immVertex2f(BLF_POS_ID, dx1, y1);
}
-static void blf_texture5_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
+static void blf_texture5_draw(const unsigned char color_in[4], float uv[2][2], float x1, float y1, float x2, float y2)
{
const float soft[25] = {1 / 60.0f, 1 / 60.0f, 2 / 60.0f, 1 / 60.0f, 1 / 60.0f,
1 / 60.0f, 3 / 60.0f, 5 / 60.0f, 3 / 60.0f, 1 / 60.0f,
2 / 60.0f, 5 / 60.0f, 8 / 60.0f, 5 / 60.0f, 2 / 60.0f,
1 / 60.0f, 3 / 60.0f, 5 / 60.0f, 3 / 60.0f, 1 / 60.0f,
1 / 60.0f, 1 / 60.0f, 2 / 60.0f, 1 / 60.0f, 1 / 60.0f};
-
+
const float *fp = soft;
- float color[4];
+ unsigned char color[4];
float dx, dy;
- color[0] = shadow_col[0];
- color[1] = shadow_col[1];
- color[2] = shadow_col[2];
-
+ color[0] = color_in[0];
+ color[1] = color_in[1];
+ color[2] = color_in[2];
+
+ const float alpha_in = (1 / 255.0f) * color_in[3];
+
for (dx = -2; dx < 3; dx++) {
for (dy = -2; dy < 3; dy++, fp++) {
- color[3] = *(fp) * shadow_col[3];
- glColor4fv(color);
- blf_texture_draw(uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
+ color[3] = FTOCHAR(*fp * alpha_in);
+ blf_texture_draw(color, uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
}
}
-
- glColor4fv(color);
}
-static void blf_texture3_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
+static void blf_texture3_draw(const unsigned char color_in[4], float uv[2][2], float x1, float y1, float x2, float y2)
{
const float soft[9] = {1 / 16.0f, 2 / 16.0f, 1 / 16.0f,
2 / 16.0f, 4 / 16.0f, 2 / 16.0f,
1 / 16.0f, 2 / 16.0f, 1 / 16.0f};
const float *fp = soft;
- float color[4];
+ unsigned char color[4];
float dx, dy;
- color[0] = shadow_col[0];
- color[1] = shadow_col[1];
- color[2] = shadow_col[2];
+ color[0] = color_in[0];
+ color[1] = color_in[1];
+ color[2] = color_in[2];
+
+ const float alpha_in = (1 / 255.0f) * color_in[3];
for (dx = -1; dx < 2; dx++) {
for (dy = -1; dy < 2; dy++, fp++) {
- color[3] = *(fp) * shadow_col[3];
- glColor4fv(color);
- blf_texture_draw(uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
+ color[3] = FTOCHAR(*fp * alpha_in);
+ blf_texture_draw(color, uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
}
}
-
- glColor4fv(color);
}
static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y)
@@ -450,14 +449,21 @@ void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
}
- glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+ GLint lsb_first, row_length, alignment;
+ glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsb_first);
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
+
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, g->tex);
- glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap);
- glPopClientAttrib();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_RED, GL_UNSIGNED_BYTE, g->bitmap);
+
+ glPixelStorei(GL_UNPACK_LSB_FIRST, lsb_first);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
g->uv[0][0] = ((float)g->xoff) / ((float)gc->p2_width);
g->uv[0][1] = ((float)g->yoff) / ((float)gc->p2_height);
@@ -487,39 +493,37 @@ void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = g->tex));
}
+ /* TODO: blur & shadow in shader, single quad per glyph */
+
if (font->flags & BLF_SHADOW) {
rctf rect_ofs;
blf_glyph_calc_rect(&rect_ofs, g,
x + (float)font->shadow_x,
y + (float)font->shadow_y);
- switch (font->shadow) {
- case 3:
- blf_texture3_draw(font->shadow_col, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
- break;
- case 5:
- blf_texture5_draw(font->shadow_col, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
- break;
- default:
- glColor4fv(font->shadow_col);
- blf_texture_draw(g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
- break;
+ if (font->shadow == 0) {
+ blf_texture_draw(font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
+ }
+ else if (font->shadow <= 4) {
+ blf_texture3_draw(font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
+ }
+ else {
+ blf_texture5_draw(font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
}
-
- glColor4fv(font->orig_col);
}
+#if BLF_BLUR_ENABLE
switch (font->blur) {
case 3:
- blf_texture3_draw(font->orig_col, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ blf_texture3_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
break;
case 5:
- blf_texture5_draw(font->orig_col, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ blf_texture5_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
break;
default:
- blf_texture_draw(g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- break;
+ blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
-
- return;
+#else
+ blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+#endif
}
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index d9d758ce548..ba17e050399 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -37,6 +37,11 @@ struct GlyphBLF;
struct GlyphCacheBLF;
struct rctf;
+/* vertex attribute IDs (fixed IDs so we don't have to pass them around) */
+#define BLF_POS_ID 0
+#define BLF_COORD_ID 1
+#define BLF_COLOR_ID 2
+
unsigned int blf_next_p2(unsigned int x);
unsigned int blf_hash(unsigned int val);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 0fac576a8cc..9164a02b2cc 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -175,8 +175,10 @@ typedef struct FontBLF {
/* angle in radians. */
float angle;
+#if 0 /* BLF_BLUR_ENABLE */
/* blur: 3 or 5 large kernel */
int blur;
+#endif
/* shadow level. */
int shadow;
@@ -186,10 +188,10 @@ typedef struct FontBLF {
int shadow_y;
/* shadow color. */
- float shadow_col[4];
+ unsigned char shadow_color[4];
- /* store color here when drawing shadow or blur. */
- float orig_col[4];
+ /* main text color. */
+ unsigned char color[4];
/* Multiplied this matrix with the current one before
* draw the text! see blf_draw__start.
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 789bc8df7e5..116724463ca 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -142,8 +142,6 @@ typedef int (*DMSetMaterial)(int mat_nr, void *attribs);
typedef int (*DMCompareDrawOptions)(void *userData, int cur_index, int next_index);
typedef void (*DMSetDrawInterpOptions)(void *userData, int index, float t);
typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index);
-typedef DMDrawOption (*DMSetDrawOptionsMappedTex)(void *userData, int origindex, int mat_nr);
-typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTexPoly *mtexpoly, const bool has_vcol, int matnr);
typedef enum DMDrawFlag {
DM_DRAW_USE_COLORS = (1 << 0),
@@ -387,9 +385,6 @@ struct DerivedMesh {
/** Draw all vertices as bgl points (no options) */
void (*drawVerts)(DerivedMesh *dm);
- /** Draw edges in the UV mesh (if exists) */
- void (*drawUVEdges)(DerivedMesh *dm);
-
/** Draw all edges as lines (no options)
*
* Also called for *final* editmode DerivedMeshes
@@ -409,14 +404,6 @@ struct DerivedMesh {
void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4],
bool fast, DMSetMaterial setMaterial);
- /** Draw all faces using MTFace
- * - Drawing options too complicated to enumerate, look at code.
- */
- void (*drawFacesTex)(DerivedMesh *dm,
- DMSetDrawOptionsTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag);
-
/** Draw all faces with GLSL materials
* o setMaterial is called for every different material nr
* o Only if setMaterial returns true
@@ -443,14 +430,6 @@ struct DerivedMesh {
void *userData,
DMDrawFlag flag);
- /** Draw mapped faces using MTFace
- * - Drawing options too complicated to enumerate, look at code.
- */
- void (*drawMappedFacesTex)(DerivedMesh *dm,
- DMSetDrawOptionsMappedTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag);
-
/** Draw mapped faces with GLSL materials
* - setMaterial is called for every different material nr
* - setDrawOptions is called for every face
@@ -788,17 +767,11 @@ void DM_draw_attrib_vertex_uniforms(const DMVertexAttribs *attribs);
void DM_calc_tangents_names_from_gpu(
const struct GPUVertexAttribs *gattribs,
char (*tangent_names)[MAX_NAME], int *tangent_names_count);
-void DM_add_named_tangent_layer_for_uv(
- CustomData *uv_data, CustomData *tan_data, int numLoopData,
- const char *layer_name);
-void DM_calc_loop_tangents_step_0(
- const CustomData *loopData, bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME], int tangent_names_count,
- bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
- char *ract_uv_name, char *rren_uv_name, char *rtangent_mask);
+
void DM_calc_loop_tangents(
DerivedMesh *dm, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME],
int tangent_names_count);
+
void DM_calc_auto_bump_scale(DerivedMesh *dm);
/** Set object's bounding box based on DerivedMesh min/max data */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 23bb526073b..a68f1e763fd 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -97,7 +97,6 @@ void BKE_armature_where_is(struct bArmature *arm);
void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion);
void BKE_pose_clear_pointers(struct bPose *pose);
void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm);
-void BKE_pose_rebuild_ex(struct Object *ob, struct bArmature *arm, const bool sort_bones);
void BKE_pose_where_is(struct Scene *scene, struct Object *ob);
void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 207631d36bd..bc3db11f34b 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -27,8 +27,8 @@
/* these lines are grep'd, watch out for our not-so-awesome regex
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
-#define BLENDER_VERSION 278
-#define BLENDER_SUBVERSION 5
+#define BLENDER_VERSION 280
+#define BLENDER_SUBVERSION 0
/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 6
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index 0d4ed2083b1..b8e08524dbe 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -63,7 +63,7 @@ bool BKE_cachefile_filepath_get(
float BKE_cachefile_time_offset(struct CacheFile *cache_file, const float time, const float fps);
-void BKE_cachefile_clean(struct Scene *scene, struct CacheFile *cache_file);
+void BKE_cachefile_clean(struct Main *bmain, struct CacheFile *cache_file);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 31a732cf7e5..740a1f2b257 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -44,6 +44,7 @@ struct Object;
struct RegionView3D;
struct RenderData;
struct Scene;
+struct SceneLayer;
struct rctf;
struct View3D;
struct GPUFXSettings;
@@ -127,7 +128,7 @@ void BKE_camera_view_frame(
float r_vec[4][3]);
bool BKE_camera_view_frame_fit_to_scene(
- struct Scene *scene, struct View3D *v3d, struct Object *camera_ob,
+ struct Scene *scene, struct SceneLayer *sl, struct Object *camera_ob,
float r_co[3], float *r_scale);
bool BKE_camera_view_frame_fit_to_coords(
const struct Scene *scene,
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
new file mode 100644
index 00000000000..35d8f336207
--- /dev/null
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -0,0 +1,100 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_COLLECTION_H__
+#define __BKE_COLLECTION_H__
+
+/** \file blender/blenkernel/BKE_collection.h
+ * \ingroup bke
+ */
+
+#include "BLI_ghash.h"
+#include "BLI_iterator.h"
+#include "DNA_listBase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct BLI_Iterator;
+struct SceneCollection;
+struct Object;
+struct Base;
+struct Main;
+struct Scene;
+
+struct SceneCollection *BKE_collection_add(struct Scene *scene, struct SceneCollection *sc_parent, const char *name);
+bool BKE_collection_remove(struct Scene *scene, struct SceneCollection *sc);
+struct SceneCollection *BKE_collection_master(const struct Scene *scene);
+void BKE_collection_rename(const struct Scene *scene, struct SceneCollection *sc, const char *name);
+void BKE_collection_master_free(struct Scene *scene);
+void BKE_collection_object_add(const struct Scene *scene, struct SceneCollection *sc, struct Object *object);
+void BKE_collection_object_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst);
+void BKE_collection_object_remove(struct Main *bmain, const struct Scene *scene, struct SceneCollection *sc, struct Object *object, const bool free_us);
+void BKE_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, const bool free_us);
+void BKE_collection_object_move(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src, struct Object *ob);
+
+void BKE_collection_reinsert_after(const struct Scene *scene, struct SceneCollection *sc_reinsert, struct SceneCollection *sc_after);
+void BKE_collection_reinsert_into(struct SceneCollection *sc_reinsert, struct SceneCollection *sc_into);
+
+bool BKE_collection_move_above(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_below(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_into(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+
+typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
+typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data);
+
+void BKE_scene_collections_callback(struct Scene *scene, BKE_scene_collections_Cb callback, void *data);
+void BKE_scene_objects_callback(struct Scene *scene, BKE_scene_objects_Cb callback, void *data);
+
+/* iterators */
+void BKE_scene_collections_iterator_begin(struct BLI_Iterator *iter, void *data_in);
+void BKE_scene_collections_iterator_next(struct BLI_Iterator *iter);
+void BKE_scene_collections_iterator_end(struct BLI_Iterator *iter);
+
+void BKE_scene_objects_iterator_begin(struct BLI_Iterator *iter, void *data_in);
+void BKE_scene_objects_iterator_next(struct BLI_Iterator *iter);
+void BKE_scene_objects_iterator_end(struct BLI_Iterator *iter);
+
+#define FOREACH_SCENE_COLLECTION(scene, _instance) \
+ ITER_BEGIN(BKE_scene_collections_iterator_begin, \
+ BKE_scene_collections_iterator_next, \
+ BKE_scene_collections_iterator_end, \
+ scene, SceneCollection *, _instance)
+
+#define FOREACH_SCENE_COLLECTION_END \
+ ITER_END
+
+#define FOREACH_SCENE_OBJECT(scene, _instance) \
+ ITER_BEGIN(BKE_scene_objects_iterator_begin, \
+ BKE_scene_objects_iterator_next, \
+ BKE_scene_objects_iterator_end, \
+ scene, Object *, _instance)
+
+#define FOREACH_SCENE_OBJECT_END \
+ ITER_END
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_COLLECTION_H__ */
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index 8fedcd4ab06..0bf7f657f70 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -148,7 +148,7 @@ void collision_get_collider_velocity(float vel_old[3], float vel_new[3], struct
/////////////////////////////////////////////////
/* explicit control over layer mask and dupli recursion */
-struct Object **get_collisionobjects_ext(struct Scene *scene, struct Object *self, struct Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli);
+struct Object **get_collisionobjects_ext(struct Scene *scene, struct Object *self, struct Group *group, unsigned int *numcollobj, unsigned int modifier_type, bool dupli);
struct Object **get_collisionobjects(struct Scene *scene, struct Object *self, struct Group *group, unsigned int *numcollobj, unsigned int modifier_type);
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 4da6a61cbfa..c911d9ec952 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -40,12 +40,17 @@ extern "C" {
struct ARegion;
struct bScreen;
struct CacheFile;
+struct Depsgraph;
+struct LayerCollection;
struct ListBase;
struct Main;
struct Object;
+struct Base;
struct PointerRNA;
struct ReportList;
struct Scene;
+struct SceneCollection;
+struct SceneLayer;
struct ScrArea;
struct SpaceLink;
struct View3D;
@@ -239,9 +244,13 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
struct Main *CTX_data_main(const bContext *C);
struct Scene *CTX_data_scene(const bContext *C);
+struct LayerCollection *CTX_data_layer_collection(const bContext *C);
+struct SceneCollection *CTX_data_scene_collection(const bContext *C);
+struct SceneLayer *CTX_data_scene_layer(const bContext *C);
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
const char *CTX_data_mode_string(const bContext *C);
+int CTX_data_mode_enum_ex(const struct Object *obedit, const struct Object *ob);
int CTX_data_mode_enum(const bContext *C);
void CTX_data_main_set(bContext *C, struct Main *bmain);
@@ -296,6 +305,7 @@ int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
+struct Depsgraph *CTX_data_depsgraph(const bContext *C);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index e111bd0e16b..411e71e31e3 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -219,4 +219,12 @@ void BKE_curve_eval_geometry(struct EvaluationContext *eval_ctx,
void BKE_curve_eval_path(struct EvaluationContext *eval_ctx,
struct Curve *curve);
+/* Draw Cache */
+enum {
+ BKE_CURVE_BATCH_DIRTY_ALL = 0,
+ BKE_CURVE_BATCH_DIRTY_SELECT,
+};
+void BKE_curve_batch_cache_dirty(struct Curve *cu, int mode);
+void BKE_curve_batch_cache_free(struct Curve *cu);
+
#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 2cdda34b9b5..51cd4da183a 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -376,15 +376,14 @@ void CustomData_validate_layer_name(const struct CustomData *data, int type, con
bool CustomData_verify_versions(struct CustomData *data, int index);
/*BMesh specific customdata stuff*/
-void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata,
- struct CustomData *ldata, int totloop, int totpoly);
-void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total);
-void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
-void CustomData_bmesh_do_versions_update_active_layers(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
+void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *ldata, int totloop);
+void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *ldata, int total);
+void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *ldata);
+void CustomData_bmesh_do_versions_update_active_layers(struct CustomData *fdata, struct CustomData *ldata);
void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, const char htype);
#ifndef NDEBUG
-bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *pdata, CustomData *ldata, bool fallback);
+bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool fallback);
#endif
/* External file storage */
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 40564aeabe9..363f8c82853 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -44,40 +44,12 @@
extern "C" {
#endif
+struct Depsgraph;
struct ID;
struct Main;
struct Object;
struct Scene;
-/* Dependency graph evaluation context
- *
- * This structure stores all the local dependency graph data,
- * which is needed for it's evaluation,
- */
-typedef struct EvaluationContext {
- int mode; /* evaluation mode */
- float ctime; /* evaluation time */
-} EvaluationContext;
-
-typedef enum eEvaluationMode {
- DAG_EVAL_VIEWPORT = 0, /* evaluate for OpenGL viewport */
- DAG_EVAL_PREVIEW = 1, /* evaluate for render with preview settings */
- DAG_EVAL_RENDER = 2, /* evaluate for render purposes */
-} eEvaluationMode;
-
-/* DagNode->eval_flags */
-enum {
- /* Regardless to curve->path animation flag path is to be evaluated anyway,
- * to meet dependencies with such a things as curve modifier and other guys
- * who're using curve deform, where_on_path and so.
- */
- DAG_EVAL_NEED_CURVE_PATH = 1,
- /* Scene evaluation would need to have object's data on CPU,
- * meaning no GPU shortcuts is allowed.
- */
- DAG_EVAL_NEED_CPU = 2,
-};
-
/* Global initialization/deinitialization */
void DAG_init(void);
void DAG_exit(void);
@@ -116,7 +88,6 @@ void DAG_scene_free(struct Scene *sce);
* not cause any updates but is used by external render engines to detect if for
* example a datablock was removed. */
-void DAG_scene_update_flags(struct Main *bmain, struct Scene *sce, unsigned int lay, const bool do_time, const bool do_invisible_flush);
void DAG_on_visible_update(struct Main *bmain, const bool do_time);
void DAG_id_tag_update(struct ID *id, short flag);
@@ -135,15 +106,10 @@ int DAG_id_type_tagged(struct Main *bmain, short idtype);
* DAG_ids_check_recalc and DAG_ids_clear_recalc are used for external render
* engines to detect changes. */
-void DAG_scene_flush_update(struct Main *bmain, struct Scene *sce, unsigned int lay, const short do_time);
void DAG_ids_flush_tagged(struct Main *bmain);
void DAG_ids_check_recalc(struct Main *bmain, struct Scene *scene, bool time);
void DAG_ids_clear_recalc(struct Main *bmain);
-/* Armature: sorts the bones according to dependencies between them */
-
-void DAG_pose_sort(struct Object *ob);
-
/* Editors: callbacks to notify editors of datablock changes */
void DAG_editors_update_cb(void (*id_func)(struct Main *bmain, struct ID *id),
@@ -154,25 +120,13 @@ void DAG_editors_update_pre(struct Main *bmain, struct Scene *scene, bool time);
/* ** Threaded update ** */
-/* Initialize the DAG for threaded update. */
-void DAG_threaded_update_begin(struct Scene *scene,
- void (*func)(void *node, void *user_data),
- void *user_data);
-
-void DAG_threaded_update_handle_node_updated(void *node_v,
- void (*func)(void *node, void *user_data),
- void *user_data);
-
/* Debugging: print dependency graph for scene or armature object to console */
void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Object *ob);
/* ************************ DAG querying ********************* */
-struct Object *DAG_get_node_object(void *node_v);
-const char *DAG_get_node_name(struct Scene *scene, void *node_v);
short DAG_get_eval_flags_for_object(struct Scene *scene, void *object);
-bool DAG_is_acyclic(struct Scene *scene);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 5abb53d4c52..b22f5fa7630 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -28,6 +28,7 @@
*/
struct Scene;
+struct SceneLayer;
/* Actual surface point */
typedef struct PaintSurfaceData {
@@ -60,7 +61,8 @@ typedef struct PaintWavePoint {
short state;
} PaintWavePoint;
-struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
+struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct Scene *scene,
+ struct SceneLayer *sl, struct Object *ob, struct DerivedMesh *dm);
void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd);
void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tsmd);
@@ -83,7 +85,7 @@ struct DynamicPaintSurface *get_activeSurface(struct DynamicPaintCanvasSettings
/* image sequence baking */
int dynamicPaint_createUVSurface(struct Scene *scene, struct DynamicPaintSurface *surface, float *progress, short *do_update);
-int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct Scene *scene, struct Object *cObject, int frame);
+int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct Scene *scene, struct SceneLayer *sl, struct Object *cObject, int frame);
void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface, char *filename, short output_layer);
/* PaintPoint state */
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 55a9db9b1e5..9ee1bcf2d37 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -88,7 +88,6 @@ BMEditMesh *BKE_editmesh_copy(BMEditMesh *em);
BMEditMesh *BKE_editmesh_from_object(struct Object *ob);
void BKE_editmesh_free_derivedmesh(BMEditMesh *em);
void BKE_editmesh_free(BMEditMesh *em);
-void BKE_editmesh_update_linked_customdata(BMEditMesh *em);
void BKE_editmesh_color_free(BMEditMesh *em);
void BKE_editmesh_color_ensure(BMEditMesh *em, const char htype);
diff --git a/source/blender/blenkernel/BKE_editmesh_tangent.h b/source/blender/blenkernel/BKE_editmesh_tangent.h
new file mode 100644
index 00000000000..7d6839a4e6a
--- /dev/null
+++ b/source/blender/blenkernel/BKE_editmesh_tangent.h
@@ -0,0 +1,40 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Joseph Eagar.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_EDITMESH_TANGENT_H__
+#define __BKE_EDITMESH_TANGENT_H__
+
+/** \file BKE_editmesh_tangent.h
+ * \ingroup bke
+ */
+
+void BKE_editmesh_loop_tangent_calc(
+ BMEditMesh *em, bool calc_active_tangent,
+ const char (*tangent_names)[MAX_NAME], int tangent_names_len,
+ const float (*poly_normals)[3],
+ const float (*loop_normals)[3],
+ const float (*vert_orco)[3],
+ CustomData *dm_loopdata_out,
+ const uint dm_loopdata_out_len,
+ char *tangent_mask_curr_p);
+
+#endif /* __BKE_EDITMESH_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 09a069ee36f..f718e9c8555 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -33,6 +33,7 @@
* \author nzc
*/
+struct BaseLegacy;
struct Base;
struct EvaluationContext;
struct Group;
@@ -44,8 +45,8 @@ void BKE_group_free(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
struct Group *BKE_group_copy(struct Main *bmain, struct Group *group);
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
-bool BKE_group_object_add(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
-bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
+bool BKE_group_object_add(struct Group *group, struct Object *ob);
+bool BKE_group_object_unlink(struct Group *group, struct Object *ob);
struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
bool BKE_group_object_exists(struct Group *group, struct Object *ob);
bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 226c82da295..1f8da15fcb7 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -103,4 +103,12 @@ struct EvaluationContext;
void BKE_lattice_eval_geometry(struct EvaluationContext *eval_ctx,
struct Lattice *latt);
+/* Draw Cache */
+enum {
+ BKE_LATTICE_BATCH_DIRTY_ALL = 0,
+ BKE_LATTICE_BATCH_DIRTY_SELECT,
+};
+void BKE_lattice_batch_cache_dirty(struct Lattice *lt, int mode);
+void BKE_lattice_batch_cache_free(struct Lattice *lt);
+
#endif /* __BKE_LATTICE_H__ */
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
new file mode 100644
index 00000000000..c6ec7e9df25
--- /dev/null
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -0,0 +1,253 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Blender Foundation, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_LAYER_H__
+#define __BKE_LAYER_H__
+
+/** \file blender/blenkernel/BKE_layer.h
+ * \ingroup bke
+ */
+
+#include "BKE_collection.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TODO_LAYER_SYNC /* syncing of SceneCollection and LayerCollection trees*/
+#define TODO_LAYER_SYNC_FILTER /* syncing of filter_objects across all trees */
+#define TODO_LAYER_OVERRIDE /* CollectionOverride */
+#define TODO_LAYER_CONTEXT /* get/set current (context) SceneLayer */
+#define TODO_LAYER_BASE /* BaseLegacy to Base related TODO */
+#define TODO_LAYER_OPERATORS /* collection mamanger and property panel operators */
+#define TODO_LAYER_DEPSGRAPH /* placeholder for real Depsgraph fix */
+#define TODO_LAYER /* generic todo */
+
+#define ROOT_PROP "root"
+
+struct EvaluationContext;
+struct LayerCollection;
+struct ID;
+struct IDProperty;
+struct ListBase;
+struct Main;
+struct Object;
+struct Base;
+struct RenderEngine;
+struct Scene;
+struct SceneCollection;
+struct SceneLayer;
+
+void BKE_layer_exit(void);
+
+struct SceneLayer *BKE_scene_layer_render_active(const struct Scene *scene);
+struct SceneLayer *BKE_scene_layer_context_active(const struct Scene *scene);
+struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
+
+bool BKE_scene_layer_remove(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl);
+
+void BKE_scene_layer_free(struct SceneLayer *sl);
+
+void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);
+
+void BKE_scene_layer_selected_objects_tag(struct SceneLayer *sl, const int tag);
+
+struct SceneLayer *BKE_scene_layer_find_from_collection(const struct Scene *scene, struct LayerCollection *lc);
+struct Base *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob);
+void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl);
+void BKE_scene_layer_base_select(struct SceneLayer *sl, struct Base *selbase);
+
+void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
+
+struct LayerCollection *BKE_layer_collection_get_active(struct SceneLayer *sl);
+struct LayerCollection *BKE_layer_collection_get_active_ensure(struct Scene *scene, struct SceneLayer *sl);
+
+int BKE_layer_collection_count(struct SceneLayer *sl);
+
+int BKE_layer_collection_findindex(struct SceneLayer *sl, const struct LayerCollection *lc);
+
+bool BKE_layer_collection_move_above(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_below(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_into(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+
+void BKE_layer_collection_resync(const struct Scene *scene, const struct SceneCollection *sc);
+
+struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
+
+void BKE_collection_unlink(struct SceneLayer *sl, struct LayerCollection *lc);
+
+bool BKE_scene_layer_has_collection(struct SceneLayer *sl, const struct SceneCollection *sc);
+bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
+
+/* syncing */
+
+void BKE_layer_sync_new_scene_collection(struct Scene *scene, const struct SceneCollection *sc_parent, struct SceneCollection *sc);
+void BKE_layer_sync_object_link(const struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
+void BKE_layer_sync_object_unlink(const struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
+
+/* override */
+
+void BKE_collection_override_datablock_add(struct LayerCollection *lc, const char *data_path, struct ID *id);
+
+/* engine settings */
+typedef void (*EngineSettingsCB)(struct RenderEngine *engine, struct IDProperty *props);
+
+struct IDProperty *BKE_layer_collection_engine_evaluated_get(struct Object *ob, const int type, const char *engine_name);
+struct IDProperty *BKE_layer_collection_engine_collection_get(struct LayerCollection *lc, const int type, const char *engine_name);
+struct IDProperty *BKE_layer_collection_engine_scene_get(struct Scene *scene, const int type, const char *engine_name);
+void BKE_layer_collection_engine_settings_callback_register(struct Main *bmain, const char *engine_name, EngineSettingsCB func);
+void BKE_layer_collection_engine_settings_callback_free(void);
+void BKE_layer_collection_engine_settings_create(struct IDProperty *root);
+void BKE_layer_collection_engine_settings_validate_scene(struct Scene *scene);
+void BKE_layer_collection_engine_settings_validate_collection(struct LayerCollection *lc);
+
+struct IDProperty *BKE_scene_layer_engine_evaluated_get(struct SceneLayer *sl, const int type, const char *engine_name);
+struct IDProperty *BKE_scene_layer_engine_layer_get(struct SceneLayer *sl, const int type, const char *engine_name);
+struct IDProperty *BKE_scene_layer_engine_scene_get(struct Scene *scene, const int type, const char *engine_name);
+void BKE_scene_layer_engine_settings_callback_register(struct Main *bmain, const char *engine_name, EngineSettingsCB func);
+void BKE_scene_layer_engine_settings_callback_free(void);
+void BKE_scene_layer_engine_settings_validate_scene(struct Scene *scene);
+void BKE_scene_layer_engine_settings_validate_layer(struct SceneLayer *sl);
+void BKE_scene_layer_engine_settings_create(struct IDProperty *root);
+
+void BKE_collection_engine_property_add_float(struct IDProperty *props, const char *name, float value);
+void BKE_collection_engine_property_add_float_array(
+ struct IDProperty *props, const char *name, const float *values, const int array_length);
+void BKE_collection_engine_property_add_int(struct IDProperty *props, const char *name, int value);
+void BKE_collection_engine_property_add_bool(struct IDProperty *props, const char *name, bool value);
+
+int BKE_collection_engine_property_value_get_int(struct IDProperty *props, const char *name);
+float BKE_collection_engine_property_value_get_float(struct IDProperty *props, const char *name);
+const float *BKE_collection_engine_property_value_get_float_array(struct IDProperty *props, const char *name);
+bool BKE_collection_engine_property_value_get_bool(struct IDProperty *props, const char *name);
+void BKE_collection_engine_property_value_set_int(struct IDProperty *props, const char *name, int value);
+void BKE_collection_engine_property_value_set_float(struct IDProperty *props, const char *name, float value);
+void BKE_collection_engine_property_value_set_float_array(struct IDProperty *props, const char *name, const float *values);
+void BKE_collection_engine_property_value_set_bool(struct IDProperty *props, const char *name, bool value);
+
+/* evaluation */
+
+void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *eval_ctx,
+ struct Scene *scene,
+ struct SceneLayer *scene_layer);
+void BKE_layer_eval_layer_collection(struct EvaluationContext *eval_ctx,
+ struct LayerCollection *layer_collection,
+ struct LayerCollection *parent_layer_collection);
+void BKE_layer_eval_layer_collection_post(struct EvaluationContext *eval_ctx,
+ struct SceneLayer *scene_layer);
+
+/* iterators */
+
+void BKE_selected_objects_iterator_begin(BLI_Iterator *iter, void *data_in);
+void BKE_selected_objects_iterator_next(BLI_Iterator *iter);
+void BKE_selected_objects_iterator_end(BLI_Iterator *iter);
+
+void BKE_visible_objects_iterator_begin(BLI_Iterator *iter, void *data_in);
+void BKE_visible_objects_iterator_next(BLI_Iterator *iter);
+void BKE_visible_objects_iterator_end(BLI_Iterator *iter);
+
+void BKE_selected_bases_iterator_begin(BLI_Iterator *iter, void *data_in);
+void BKE_selected_bases_iterator_next(BLI_Iterator *iter);
+void BKE_selected_bases_iterator_end(BLI_Iterator *iter);
+
+void BKE_visible_bases_iterator_begin(BLI_Iterator *iter, void *data_in);
+void BKE_visible_bases_iterator_next(BLI_Iterator *iter);
+void BKE_visible_bases_iterator_end(BLI_Iterator *iter);
+
+#define FOREACH_SELECTED_OBJECT(sl, _instance) \
+ ITER_BEGIN(BKE_selected_objects_iterator_begin, \
+ BKE_selected_objects_iterator_next, \
+ BKE_selected_objects_iterator_end, \
+ sl, Object *, _instance)
+
+#define FOREACH_SELECTED_OBJECT_END \
+ ITER_END
+
+#define FOREACH_VISIBLE_OBJECT(sl, _instance) \
+ ITER_BEGIN(BKE_visible_objects_iterator_begin, \
+ BKE_visible_objects_iterator_next, \
+ BKE_visible_objects_iterator_end, \
+ sl, Object *, _instance)
+
+#define FOREACH_VISIBLE_OBJECT_END \
+ ITER_END
+
+#define FOREACH_SELECTED_BASE(sl, _instance) \
+ ITER_BEGIN(BKE_selected_bases_iterator_begin, \
+ BKE_selected_bases_iterator_next, \
+ BKE_selected_bases_iterator_end, \
+ sl, Base *, _instance)
+
+#define FOREACH_SELECTED_BASE_END \
+ ITER_END
+
+#define FOREACH_VISIBLE_BASE(sl, _instance) \
+ ITER_BEGIN(BKE_visible_bases_iterator_begin, \
+ BKE_visible_bases_iterator_next, \
+ BKE_visible_bases_iterator_end, \
+ sl, Base *, _instance)
+
+#define FOREACH_VISIBLE_BASE_END \
+ ITER_END
+
+
+#define FOREACH_OBJECT(sl, _instance) \
+{ \
+ Object *_instance; \
+ Base *base; \
+ for (base = (sl)->object_bases.first; base; base = base->next) { \
+ _instance = base->object;
+
+#define FOREACH_OBJECT_END \
+ } \
+}
+
+#define FOREACH_OBJECT_FLAG(scene, sl, flag, _instance) \
+{ \
+ IteratorBeginCb func_begin; \
+ IteratorCb func_next, func_end; \
+ void *data_in; \
+ \
+ if (flag == SELECT) { \
+ func_begin = &BKE_selected_objects_iterator_begin; \
+ func_next = &BKE_selected_objects_iterator_next; \
+ func_end = &BKE_selected_objects_iterator_end; \
+ data_in = (sl); \
+ } \
+ else { \
+ func_begin = BKE_scene_objects_iterator_begin; \
+ func_next = BKE_scene_objects_iterator_next; \
+ func_end = BKE_scene_objects_iterator_end; \
+ data_in = (scene); \
+ } \
+ ITER_BEGIN(func_begin, func_next, func_end, data_in, Object *, _instance)
+
+
+#define FOREACH_OBJECT_FLAG_END \
+ ITER_END \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_LAYER_H__ */
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 8ae5c2b3c45..0a5d37631d1 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -86,6 +86,10 @@ short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma
bool BKE_object_material_slot_add(struct Object *ob);
bool BKE_object_material_slot_remove(struct Object *ob);
+struct Image *BKE_object_material_edit_image_get(struct Object *ob, short mat_nr);
+struct Image **BKE_object_material_edit_image_get_array(struct Object *ob);
+bool BKE_object_material_edit_image_set(struct Object *ob, short mat_nr, struct Image *image);
+
void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
@@ -114,9 +118,6 @@ void free_matcopybuf(void);
void copy_matcopybuf(struct Material *ma);
void paste_matcopybuf(struct Material *ma);
-/* handle backward compatibility for tface/materials called from doversion */
-int do_version_tface(struct Main *main);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index b83bec5a302..57922e60f4b 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -186,13 +186,6 @@ void BKE_mesh_calc_normals_looptri(
const struct MLoop *mloop,
const struct MLoopTri *looptri, int looptri_num,
float (*r_tri_nors)[3]);
-void BKE_mesh_loop_tangents_ex(
- const struct MVert *mverts, const int numVerts, const struct MLoop *mloops,
- float (*r_looptangent)[4], float (*loopnors)[3], const struct MLoopUV *loopuv,
- const int numLoops, const struct MPoly *mpolys, const int numPolys,
- struct ReportList *reports);
-void BKE_mesh_loop_tangents(
- struct Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], struct ReportList *reports);
/**
* References a contiguous loop-fan with normal offset vars.
@@ -294,7 +287,7 @@ void BKE_mesh_loops_to_mface_corners(
const int numTex, const int numCol,
const bool hasPCol, const bool hasOrigSpace, const bool hasLNor);
void BKE_mesh_loops_to_tessdata(
- struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, struct MFace *mface,
+ struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
void BKE_mesh_tangent_loops_to_tessdata(
struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
@@ -372,7 +365,6 @@ void BKE_mesh_calc_relative_deform(
/* *** mesh_validate.c *** */
int BKE_mesh_validate(struct Mesh *me, const int do_verbose, const int cddata_check_mask);
-void BKE_mesh_cd_validate(struct Mesh *me);
int BKE_mesh_validate_material_indices(struct Mesh *me);
bool BKE_mesh_validate_arrays(
@@ -407,6 +399,15 @@ struct EvaluationContext;
void BKE_mesh_eval_geometry(struct EvaluationContext *eval_ctx,
struct Mesh *mesh);
+/* Draw Cache */
+enum {
+ BKE_MESH_BATCH_DIRTY_ALL = 0,
+ BKE_MESH_BATCH_DIRTY_SELECT,
+ BKE_MESH_BATCH_DIRTY_PAINT,
+};
+void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode);
+void BKE_mesh_batch_cache_free(struct Mesh *me);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h
new file mode 100644
index 00000000000..66b8a26e35b
--- /dev/null
+++ b/source/blender/blenkernel/BKE_mesh_tangent.h
@@ -0,0 +1,59 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_MESH_TANGENT_H__
+#define __BKE_MESH_TANGENT_H__
+
+void BKE_mesh_calc_loop_tangent_single_ex(
+ const struct MVert *mverts, const int numVerts, const struct MLoop *mloops,
+ float (*r_looptangent)[4], float (*loopnors)[3], const struct MLoopUV *loopuv,
+ const int numLoops, const struct MPoly *mpolys, const int numPolys,
+ struct ReportList *reports);
+void BKE_mesh_calc_loop_tangent_single(
+ struct Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], struct ReportList *reports);
+
+void BKE_mesh_calc_loop_tangent_ex(
+ const struct MVert *mvert,
+ const struct MPoly *mpoly, const uint mpoly_len,
+ const struct MLoop *mloop,
+ const struct MLoopTri *looptri, const uint looptri_len,
+
+ struct CustomData *loopdata,
+ bool calc_active_tangent,
+ const char (*tangent_names)[64], int tangent_names_len,
+ const float (*poly_normals)[3],
+ const float (*loop_normals)[3],
+ const float (*vert_orco)[3],
+ /* result */
+ struct CustomData *loopdata_out,
+ const uint loopdata_out_len,
+ char *tangent_mask_curr_p);
+
+/* Helpers */
+void BKE_mesh_add_loop_tangent_named_layer_for_uv(
+ struct CustomData *uv_data, struct CustomData *tan_data, int numLoopData,
+ const char *layer_name);
+void BKE_mesh_calc_loop_tangent_step_0(
+ const struct CustomData *loopData, bool calc_active_tangent,
+ const char (*tangent_names)[64], int tangent_names_count,
+ bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
+ char *ract_uv_name, char *rren_uv_name, char *rtangent_mask);
+
+#endif /* __BKE_MESH_TANGENT_H__ */
+
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b241b5ca5b7..be6ed4f254d 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -38,6 +38,7 @@ struct DagForest;
struct DagNode;
struct Object;
struct Scene;
+struct SceneLayer;
struct ListBase;
struct bArmature;
struct Main;
@@ -260,15 +261,6 @@ typedef struct ModifierTypeInfo {
*/
bool (*isDisabled)(struct ModifierData *md, int userRenderParams);
- /* Add the appropriate relations to the DEP graph depending on the
- * modifier data.
- *
- * This function is optional.
- */
- void (*updateDepgraph)(struct ModifierData *md, struct DagForest *forest,
- struct Main *bmain, struct Scene *scene,
- struct Object *ob, struct DagNode *obNode);
-
/* Add the appropriate relations to the dependency graph.
*
* This function is optional.
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 41028c73014..e87bd5e3a39 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -253,6 +253,7 @@ typedef struct bNodeType {
/* nodetype->compatibility */
#define NODE_OLD_SHADING 1
#define NODE_NEW_SHADING 2
+#define NODE_NEWER_SHADING 3
/* node resize directions */
#define NODE_RESIZE_TOP 1
@@ -687,6 +688,13 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Tree
+ */
+
+void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, const int layer_index);
+
/* -------------------------------------------------------------------- */
/** \name Shader Nodes
*/
@@ -786,6 +794,8 @@ struct ShadeResult;
#define SH_NODE_UVALONGSTROKE 191
#define SH_NODE_TEX_POINTDENSITY 192
#define SH_NODE_BSDF_PRINCIPLED 193
+#define SH_NODE_OUTPUT_METALLIC 194
+#define SH_NODE_OUTPUT_SPECULAR 195
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index b6633ea6198..69ff9765a93 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -35,9 +35,10 @@ extern "C" {
#include "BLI_compiler_attrs.h"
-struct Base;
+struct BaseLegacy;
struct EvaluationContext;
struct Scene;
+struct SceneLayer;
struct Object;
struct BoundBox;
struct View3D;
@@ -89,9 +90,9 @@ struct Object *BKE_object_add_only_object(
int type, const char *name)
ATTR_NONNULL(1) ATTR_RETURNS_NONNULL;
struct Object *BKE_object_add(
- struct Main *bmain, struct Scene *scene,
+ struct Main *bmain, struct Scene *scene, struct SceneLayer *sl,
int type, const char *name)
- ATTR_NONNULL(1, 2) ATTR_RETURNS_NONNULL;
+ ATTR_NONNULL(1, 2, 3) ATTR_RETURNS_NONNULL;
void *BKE_object_obdata_add_from_type(
struct Main *bmain,
int type, const char *name)
@@ -101,9 +102,9 @@ void BKE_object_lod_add(struct Object *ob);
void BKE_object_lod_sort(struct Object *ob);
bool BKE_object_lod_remove(struct Object *ob, int level);
void BKE_object_lod_update(struct Object *ob, const float camera_position[3]);
-bool BKE_object_lod_is_usable(struct Object *ob, struct Scene *scene);
-struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct Scene *scene);
-struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene);
+bool BKE_object_lod_is_usable(struct Object *ob, struct SceneLayer *sl);
+struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct SceneLayer *sl);
+struct Object *BKE_object_lod_matob_get(struct Object *ob, struct SceneLayer *sl);
struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, bool copy_caches);
struct Object *BKE_object_copy(struct Main *bmain, struct Object *ob);
@@ -152,8 +153,7 @@ bool BKE_object_minmax_dupli(struct Scene *scene, struct Object *ob, float r_min
void BKE_object_foreach_display_point(struct Object *ob, float obmat[4][4],
void (*func_cb)(const float[3], void *), void *user_data);
void BKE_scene_foreach_display_point(struct Scene *scene,
- struct View3D *v3d,
- const short flag,
+ struct SceneLayer *sl,
void (*func_cb)(const float[3], void *), void *user_data);
bool BKE_object_parent_loop_check(const struct Object *parent, const struct Object *ob);
@@ -255,9 +255,9 @@ typedef enum eObjectSet {
OB_SET_ALL /* All Objects */
} eObjectSet;
-struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
+struct LinkNode *BKE_object_relational_superset(struct SceneLayer *scene_layer, eObjectSet objectSet, eObRelationTypes includeFilter);
struct LinkNode *BKE_object_groups(struct Object *ob);
-void BKE_object_groups_clear(struct Scene *scene, struct Base *base, struct Object *object);
+void BKE_object_groups_clear(struct Object *object);
struct KDTree *BKE_object_as_kdtree(struct Object *ob, int *r_tot);
diff --git a/source/blender/blenkernel/BKE_object_facemap.h b/source/blender/blenkernel/BKE_object_facemap.h
new file mode 100644
index 00000000000..332b2851e85
--- /dev/null
+++ b/source/blender/blenkernel/BKE_object_facemap.h
@@ -0,0 +1,53 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Antony Riakiotakis
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_OBJECT_FACEMAP_H__
+#define __BKE_OBJECT_FACEMAP_H__
+
+/** \file BKE_object_facemap.h
+ * \ingroup bke
+ * \brief Functions for dealing with object face-maps.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bFaceMap;
+struct ListBase;
+struct Object;
+
+struct bFaceMap *BKE_object_facemap_add(struct Object *ob);
+struct bFaceMap *BKE_object_facemap_add_name(struct Object *ob, const char *name);
+void BKE_object_facemap_remove(struct Object *ob, struct bFaceMap *fmap);
+void BKE_object_facemap_clear(struct Object *ob);
+
+int BKE_object_facemap_name_index(struct Object *ob, const char *name);
+void BKE_object_facemap_unique_name(struct Object *ob, struct bFaceMap *fmap);
+struct bFaceMap *BKE_object_facemap_find_name(struct Object *ob, const char *name);
+void BKE_object_facemap_copy_list(struct ListBase *outbase, struct ListBase *inbase);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_OBJECT_FACEMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_outliner_treehash.h b/source/blender/blenkernel/BKE_outliner_treehash.h
index 454edb40c4e..b82bc692402 100644
--- a/source/blender/blenkernel/BKE_outliner_treehash.h
+++ b/source/blender/blenkernel/BKE_outliner_treehash.h
@@ -36,8 +36,9 @@ void *BKE_outliner_treehash_create_from_treestore(struct BLI_mempool *treestore)
/* full rebuild for already allocated hashtable */
void *BKE_outliner_treehash_rebuild_from_treestore(void *treehash, struct BLI_mempool *treestore);
-/* full rebuild for already allocated hashtable */
+/* Add/remove hashtable elements */
void BKE_outliner_treehash_add_element(void *treehash, struct TreeStoreElem *elem);
+void BKE_outliner_treehash_remove_element(void *treehash, struct TreeStoreElem *elem);
/* find first unused element with specific type, nr and id */
struct TreeStoreElem *BKE_outliner_treehash_lookup_unused(void *treehash, short type, short nr, struct ID *id);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 0a3cc950f32..f72c4ad9dac 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -52,6 +52,7 @@ struct PaletteColor;
struct PBVH;
struct ReportList;
struct Scene;
+struct SceneLayer;
struct Sculpt;
struct StrokeCache;
struct Tex;
@@ -89,8 +90,8 @@ typedef enum OverlayControlFlags {
PAINT_OVERLAY_OVERRIDE_PRIMARY | \
PAINT_OVERLAY_OVERRIDE_CURSOR)
-void BKE_paint_invalidate_overlay_tex(struct Scene *scene, const struct Tex *tex);
-void BKE_paint_invalidate_cursor_overlay(struct Scene *scene, struct CurveMapping *curve);
+void BKE_paint_invalidate_overlay_tex(struct Scene *scene, struct SceneLayer *sl, const struct Tex *tex);
+void BKE_paint_invalidate_cursor_overlay(struct Scene *scene, struct SceneLayer *sl, struct CurveMapping *curve);
void BKE_paint_invalidate_overlay_all(void);
OverlayControlFlags BKE_paint_get_overlay_flags(void);
void BKE_paint_reset_overlay_invalid(OverlayControlFlags flag);
@@ -120,7 +121,7 @@ void BKE_paint_cavity_curve_preset(struct Paint *p, int preset);
short BKE_paint_object_mode_from_paint_mode(PaintMode mode);
struct Paint *BKE_paint_get_active_from_paintmode(struct Scene *sce, PaintMode mode);
-struct Paint *BKE_paint_get_active(struct Scene *sce);
+struct Paint *BKE_paint_get_active(struct Scene *sce, struct SceneLayer *sl);
struct Paint *BKE_paint_get_active_from_context(const struct bContext *C);
PaintMode BKE_paintmode_get_active_from_context(const struct bContext *C);
struct Brush *BKE_paint_brush(struct Paint *paint);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 2b6a84a2f87..90f7703b967 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -479,3 +479,10 @@ void BKE_particle_system_eval(struct EvaluationContext *eval_ctx,
struct ParticleSystem *psys);
#endif
+
+/* Draw Cache */
+enum {
+ BKE_PARTICLE_BATCH_DIRTY_ALL = 0,
+};
+void BKE_particle_batch_cache_dirty(struct ParticleSystem *psys, int mode);
+void BKE_particle_batch_cache_free(struct ParticleSystem *psys);
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 927303f8b3c..27c6814b959 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -30,6 +30,7 @@
#include "BLI_ghash.h"
#include "BLI_utildefines.h"
+struct Batch;
struct CCGElem;
struct CCGKey;
struct CustomData;
@@ -118,6 +119,9 @@ void BKE_pbvh_raycast_project_ray_root(
void BKE_pbvh_node_draw(PBVHNode *node, void *data);
void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
int (*setMaterial)(int matnr, void *attribs), bool wireframe, bool fast);
+void BKE_pbvh_draw_cb(
+ PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast,
+ void (*draw_fn)(void *user_data, struct Batch *batch), void *user_data);
/* PBVH Access */
typedef enum {
@@ -354,6 +358,7 @@ bool BKE_pbvh_node_vert_update_check_any(PBVH *bvh, PBVHNode *node);
//void BKE_pbvh_node_BB_reset(PBVHNode *node);
//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
+bool pbvh_has_mask(PBVH *bvh);
void pbvh_show_diffuse_color_set(PBVH *bvh, bool show_diffuse_color);
#endif /* __BKE_PBVH_H__ */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index d2152950bff..454fba0126e 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -38,14 +38,17 @@ extern "C" {
#endif
struct AviCodecData;
-struct Base;
+struct BaseLegacy;
struct EvaluationContext;
struct Main;
struct Object;
+struct Base;
struct QuicktimeCodecData;
struct RenderData;
struct SceneRenderLayer;
struct Scene;
+struct SceneCollection;
+struct SceneLayer;
struct UnitSettings;
struct Main;
@@ -70,13 +73,15 @@ void BKE_scene_free(struct Scene *sce);
void BKE_scene_init(struct Scene *sce);
struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
+void BKE_scene_remove_rigidbody_object(struct Scene *scene, struct Object *ob);
+
/* base functions */
-struct Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
-struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
-struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
-void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
+struct BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
+struct BaseLegacy *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
+struct BaseLegacy *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
+void BKE_scene_base_unlink(struct Scene *sce, struct BaseLegacy *base);
void BKE_scene_base_deselect_all(struct Scene *sce);
-void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
+void BKE_scene_base_select(struct Scene *sce, struct BaseLegacy *selbase);
/* Scene base iteration function.
* Define struct here, so no need to bother with alloc/free it.
@@ -90,10 +95,14 @@ typedef struct SceneBaseIter {
} SceneBaseIter;
int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
- struct Scene **scene, int val, struct Base **base, struct Object **ob);
+ struct Scene **scene, int val, struct BaseLegacy **base, struct Object **ob);
-void BKE_scene_base_flag_to_objects(struct Scene *scene);
+void BKE_scene_base_flag_to_objects(struct SceneLayer *sl);
void BKE_scene_base_flag_from_objects(struct Scene *scene);
+void BKE_scene_base_flag_sync_from_base(struct BaseLegacy *base);
+void BKE_scene_base_flag_sync_from_object(struct BaseLegacy *base);
+void BKE_scene_object_base_flag_sync_from_base(struct Base *base);
+void BKE_scene_object_base_flag_sync_from_object(struct Base *base);
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
@@ -103,6 +112,8 @@ void BKE_scene_groups_relink(struct Scene *sce);
void BKE_scene_make_local(struct Main *bmain, struct Scene *sce, const bool lib_local);
+struct Scene *BKE_scene_find_from_collection(const struct Main *bmain, const struct SceneCollection *scene_collection);
+
struct Object *BKE_scene_camera_find(struct Scene *sc);
#ifdef DURIAN_CAMERA_SWITCH
struct Object *BKE_scene_camera_switch_find(struct Scene *scene); // DURIAN_CAMERA_SWITCH
@@ -121,8 +132,7 @@ void BKE_scene_frame_set(struct Scene *scene, double cfra);
/* ** Scene evaluation ** */
void BKE_scene_update_tagged(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce);
-void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay);
-void BKE_scene_update_for_newframe_ex(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay, bool do_invisible_flush);
+void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce);
struct SceneRenderLayer *BKE_scene_add_render_layer(struct Scene *sce, const char *name);
bool BKE_scene_remove_render_layer(struct Main *main, struct Scene *scene, struct SceneRenderLayer *srl);
@@ -143,6 +153,7 @@ bool BKE_scene_use_spherical_stereo(struct Scene *scene);
bool BKE_scene_uses_blender_internal(const struct Scene *scene);
bool BKE_scene_uses_blender_game(const struct Scene *scene);
+bool BKE_scene_uses_blender_eevee(const struct Scene *scene);
void BKE_scene_disable_color_management(struct Scene *scene);
bool BKE_scene_check_color_management_enabled(const struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 14e978b23f2..7def41d0540 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -49,6 +49,7 @@ struct bScreen;
struct uiLayout;
struct uiList;
struct wmKeyConfig;
+struct wmManipulatorMap;
struct wmNotifier;
struct wmWindow;
struct wmWindowManager;
@@ -81,7 +82,8 @@ typedef struct SpaceType {
/* exit is called when the area is hidden or removed */
void (*exit)(struct wmWindowManager *, struct ScrArea *);
/* Listeners can react to bContext changes */
- void (*listener)(struct bScreen *sc, struct ScrArea *, struct wmNotifier *);
+ void (*listener)(struct bScreen *sc, struct ScrArea *,
+ struct wmNotifier *, const struct Scene *scene);
/* refresh context, called after filereads, ED_area_tag_refresh() */
void (*refresh)(const struct bContext *, struct ScrArea *);
@@ -96,6 +98,9 @@ typedef struct SpaceType {
/* on startup, define dropboxes for spacetype+regions */
void (*dropboxes)(void);
+ /* initialize manipulator-map-types and manipulator-group-types with the region */
+ void (*manipulators)(void);
+
/* return context data */
int (*context)(const struct bContext *, const char *, struct bContextDataResult *);
@@ -129,8 +134,9 @@ typedef struct ARegionType {
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *, struct ARegion *);
/* contextual changes should be handled here */
- void (*listener)(struct bScreen *sc, struct ScrArea *, struct ARegion *, struct wmNotifier *);
-
+ void (*listener)(struct bScreen *, struct ScrArea *, struct ARegion *,
+ struct wmNotifier *, const struct Scene *scene);
+
void (*free)(struct ARegion *);
/* split region, copy data optionally */
@@ -284,6 +290,8 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
void BKE_screen_area_free(struct ScrArea *sa);
+/* Manipulator-maps of a region need to be freed with the region. Uses callback to avoid low-level call. */
+void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *));
struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 811e9136fc9..7c09cafaf64 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -421,7 +421,7 @@ struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seq
/* view3d draw callback, run when not in background view */
typedef struct ImBuf *(*SequencerDrawView)(
- struct Scene *, struct Object *, int, int,
+ struct Scene *, struct SceneLayer *sl, struct Object *, int, int,
unsigned int, int, bool, bool, bool,
int, int, bool, const char *,
struct GPUFX *, struct GPUOffScreen *, char[256]);
diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h
index 20366f00df6..33d7acdd864 100644
--- a/source/blender/blenkernel/BKE_smoke.h
+++ b/source/blender/blenkernel/BKE_smoke.h
@@ -35,7 +35,7 @@
typedef float (*bresenham_callback)(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
-struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
+struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct SceneLayer *sl, struct Object *ob, struct DerivedMesh *dm);
void smoke_reallocate_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old);
void smoke_reallocate_highres_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old);
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 486fe8ed5a8..75c5faf4088 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -59,7 +59,8 @@ extern void sbFree(struct SoftBody *sb);
extern void sbFreeSimulation(struct SoftBody *sb);
/* do one simul step, reading and writing vertex locs from given array */
-extern void sbObjectStep(struct Scene *scene, struct Object *ob, float framnr, float (*vertexCos)[3], int numVerts);
+extern void sbObjectStep(struct Scene *scene, struct SceneLayer *sl, struct Object *ob,
+ float framnr, float (*vertexCos)[3], int numVerts);
/* makes totally fresh start situation, resets time */
extern void sbObjectToSoftbody(struct Object *ob);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 157c4408d6a..1ddc6fce818 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../blenloader
../blentranslation
../depsgraph
+ ../draw
../gpu
../ikplugin
../imbuf
@@ -85,6 +86,7 @@ set(SRC
intern/camera.c
intern/cdderivedmesh.c
intern/cloth.c
+ intern/collection.c
intern/collision.c
intern/colortools.c
intern/constraint.c
@@ -101,6 +103,7 @@ set(SRC
intern/editderivedmesh.c
intern/editmesh.c
intern/editmesh_bvh.c
+ intern/editmesh_tangent.c
intern/effect.c
intern/fcurve.c
intern/fluidsim.c
@@ -133,6 +136,7 @@ set(SRC
intern/mesh_evaluate.c
intern/mesh_mapping.c
intern/mesh_remap.c
+ intern/mesh_tangent.c
intern/mesh_validate.c
intern/modifier.c
intern/modifiers_bmesh.c
@@ -141,6 +145,7 @@ set(SRC
intern/nla.c
intern/node.c
intern/object.c
+ intern/object_facemap.c
intern/object_deform.c
intern/object_dupli.c
intern/object_update.c
@@ -156,6 +161,7 @@ set(SRC
intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
+ intern/layer.c
intern/report.c
intern/rigidbody.c
intern/sca.c
@@ -213,6 +219,7 @@ set(SRC
BKE_ccg.h
BKE_cdderivedmesh.h
BKE_cloth.h
+ BKE_collection.h
BKE_collision.h
BKE_colortools.h
BKE_constraint.h
@@ -228,6 +235,7 @@ set(SRC
BKE_dynamicpaint.h
BKE_editmesh.h
BKE_editmesh_bvh.h
+ BKE_editmesh_tangent.h
BKE_effect.h
BKE_fcurve.h
BKE_fluidsim.h
@@ -257,12 +265,14 @@ set(SRC
BKE_mesh.h
BKE_mesh_mapping.h
BKE_mesh_remap.h
+ BKE_mesh_tangent.h
BKE_modifier.h
BKE_movieclip.h
BKE_multires.h
BKE_nla.h
BKE_node.h
BKE_object.h
+ BKE_object_facemap.h
BKE_object_deform.h
BKE_ocean.h
BKE_outliner_treehash.h
@@ -272,6 +282,7 @@ set(SRC
BKE_pbvh.h
BKE_pointcache.h
BKE_property.h
+ BKE_layer.h
BKE_report.h
BKE_rigidbody.h
BKE_sca.h
@@ -295,7 +306,6 @@ set(SRC
BKE_writeavi.h
BKE_writeframeserver.h
- depsgraph_private.h
nla_private.h
tracking_private.h
intern/CCGSubSurf.h
@@ -535,8 +545,4 @@ endif()
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
#endif()
-if(WITH_LEGACY_DEPSGRAPH)
- add_definitions(-DWITH_LEGACY_DEPSGRAPH)
-endif()
-
blender_add_lib(bf_blenkernel "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
deleted file mode 100644
index 69ca75836d9..00000000000
--- a/source/blender/blenkernel/depsgraph_private.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * 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) 2004 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/blenkernel/depsgraph_private.h
- * \ingroup bke
- */
-
-#ifndef __DEPSGRAPH_PRIVATE_H__
-#define __DEPSGRAPH_PRIVATE_H__
-
-#include "BKE_depsgraph.h"
-#include "DNA_constraint_types.h"
-#include "BKE_constraint.h"
-
-struct Scene;
-struct Group;
-struct EffectorWeights;
-struct ModifierData;
-
-/* **** DAG relation types *** */
-
-/* scene link to object */
-#define DAG_RL_SCENE (1 << 0)
-/* object link to data */
-#define DAG_RL_DATA (1 << 1)
-
-/* object changes object (parent, track, constraints) */
-#define DAG_RL_OB_OB (1 << 2)
-/* object changes obdata (hooks, constraints) */
-#define DAG_RL_OB_DATA (1 << 3)
-/* data changes object (vertex parent) */
-#define DAG_RL_DATA_OB (1 << 4)
-/* data changes data (deformers) */
-#define DAG_RL_DATA_DATA (1 << 5)
-
-#define DAG_NO_RELATION (1 << 6)
-
-#define DAG_RL_ALL_BUT_DATA (DAG_RL_SCENE | DAG_RL_OB_OB | DAG_RL_OB_DATA | DAG_RL_DATA_OB | DAG_RL_DATA_DATA)
-#define DAG_RL_ALL (DAG_RL_ALL_BUT_DATA | DAG_RL_DATA)
-
-
-#define DAGQUEUEALLOC 50
-
-enum {
- DAG_WHITE = 0,
- DAG_GRAY = 1,
- DAG_BLACK = 2
-};
-
-typedef struct DagAdjList {
- struct DagNode *node;
- short type;
- int count; /* number of identical arcs */
- unsigned int lay; // for flushing redraw/rebuild events
- const char *name;
- struct DagAdjList *next;
-} DagAdjList;
-
-
-typedef struct DagNode {
- int color;
- short type;
- float x, y, k;
- void *ob;
- void *first_ancestor;
- int ancestor_count;
- unsigned int lay; /* accumulated layers of its relations + itself */
- unsigned int scelay; /* layers due to being in scene */
- uint64_t customdata_mask; /* customdata mask */
- int lasttime; /* if lasttime != DagForest->time, this node was not evaluated yet for flushing */
- int BFS_dist; /* BFS distance */
- int DFS_dist; /* DFS distance */
- int DFS_dvtm; /* DFS discovery time */
- int DFS_fntm; /* DFS Finishing time */
- struct DagAdjList *child;
- struct DagAdjList *parent;
- struct DagNode *next;
-
- /* Threaded evaluation routines */
- uint32_t num_pending_parents; /* number of parents which are not updated yet
- * this node has got.
- * Used by threaded update for faster detect whether node could be
- * updated aready.
- */
- bool scheduled;
-
- /* Runtime flags mainly used to determine which extra data is to be evaluated
- * during object_handle_update(). Such an extra data is what depends on the
- * DAG topology, meaning this flags indicates the data evaluation of which
- * depends on the node dependencies.
- */
- short eval_flags;
-} DagNode;
-
-typedef struct DagNodeQueueElem {
- struct DagNode *node;
- struct DagNodeQueueElem *next;
-} DagNodeQueueElem;
-
-typedef struct DagNodeQueue {
- DagNodeQueueElem *first;
- DagNodeQueueElem *last;
- int count;
- int maxlevel;
- struct DagNodeQueue *freenodes;
-} DagNodeQueue;
-
-/* forest as we may have more than one DAG unconnected */
-typedef struct DagForest {
- ListBase DagNode;
- struct GHash *nodeHash;
- int numNodes;
- bool is_acyclic;
- int time; /* for flushing/tagging, compare with node->lasttime */
- bool ugly_hack_sorry; /* prevent type check */
- bool need_update;
-} DagForest;
-
-// queue operations
-DagNodeQueue *queue_create(int slots);
-void queue_raz(DagNodeQueue *queue);
-void push_queue(DagNodeQueue *queue, DagNode *node);
-void push_stack(DagNodeQueue *queue, DagNode *node);
-DagNode *pop_queue(DagNodeQueue *queue);
-DagNode *get_top_node_queue(DagNodeQueue *queue);
-void queue_delete(DagNodeQueue *queue);
-
-// Dag management
-DagForest *dag_init(void);
-DagForest *build_dag(struct Main *bmain, struct Scene *sce, short mask);
-void free_forest(struct DagForest *Dag);
-DagNode *dag_find_node(DagForest *forest, void *fob);
-DagNode *dag_add_node(DagForest *forest, void *fob);
-DagNode *dag_get_node(DagForest *forest, void *fob);
-DagNode *dag_get_sub_node(DagForest *forest, void *fob);
-void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name);
-
-typedef bool (*DagCollobjFilterFunction)(struct Object *obj, struct ModifierData *md);
-
-void dag_add_collision_relations(DagForest *dag, struct Scene *scene, Object *ob, DagNode *node, struct Group *group, int layer, unsigned int modifier_type, DagCollobjFilterFunction fn, bool dupli, const char *name);
-void dag_add_forcefield_relations(DagForest *dag, struct Scene *scene, Object *ob, DagNode *node, struct EffectorWeights *eff, bool add_absorption, int skip_forcefield, const char *name);
-
-void graph_print_queue(DagNodeQueue *nqueue);
-void graph_print_queue_dist(DagNodeQueue *nqueue);
-void graph_print_adj_list(DagForest *dag);
-
-#endif /* __DEPSGRAPH_PRIVATE_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 792e9195f12..68bcfa878ac 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -42,7 +42,7 @@
# include "opensubdiv_converter_capi.h"
#endif
-#include "GL/glew.h"
+#include "GPU_glew.h"
/***/
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index 65cf899b42b..9c86a22a1f8 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
@@ -43,7 +43,7 @@
#include "opensubdiv_capi.h"
#include "opensubdiv_converter_capi.h"
-#include "GL/glew.h"
+#include "GPU_glew.h"
#include "GPU_extensions.h"
#define OSD_LOG if (false) printf
@@ -993,7 +993,7 @@ void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subdiv_uvs)
void BKE_subsurf_osd_init(void)
{
- openSubdiv_init(GPU_legacy_support());
+ openSubdiv_init();
BLI_spin_init(&delete_spin);
}
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 18e9bdf6cd1..874637896cd 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -54,11 +54,13 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_editmesh.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_tangent.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_paint.h"
@@ -76,11 +78,12 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
#include "BLI_sys_types.h" /* for intptr_t support */
#include "GPU_buffers.h"
-#include "GPU_glew.h"
#include "GPU_shader.h"
+#include "GPU_immediate.h"
#ifdef WITH_OPENSUBDIV
-# include "BKE_depsgraph.h"
+# include "DEG_depsgraph.h"
+# include "DEG_depsgraph_query.h"
# include "DNA_userdef_types.h"
#endif
@@ -317,7 +320,7 @@ void DM_init(
dm->numPolyData = numPolys;
DM_init_funcs(dm);
-
+
dm->needsFree = 1;
dm->auto_bump_scale = -1.0f;
dm->dirty = 0;
@@ -377,6 +380,7 @@ int DM_release(DerivedMesh *dm)
if (dm->needsFree) {
bvhcache_free(&dm->bvhCache);
GPU_drawobject_free(dm);
+
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
CustomData_free(&dm->faceData, dm->numTessFaceData);
@@ -529,7 +533,6 @@ void DM_update_tessface_data(DerivedMesh *dm)
MLoop *ml = dm->getLoopArray(dm);
CustomData *fdata = dm->getTessFaceDataLayout(dm);
- CustomData *pdata = dm->getPolyDataLayout(dm);
CustomData *ldata = dm->getLoopDataLayout(dm);
const int totface = dm->getNumTessFaces(dm);
@@ -542,7 +545,7 @@ void DM_update_tessface_data(DerivedMesh *dm)
if (!polyindex)
return;
- CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+ CustomData_from_bmeshpoly(fdata, ldata, totface);
if (CustomData_has_layer(fdata, CD_MTFACE) ||
CustomData_has_layer(fdata, CD_MCOL) ||
@@ -574,7 +577,7 @@ void DM_update_tessface_data(DerivedMesh *dm)
* 0 for quads (because our quads may have been rotated compared to their org poly, see tessellation code).
* So we pass the MFace's, and BKE_mesh_loops_to_tessdata will use MFace->v4 index as quad test.
*/
- BKE_mesh_loops_to_tessdata(fdata, ldata, pdata, mface, polyindex, loopindex, totface);
+ BKE_mesh_loops_to_tessdata(fdata, ldata, mface, polyindex, loopindex, totface);
MEM_freeN(loopindex);
}
@@ -592,7 +595,6 @@ void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate)
MLoop *ml = dm->getLoopArray(dm);
CustomData *fdata = dm->getTessFaceDataLayout(dm);
- CustomData *pdata = dm->getPolyDataLayout(dm);
CustomData *ldata = dm->getLoopDataLayout(dm);
const int totface = dm->getNumTessFaces(dm);
@@ -609,7 +611,7 @@ void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate)
for (int j = 0; j < ldata->totlayer; j++) {
if (ldata->layers[j].type == CD_TANGENT) {
CustomData_add_layer_named(fdata, CD_TANGENT, CD_CALLOC, NULL, totface, ldata->layers[j].name);
- CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
+ CustomData_bmesh_update_active_layers(fdata, ldata);
if (!loopindex) {
loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
@@ -639,7 +641,7 @@ void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate)
}
if (loopindex)
MEM_freeN(loopindex);
- BLI_assert(CustomData_from_bmeshpoly_test(fdata, pdata, ldata, true));
+ BLI_assert(CustomData_from_bmeshpoly_test(fdata, ldata, true));
}
if (G.debug & G_DEBUG)
@@ -2603,7 +2605,7 @@ static bool calc_modifiers_skip_orco(Scene *scene,
else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
return false;
}
- else if ((DAG_get_eval_flags_for_object(scene, ob) & DAG_EVAL_NEED_CPU) != 0) {
+ else if ((DEG_get_eval_flags_for_id(scene->depsgraph, &ob->id) & DAG_EVAL_NEED_CPU) != 0) {
return false;
}
SubsurfModifierData *smd = (SubsurfModifierData *)last_md;
@@ -2679,7 +2681,9 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C
static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *r_need_mapping)
{
- Object *actob = scene->basact ? scene->basact->object : NULL;
+ /* TODO(sergey): Avoid this linear list lookup. */
+ SceneLayer *sl = BKE_scene_layer_context_active(scene);
+ Object *actob = sl->basact ? sl->basact->object : NULL;
CustomDataMask mask = ob->customdata_mask;
if (r_need_mapping) {
@@ -3037,234 +3041,6 @@ void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int
/* ******************* GLSL ******************** */
-/** \name Tangent Space Calculation
- * \{ */
-
-/* Necessary complexity to handle looptri's as quads for correct tangents */
-#define USE_LOOPTRI_DETECT_QUADS
-
-typedef struct {
- float (*precomputedFaceNormals)[3];
- float (*precomputedLoopNormals)[3];
- const MLoopTri *looptri;
- MLoopUV *mloopuv; /* texture coordinates */
- MPoly *mpoly; /* indices */
- MLoop *mloop; /* indices */
- MVert *mvert; /* vertices & normals */
- float (*orco)[3];
- float (*tangent)[4]; /* destination */
- int numTessFaces;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- /* map from 'fake' face index to looptri,
- * quads will point to the first looptri of the quad */
- const int *face_as_quad_map;
- int num_face_as_quad_map;
-#endif
-
-} SGLSLMeshToTangent;
-
-/* interface */
-#include "mikktspace.h"
-
-static int dm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
-{
- SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- return pMesh->num_face_as_quad_map;
-#else
- return pMesh->numTessFaces;
-#endif
-}
-
-static int dm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
-{
-#ifdef USE_LOOPTRI_DETECT_QUADS
- SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
- if (pMesh->face_as_quad_map) {
- const MLoopTri *lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
- const MPoly *mp = &pMesh->mpoly[lt->poly];
- if (mp->totloop == 4) {
- return 4;
- }
- }
- return 3;
-#else
- UNUSED_VARS(pContext, face_num);
- return 3;
-#endif
-}
-
-static void dm_ts_GetPosition(
- const SMikkTSpaceContext *pContext, float r_co[3],
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
- const MLoopTri *lt;
- int loop_index;
- const float *co;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
- const MPoly *mp = &pMesh->mpoly[lt->poly];
- if (mp->totloop == 4) {
- loop_index = mp->loopstart + vert_index;
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = &pMesh->looptri[face_num];
- }
-#else
- lt = &pMesh->looptri[face_num];
-#endif
- loop_index = lt->tri[vert_index];
-
-finally:
- co = pMesh->mvert[pMesh->mloop[loop_index].v].co;
- copy_v3_v3(r_co, co);
-}
-
-static void dm_ts_GetTextureCoordinate(
- const SMikkTSpaceContext *pContext, float r_uv[2],
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
- const MLoopTri *lt;
- int loop_index;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
- const MPoly *mp = &pMesh->mpoly[lt->poly];
- if (mp->totloop == 4) {
- loop_index = mp->loopstart + vert_index;
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = &pMesh->looptri[face_num];
- }
-#else
- lt = &pMesh->looptri[face_num];
-#endif
- loop_index = lt->tri[vert_index];
-
-finally:
- if (pMesh->mloopuv != NULL) {
- const float *uv = pMesh->mloopuv[loop_index].uv;
- copy_v2_v2(r_uv, uv);
- }
- else {
- const float *orco = pMesh->orco[pMesh->mloop[loop_index].v];
- map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
- }
-}
-
-static void dm_ts_GetNormal(
- const SMikkTSpaceContext *pContext, float r_no[3],
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- const MLoopTri *lt;
- int loop_index;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
- const MPoly *mp = &pMesh->mpoly[lt->poly];
- if (mp->totloop == 4) {
- loop_index = mp->loopstart + vert_index;
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = &pMesh->looptri[face_num];
- }
-#else
- lt = &pMesh->looptri[face_num];
-#endif
- loop_index = lt->tri[vert_index];
-
-finally:
- if (pMesh->precomputedLoopNormals) {
- copy_v3_v3(r_no, pMesh->precomputedLoopNormals[loop_index]);
- }
- else if ((pMesh->mpoly[lt->poly].flag & ME_SMOOTH) == 0) { /* flat */
- if (pMesh->precomputedFaceNormals) {
- copy_v3_v3(r_no, pMesh->precomputedFaceNormals[lt->poly]);
- }
- else {
-#ifdef USE_LOOPTRI_DETECT_QUADS
- const MPoly *mp = &pMesh->mpoly[lt->poly];
- if (mp->totloop == 4) {
- normal_quad_v3(
- r_no,
- pMesh->mvert[pMesh->mloop[mp->loopstart + 0].v].co,
- pMesh->mvert[pMesh->mloop[mp->loopstart + 1].v].co,
- pMesh->mvert[pMesh->mloop[mp->loopstart + 2].v].co,
- pMesh->mvert[pMesh->mloop[mp->loopstart + 3].v].co);
- }
- else
-#endif
- {
- normal_tri_v3(
- r_no,
- pMesh->mvert[pMesh->mloop[lt->tri[0]].v].co,
- pMesh->mvert[pMesh->mloop[lt->tri[1]].v].co,
- pMesh->mvert[pMesh->mloop[lt->tri[2]].v].co);
- }
- }
- }
- else {
- const short *no = pMesh->mvert[pMesh->mloop[loop_index].v].no;
- normal_short_to_float_v3(r_no, no);
- }
-}
-
-static void dm_ts_SetTSpace(
- const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign,
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- const MLoopTri *lt;
- int loop_index;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
- const MPoly *mp = &pMesh->mpoly[lt->poly];
- if (mp->totloop == 4) {
- loop_index = mp->loopstart + vert_index;
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = &pMesh->looptri[face_num];
- }
-#else
- lt = &pMesh->looptri[face_num];
-#endif
- loop_index = lt->tri[vert_index];
-
- float *pRes;
-
-finally:
- pRes = pMesh->tangent[loop_index];
- copy_v3_v3(pRes, fvTangent);
- pRes[3] = fSign;
-}
-
void DM_calc_tangents_names_from_gpu(
const GPUVertexAttribs *gattribs,
char (*tangent_names)[MAX_NAME], int *r_tangent_names_count)
@@ -3278,240 +3054,29 @@ void DM_calc_tangents_names_from_gpu(
*r_tangent_names_count = count;
}
-static void DM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
-{
- struct SGLSLMeshToTangent *mesh2tangent = taskdata;
- /* new computation method */
- {
- SMikkTSpaceContext sContext = {NULL};
- SMikkTSpaceInterface sInterface = {NULL};
-
- sContext.m_pUserData = mesh2tangent;
- sContext.m_pInterface = &sInterface;
- sInterface.m_getNumFaces = dm_ts_GetNumFaces;
- sInterface.m_getNumVerticesOfFace = dm_ts_GetNumVertsOfFace;
- sInterface.m_getPosition = dm_ts_GetPosition;
- sInterface.m_getTexCoord = dm_ts_GetTextureCoordinate;
- sInterface.m_getNormal = dm_ts_GetNormal;
- sInterface.m_setTSpaceBasic = dm_ts_SetTSpace;
-
- /* 0 if failed */
- genTangSpaceDefault(&sContext);
- }
-}
-
-void DM_add_named_tangent_layer_for_uv(
- CustomData *uv_data, CustomData *tan_data, int numLoopData,
- const char *layer_name)
-{
- if (CustomData_get_named_layer_index(tan_data, CD_TANGENT, layer_name) == -1 &&
- CustomData_get_named_layer_index(uv_data, CD_MLOOPUV, layer_name) != -1)
- {
- CustomData_add_layer_named(
- tan_data, CD_TANGENT, CD_CALLOC, NULL,
- numLoopData, layer_name);
- }
-}
-
-/**
- * Here we get some useful information such as active uv layer name and search if it is already in tangent_names.
- * Also, we calculate tangent_mask that works as a descriptor of tangents state.
- * If tangent_mask has changed, then recalculate tangents.
- */
-void DM_calc_loop_tangents_step_0(
- const CustomData *loopData, bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME], int tangent_names_count,
- bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
- char *ract_uv_name, char *rren_uv_name, char *rtangent_mask) {
- /* Active uv in viewport */
- int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV);
- *ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV);
- ract_uv_name[0] = 0;
- if (*ract_uv_n != -1) {
- strcpy(ract_uv_name, loopData->layers[*ract_uv_n + layer_index].name);
- }
-
- /* Active tangent in render */
- *rren_uv_n = CustomData_get_render_layer(loopData, CD_MLOOPUV);
- rren_uv_name[0] = 0;
- if (*rren_uv_n != -1) {
- strcpy(rren_uv_name, loopData->layers[*rren_uv_n + layer_index].name);
- }
-
- /* If active tangent not in tangent_names we take it into account */
- *rcalc_act = false;
- *rcalc_ren = false;
- for (int i = 0; i < tangent_names_count; i++) {
- if (tangent_names[i][0] == 0) {
- calc_active_tangent = true;
- }
- }
- if (calc_active_tangent) {
- *rcalc_act = true;
- *rcalc_ren = true;
- for (int i = 0; i < tangent_names_count; i++) {
- if (STREQ(ract_uv_name, tangent_names[i]))
- *rcalc_act = false;
- if (STREQ(rren_uv_name, tangent_names[i]))
- *rcalc_ren = false;
- }
- }
- *rtangent_mask = 0;
-
- const int uv_layer_num = CustomData_number_of_layers(loopData, CD_MLOOPUV);
- for (int n = 0; n < uv_layer_num; n++) {
- const char *name = CustomData_get_layer_name(loopData, CD_MLOOPUV, n);
- bool add = false;
- for (int i = 0; i < tangent_names_count; i++) {
- if (tangent_names[i][0] && STREQ(tangent_names[i], name)) {
- add = true;
- break;
- }
- }
- if ((*rcalc_act && ract_uv_name[0] && STREQ(ract_uv_name, name)) ||
- (*rcalc_ren && rren_uv_name[0] && STREQ(rren_uv_name, name)))
- {
- add = true;
- }
- if (add)
- *rtangent_mask |= 1 << n;
- }
-}
-
void DM_calc_loop_tangents(
DerivedMesh *dm, bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME], int tangent_names_count)
+ const char (*tangent_names)[MAX_NAME], int tangent_names_len)
{
- if (CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV) == 0)
+ if (CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV) == 0) {
return;
- int act_uv_n = -1;
- int ren_uv_n = -1;
- bool calc_act = false;
- bool calc_ren = false;
- char act_uv_name[MAX_NAME];
- char ren_uv_name[MAX_NAME];
- char tangent_mask = 0;
- DM_calc_loop_tangents_step_0(
- &dm->loopData, calc_active_tangent, tangent_names, tangent_names_count,
- &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
- if ((dm->tangent_mask | tangent_mask) != dm->tangent_mask) {
- /* Check we have all the needed layers */
- MPoly *mpoly = dm->getPolyArray(dm);
- const MLoopTri *looptri = dm->getLoopTriArray(dm);
- int totface = dm->getNumLoopTri(dm);
- /* Allocate needed tangent layers */
- for (int i = 0; i < tangent_names_count; i++)
- if (tangent_names[i][0])
- DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, tangent_names[i]);
- if (calc_act && act_uv_name[0])
- DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, act_uv_name);
- if (calc_ren && ren_uv_name[0])
- DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, ren_uv_name);
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- int num_face_as_quad_map;
- int *face_as_quad_map = NULL;
-
- /* map faces to quads */
- if (totface != dm->getNumPolys(dm)) {
- /* over alloc, since we dont know how many ngon or quads we have */
-
- /* map fake face index to looptri */
- face_as_quad_map = MEM_mallocN(sizeof(int) * totface, __func__);
- int k, j;
- for (k = 0, j = 0; j < totface; k++, j++) {
- face_as_quad_map[k] = j;
- /* step over all quads */
- if (mpoly[looptri[j].poly].totloop == 4) {
- j++; /* skips the nest looptri */
- }
- }
- num_face_as_quad_map = k;
- }
- else {
- num_face_as_quad_map = totface;
- }
-#endif
-
- /* Calculation */
- {
- TaskScheduler *scheduler = BLI_task_scheduler_get();
- TaskPool *task_pool;
- task_pool = BLI_task_pool_create(scheduler, NULL);
-
- dm->tangent_mask = 0;
- /* Calculate tangent layers */
- SGLSLMeshToTangent data_array[MAX_MTFACE];
- const int tangent_layer_num = CustomData_number_of_layers(&dm->loopData, CD_TANGENT);
- for (int n = 0; n < tangent_layer_num; n++) {
- int index = CustomData_get_layer_index_n(&dm->loopData, CD_TANGENT, n);
- BLI_assert(n < MAX_MTFACE);
- SGLSLMeshToTangent *mesh2tangent = &data_array[n];
- mesh2tangent->numTessFaces = totface;
-#ifdef USE_LOOPTRI_DETECT_QUADS
- mesh2tangent->face_as_quad_map = face_as_quad_map;
- mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
-#endif
- mesh2tangent->mvert = dm->getVertArray(dm);
- mesh2tangent->mpoly = dm->getPolyArray(dm);
- mesh2tangent->mloop = dm->getLoopArray(dm);
- mesh2tangent->looptri = dm->getLoopTriArray(dm);
- /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
- * have to check this is valid...
- */
- mesh2tangent->precomputedLoopNormals = dm->getLoopDataArray(dm, CD_NORMAL);
- mesh2tangent->precomputedFaceNormals = CustomData_get_layer(&dm->polyData, CD_NORMAL);
-
- mesh2tangent->orco = NULL;
- mesh2tangent->mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name);
- if (!mesh2tangent->mloopuv) {
- mesh2tangent->orco = dm->getVertDataArray(dm, CD_ORCO);
- if (!mesh2tangent->orco)
- continue;
- }
- mesh2tangent->tangent = dm->loopData.layers[index].data;
-
- /* Fill the resulting tangent_mask */
- int uv_ind = CustomData_get_named_layer_index(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name);
- int uv_start = CustomData_get_layer_index(&dm->loopData, CD_MLOOPUV);
- BLI_assert(uv_ind != -1 && uv_start != -1);
- BLI_assert(uv_ind - uv_start < MAX_MTFACE);
- dm->tangent_mask |= 1 << (uv_ind - uv_start);
- BLI_task_pool_push(task_pool, DM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
- }
-
- BLI_assert(dm->tangent_mask == tangent_mask);
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
- }
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (face_as_quad_map) {
- MEM_freeN(face_as_quad_map);
- }
-#undef USE_LOOPTRI_DETECT_QUADS
-
-#endif
-
- int uv_index, tan_index;
-
- /* Update active layer index */
- uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, act_uv_n);
- if (uv_index != -1) {
- tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[uv_index].name);
- CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index);
- }
-
- /* Update render layer index */
- uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, ren_uv_n);
- if (uv_index != -1) {
- tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[uv_index].name);
- CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index);
- }
}
-}
-
-/** \} */
+ BKE_mesh_calc_loop_tangent_ex(
+ dm->getVertArray(dm),
+ dm->getPolyArray(dm), dm->getNumPolys(dm),
+ dm->getLoopArray(dm),
+ dm->getLoopTriArray(dm), dm->getNumLoopTri(dm),
+ &dm->loopData,
+ calc_active_tangent,
+ tangent_names, tangent_names_len,
+ CustomData_get_layer(&dm->polyData, CD_NORMAL),
+ dm->getLoopDataArray(dm, CD_NORMAL),
+ dm->getVertDataArray(dm, CD_ORCO), /* may be NULL */
+ /* result */
+ &dm->loopData, dm->getNumLoops(dm),
+ &dm->tangent_mask);
+}
void DM_calc_auto_bump_scale(DerivedMesh *dm)
{
@@ -3941,7 +3506,6 @@ BLI_INLINE void navmesh_intToCol(int i, float col[3])
static void navmesh_drawColored(DerivedMesh *dm)
{
- int a, glmode;
MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT);
MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE);
int *polygonIdx = (int *)CustomData_get_layer(&dm->polyData, CD_RECAST);
@@ -3956,43 +3520,42 @@ static void navmesh_drawColored(DerivedMesh *dm)
dm->drawEdges(dm, 0, 1);
#endif
- /* if (GPU_buffer_legacy(dm) ) */ /* TODO - VBO draw code, not high priority - campbell */
- {
- DEBUG_VBO("Using legacy code. drawNavMeshColored\n");
- glBegin(glmode = GL_QUADS);
- for (a = 0; a < dm->numTessFaceData; a++, mface++) {
- int new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
- int pi = polygonIdx[a];
- if (pi <= 0) {
- zero_v3(col);
- }
- else {
- navmesh_intToCol(pi, col);
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
- if (new_glmode != glmode) {
- glEnd();
- glBegin(glmode = new_glmode);
- }
- glColor3fv(col);
- glVertex3fv(mvert[mface->v1].co);
- glVertex3fv(mvert[mface->v2].co);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glVertex3fv(mvert[mface->v4].co);
- }
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ /* Note: batch drawing API would let us share vertices */
+ immBeginAtMost(PRIM_TRIANGLES, dm->numTessFaceData * 6);
+ for (int a = 0; a < dm->numTessFaceData; a++, mface++) {
+ int pi = polygonIdx[a];
+ if (pi <= 0) {
+ zero_v3(col);
+ }
+ else {
+ navmesh_intToCol(pi, col);
}
- glEnd();
- }
-}
-static void navmesh_DM_drawFacesTex(
- DerivedMesh *dm,
- DMSetDrawOptionsTex UNUSED(setDrawOptions),
- DMCompareDrawOptions UNUSED(compareDrawOptions),
- void *UNUSED(userData), DMDrawFlag UNUSED(flag))
-{
- navmesh_drawColored(dm);
+ immSkipAttrib(color);
+ immVertex3fv(pos, mvert[mface->v1].co);
+ immSkipAttrib(color);
+ immVertex3fv(pos, mvert[mface->v2].co);
+ immAttrib3fv(color, col);
+ immVertex3fv(pos, mvert[mface->v3].co);
+
+ if (mface->v4) {
+ /* this tess face is a quad, so draw the other triangle */
+ immSkipAttrib(color);
+ immVertex3fv(pos, mvert[mface->v1].co);
+ immSkipAttrib(color);
+ immVertex3fv(pos, mvert[mface->v3].co);
+ immAttrib3fv(color, col);
+ immVertex3fv(pos, mvert[mface->v4].co);
+ }
+ }
+ immEnd();
+ immUnbindProgram();
}
static void navmesh_DM_drawFacesSolid(
@@ -4028,7 +3591,6 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm)
recastData = (int *)CustomData_get_layer(&result->polyData, CD_RECAST);
/* note: This is not good design! - really should not be doing this */
- result->drawFacesTex = navmesh_DM_drawFacesTex;
result->drawFacesSolid = navmesh_DM_drawFacesSolid;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 1e33fe4ab46..30097a98b40 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -55,7 +55,6 @@
#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_deform.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -65,6 +64,8 @@
#include "BKE_main.h"
#include "BKE_object.h"
+#include "DEG_depsgraph_build.h"
+
#include "BIK_api.h"
#include "RNA_access.h"
@@ -578,6 +579,8 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints)
if (pchan->prop) {
pchan->prop = IDP_CopyProperty(pchan->prop);
}
+
+ pchan->draw_data = NULL; /* Drawing cache, no need to copy. */
}
/* for now, duplicate Bone Groups too when doing this */
@@ -766,6 +769,9 @@ void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user)
IDP_FreeProperty(pchan->prop);
MEM_freeN(pchan->prop);
}
+
+ /* Cached data, for new draw manager rendering code. */
+ MEM_SAFE_FREE(pchan->draw_data);
}
void BKE_pose_channel_free(bPoseChannel *pchan)
@@ -1403,7 +1409,7 @@ void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
/* Depsgraph components depends on actual pose state,
* if pose was changed depsgraph is to be updated as well.
*/
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
/* For the calculation of the effects of an Action at the given frame on an object
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 2f65e71c6d2..59484724aee 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -44,7 +44,6 @@
#include "DNA_scene_types.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_main.h"
@@ -54,6 +53,8 @@
#include "BKE_anim.h"
#include "BKE_report.h"
+#include "DEG_depsgraph_build.h"
+
// XXX bad level call...
/* --------------------- */
@@ -283,7 +284,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
/* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */
static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
{
- Base *base, *baseNext;
+ BaseLegacy *base, *baseNext;
MPathTarget *mpt;
/* make sure our temp-tag isn't already in use */
@@ -308,53 +309,21 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
}
/* "brew me a list that's sorted a bit faster now depsy" */
- DAG_scene_relations_rebuild(G.main, scene);
+ DEG_scene_relations_rebuild(G.main, scene);
}
/* update scene for current frame */
static void motionpaths_calc_update_scene(Scene *scene)
{
-#if 1 // 'production' optimizations always on
- /* rigid body simulation needs complete update to work correctly for now */
- /* RB_TODO investigate if we could avoid updating everything */
- if (BKE_scene_check_rigidbody_active(scene)) {
- BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay);
- }
- else { /* otherwise we can optimize by restricting updates */
- Base *base, *last = NULL;
-
- /* only stuff that moves or needs display still */
- DAG_scene_update_flags(G.main, scene, scene->lay, true, false);
-
- /* find the last object with the tag
- * - all those afterwards are assumed to not be relevant for our calculations
- */
- /* optimize further by moving out... */
- for (base = scene->base.first; base; base = base->next) {
- if (base->object->flag & BA_TEMP_TAG)
- last = base;
- }
-
- /* perform updates for tagged objects */
- /* XXX: this will break if rigs depend on scene or other data that
- * is animated but not attached to/updatable from objects */
- for (base = scene->base.first; base; base = base->next) {
- /* update this object */
- BKE_object_handle_update(G.main->eval_ctx, scene, base->object);
-
- /* if this is the last one we need to update, let's stop to save some time */
- if (base == last)
- break;
- }
- }
-#else // original, 'always correct' version
- /* do all updates
+ /* Do all updates
* - if this is too slow, resort to using a more efficient way
* that doesn't force complete update, but for now, this is the
* most accurate way!
+ *
+ * TODO(segey): Bring back partial updates, which became impossible
+ * with the new depsgraph due to unsorted nature of bases.
*/
- BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay); /* XXX this is the best way we can get anything moving */
-#endif
+ BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene);
}
/* ........ */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 0b637355ecf..b9937957236 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -60,7 +60,6 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_global.h"
@@ -70,6 +69,8 @@
#include "BKE_report.h"
#include "BKE_texture.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#include "nla_private.h"
@@ -1661,7 +1662,7 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
* notify anyone of updates */
if (!(id->tag & LIB_TAG_ANIM_NO_RECALC)) {
BKE_id_tag_set_atomic(id, LIB_TAG_ID_RECALC);
- DAG_id_type_tag(G.main, GS(id->name));
+ DEG_id_type_tag(G.main, GS(id->name));
}
}
@@ -2616,7 +2617,7 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
ID *id = ptr->id.data;
if (!(id->tag & LIB_TAG_ANIM_NO_RECALC)) {
id->tag |= LIB_TAG_ID_RECALC;
- DAG_id_type_tag(G.main, GS(id->name));
+ DEG_id_type_tag(G.main, GS(id->name));
}
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index d7ea534068d..6f04be653d1 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -60,7 +60,6 @@
#include "BKE_anim.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_deform.h"
#include "BKE_displist.h"
@@ -1935,7 +1934,7 @@ void BKE_pose_clear_pointers(bPose *pose)
/* only after leave editmode, duplicating, validating older files, library syncing */
/* NOTE: pose->flag is set for it */
-void BKE_pose_rebuild_ex(Object *ob, bArmature *arm, const bool sort_bones)
+void BKE_pose_rebuild(Object *ob, bArmature *arm)
{
Bone *bone;
bPose *pose;
@@ -1979,27 +1978,12 @@ void BKE_pose_rebuild_ex(Object *ob, bArmature *arm, const bool sort_bones)
BKE_pose_update_constraint_flags(ob->pose); /* for IK detection for example */
-#ifdef WITH_LEGACY_DEPSGRAPH
- /* the sorting */
- /* Sorting for new dependnecy graph is done on the scene graph level. */
- if (counter > 1 && sort_bones) {
- DAG_pose_sort(ob);
- }
-#else
- UNUSED_VARS(sort_bones);
-#endif
-
ob->pose->flag &= ~POSE_RECALC;
ob->pose->flag |= POSE_WAS_REBUILT;
BKE_pose_channels_hash_make(ob->pose);
}
-void BKE_pose_rebuild(Object *ob, bArmature *arm)
-{
- BKE_pose_rebuild_ex(ob, arm, true);
-}
-
/* ********************** THE POSE SOLVER ******************* */
/* loc/rot/size to given mat4 */
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index a4714041edf..73e9f5d0774 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -41,7 +41,6 @@
#include "BKE_anim.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_fcurve.h"
#include "BKE_scene.h"
@@ -51,13 +50,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
-#include "DEG_depsgraph.h"
-
-#ifdef WITH_LEGACY_DEPSGRAPH
-# define DEBUG_PRINT if (!DEG_depsgraph_use_legacy() && G.debug & G_DEBUG_DEPSGRAPH) printf
-#else
-# define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
-#endif
+#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
/* ********************** SPLINE IK SOLVER ******************* */
@@ -558,7 +551,7 @@ void BKE_splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_roo
/* *************** Depsgraph evaluation callbacks ************ */
-void BKE_pose_eval_init(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_eval_init(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPose *pose)
@@ -592,7 +585,7 @@ void BKE_pose_eval_init(EvaluationContext *UNUSED(eval_ctx),
BKE_pose_splineik_init_tree(scene, ob, ctime);
}
-void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_eval_bone(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPoseChannel *pchan)
@@ -627,7 +620,7 @@ void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_pose_constraints_evaluate(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_constraints_evaluate(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPoseChannel *pchan)
@@ -648,7 +641,7 @@ void BKE_pose_constraints_evaluate(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_pose_bone_done(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_bone_done(struct EvaluationContext *UNUSED(eval_ctx),
bPoseChannel *pchan)
{
float imat[4][4];
@@ -659,7 +652,7 @@ void BKE_pose_bone_done(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_pose_iktree_evaluate(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_iktree_evaluate(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPoseChannel *rootchan)
@@ -669,7 +662,7 @@ void BKE_pose_iktree_evaluate(EvaluationContext *UNUSED(eval_ctx),
BIK_execute_tree(scene, ob, rootchan, ctime);
}
-void BKE_pose_splineik_evaluate(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_splineik_evaluate(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPoseChannel *rootchan)
@@ -679,7 +672,7 @@ void BKE_pose_splineik_evaluate(EvaluationContext *UNUSED(eval_ctx),
BKE_splineik_execute_tree(scene, ob, rootchan, ctime);
}
-void BKE_pose_eval_flush(EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_eval_flush(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPose *UNUSED(pose))
@@ -694,7 +687,7 @@ void BKE_pose_eval_flush(EvaluationContext *UNUSED(eval_ctx),
ob->recalc &= ~OB_RECALC_ALL;
}
-void BKE_pose_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx), Object *ob)
+void BKE_pose_eval_proxy_copy(struct EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
BLI_assert(ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from != NULL);
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index ceb641073e0..ebb10c02683 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -51,10 +51,10 @@
#include "BKE_brush.h"
#include "BKE_cachefile.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_node.h"
#include "BKE_report.h"
@@ -62,6 +62,8 @@
#include "BKE_screen.h"
#include "BKE_sequencer.h"
+#include "DEG_depsgraph.h"
+
#include "RE_pipeline.h"
#include "RE_render_ext.h"
@@ -87,7 +89,7 @@ void BKE_blender_free(void)
IMB_exit();
BKE_cachefiles_exit();
BKE_images_exit();
- DAG_exit();
+ DEG_free_node_types();
BKE_brush_system_exit();
RE_texture_rng_exit();
@@ -96,6 +98,8 @@ void BKE_blender_free(void)
BKE_sequencer_cache_destruct();
IMB_moviecache_destruct();
+
+ BKE_layer_exit();
free_nodesystem();
}
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index e57524af546..206b0f2a8cc 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -44,12 +44,13 @@
#include "BKE_blender_copybuffer.h" /* own include */
#include "BKE_blendfile.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph_build.h"
+
#include "BLO_readfile.h"
#include "BLO_writefile.h"
@@ -117,7 +118,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Main *mainl = NULL;
Library *lib;
BlendHandle *bh;
@@ -142,7 +143,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
BLO_library_link_copypaste(mainl, bh);
- BLO_library_link_end(mainl, &bh, flag, scene, v3d);
+ BLO_library_link_end(mainl, &bh, flag, scene, sl);
/* mark all library linked objects to be updated */
BKE_main_lib_objects_recalc_all(bmain);
@@ -157,7 +158,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
/* recreate dependency graph to include new objects */
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
BLO_blendhandle_close(bh);
/* remove library... */
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index e3a5edb2049..b8f46756445 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -56,7 +56,6 @@
#include "BKE_appdir.h"
#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -66,6 +65,8 @@
#include "BLO_readfile.h"
#include "BLO_writefile.h"
+#include "DEG_depsgraph.h"
+
/* -------------------------------------------------------------------- */
/** \name Global Undo
@@ -118,7 +119,7 @@ static int read_undosave(bContext *C, UndoElem *uel)
if (success) {
/* important not to update time here, else non keyed tranforms are lost */
- DAG_on_visible_update(G.main, false);
+ DEG_on_visible_update(G.main, false);
}
return success;
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 67c66d4e40b..859aa628781 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -204,11 +204,9 @@ float BKE_cachefile_time_offset(CacheFile *cache_file, const float time, const f
}
/* TODO(kevin): replace this with some depsgraph mechanism, or something similar. */
-void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
+void BKE_cachefile_clean(struct Main *bmain, CacheFile *cache_file)
{
- for (Base *base = scene->base.first; base; base = base->next) {
- Object *ob = base->object;
-
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
if (md) {
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 9cb553aa27b..be75048492c 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -633,7 +633,7 @@ static bool camera_frame_fit_calc_from_data(
/* don't move the camera, just yield the fit location */
/* r_scale only valid/useful for ortho cameras */
bool BKE_camera_view_frame_fit_to_scene(
- Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3], float *r_scale)
+ Scene *scene, SceneLayer *sl, Object *camera_ob, float r_co[3], float *r_scale)
{
CameraParams params;
CameraViewFrameData data_cb;
@@ -644,7 +644,7 @@ bool BKE_camera_view_frame_fit_to_scene(
camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
/* run callback on all visible points */
- BKE_scene_foreach_display_point(scene, v3d, BA_SELECT, camera_to_frame_view_cb, &data_cb);
+ BKE_scene_foreach_display_point(scene, sl, camera_to_frame_view_cb, &data_cb);
return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
}
@@ -853,7 +853,7 @@ static Object *camera_multiview_advanced(Scene *scene, Object *camera, const cha
}
if (name[0] != '\0') {
- Base *base = BKE_scene_base_find_by_name(scene, name);
+ BaseLegacy *base = BKE_scene_base_find_by_name(scene, name);
if (base) {
return base->object;
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 46a067ea0bc..c743d1f7e11 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -58,6 +58,7 @@
#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_glew.h"
+#include "GPU_immediate.h"
#include "GPU_shader.h"
#include "GPU_basic_shader.h"
@@ -372,40 +373,10 @@ static void cdDM_drawVerts(DerivedMesh *dm)
GPU_buffers_unbind();
}
-static void cdDM_drawUVEdges(DerivedMesh *dm)
+static void cdDM_drawEdges(DerivedMesh *dm, bool UNUSED(drawLooseEdges), bool UNUSED(drawAllEdges))
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- const MPoly *mpoly = cddm->mpoly;
- int totpoly = dm->getNumPolys(dm);
- int prevstart = 0;
- bool prevdraw = true;
- int curpos = 0;
- int i;
-
- GPU_uvedge_setup(dm);
- for (i = 0; i < totpoly; i++, mpoly++) {
- const bool draw = (mpoly->flag & ME_HIDE) == 0;
-
- if (prevdraw != draw) {
- if (prevdraw && (curpos != prevstart)) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- prevstart = curpos;
- }
- curpos += 2 * mpoly->totloop;
- prevdraw = draw;
- }
- if (prevdraw && (curpos != prevstart)) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- GPU_buffers_unbind();
-}
-
-static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
-{
- CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- GPUDrawObject *gdo;
if (cddm->pbvh && cddm->pbvh_draw &&
BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
{
@@ -413,22 +384,37 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg
return;
}
-
- GPU_edge_setup(dm);
- gdo = dm->drawObject;
- if (gdo->edges && gdo->points) {
- if (drawAllEdges && drawLooseEdges) {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->totedge * 2);
- }
- else if (drawAllEdges) {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->loose_edge_offset * 2);
- }
- else {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->tot_edge_drawn * 2);
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->loose_edge_offset * 2, dm->drawObject->tot_loose_edge_drawn * 2);
+
+ MVert *vert = cddm->mvert;
+ MEdge *edge = cddm->medge;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ /* NOTE: This is active object color, which is not really perfect.
+ * But we can't query color set by glColor() :(
+ */
+ float color[4] = {1.0f, 0.667f, 0.251f, 1.0f};
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+
+ const int chunk_size = 1024;
+ const int num_chunks = (dm->numEdgeData + chunk_size - 1) / chunk_size;
+
+ for (int chunk = 0; chunk < num_chunks; ++chunk) {
+ const int num_current_edges = (chunk < num_chunks - 1)
+ ? chunk_size
+ : dm->numEdgeData - chunk_size * (num_chunks - 1);
+ immBeginAtMost(PRIM_LINES, num_current_edges * 2);
+ for (int i = 0; i < num_current_edges; i++, edge++) {
+ immVertex3fv(pos, vert[edge->v1].co);
+ immVertex3fv(pos, vert[edge->v2].co);
}
+ immEnd();
}
- GPU_buffers_unbind();
+
+ immUnbindProgram();
}
static void cdDM_drawLooseEdges(DerivedMesh *dm)
@@ -451,8 +437,9 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
static void cdDM_drawFacesSolid(
DerivedMesh *dm,
float (*partial_redraw_planes)[4],
- bool UNUSED(fast), DMSetMaterial setMaterial)
+ bool fast, DMSetMaterial setMaterial)
{
+ UNUSED_VARS(partial_redraw_planes, fast, setMaterial);
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
int a;
@@ -465,177 +452,79 @@ static void cdDM_drawFacesSolid(
return;
}
}
-
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- GPU_triangle_setup(dm);
- for (a = 0; a < dm->drawObject->totmaterial; a++) {
- if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
- GPU_buffer_draw_elements(
- dm->drawObject->triangles, GL_TRIANGLES,
- dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements);
- }
- }
- GPU_buffers_unbind();
-}
-static void cdDM_drawFacesTex_common(
- DerivedMesh *dm,
- DMSetDrawOptionsTex drawParams,
- DMSetDrawOptionsMappedTex drawParamsMapped,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
+ const MVert *mvert = cddm->mvert;
+ const MLoop *mloop = cddm->mloop;
const MPoly *mpoly = cddm->mpoly;
- MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
- const MLoopCol *mloopcol = NULL;
- int i;
- int colType, start_element, tot_drawn;
- const bool use_hide = (flag & DM_DRAW_SKIP_HIDDEN) != 0;
- const bool use_tface = (flag & DM_DRAW_USE_ACTIVE_UV) != 0;
- const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0;
- int totpoly;
- int next_actualFace;
- int mat_index;
- int tot_element;
-
- /* double lookup */
- const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
-
- /* TODO: not entirely correct, but currently dynamic topology will
- * destroy UVs anyway, so textured display wouldn't work anyway
- *
- * this will do more like solid view with lights set up for
- * textured view, but object itself will be displayed gray
- * (the same as it'll display without UV maps in textured view)
- */
- if (cddm->pbvh) {
- if (cddm->pbvh_draw &&
- BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH &&
- BKE_pbvh_has_faces(cddm->pbvh))
- {
- GPU_set_tpage(NULL, false, false);
- BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, false);
- return;
- }
- else {
- cdDM_update_normals_from_pbvh(dm);
- }
- }
+ const int num_looptris = dm->getNumLoopTri(dm);
+ const MLoopTri *looptri = dm->getLoopTriArray(dm);
+ const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL);
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
- if (use_colors) {
- colType = CD_TEXTURE_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- if (!mloopcol) {
- colType = CD_PREVIEW_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- }
- if (!mloopcol) {
- colType = CD_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- }
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int nor = VertexFormat_add_attrib(format, "nor", COMP_F32, 3, KEEP_FLOAT);
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- GPU_triangle_setup(dm);
- if (flag & DM_DRAW_USE_TEXPAINT_UV)
- GPU_texpaint_uv_setup(dm);
- else
- GPU_uv_setup(dm);
- if (mloopcol) {
- GPU_color_setup(dm, colType);
- }
+ float color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
- /* lastFlag = 0; */ /* UNUSED */
- for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
- GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
- next_actualFace = bufmat->polys[0];
- totpoly = bufmat->totpolys;
+ immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING);
+ immUniformColor4fv(color);
+ immUniform3fv("light", light_vec);
- tot_element = 0;
- tot_drawn = 0;
- start_element = 0;
+ const int chunk_size = 1024;
+ const int num_chunks = (num_looptris + chunk_size - 1) / chunk_size;
- for (i = 0; i < totpoly; i++) {
- int actualFace = bufmat->polys[i];
- DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- int flush = 0;
- int tot_tri_verts;
+ for (int chunk = 0; chunk < num_chunks; ++chunk) {
+ const int num_current_looptris = (chunk < num_chunks - 1)
+ ? chunk_size
+ : num_looptris - chunk_size * (num_chunks - 1);
- if (i != totpoly - 1)
- next_actualFace = bufmat->polys[i + 1];
+ immBeginAtMost(PRIM_TRIANGLES, num_current_looptris * 3);
- if (use_hide && (mpoly[actualFace].flag & ME_HIDE)) {
- draw_option = DM_DRAW_OPTION_SKIP;
- }
- else if (drawParams) {
- MTexPoly *tp = use_tface && mtexpoly ? &mtexpoly[actualFace] : NULL;
- draw_option = drawParams(tp, (mloopcol != NULL), mpoly[actualFace].mat_nr);
- }
- else {
- if (index_mp_to_orig) {
- const int orig = index_mp_to_orig[actualFace];
- if (orig == ORIGINDEX_NONE) {
- /* XXX, this is not really correct
- * it will draw the previous faces context for this one when we don't know its settings.
- * but better then skipping it altogether. - campbell */
- draw_option = DM_DRAW_OPTION_NORMAL;
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, orig, mpoly[actualFace].mat_nr);
- }
+ for (a = 0; a < num_current_looptris; a++, looptri++) {
+ const MPoly *mp = &mpoly[looptri->poly];
+ const bool smoothnormal = (lnors != NULL) || (mp->flag & ME_SMOOTH);
+ const unsigned int vtri[3] = {mloop[looptri->tri[0]].v,
+ mloop[looptri->tri[1]].v,
+ mloop[looptri->tri[2]].v};
+ const unsigned int *ltri = looptri->tri;
+ float normals[3][3];
+ if (!smoothnormal) {
+ if (nors != NULL) {
+ copy_v3_v3(normals[0], nors[looptri->poly]);
}
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, actualFace, mpoly[actualFace].mat_nr);
+ else {
+ normal_tri_v3(normals[0],
+ mvert[vtri[0]].co,
+ mvert[vtri[1]].co,
+ mvert[vtri[2]].co);
}
+ copy_v3_v3(normals[1], normals[0]);
+ copy_v3_v3(normals[2], normals[0]);
}
-
- /* flush buffer if current triangle isn't drawable or it's last triangle */
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 1);
-
- if (!flush && compareDrawOptions) {
- /* also compare draw options and flush buffer if they're different
- * need for face selection highlight in edit mode */
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- tot_tri_verts = ME_POLY_TRI_TOT(&mpoly[actualFace]) * 3;
- tot_element += tot_tri_verts;
-
- if (flush) {
- if (draw_option != DM_DRAW_OPTION_SKIP)
- tot_drawn += tot_tri_verts;
-
- if (tot_drawn) {
- if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
- GPU_color_switch(1);
- else
- GPU_color_switch(0);
-
- GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn);
- tot_drawn = 0;
- }
- start_element = tot_element;
+ else if (lnors != NULL) {
+ copy_v3_v3(normals[0], lnors[ltri[0]]);
+ copy_v3_v3(normals[1], lnors[ltri[1]]);
+ copy_v3_v3(normals[2], lnors[ltri[2]]);
}
else {
- tot_drawn += tot_tri_verts;
+ normal_short_to_float_v3(normals[0], mvert[vtri[0]].no);
+ normal_short_to_float_v3(normals[1], mvert[vtri[1]].no);
+ normal_short_to_float_v3(normals[2], mvert[vtri[2]].no);
}
+
+ immAttrib3fv(nor, normals[0]);
+ immVertex3fv(pos, mvert[vtri[0]].co);
+ immAttrib3fv(nor, normals[1]);
+ immVertex3fv(pos, mvert[vtri[1]].co);
+ immAttrib3fv(nor, normals[2]);
+ immVertex3fv(pos, mvert[vtri[2]].co);
}
+ immEnd();
}
- GPU_buffers_unbind();
-
-}
-
-static void cdDM_drawFacesTex(
- DerivedMesh *dm,
- DMSetDrawOptionsTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
+ immUnbindProgram();
}
static void cdDM_drawMappedFaces(
@@ -842,15 +731,6 @@ static void cdDM_drawMappedFaces(
}
-static void cdDM_drawMappedFacesTex(
- DerivedMesh *dm,
- DMSetDrawOptionsMappedTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
-}
-
static void cddm_draw_attrib_vertex(
DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int loop, int vert,
const float *lnor, const bool smoothnormal)
@@ -1904,7 +1784,7 @@ void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const bool do_face_nor_cpy)
/* Tessellation recreated faceData, and the active layer indices need to get re-propagated
* from loops and polys to faces */
- CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
+ CustomData_bmesh_update_active_layers(&dm->faceData, &dm->loopData);
}
void CDDM_recalc_tessellation(DerivedMesh *dm)
@@ -2008,16 +1888,13 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->drawVerts = cdDM_drawVerts;
- dm->drawUVEdges = cdDM_drawUVEdges;
dm->drawEdges = cdDM_drawEdges;
dm->drawLooseEdges = cdDM_drawLooseEdges;
dm->drawMappedEdges = cdDM_drawMappedEdges;
dm->drawFacesSolid = cdDM_drawFacesSolid;
- dm->drawFacesTex = cdDM_drawFacesTex;
dm->drawFacesGLSL = cdDM_drawFacesGLSL;
dm->drawMappedFaces = cdDM_drawMappedFaces;
- dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
@@ -2154,7 +2031,6 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
if (alluv) {
const char *uvname = "Orco";
- CustomData_add_layer_named(&cddm->dm.polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, totpoly, uvname);
CustomData_add_layer_named(&cddm->dm.loopData, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
}
@@ -2169,22 +2045,18 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
static void loops_to_customdata_corners(
BMesh *bm, CustomData *facedata,
int cdindex, const BMLoop *l3[3],
- int numCol, int numTex)
+ int numCol, int numUV)
{
const BMLoop *l;
- BMFace *f = l3[0]->f;
+// BMFace *f = l3[0]->f;
MTFace *texface;
- MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
- for (i = 0; i < numTex; i++) {
+ for (i = 0; i < numUV; i++) {
texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
- texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
-
- ME_MTEXFACE_CPY(texface, texpoly);
for (j = 0; j < 3; j++) {
l = l3[j];
@@ -2238,7 +2110,7 @@ static DerivedMesh *cddm_from_bmesh_ex(
MLoop *mloop = cddm->mloop;
MPoly *mpoly = cddm->mpoly;
int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
- int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ int numUV = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
int *index, add_orig;
CustomDataMask mask;
unsigned int i, j;
@@ -2268,7 +2140,7 @@ static DerivedMesh *cddm_from_bmesh_ex(
/* add tessellation mface layers */
if (use_tessface) {
- CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
+ CustomData_from_bmeshpoly(&dm->faceData, &dm->loopData, em_tottri);
}
index = dm->getVertDataArray(dm, CD_ORIGINDEX);
@@ -2340,7 +2212,7 @@ static DerivedMesh *cddm_from_bmesh_ex(
/* map mfaces to polygons in the same cddm intentionally */
*index++ = BM_elem_index_get(efa);
- loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
+ loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numUV);
test_index_face(mf, &dm->faceData, i, 3);
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index ee0fde1ea61..8190a7c2a8b 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -478,7 +478,6 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
return;
}
- if (!can_simulate)
return;
/* if on second frame, write cache for first frame */
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
new file mode 100644
index 00000000000..7d265b8fd02
--- /dev/null
+++ b/source/blender/blenkernel/intern/collection.c
@@ -0,0 +1,640 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/collection.c
+ * \ingroup bke
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_iterator.h"
+#include "BLI_listbase.h"
+#include "BLT_translation.h"
+#include "BLI_string_utils.h"
+
+#include "BKE_collection.h"
+#include "BKE_layer.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_scene.h"
+
+#include "DNA_ID.h"
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+
+/**
+ * Add a collection to a collection ListBase and syncronize all render layers
+ * The ListBase is NULL when the collection is to be added to the master collection
+ */
+SceneCollection *BKE_collection_add(Scene *scene, SceneCollection *sc_parent, const char *name)
+{
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
+
+ if (!name) {
+ name = DATA_("New Collection");
+ }
+
+ if (!sc_parent) {
+ sc_parent = sc_master;
+ }
+
+ BKE_collection_rename(scene, sc, name);
+ BLI_addtail(&sc_parent->scene_collections, sc);
+
+ BKE_layer_sync_new_scene_collection(scene, sc_parent, sc);
+ return sc;
+}
+
+/**
+ * Free the collection items recursively
+ */
+static void collection_free(SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ id_us_min(link->data);
+ }
+ BLI_freelistN(&sc->objects);
+
+ for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
+ id_us_min(link->data);
+ }
+ BLI_freelistN(&sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ collection_free(nsc);
+ }
+ BLI_freelistN(&sc->scene_collections);
+}
+
+/**
+ * Unlink the collection recursively
+ * \return true if unlinked.
+ */
+static bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
+{
+ for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next) {
+ if (sc == sc_gone) {
+ BLI_remlink(&sc_parent->scene_collections, sc_gone);
+ return true;
+ }
+
+ if (collection_remlink(sc, sc_gone)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Recursively remove any instance of this SceneCollection
+ */
+static void layer_collection_remove(SceneLayer *sl, ListBase *lb, const SceneCollection *sc)
+{
+ LayerCollection *lc = lb->first;
+ while (lc) {
+ if (lc->scene_collection == sc) {
+ BKE_layer_collection_free(sl, lc);
+ BLI_remlink(lb, lc);
+
+ LayerCollection *lc_next = lc->next;
+ MEM_freeN(lc);
+ lc = lc_next;
+
+ /* only the "top-level" layer collections may have the
+ * same SceneCollection in a sibling tree.
+ */
+ if (lb != &sl->layer_collections) {
+ return;
+ }
+ }
+
+ else {
+ layer_collection_remove(sl, &lc->layer_collections, sc);
+ lc = lc->next;
+ }
+ }
+}
+
+/**
+ * Remove a collection from the scene, and syncronize all render layers
+ */
+bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
+{
+ SceneCollection *sc_master = BKE_collection_master(scene);
+
+ /* the master collection cannot be removed */
+ if (sc == sc_master) {
+ return false;
+ }
+
+ /* unlink from the respective collection tree */
+ if (!collection_remlink(sc_master, sc)) {
+ BLI_assert(false);
+ }
+
+ /* clear the collection items */
+ collection_free(sc);
+
+ /* check all layers that use this collection and clear them */
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ layer_collection_remove(sl, &sl->layer_collections, sc);
+ sl->active_collection = 0;
+ }
+
+ MEM_freeN(sc);
+ return true;
+}
+
+/**
+ * Returns the master collection
+ */
+SceneCollection *BKE_collection_master(const Scene *scene)
+{
+ return scene->collection;
+}
+
+struct UniqueNameCheckData {
+ ListBase *lb;
+ SceneCollection *lookup_sc;
+};
+
+static bool collection_unique_name_check(void *arg, const char *name)
+{
+ struct UniqueNameCheckData *data = arg;
+
+ for (SceneCollection *sc = data->lb->first; sc; sc = sc->next) {
+ struct UniqueNameCheckData child_data = {.lb = &sc->scene_collections, .lookup_sc = data->lookup_sc};
+
+ if (sc != data->lookup_sc) {
+ if (STREQ(sc->name, name)) {
+ return true;
+ }
+ }
+ if (collection_unique_name_check(&child_data, name)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *name)
+{
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ struct UniqueNameCheckData data = {.lb = &sc_master->scene_collections, .lookup_sc = sc};
+
+ BLI_strncpy(sc->name, name, sizeof(sc->name));
+ BLI_uniquename_cb(collection_unique_name_check, &data, DATA_("Collection"), '.', sc->name, sizeof(sc->name));
+}
+
+/**
+ * Free (or release) any data used by the master collection (does not free the master collection itself).
+ * Used only to clear the entire scene data since it's not doing re-syncing of the LayerCollection tree
+ */
+void BKE_collection_master_free(Scene *scene)
+{
+ collection_free(BKE_collection_master(scene));
+}
+
+static void collection_object_add(const Scene *scene, SceneCollection *sc, Object *ob)
+{
+ BLI_addtail(&sc->objects, BLI_genericNodeN(ob));
+ id_us_plus((ID *)ob);
+ BKE_layer_sync_object_link(scene, sc, ob);
+}
+
+/**
+ * Add object to collection
+ */
+void BKE_collection_object_add(const Scene *scene, SceneCollection *sc, Object *ob)
+{
+ if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
+ /* don't add the same object twice */
+ return;
+ }
+ collection_object_add(scene, sc, ob);
+}
+
+/**
+ * Add object to all collections that reference objects is in
+ * (used to copy objects)
+ */
+void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst)
+{
+ FOREACH_SCENE_COLLECTION(scene, sc)
+ {
+ if (BLI_findptr(&sc->objects, ob_src, offsetof(LinkData, data))) {
+ collection_object_add(scene, sc, ob_dst);
+ }
+ }
+ FOREACH_SCENE_COLLECTION_END
+}
+
+/**
+ * Remove object from collection.
+ * \param bmain: Can be NULL if free_us is false.
+ */
+void BKE_collection_object_remove(Main *bmain, const Scene *scene, SceneCollection *sc, Object *ob, const bool free_us)
+{
+
+ LinkData *link = BLI_findptr(&sc->objects, ob, offsetof(LinkData, data));
+
+ if (link == NULL) {
+ return;
+ }
+
+ BLI_remlink(&sc->objects, link);
+ MEM_freeN(link);
+
+ TODO_LAYER_SYNC_FILTER; /* need to remove all instances of ob in scene collections -> filter_objects */
+ BKE_layer_sync_object_unlink(scene, sc, ob);
+
+ if (free_us) {
+ BKE_libblock_free_us(bmain, ob);
+ }
+ else {
+ id_us_min(&ob->id);
+ }
+}
+
+/**
+ * Move object from a collection into another
+ */
+void BKE_collection_object_move(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src, Object *ob)
+{
+ BKE_collection_object_add(scene, sc_dst, ob);
+ BKE_collection_object_remove(NULL, scene, sc_src, ob, false);
+}
+
+/**
+ * Remove object from all collections of scene
+ */
+void BKE_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us)
+{
+ BKE_scene_remove_rigidbody_object(scene, ob);
+
+ FOREACH_SCENE_COLLECTION(scene, sc)
+ {
+ BKE_collection_object_remove(bmain, scene, sc, ob, free_us);
+ }
+ FOREACH_SCENE_COLLECTION_END
+}
+
+/* ---------------------------------------------------------------------- */
+/* Outliner drag and drop */
+
+/**
+ * Find and return the SceneCollection that has \a sc_child as one of its directly
+ * nested SceneCollection.
+ *
+ * \param sc_parent Initial SceneCollection to look into recursively, usually the master collection
+ */
+static SceneCollection *find_collection_parent(const SceneCollection *sc_child, SceneCollection *sc_parent)
+{
+ for (SceneCollection *sc_nested = sc_parent->scene_collections.first; sc_nested; sc_nested = sc_nested->next) {
+ if (sc_nested == sc_child) {
+ return sc_parent;
+ }
+
+ SceneCollection *found = find_collection_parent(sc_child, sc_nested);
+ if (found) {
+ return found;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Check if \a sc_reference is nested to \a sc_parent SceneCollection
+ */
+static bool is_collection_in_tree(const SceneCollection *sc_reference, SceneCollection *sc_parent)
+{
+ return find_collection_parent(sc_reference, sc_parent) != NULL;
+}
+
+bool BKE_collection_move_above(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+{
+ /* Find the SceneCollection the sc_src belongs to */
+ SceneCollection *sc_master = BKE_collection_master(scene);
+
+ /* Master Layer can't be moved around*/
+ if (ELEM(sc_master, sc_src, sc_dst)) {
+ return false;
+ }
+
+ /* collection is already where we wanted it to be */
+ if (sc_dst->prev == sc_src) {
+ return false;
+ }
+
+ /* We can't move a collection fs the destiny collection
+ * is nested to the source collection */
+ if (is_collection_in_tree(sc_dst, sc_src)) {
+ return false;
+ }
+
+ SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
+ SceneCollection *sc_dst_parent = find_collection_parent(sc_dst, sc_master);
+ BLI_assert(sc_src_parent);
+ BLI_assert(sc_dst_parent);
+
+ /* Remove sc_src from its parent */
+ BLI_remlink(&sc_src_parent->scene_collections, sc_src);
+
+ /* Re-insert it where it belongs */
+ BLI_insertlinkbefore(&sc_dst_parent->scene_collections, sc_dst, sc_src);
+
+ /* Update the tree */
+ BKE_layer_collection_resync(scene, sc_src_parent);
+ BKE_layer_collection_resync(scene, sc_dst_parent);
+
+ return true;
+}
+
+bool BKE_collection_move_below(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+{
+ /* Find the SceneCollection the sc_src belongs to */
+ SceneCollection *sc_master = BKE_collection_master(scene);
+
+ /* Master Layer can't be moved around*/
+ if (ELEM(sc_master, sc_src, sc_dst)) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (sc_dst->next == sc_src) {
+ return false;
+ }
+
+ /* We can't move a collection if the destiny collection
+ * is nested to the source collection */
+ if (is_collection_in_tree(sc_dst, sc_src)) {
+ return false;
+ }
+
+ SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
+ SceneCollection *sc_dst_parent = find_collection_parent(sc_dst, sc_master);
+ BLI_assert(sc_src_parent);
+ BLI_assert(sc_dst_parent);
+
+ /* Remove sc_src from its parent */
+ BLI_remlink(&sc_src_parent->scene_collections, sc_src);
+
+ /* Re-insert it where it belongs */
+ BLI_insertlinkafter(&sc_dst_parent->scene_collections, sc_dst, sc_src);
+
+ /* Update the tree */
+ BKE_layer_collection_resync(scene, sc_src_parent);
+ BKE_layer_collection_resync(scene, sc_dst_parent);
+
+ return true;
+}
+
+bool BKE_collection_move_into(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+{
+ /* Find the SceneCollection the sc_src belongs to */
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ if (sc_src == sc_master) {
+ return false;
+ }
+
+ /* We can't move a collection if the destiny collection
+ * is nested to the source collection */
+ if (is_collection_in_tree(sc_dst, sc_src)) {
+ return false;
+ }
+
+ SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
+ BLI_assert(sc_src_parent);
+
+ /* collection is already where we wanted it to be */
+ if (sc_dst->scene_collections.last == sc_src) {
+ return false;
+ }
+
+ /* Remove sc_src from it */
+ BLI_remlink(&sc_src_parent->scene_collections, sc_src);
+
+ /* Insert sc_src into sc_dst */
+ BLI_addtail(&sc_dst->scene_collections, sc_src);
+
+ /* Update the tree */
+ BKE_layer_collection_resync(scene, sc_src_parent);
+ BKE_layer_collection_resync(scene, sc_dst);
+
+ return true;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Iteractors */
+/* scene collection iteractor */
+
+typedef struct SceneCollectionsIteratorData {
+ Scene *scene;
+ void **array;
+ int tot, cur;
+} SceneCollectionsIteratorData;
+
+static void scene_collection_callback(SceneCollection *sc, BKE_scene_collections_Cb callback, void *data)
+{
+ callback(sc, data);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ scene_collection_callback(nsc, callback, data);
+ }
+}
+
+static void scene_collections_count(SceneCollection *UNUSED(sc), void *data)
+{
+ int *tot = data;
+ (*tot)++;
+}
+
+static void scene_collections_build_array(SceneCollection *sc, void *data)
+{
+ SceneCollection ***array = data;
+ **array = sc;
+ (*array)++;
+}
+
+static void scene_collections_array(Scene *scene, SceneCollection ***collections_array, int *tot)
+{
+ SceneCollection *sc = BKE_collection_master(scene);
+ SceneCollection **array;
+
+ *collections_array = NULL;
+ *tot = 0;
+
+ if (scene == NULL)
+ return;
+
+ scene_collection_callback(sc, scene_collections_count, tot);
+
+ if (*tot == 0)
+ return;
+
+ *collections_array = array = MEM_mallocN(sizeof(SceneCollection *) * (*tot), "SceneCollectionArray");
+ scene_collection_callback(sc, scene_collections_build_array, &array);
+}
+
+/**
+ * Only use this in non-performance critical situations
+ * (it iterates over all scene collections twice)
+ */
+void BKE_scene_collections_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ Scene *scene = data_in;
+ SceneCollectionsIteratorData *data = MEM_callocN(sizeof(SceneCollectionsIteratorData), __func__);
+
+ data->scene = scene;
+ iter->data = data;
+
+ scene_collections_array(scene, (SceneCollection ***)&data->array, &data->tot);
+ BLI_assert(data->tot != 0);
+
+ data->cur = 0;
+ iter->current = data->array[data->cur];
+ iter->valid = true;
+}
+
+void BKE_scene_collections_iterator_next(struct BLI_Iterator *iter)
+{
+ SceneCollectionsIteratorData *data = iter->data;
+
+ if (++data->cur < data->tot) {
+ iter->current = data->array[data->cur];
+ }
+ else {
+ iter->valid = false;
+ }
+}
+
+void BKE_scene_collections_iterator_end(struct BLI_Iterator *iter)
+{
+ SceneCollectionsIteratorData *data = iter->data;
+
+ if (data) {
+ if (data->array) {
+ MEM_freeN(data->array);
+ }
+ MEM_freeN(data);
+ }
+ iter->valid = false;
+}
+
+
+/* scene objects iteractor */
+
+typedef struct SceneObjectsIteratorData {
+ GSet *visited;
+ LinkData *link;
+ BLI_Iterator scene_collection_iter;
+} SceneObjectsIteratorData;
+
+void BKE_scene_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ Scene *scene = data_in;
+ SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __func__);
+ iter->data = data;
+
+ /* lookup list ot make sure each object is object called once */
+ data->visited = BLI_gset_ptr_new(__func__);
+
+ /* we wrap the scenecollection iterator here to go over the scene collections */
+ BKE_scene_collections_iterator_begin(&data->scene_collection_iter, scene);
+
+ SceneCollection *sc = data->scene_collection_iter.current;
+ iter->current = sc->objects.first ? ((LinkData *)sc->objects.first)->data : NULL;
+ iter->valid = true;
+
+ if (iter->current == NULL) {
+ BKE_scene_objects_iterator_next(iter);
+ }
+}
+
+/**
+ * Gets the first unique object in the sequence
+ */
+static LinkData *object_base_unique(GSet *gs, LinkData *link)
+{
+ if (link == NULL) {
+ return NULL;
+ }
+
+ Object *ob = link->data;
+ if (!BLI_gset_haskey(gs, ob)) {
+ BLI_gset_add(gs, ob);
+ return link;
+ }
+ else {
+ return object_base_unique(gs, link->next);
+ }
+}
+
+void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
+{
+ SceneObjectsIteratorData *data = iter->data;
+ LinkData *link = data->link ? object_base_unique(data->visited, data->link->next) : NULL;
+
+ if (link) {
+ data->link = link;
+ iter->current = link->data;
+ }
+ else {
+ /* if this is the last object of this ListBase look at the next SceneCollection */
+ SceneCollection *sc;
+ BKE_scene_collections_iterator_next(&data->scene_collection_iter);
+ do {
+ sc = data->scene_collection_iter.current;
+ /* get the first unique object of this collection */
+ LinkData *new_link = object_base_unique(data->visited, sc->objects.first);
+ if (new_link) {
+ data->link = new_link;
+ iter->current = data->link->data;
+ return;
+ }
+ BKE_scene_collections_iterator_next(&data->scene_collection_iter);
+ } while (data->scene_collection_iter.valid);
+
+ if (!data->scene_collection_iter.valid) {
+ iter->valid = false;
+ }
+ }
+}
+
+void BKE_scene_objects_iterator_end(BLI_Iterator *iter)
+{
+ SceneObjectsIteratorData *data = iter->data;
+ if (data) {
+ BKE_scene_collections_iterator_end(&data->scene_collection_iter);
+ BLI_gset_free(data->visited, NULL);
+ MEM_freeN(data);
+ }
+}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index ee25be36855..acb48a9646f 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -512,7 +512,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
// return all collision objects in scene
// collision object will exclude self
-Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
+Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
{
Base *base;
Object **objs;
@@ -532,9 +532,9 @@ Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int
Scene *sce_iter;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
- if ( base->lay & layer )
+ if ((base->flag & BASE_VISIBLED) != 0) {
add_collision_object(&objs, &numobj, &maxobj, base->object, self, level, modifier_type);
-
+ }
}
}
@@ -547,7 +547,7 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned
{
/* Need to check for active layers, too.
Otherwise this check fails if the objects are not on the same layer - DG */
- return get_collisionobjects_ext(scene, self, group, self->lay | scene->lay, numcollobj, modifier_type, true);
+ return get_collisionobjects_ext(scene, self, group, numcollobj, modifier_type, true);
}
static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, int level)
@@ -600,7 +600,7 @@ ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
- if (!self || (base->lay & self->lay))
+ if (!self || ((base->flag & BASE_VISIBLED) != 0))
add_collider_cache_object(&objs, base->object, self, 0);
}
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 4c01bfd35f2..ec0e14d814f 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -39,6 +39,8 @@
#include "DNA_linestyle_types.h"
#include "DNA_gpencil_types.h"
+#include "DEG_depsgraph.h"
+
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_threads.h"
@@ -47,6 +49,7 @@
#include "BLT_translation.h"
#include "BKE_context.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_screen.h"
#include "BKE_sound.h"
@@ -836,8 +839,9 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
void CTX_wm_screen_set(bContext *C, bScreen *screen)
{
C->wm.screen = screen;
- if (C->wm.screen)
- C->data.scene = C->wm.screen->scene;
+ if (C->wm.screen) {
+ CTX_data_scene_set(C, C->wm.screen->scene);
+ }
C->wm.area = NULL;
C->wm.region = NULL;
}
@@ -896,10 +900,62 @@ Scene *CTX_data_scene(const bContext *C)
return C->data.scene;
}
-int CTX_data_mode_enum(const bContext *C)
+SceneLayer *CTX_data_scene_layer(const bContext *C)
{
- Object *obedit = CTX_data_edit_object(C);
+ SceneLayer *sl;
+
+ if (ctx_data_pointer_verify(C, "render_layer", (void *)&sl)) {
+ return sl;
+ }
+ else {
+ return BKE_scene_layer_context_active(CTX_data_scene(C));
+ }
+}
+
+/**
+ * This is tricky. Sometimes the user overrides the render_layer
+ * but not the scene_collection. In this case what to do?
+ *
+ * If the scene_collection is linked to the SceneLayer we use it.
+ * Otherwise we fallback to the active one of the SceneLayer.
+ */
+LayerCollection *CTX_data_layer_collection(const bContext *C)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ LayerCollection *lc;
+ if (ctx_data_pointer_verify(C, "layer_collection", (void *)&lc)) {
+ if (BKE_scene_layer_has_collection(sl, lc->scene_collection)) {
+ return lc;
+ }
+ }
+
+ /* fallback */
+ return BKE_layer_collection_get_active(sl);
+}
+
+SceneCollection *CTX_data_scene_collection(const bContext *C)
+{
+ SceneCollection *sc;
+ if (ctx_data_pointer_verify(C, "scene_collection", (void *)&sc)) {
+ if (BKE_scene_layer_has_collection(CTX_data_scene_layer(C), sc)) {
+ return sc;
+ }
+ }
+
+ LayerCollection *lc = CTX_data_layer_collection(C);
+ if (lc) {
+ return lc->scene_collection;
+ }
+
+ /* fallback */
+ Scene *scene = CTX_data_scene(C);
+ return BKE_collection_master(scene);
+}
+
+int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob)
+{
+ // Object *obedit = CTX_data_edit_object(C);
if (obedit) {
switch (obedit->type) {
case OB_MESH:
@@ -919,8 +975,7 @@ int CTX_data_mode_enum(const bContext *C)
}
}
else {
- Object *ob = CTX_data_active_object(C);
-
+ // Object *ob = CTX_data_active_object(C);
if (ob) {
if (ob->mode & OB_MODE_POSE) return CTX_MODE_POSE;
else if (ob->mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT;
@@ -934,6 +989,12 @@ int CTX_data_mode_enum(const bContext *C)
return CTX_MODE_OBJECT;
}
+int CTX_data_mode_enum(const bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Object *obact = obedit ? NULL : CTX_data_active_object(C);
+ return CTX_data_mode_enum_ex(obedit, obact);
+}
/* would prefer if we can use the enum version below over this one - Campbell */
/* must be aligned with above enum */
@@ -1154,3 +1215,8 @@ int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
return ctx_data_collection_get(C, "editable_gpencil_strokes", list);
}
+Depsgraph *CTX_data_depsgraph(const bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ return scene->depsgraph;
+}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 439abb1d593..0cfc4a99eb2 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -52,7 +52,6 @@
#include "BKE_animsys.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_font.h"
#include "BKE_global.h"
@@ -64,6 +63,8 @@
#include "BKE_object.h"
#include "BKE_material.h"
+#include "DEG_depsgraph.h"
+
/* globals */
/* local */
@@ -126,6 +127,8 @@ void BKE_curve_free(Curve *cu)
{
BKE_animdata_free((ID *)cu, false);
+ BKE_curve_batch_cache_free(cu);
+
BKE_nurbList_free(&cu->nurb);
BKE_curve_editfont_free(cu);
@@ -206,6 +209,7 @@ Curve *BKE_curve_copy(Main *bmain, Curve *cu)
cun->strinfo = MEM_dupallocN(cu->strinfo);
cun->tb = MEM_dupallocN(cu->tb);
cun->bb = MEM_dupallocN(cu->bb);
+ cun->batch_cache = NULL;
if (cu->key) {
cun->key = BKE_key_copy(bmain, cu->key);
@@ -4568,7 +4572,7 @@ int BKE_curve_material_index_validate(Curve *cu)
}
if (!is_valid) {
- DAG_id_tag_update(&cu->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&cu->id, OB_RECALC_DATA);
return true;
}
else {
@@ -4656,3 +4660,20 @@ void BKE_curve_eval_path(EvaluationContext *UNUSED(eval_ctx),
printf("%s on %s\n", __func__, curve->id.name);
}
}
+
+/* Draw Engine */
+void (*BKE_curve_batch_cache_dirty_cb)(Curve *cu, int mode) = NULL;
+void (*BKE_curve_batch_cache_free_cb)(Curve *cu) = NULL;
+
+void BKE_curve_batch_cache_dirty(Curve *cu, int mode)
+{
+ if (cu->batch_cache) {
+ BKE_curve_batch_cache_dirty_cb(cu, mode);
+ }
+}
+void BKE_curve_batch_cache_free(Curve *cu)
+{
+ if (cu->batch_cache) {
+ BKE_curve_batch_cache_free_cb(cu);
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 0939d35ed8d..3ccf619fd11 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -390,37 +390,19 @@ static void layerSwap_tface(void *data, const int *corner_indices)
{
MTFace *tf = data;
float uv[4][2];
- static const short pin_flags[4] = { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 };
- static const char sel_flags[4] = { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 };
- short unwrap = tf->unwrap & ~(TF_PIN1 | TF_PIN2 | TF_PIN3 | TF_PIN4);
- char flag = tf->flag & ~(TF_SEL1 | TF_SEL2 | TF_SEL3 | TF_SEL4);
int j;
for (j = 0; j < 4; ++j) {
const int source_index = corner_indices[j];
-
copy_v2_v2(uv[j], tf->uv[source_index]);
-
- /* swap pinning flags around */
- if (tf->unwrap & pin_flags[source_index]) {
- unwrap |= pin_flags[j];
- }
-
- /* swap selection flags around */
- if (tf->flag & sel_flags[source_index]) {
- flag |= sel_flags[j];
- }
}
memcpy(tf->uv, uv, sizeof(tf->uv));
- tf->unwrap = unwrap;
- tf->flag = flag;
}
static void layerDefault_tface(void *data, int count)
{
- static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
- 0, 0, TF_DYNAMIC | TF_CONVERTED, 0, 0};
+ static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
MTFace *tf = (MTFace *)data;
int i;
@@ -1190,6 +1172,15 @@ static void layerSwap_flnor(void *data, const int *corner_indices)
memcpy(flnors, nors, sizeof(nors));
}
+static void layerDefault_fmap(void *data, int count)
+{
+ int *fmap_num = (int *)data;
+ int i;
+ for (i = 0; i < count; i++) {
+ *fmap_num = -1;
+ }
+}
+
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
@@ -1215,8 +1206,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 3 floats per normal vector */
{sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, layerInterp_normal, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, layerCopyValue_normal},
- /* 9: CD_POLYINDEX */ /* DEPRECATED */
- {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 9: CD_FACEMAP */
+ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_fmap, NULL},
/* 10: CD_PROP_FLT */
{sizeof(MFloatProperty), "MFloatProperty", 1, N_("Float"), layerCopy_propFloat, NULL, NULL, NULL},
/* 11: CD_PROP_INT */
@@ -1228,10 +1219,9 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
/* 14: CD_ORCO */
{sizeof(float) * 3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
- /* 15: CD_MTEXPOLY */
+ /* 15: CD_MTEXPOLY */ /* DEPRECATED */
/* note, when we expose the UV Map / TexFace split to the user, change this back to face Texture */
- {sizeof(MTexPoly), "MTexPoly", 1, N_("UVMap") /* "Face Texture" */, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_tface},
+ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 16: CD_MLOOPUV */
{sizeof(MLoopUV), "MLoopUV", 1, N_("UVMap"), NULL, NULL, layerInterp_mloopuv, NULL, NULL,
layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,
@@ -1310,7 +1300,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace",
- /* 5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags",
+ /* 5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFaceMap",
/* 10-14 */ "CDMFloatProperty", "CDMIntProperty", "CDMStringProperty", "CDOrigSpace", "CDOrco",
/* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
/* 20-24 */ "CDPreviewMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast",
@@ -1325,41 +1315,41 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
const CustomDataMask CD_MASK_BAREMESH =
- CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT;
+ CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT | CD_MASK_FACEMAP;
const CustomDataMask CD_MASK_MESH =
CD_MASK_MVERT | CD_MASK_MEDGE |
CD_MASK_MDEFORMVERT |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
- CD_MASK_MTEXPOLY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+ CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
- CD_MASK_CUSTOMLOOPNORMAL;
+ CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MDEFORMVERT | CD_MASK_MLOOPUV |
- CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
+ CD_MASK_MLOOPCOL | CD_MASK_SHAPE_KEYINDEX |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
- CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_CUSTOMLOOPNORMAL;
+ CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MDEFORMVERT |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
- CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOOPCOL |
+ CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_PREVIEW_MLOOPCOL |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT |
CD_MASK_PREVIEW_MCOL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
- CD_MASK_CUSTOMLOOPNORMAL;
+ CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP;
const CustomDataMask CD_MASK_BMESH =
- CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
+ CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL |
CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS |
CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
- CD_MASK_CUSTOMLOOPNORMAL;
+ CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP;
/**
* cover values copied by #BKE_mesh_loops_to_tessdata
*/
const CustomDataMask CD_MASK_FACECORNERS =
- CD_MASK_MTFACE | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
+ CD_MASK_MTFACE | CD_MASK_MLOOPUV |
CD_MASK_MCOL | CD_MASK_MLOOPCOL |
CD_MASK_PREVIEW_MCOL | CD_MASK_PREVIEW_MLOOPCOL |
CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP |
@@ -1368,7 +1358,7 @@ const CustomDataMask CD_MASK_FACECORNERS =
const CustomDataMask CD_MASK_EVERYTHING =
CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_NORMAL /* | CD_MASK_POLYINDEX */ | CD_MASK_PROP_FLT |
- CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
+ CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL | CD_MASK_TANGENT | CD_MASK_MDISPS | CD_MASK_PREVIEW_MCOL | CD_MASK_CLOTH_ORCO | CD_MASK_RECAST |
/* BMESH ONLY START */
CD_MASK_MPOLY | CD_MASK_MLOOP | CD_MASK_SHAPE_KEYINDEX | CD_MASK_SHAPEKEY | CD_MASK_BWEIGHT | CD_MASK_CREASE |
@@ -1376,7 +1366,7 @@ const CustomDataMask CD_MASK_EVERYTHING =
/* BMESH ONLY END */
CD_MASK_PAINT_MASK | CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN |
CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
- CD_MASK_MLOOPTANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_CUSTOMLOOPNORMAL;
+ CD_MASK_MLOOPTANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP;
static const LayerTypeInfo *layerType_getInfo(int type)
{
@@ -2502,13 +2492,10 @@ void CustomData_set(const CustomData *data, int index, int type, const void *sou
/* BMesh functions */
/* needed to convert to/from different face reps */
-void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata,
- int totloop, int totpoly)
+void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int totloop)
{
- int i;
- for (i = 0; i < fdata->totlayer; i++) {
+ for (int i = 0; i < fdata->totlayer; i++) {
if (fdata->layers[i].type == CD_MTFACE) {
- CustomData_add_layer_named(pdata, CD_MTEXPOLY, CD_CALLOC, NULL, totpoly, fdata->layers[i].name);
CustomData_add_layer_named(ldata, CD_MLOOPUV, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
}
else if (fdata->layers[i].type == CD_MCOL) {
@@ -2523,19 +2510,18 @@ void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *l
}
}
-void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total)
+void CustomData_from_bmeshpoly(
+ CustomData *fdata, CustomData *ldata, int total)
{
int i;
/* avoid accumulating extra layers */
- BLI_assert(!CustomData_from_bmeshpoly_test(fdata, pdata, ldata, false));
+ BLI_assert(!CustomData_from_bmeshpoly_test(fdata, ldata, false));
- for (i = 0; i < pdata->totlayer; i++) {
- if (pdata->layers[i].type == CD_MTEXPOLY) {
- CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, pdata->layers[i].name);
- }
- }
for (i = 0; i < ldata->totlayer; i++) {
+ if (ldata->layers[i].type == CD_MLOOPUV) {
+ CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
+ }
if (ldata->layers[i].type == CD_MLOOPCOL) {
CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
}
@@ -2553,7 +2539,7 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
}
}
- CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
+ CustomData_bmesh_update_active_layers(fdata, ldata);
}
#ifndef NDEBUG
@@ -2563,13 +2549,13 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
* \param fallback: Use when there are no layers to handle,
* since callers may expect success or failure.
*/
-bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *pdata, CustomData *ldata, bool fallback)
+bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool fallback)
{
int a_num = 0, b_num = 0;
#define LAYER_CMP(l_a, t_a, l_b, t_b) \
((a_num += CustomData_number_of_layers(l_a, t_a)) == (b_num += CustomData_number_of_layers(l_b, t_b)))
- if (!LAYER_CMP(pdata, CD_MTEXPOLY, fdata, CD_MTFACE))
+ if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE))
return false;
if (!LAYER_CMP(ldata, CD_MLOOPCOL, fdata, CD_MCOL))
return false;
@@ -2591,25 +2577,21 @@ bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *pdata, Custom
#endif
-void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *pdata, CustomData *ldata)
+void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *ldata)
{
int act;
- if (CustomData_has_layer(pdata, CD_MTEXPOLY)) {
- act = CustomData_get_active_layer(pdata, CD_MTEXPOLY);
- CustomData_set_layer_active(ldata, CD_MLOOPUV, act);
+ if (CustomData_has_layer(ldata, CD_MLOOPUV)) {
+ act = CustomData_get_active_layer(ldata, CD_MLOOPUV);
CustomData_set_layer_active(fdata, CD_MTFACE, act);
- act = CustomData_get_render_layer(pdata, CD_MTEXPOLY);
- CustomData_set_layer_render(ldata, CD_MLOOPUV, act);
+ act = CustomData_get_render_layer(ldata, CD_MLOOPUV);
CustomData_set_layer_render(fdata, CD_MTFACE, act);
- act = CustomData_get_clone_layer(pdata, CD_MTEXPOLY);
- CustomData_set_layer_clone(ldata, CD_MLOOPUV, act);
+ act = CustomData_get_clone_layer(ldata, CD_MLOOPUV);
CustomData_set_layer_clone(fdata, CD_MTFACE, act);
- act = CustomData_get_stencil_layer(pdata, CD_MTEXPOLY);
- CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act);
+ act = CustomData_get_stencil_layer(ldata, CD_MLOOPUV);
CustomData_set_layer_stencil(fdata, CD_MTFACE, act);
}
@@ -2633,25 +2615,21 @@ void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *pdata,
* used by do_versions in readfile.c when creating pdata and ldata for pre-bmesh
* meshes and needed to preserve active/render/clone/stencil flags set in pre-bmesh files
*/
-void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, CustomData *pdata, CustomData *ldata)
+void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, CustomData *ldata)
{
int act;
if (CustomData_has_layer(fdata, CD_MTFACE)) {
act = CustomData_get_active_layer(fdata, CD_MTFACE);
- CustomData_set_layer_active(pdata, CD_MTEXPOLY, act);
CustomData_set_layer_active(ldata, CD_MLOOPUV, act);
act = CustomData_get_render_layer(fdata, CD_MTFACE);
- CustomData_set_layer_render(pdata, CD_MTEXPOLY, act);
CustomData_set_layer_render(ldata, CD_MLOOPUV, act);
act = CustomData_get_clone_layer(fdata, CD_MTFACE);
- CustomData_set_layer_clone(pdata, CD_MTEXPOLY, act);
CustomData_set_layer_clone(ldata, CD_MLOOPUV, act);
act = CustomData_get_stencil_layer(fdata, CD_MTFACE);
- CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, act);
CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act);
}
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 3bc09c0173b..a83ec8f0486 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -79,7 +79,7 @@ CustomDataMask BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types
cddata_mask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */
}
else if (cddata_type == CD_FAKE_UV) {
- cddata_mask |= CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV;
+ cddata_mask |= CD_MASK_MLOOPUV;
}
else if (cddata_type == CD_FAKE_LNOR) {
cddata_mask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
@@ -962,7 +962,7 @@ static bool data_transfer_layersmapping_generate(
}
else if (elem_type == ME_POLY) {
if (cddata_type == CD_FAKE_UV) {
- cddata_type = CD_MTEXPOLY;
+ cddata_type = CD_MLOOPUV;
}
if (!(cddata_type & CD_FAKE)) {
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 13b1aab5e1c..3b91534e321 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -54,6 +54,7 @@
#include "BKE_customdata.h"
#include "BKE_data_transfer.h"
#include "BKE_deform.h" /* own include */
+#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_object_deform.h"
@@ -73,6 +74,8 @@ bDeformGroup *BKE_defgroup_new(Object *ob, const char *name)
BLI_addtail(&ob->defbase, defgroup);
defgroup_unique_name(defgroup, ob);
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
+
return defgroup;
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 019e0df1623..f99a4acd81e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -40,3551 +40,20 @@
#endif
#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
-#include "BLI_ghash.h"
-#include "BLI_threads.h"
-#include "DNA_anim_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_cachefile_types.h"
-#include "DNA_group_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_key_types.h"
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_node_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_windowmanager_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_mask_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_rigidbody_types.h"
-#include "BKE_anim.h"
-#include "BKE_animsys.h"
-#include "BKE_action.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_collision.h"
-#include "BKE_effect.h"
-#include "BKE_fcurve.h"
#include "BKE_global.h"
-#include "BKE_idcode.h"
-#include "BKE_image.h"
-#include "BKE_key.h"
-#include "BKE_library.h"
+#include "BKE_depsgraph.h"
#include "BKE_main.h"
-#include "BKE_node.h"
-#include "BKE_material.h"
-#include "BKE_mball.h"
-#include "BKE_modifier.h"
-#include "BKE_object.h"
-#include "BKE_paint.h"
-#include "BKE_particle.h"
-#include "BKE_pointcache.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
-#include "BKE_tracking.h"
-
-#include "GPU_buffers.h"
-
-#include "atomic_ops.h"
-
-#include "depsgraph_private.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_debug.h"
#include "DEG_depsgraph_query.h"
-#ifdef WITH_LEGACY_DEPSGRAPH
-
-static SpinLock threaded_update_lock;
-
-void DAG_init(void)
-{
- BLI_spin_init(&threaded_update_lock);
- DEG_register_node_types();
-}
-
-void DAG_exit(void)
-{
- BLI_spin_end(&threaded_update_lock);
- DEG_free_node_types();
-}
-
-/* Queue and stack operations for dag traversal
- *
- * the queue store a list of freenodes to avoid successive alloc/dealloc
- */
-
-DagNodeQueue *queue_create(int slots)
-{
- DagNodeQueue *queue;
- DagNodeQueueElem *elem;
- int i;
-
- queue = MEM_mallocN(sizeof(DagNodeQueue), "DAG queue");
- queue->freenodes = MEM_mallocN(sizeof(DagNodeQueue), "DAG queue");
- queue->count = 0;
- queue->maxlevel = 0;
- queue->first = queue->last = NULL;
- elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem3");
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->first = queue->freenodes->last = elem;
-
- for (i = 1; i < slots; i++) {
- elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem4");
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->last->next = elem;
- queue->freenodes->last = elem;
- }
- queue->freenodes->count = slots;
- return queue;
-}
-
-void queue_raz(DagNodeQueue *queue)
-{
- DagNodeQueueElem *elem;
-
- elem = queue->first;
- if (queue->freenodes->last)
- queue->freenodes->last->next = elem;
- else
- queue->freenodes->first = queue->freenodes->last = elem;
-
- elem->node = NULL;
- queue->freenodes->count++;
- while (elem->next) {
- elem = elem->next;
- elem->node = NULL;
- queue->freenodes->count++;
- }
- queue->freenodes->last = elem;
- queue->count = 0;
-}
-
-void queue_delete(DagNodeQueue *queue)
-{
- DagNodeQueueElem *elem;
- DagNodeQueueElem *temp;
-
- elem = queue->first;
- while (elem) {
- temp = elem;
- elem = elem->next;
- MEM_freeN(temp);
- }
-
- elem = queue->freenodes->first;
- while (elem) {
- temp = elem;
- elem = elem->next;
- MEM_freeN(temp);
- }
-
- MEM_freeN(queue->freenodes);
- MEM_freeN(queue);
-}
-
-/* insert in queue, remove in front */
-void push_queue(DagNodeQueue *queue, DagNode *node)
-{
- DagNodeQueueElem *elem;
- int i;
-
- if (node == NULL) {
- fprintf(stderr, "pushing null node\n");
- return;
- }
- /*fprintf(stderr, "BFS push : %s %d\n", ((ID *) node->ob)->name, queue->count);*/
-
- elem = queue->freenodes->first;
- if (elem != NULL) {
- queue->freenodes->first = elem->next;
- if (queue->freenodes->last == elem) {
- queue->freenodes->last = NULL;
- queue->freenodes->first = NULL;
- }
- queue->freenodes->count--;
- }
- else { /* alllocating more */
- elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem1");
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->first = queue->freenodes->last = elem;
-
- for (i = 1; i < DAGQUEUEALLOC; i++) {
- elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem2");
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->last->next = elem;
- queue->freenodes->last = elem;
- }
- queue->freenodes->count = DAGQUEUEALLOC;
-
- elem = queue->freenodes->first;
- queue->freenodes->first = elem->next;
- }
- elem->next = NULL;
- elem->node = node;
- if (queue->last != NULL)
- queue->last->next = elem;
- queue->last = elem;
- if (queue->first == NULL) {
- queue->first = elem;
- }
- queue->count++;
-}
-
-
-/* insert in front, remove in front */
-void push_stack(DagNodeQueue *queue, DagNode *node)
-{
- DagNodeQueueElem *elem;
- int i;
-
- elem = queue->freenodes->first;
- if (elem != NULL) {
- queue->freenodes->first = elem->next;
- if (queue->freenodes->last == elem) {
- queue->freenodes->last = NULL;
- queue->freenodes->first = NULL;
- }
- queue->freenodes->count--;
- }
- else { /* alllocating more */
- elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem1");
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->first = queue->freenodes->last = elem;
-
- for (i = 1; i < DAGQUEUEALLOC; i++) {
- elem = MEM_mallocN(sizeof(DagNodeQueueElem), "DAG queue elem2");
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->last->next = elem;
- queue->freenodes->last = elem;
- }
- queue->freenodes->count = DAGQUEUEALLOC;
-
- elem = queue->freenodes->first;
- queue->freenodes->first = elem->next;
- }
- elem->next = queue->first;
- elem->node = node;
- queue->first = elem;
- if (queue->last == NULL)
- queue->last = elem;
- queue->count++;
-}
-
-
-DagNode *pop_queue(DagNodeQueue *queue)
-{
- DagNodeQueueElem *elem;
- DagNode *node;
-
- elem = queue->first;
- if (elem) {
- queue->first = elem->next;
- if (queue->last == elem) {
- queue->last = NULL;
- queue->first = NULL;
- }
- queue->count--;
- if (queue->freenodes->last)
- queue->freenodes->last->next = elem;
- queue->freenodes->last = elem;
- if (queue->freenodes->first == NULL)
- queue->freenodes->first = elem;
- node = elem->node;
- elem->node = NULL;
- elem->next = NULL;
- queue->freenodes->count++;
- return node;
- }
- else {
- fprintf(stderr, "return null\n");
- return NULL;
- }
-}
-
-DagNode *get_top_node_queue(DagNodeQueue *queue)
-{
- return queue->first->node;
-}
-
-DagForest *dag_init(void)
-{
- DagForest *forest;
- /* use callocN to init all zero */
- forest = MEM_callocN(sizeof(DagForest), "DAG root");
- forest->ugly_hack_sorry = true;
- return forest;
-}
-
-/* isdata = object data... */
-/* XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)... */
-static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata)
-{
- FCurve *fcu;
- DagNode *node1;
-
- for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
- int isdata_fcu = (isdata) || (fcu->rna_path && strstr(fcu->rna_path, "modifiers["));
-
- /* loop over variables to get the target relationships */
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* only used targets */
- DRIVER_TARGETS_USED_LOOPER(dvar)
- {
- if (dtar->id) {
- /* FIXME: other data types need to be added here so that they can work! */
- if (GS(dtar->id->name) == ID_OB) {
- Object *ob = (Object *)dtar->id;
-
- /* normal channel-drives-channel */
- node1 = dag_get_node(dag, dtar->id);
-
- /* check if bone... */
- if ((ob->type == OB_ARMATURE) &&
- ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) ||
- ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) ))
- {
- dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
- }
- /* check if ob data */
- else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
- dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
- /* normal */
- else
- dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_OB_DATA : DAG_RL_OB_OB, "Driver");
- }
- }
- }
- DRIVER_TARGETS_LOOPER_END
- }
- }
-}
-
-/* XXX: forward def for material driver handling... */
-static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma);
-
-/* recursive handling for shader nodetree drivers */
-static void dag_add_shader_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree)
-{
- bNode *n;
-
- /* nodetree itself */
- if (ntree->adt) {
- dag_add_driver_relation(ntree->adt, dag, node, 1);
- }
-
- /* nodetree's nodes... */
- for (n = ntree->nodes.first; n; n = n->next) {
- if (n->id) {
- if (GS(n->id->name) == ID_MA) {
- dag_add_material_driver_relations(dag, node, (Material *)n->id);
- }
- else if (n->type == NODE_GROUP) {
- dag_add_shader_nodetree_driver_relations(dag, node, (bNodeTree *)n->id);
- }
- }
- }
-}
-
-/* recursive handling for material drivers */
-static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma)
-{
- /* Prevent infinite recursion by checking (and tagging the material) as having been visited
- * already (see build_dag()). This assumes ma->id.tag & LIB_TAG_DOIT isn't set by anything else
- * in the meantime... [#32017]
- */
- if (ma->id.tag & LIB_TAG_DOIT)
- return;
-
- ma->id.tag |= LIB_TAG_DOIT;
-
- /* material itself */
- if (ma->adt)
- dag_add_driver_relation(ma->adt, dag, node, 1);
-
- /* textures */
- // TODO...
- //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id);
-
- /* material's nodetree */
- if (ma->nodetree)
- dag_add_shader_nodetree_driver_relations(dag, node, ma->nodetree);
-
- ma->id.tag &= ~LIB_TAG_DOIT;
-}
-
-/* recursive handling for lamp drivers */
-static void dag_add_lamp_driver_relations(DagForest *dag, DagNode *node, Lamp *la)
-{
- /* Prevent infinite recursion by checking (and tagging the lamp) as having been visited
- * already (see build_dag()). This assumes la->id.tag & LIB_TAG_DOIT isn't set by anything else
- * in the meantime... [#32017]
- */
- if (la->id.tag & LIB_TAG_DOIT)
- return;
-
- la->id.tag |= LIB_TAG_DOIT;
-
- /* lamp itself */
- if (la->adt)
- dag_add_driver_relation(la->adt, dag, node, 1);
-
- /* textures */
- // TODO...
- //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id);
-
- /* lamp's nodetree */
- if (la->nodetree)
- dag_add_shader_nodetree_driver_relations(dag, node, la->nodetree);
-
- la->id.tag &= ~LIB_TAG_DOIT;
-}
-
-static void create_collision_relation(DagForest *dag, DagNode *node, Object *ob1, const char *name)
-{
- DagNode *node2 = dag_get_node(dag, ob1);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, name);
-}
-
-void dag_add_collision_relations(DagForest *dag, Scene *scene, Object *ob, DagNode *node, Group *group, int layer, unsigned int modifier_type, DagCollobjFilterFunction fn, bool dupli, const char *name)
-{
- unsigned int numcollobj;
- Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, modifier_type, dupli);
-
- for (unsigned int i = 0; i < numcollobj; i++) {
- Object *ob1 = collobjs[i];
-
- if (!fn || fn(ob1, modifiers_findByType(ob1, modifier_type))) {
- create_collision_relation(dag, node, ob1, name);
- }
- }
-
- if (collobjs)
- MEM_freeN(collobjs);
-}
-
-void dag_add_forcefield_relations(DagForest *dag, Scene *scene, Object *ob, DagNode *node, EffectorWeights *effector_weights, bool add_absorption, int skip_forcefield, const char *name)
-{
- ListBase *effectors = pdInitEffectors(scene, ob, NULL, effector_weights, false);
-
- if (effectors) {
- for (EffectorCache *eff = effectors->first; eff; eff = eff->next) {
- if (eff->ob != ob && eff->pd->forcefield != skip_forcefield) {
- create_collision_relation(dag, node, eff->ob, name);
-
- if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
- create_collision_relation(dag, node, eff->pd->f_source, "Smoke Force Domain");
- }
-
- if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
- /* Actual code uses get_collider_cache */
- dag_add_collision_relations(dag, scene, ob, node, NULL, eff->ob->lay, eModifierType_Collision, NULL, true, "Force Absorption");
- }
- }
- }
- }
-
- pdEndEffectors(&effectors);
-}
-
-static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Object *ob, int mask)
-{
- bConstraint *con;
- DagNode *node;
- DagNode *node2;
- DagNode *node3;
- Key *key;
- ParticleSystem *psys;
- int addtoroot = 1;
-
- node = dag_get_node(dag, ob);
-
- if ((ob->data) && (mask & DAG_RL_DATA)) {
- node2 = dag_get_node(dag, ob->data);
- dag_add_relation(dag, node, node2, DAG_RL_DATA, "Object-Data Relation");
- node2->first_ancestor = ob;
- node2->ancestor_count += 1;
- }
-
- /* also build a custom data mask for dependencies that need certain layers */
-
- if (ob->type == OB_ARMATURE) {
- if (ob->pose) {
- bPoseChannel *pchan;
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- for (con = pchan->constraints.first; con; con = con->next) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
- ListBase targets = {NULL, NULL};
- bConstraintTarget *ct;
-
- if (cti && cti->get_constraint_targets) {
- cti->get_constraint_targets(con, &targets);
-
- for (ct = targets.first; ct; ct = ct->next) {
- if (ct->tar && ct->tar != ob) {
- // fprintf(stderr, "armature %s target :%s\n", ob->id.name, target->id.name);
- node3 = dag_get_node(dag, ct->tar);
-
- if (ct->subtarget[0]) {
- dag_add_relation(dag, node3, node, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, cti->name);
- if (ct->tar->type == OB_MESH)
- node3->customdata_mask |= CD_MASK_MDEFORMVERT;
- }
- else if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH,
- CONSTRAINT_TYPE_CLAMPTO,
- CONSTRAINT_TYPE_SPLINEIK,
- CONSTRAINT_TYPE_SHRINKWRAP))
- {
- dag_add_relation(dag, node3, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, cti->name);
- }
- else {
- dag_add_relation(dag, node3, node, DAG_RL_OB_DATA, cti->name);
- }
- }
- }
-
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(con, &targets, 1);
- }
-
- }
- }
- }
- }
-
- /* driver dependencies, nla modifiers */
-#if 0 // XXX old animation system
- if (ob->nlastrips.first) {
- bActionStrip *strip;
- bActionChannel *chan;
- for (strip = ob->nlastrips.first; strip; strip = strip->next) {
- if (strip->modifiers.first) {
- bActionModifier *amod;
- for (amod = strip->modifiers.first; amod; amod = amod->next) {
- if (amod->ob) {
- node2 = dag_get_node(dag, amod->ob);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "NLA Strip Modifier");
- }
- }
- }
- }
- }
-#endif // XXX old animation system
- if (ob->adt)
- dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE)); // XXX isdata arg here doesn't give an accurate picture of situation
-
- key = BKE_key_from_object(ob);
- if (key && key->adt)
- dag_add_driver_relation(key->adt, dag, node, 1);
-
- if (ob->modifiers.first) {
- ModifierData *md;
-
- for (md = ob->modifiers.first; md; md = md->next) {
- const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
- if (mti->updateDepgraph) mti->updateDepgraph(md, dag, bmain, scene, ob, node);
- }
- }
- if (ob->parent) {
- node2 = dag_get_node(dag, ob->parent);
-
- switch (ob->partype) {
- case PARSKEL:
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Parent");
- break;
- case PARVERT1: case PARVERT3:
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Vertex Parent");
- node2->customdata_mask |= CD_MASK_ORIGINDEX;
- break;
- case PARBONE:
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Bone Parent");
- break;
- default:
- if (ob->parent->type == OB_LATTICE)
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Lattice Parent");
- else if (ob->parent->type == OB_CURVE) {
- Curve *cu = ob->parent->data;
- if (cu->flag & CU_PATH)
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, "Curve Parent");
- else
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Curve Parent");
- }
- else
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Parent");
- break;
- }
- /* exception case: parent is duplivert */
- if (ob->type == OB_MBALL && (ob->parent->transflag & OB_DUPLIVERTS)) {
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Duplivert");
- }
-
- addtoroot = 0;
- }
- if (ob->proxy) {
- node2 = dag_get_node(dag, ob->proxy);
- dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_OB, "Proxy");
- /* inverted relation, so addtoroot shouldn't be set to zero */
- }
-
- if (ob->transflag & OB_DUPLI) {
- if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
- GroupObject *go;
- for (go = ob->dup_group->gobject.first; go; go = go->next) {
- if (go->ob) {
- node2 = dag_get_node(dag, go->ob);
- /* node2 changes node1, this keeps animations updated in groups?? not logical? */
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Dupligroup");
- }
- }
- }
- }
-
- /* rigidbody force fields */
- if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) {
- if (ob->rigidbody_object && scene->rigidbody_world) {
- dag_add_forcefield_relations(dag, scene, ob, node, scene->rigidbody_world->effector_weights, true, 0, "Force Field");
- }
- }
-
- /* object data drivers */
- if (ob->data) {
- AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
- if (adt)
- dag_add_driver_relation(adt, dag, node, 1);
- }
-
- /* object type/data relationships */
- switch (ob->type) {
- case OB_CAMERA:
- {
- Camera *cam = (Camera *)ob->data;
-
- if (cam->dof_ob) {
- node2 = dag_get_node(dag, cam->dof_ob);
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Camera DoF");
- }
- break;
- }
- case OB_MBALL:
- {
- Object *mom = BKE_mball_basis_find(scene, ob);
-
- if (mom != ob) {
- node2 = dag_get_node(dag, mom);
- dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Metaball"); /* mom depends on children! */
- }
- break;
- }
- case OB_CURVE:
- case OB_FONT:
- {
- Curve *cu = ob->data;
-
- if (cu->bevobj) {
- node2 = dag_get_node(dag, cu->bevobj);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Bevel");
- }
- if (cu->taperobj) {
- node2 = dag_get_node(dag, cu->taperobj);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Taper");
- }
- if (ob->type == OB_FONT) {
- /* Really rather dirty hack. needs to support font family to work
- * reliably on render export.
- *
- * This totally mimics behavior of regular verts duplication with
- * parenting. The only tricky thing here is to get list of objects
- * used for the custom "font".
- *
- * This shouldn't harm so much because this code only runs on DAG
- * rebuild and this feature is not that commonly used.
- *
- * - sergey -
- */
- if (cu->family[0] != '\n') {
- ListBase *duplilist;
- DupliObject *dob;
- duplilist = object_duplilist(G.main->eval_ctx, scene, ob);
- for (dob = duplilist->first; dob; dob = dob->next) {
- node2 = dag_get_node(dag, dob->ob);
- dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Object Font");
- }
- free_object_duplilist(duplilist);
- }
-
- if (cu->textoncurve) {
- node2 = dag_get_node(dag, cu->textoncurve);
- /* Text on curve requires path to be evaluated for the target curve. */
- node2->eval_flags |= DAG_EVAL_NEED_CURVE_PATH;
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Texture On Curve");
- }
- }
- break;
- }
- }
-
- /* material drivers */
- if (ob->totcol) {
- int a;
-
- for (a = 1; a <= ob->totcol; a++) {
- Material *ma = give_current_material(ob, a);
-
- if (ma) {
- /* recursively figure out if there are drivers, and hook these up to this object */
- dag_add_material_driver_relations(dag, node, ma);
- }
- }
- }
- else if (ob->type == OB_LAMP) {
- dag_add_lamp_driver_relations(dag, node, ob->data);
- }
-
- /* particles */
- psys = ob->particlesystem.first;
- if (psys) {
- GroupObject *go;
-
- for (; psys; psys = psys->next) {
- BoidRule *rule = NULL;
- BoidState *state = NULL;
- ParticleSettings *part = psys->part;
-
- if (part->adt) {
- dag_add_driver_relation(part->adt, dag, node, 1);
- }
-
- dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
-
- if (!psys_check_enabled(ob, psys, G.is_rendering))
- continue;
-
- if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
- ParticleTarget *pt = psys->targets.first;
-
- for (; pt; pt = pt->next) {
- if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
- node2 = dag_get_node(dag, pt->ob);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
- }
- }
- }
-
- if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
- node2 = dag_get_node(dag, part->dup_ob);
- /* note that this relation actually runs in the wrong direction, the problem
- * is that dupli system all have this (due to parenting), and the render
- * engine instancing assumes particular ordering of objects in list */
- dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
- if (part->dup_ob->type == OB_MBALL)
- dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
- }
-
- if (part->ren_as == PART_DRAW_GR && part->dup_group) {
- for (go = part->dup_group->gobject.first; go; go = go->next) {
- node2 = dag_get_node(dag, go->ob);
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
- }
- }
-
- if (part->type != PART_HAIR) {
- /* Actual code uses get_collider_cache */
- dag_add_collision_relations(dag, scene, ob, node, part->collision_group, ob->lay, eModifierType_Collision, NULL, true, "Particle Collision");
- }
- else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) {
- /* Hair uses cloth simulation, i.e. get_collision_objects */
- dag_add_collision_relations(dag, scene, ob, node, psys->clmd->coll_parms->group, ob->lay | scene->lay, eModifierType_Collision, NULL, true, "Hair Collision");
- }
-
- dag_add_forcefield_relations(dag, scene, ob, node, part->effector_weights, part->type == PART_HAIR, 0, "Particle Force Field");
-
- if (part->boids) {
- for (state = part->boids->states.first; state; state = state->next) {
- for (rule = state->rules.first; rule; rule = rule->next) {
- Object *ruleob = NULL;
- if (rule->type == eBoidRuleType_Avoid)
- ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
- else if (rule->type == eBoidRuleType_FollowLeader)
- ruleob = ((BoidRuleFollowLeader *)rule)->ob;
-
- if (ruleob) {
- node2 = dag_get_node(dag, ruleob);
- dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Boid Rule");
- }
- }
- }
- }
- }
- }
-
- /* object constraints */
- for (con = ob->constraints.first; con; con = con->next) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
- ListBase targets = {NULL, NULL};
- bConstraintTarget *ct;
-
- if (!cti)
- continue;
-
- /* special case for camera tracking -- it doesn't use targets to define relations */
- if (ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
- int depends_on_camera = 0;
-
- if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
- bFollowTrackConstraint *data = (bFollowTrackConstraint *)con->data;
-
- if ((data->clip || data->flag & FOLLOWTRACK_ACTIVECLIP) && data->track[0])
- depends_on_camera = 1;
-
- if (data->depth_ob) {
- node2 = dag_get_node(dag, data->depth_ob);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
- }
- }
- else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER)
- depends_on_camera = 1;
-
- if (depends_on_camera && scene->camera) {
- node2 = dag_get_node(dag, scene->camera);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
- }
-
- dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
- addtoroot = 0;
- }
- else if (cti->get_constraint_targets) {
- cti->get_constraint_targets(con, &targets);
-
- for (ct = targets.first; ct; ct = ct->next) {
- Object *obt;
-
- if (ct->tar)
- obt = ct->tar;
- else
- continue;
-
- node2 = dag_get_node(dag, obt);
- if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO))
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
- else {
- if (ELEM(obt->type, OB_ARMATURE, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) {
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB | DAG_RL_OB_OB, cti->name);
- if (obt->type == OB_MESH)
- node2->customdata_mask |= CD_MASK_MDEFORMVERT;
- }
- else if (cti->type == CONSTRAINT_TYPE_SHRINKWRAP) {
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, cti->name);
- }
- else {
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, cti->name);
- }
- }
- addtoroot = 0;
- }
-
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(con, &targets, 1);
- }
- }
-
- if (addtoroot == 1)
- dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
-}
-
-static void build_dag_group(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Group *group, short mask)
-{
- GroupObject *go;
-
- if (group->id.tag & LIB_TAG_DOIT)
- return;
-
- group->id.tag |= LIB_TAG_DOIT;
-
- for (go = group->gobject.first; go; go = go->next) {
- build_dag_object(dag, scenenode, bmain, scene, go->ob, mask);
- if (go->ob->dup_group)
- build_dag_group(dag, scenenode, bmain, scene, go->ob->dup_group, mask);
- }
-}
-
-DagForest *build_dag(Main *bmain, Scene *sce, short mask)
-{
- Base *base;
- Object *ob;
- DagNode *node;
- DagNode *scenenode;
- DagForest *dag;
- DagAdjList *itA;
-
- dag = sce->theDag;
- if (dag)
- free_forest(dag);
- else {
- dag = dag_init();
- sce->theDag = dag;
- }
- dag->need_update = false;
-
- BKE_main_id_tag_idcode(bmain, ID_OB, LIB_TAG_DOIT, false);
-
- /* clear "LIB_TAG_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */
- BKE_main_id_tag_idcode(bmain, ID_MA, LIB_TAG_DOIT, false);
- BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false);
- BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);
-
- /* add base node for scene. scene is always the first node in DAG */
- scenenode = dag_add_node(dag, sce);
-
- /* add current scene objects */
- for (base = sce->base.first; base; base = base->next) {
- ob = base->object;
- ob->id.tag |= LIB_TAG_DOIT;
- build_dag_object(dag, scenenode, bmain, sce, ob, mask);
- if (ob->proxy)
- build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask);
- if (ob->dup_group)
- build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask);
- }
-
- /* There might be situations when object from current scene depends on
- * objects form other scene AND objects from other scene has own
- * dependencies on objects from other scene.
- *
- * This is really important to include such indirect dependencies in order
- * to keep threaded update safe but since we don't really know if object is
- * coming from current scene or another scene we do rather stupid tag-based
- * check here: all the objects for which build_dag_object() was called are
- * getting tagged with LIB_TAG_DOIT. This way if some node has untagged
- * object we know it's an object from other scene.
- *
- * It should be enough to to it once, because if there's longer chain of
- * indirect dependencies, all the new nodes will be added to the end of the
- * list, meaning we'll keep covering them in this for loop.
- */
- for (node = sce->theDag->DagNode.first; node != NULL; node = node->next) {
- if (node->type == ID_OB) {
- ob = node->ob;
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- ob->id.tag |= LIB_TAG_DOIT;
- build_dag_object(dag, scenenode, bmain, sce, ob, mask);
- if (ob->proxy)
- build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask);
- if (ob->dup_group)
- build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask);
- }
- }
- }
-
- BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);
-
- /* Now all relations were built, but we need to solve 1 exceptional case;
- * When objects have multiple "parents" (for example parent + constraint working on same object)
- * the relation type has to be synced. One of the parents can change, and should give same event to child */
-
- /* nodes were callocced, so we can use node->color for temporal storage */
- for (node = sce->theDag->DagNode.first; node; node = node->next) {
- if (node->type == ID_OB) {
- for (itA = node->child; itA; itA = itA->next) {
- if (itA->node->type == ID_OB) {
- itA->node->color |= itA->type;
- }
- }
-
- /* also flush custom data mask */
- ((Object *)node->ob)->customdata_mask = node->customdata_mask;
-
- if (node->parent == NULL) {
- dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
- }
- }
- }
- /* now set relations equal, so that when only one parent changes, the correct recalcs are found */
- for (node = sce->theDag->DagNode.first; node; node = node->next) {
- if (node->type == ID_OB) {
- for (itA = node->child; itA; itA = itA->next) {
- if (itA->node->type == ID_OB) {
- itA->type |= itA->node->color;
- }
- }
- }
- }
-
- /* cycle detection and solving */
- // solve_cycles(dag);
-
- return dag;
-}
-
-
-void free_forest(DagForest *Dag)
-{ /* remove all nodes and deps */
- DagNode *tempN;
- DagAdjList *tempA;
- DagAdjList *itA;
- DagNode *itN = Dag->DagNode.first;
-
- while (itN) {
- itA = itN->child;
- while (itA) {
- tempA = itA;
- itA = itA->next;
- MEM_freeN(tempA);
- }
-
- itA = itN->parent;
- while (itA) {
- tempA = itA;
- itA = itA->next;
- MEM_freeN(tempA);
- }
-
- tempN = itN;
- itN = itN->next;
- MEM_freeN(tempN);
- }
-
- BLI_ghash_free(Dag->nodeHash, NULL, NULL);
- Dag->nodeHash = NULL;
- Dag->DagNode.first = NULL;
- Dag->DagNode.last = NULL;
- Dag->numNodes = 0;
-
-}
-
-DagNode *dag_find_node(DagForest *forest, void *fob)
-{
- if (forest->nodeHash)
- return BLI_ghash_lookup(forest->nodeHash, fob);
-
- return NULL;
-}
-
-static int dag_print_dependencies = 0; /* debugging */
-
-/* no checking of existence, use dag_find_node first or dag_get_node */
-DagNode *dag_add_node(DagForest *forest, void *fob)
-{
- DagNode *node;
-
- node = MEM_callocN(sizeof(DagNode), "DAG node");
- if (node) {
- node->ob = fob;
- node->color = DAG_WHITE;
-
- if (forest->ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */
- if (forest->numNodes) {
- ((DagNode *) forest->DagNode.last)->next = node;
- forest->DagNode.last = node;
- forest->numNodes++;
- }
- else {
- forest->DagNode.last = node;
- forest->DagNode.first = node;
- forest->numNodes = 1;
- }
-
- if (!forest->nodeHash)
- forest->nodeHash = BLI_ghash_ptr_new("dag_add_node gh");
- BLI_ghash_insert(forest->nodeHash, fob, node);
- }
-
- return node;
-}
-
-DagNode *dag_get_node(DagForest *forest, void *fob)
-{
- DagNode *node;
-
- node = dag_find_node(forest, fob);
- if (!node)
- node = dag_add_node(forest, fob);
- return node;
-}
-
-
-
-DagNode *dag_get_sub_node(DagForest *forest, void *fob)
-{
- DagNode *node;
- DagAdjList *mainchild, *prev = NULL;
-
- mainchild = ((DagNode *) forest->DagNode.first)->child;
- /* remove from first node (scene) adj list if present */
- while (mainchild) {
- if (mainchild->node == fob) {
- if (prev) {
- prev->next = mainchild->next;
- MEM_freeN(mainchild);
- break;
- }
- else {
- ((DagNode *) forest->DagNode.first)->child = mainchild->next;
- MEM_freeN(mainchild);
- break;
- }
- }
- prev = mainchild;
- mainchild = mainchild->next;
- }
- node = dag_find_node(forest, fob);
- if (!node)
- node = dag_add_node(forest, fob);
- return node;
-}
-
-static void dag_add_parent_relation(DagForest *UNUSED(forest), DagNode *fob1, DagNode *fob2, short rel, const char *name)
-{
- DagAdjList *itA = fob2->parent;
-
- while (itA) { /* search if relation exist already */
- if (itA->node == fob1) {
- itA->type |= rel;
- itA->count += 1;
- return;
- }
- itA = itA->next;
- }
- /* create new relation and insert at head. MALLOC alert! */
- itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
- itA->node = fob1;
- itA->type = rel;
- itA->count = 1;
- itA->next = fob2->parent;
- itA->name = name;
- fob2->parent = itA;
-}
-
-void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name)
-{
- DagAdjList *itA = fob1->child;
-
- /* parent relation is for cycle checking */
- dag_add_parent_relation(forest, fob1, fob2, rel, name);
-
- /* TODO(sergey): Find a better place for this. */
-#ifdef WITH_OPENSUBDIV
- if ((rel & (DAG_RL_DATA_DATA | DAG_RL_DATA_OB)) != 0) {
- if (fob1->type == ID_OB) {
- if ((fob1->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
- Object *ob2 = fob2->ob;
- if (ob2->recalc & OB_RECALC_ALL) {
- /* Make sure object has all the data on CPU. */
- Object *ob1 = fob1->ob;
- ob1->recalc |= OB_RECALC_DATA;
- }
- fob1->eval_flags |= DAG_EVAL_NEED_CPU;
- }
- }
- }
-#endif
-
- while (itA) { /* search if relation exist already */
- if (itA->node == fob2) {
- itA->type |= rel;
- itA->count += 1;
- return;
- }
- itA = itA->next;
- }
- /* create new relation and insert at head. MALLOC alert! */
- itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
- itA->node = fob2;
- itA->type = rel;
- itA->count = 1;
- itA->next = fob1->child;
- itA->name = name;
- fob1->child = itA;
-}
-
-static const char *dag_node_name(DagForest *dag, DagNode *node)
-{
- if (node->ob == NULL)
- return "null";
- else if (dag->ugly_hack_sorry)
- return ((ID *)(node->ob))->name + 2;
- else
- return ((bPoseChannel *)(node->ob))->name;
-}
-
-static void dag_node_print_dependencies(DagForest *dag, DagNode *node)
-{
- DagAdjList *itA;
-
- printf("%s depends on:\n", dag_node_name(dag, node));
-
- for (itA = node->parent; itA; itA = itA->next)
- printf(" %s through %s\n", dag_node_name(dag, itA->node), itA->name);
- printf("\n");
-}
-
-static int dag_node_print_dependency_recurs(DagForest *dag, DagNode *node, DagNode *endnode)
-{
- DagAdjList *itA;
-
- if (node->color == DAG_BLACK)
- return 0;
-
- node->color = DAG_BLACK;
-
- if (node == endnode)
- return 1;
-
- for (itA = node->parent; itA; itA = itA->next) {
- if (dag_node_print_dependency_recurs(dag, itA->node, endnode)) {
- printf(" %s depends on %s through %s.\n", dag_node_name(dag, node), dag_node_name(dag, itA->node), itA->name);
- return 1;
- }
- }
-
- return 0;
-}
-
-static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode, DagNode *endnode, const char *name)
-{
- DagNode *node;
-
- for (node = dag->DagNode.first; node; node = node->next)
- node->color = DAG_WHITE;
-
- printf(" %s depends on %s through %s.\n", dag_node_name(dag, endnode), dag_node_name(dag, startnode), name);
- dag_node_print_dependency_recurs(dag, startnode, endnode);
- printf("\n");
-}
-
-static int dag_node_recurs_level(DagNode *node, int level)
-{
- DagAdjList *itA;
- int newlevel;
-
- node->color = DAG_BLACK; /* done */
- newlevel = ++level;
-
- for (itA = node->parent; itA; itA = itA->next) {
- if (itA->node->color == DAG_WHITE) {
- itA->node->ancestor_count = dag_node_recurs_level(itA->node, level);
- newlevel = MAX2(newlevel, level + itA->node->ancestor_count);
- }
- else
- newlevel = MAX2(newlevel, level + itA->node->ancestor_count);
- }
-
- return newlevel;
-}
-
-static void dag_check_cycle(DagForest *dag)
-{
- DagNode *node;
- DagAdjList *itA;
-
- dag->is_acyclic = true;
-
- /* debugging print */
- if (dag_print_dependencies)
- for (node = dag->DagNode.first; node; node = node->next)
- dag_node_print_dependencies(dag, node);
-
- /* tag nodes unchecked */
- for (node = dag->DagNode.first; node; node = node->next)
- node->color = DAG_WHITE;
-
- for (node = dag->DagNode.first; node; node = node->next) {
- if (node->color == DAG_WHITE) {
- node->ancestor_count = dag_node_recurs_level(node, 0);
- }
- }
-
- /* check relations, and print errors */
- for (node = dag->DagNode.first; node; node = node->next) {
- for (itA = node->parent; itA; itA = itA->next) {
- if (itA->node->ancestor_count > node->ancestor_count) {
- if (node->ob && itA->node->ob) {
- dag->is_acyclic = false;
- printf("Dependency cycle detected:\n");
- dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
- }
- }
- }
- }
-
- /* parent relations are only needed for cycle checking, so free now */
- for (node = dag->DagNode.first; node; node = node->next) {
- while (node->parent) {
- itA = node->parent->next;
- MEM_freeN(node->parent);
- node->parent = itA;
- }
- }
-}
-
-/* debug test functions */
-
-void graph_print_queue(DagNodeQueue *nqueue)
-{
- DagNodeQueueElem *queueElem;
-
- queueElem = nqueue->first;
- while (queueElem) {
- fprintf(stderr, "** %s %i %i-%i ", ((ID *) queueElem->node->ob)->name, queueElem->node->color, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm);
- queueElem = queueElem->next;
- }
- fprintf(stderr, "\n");
-}
-
-void graph_print_queue_dist(DagNodeQueue *nqueue)
-{
- DagNodeQueueElem *queueElem;
- int count;
-
- queueElem = nqueue->first;
- count = 0;
- while (queueElem) {
- fprintf(stderr, "** %25s %2.2i-%2.2i ", ((ID *) queueElem->node->ob)->name, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm);
- while (count < queueElem->node->DFS_dvtm - 1) { fputc(' ', stderr); count++; }
- fputc('|', stderr);
- while (count < queueElem->node->DFS_fntm - 2) { fputc('-', stderr); count++; }
- fputc('|', stderr);
- fputc('\n', stderr);
- count = 0;
- queueElem = queueElem->next;
- }
- fprintf(stderr, "\n");
-}
-
-void graph_print_adj_list(DagForest *dag)
-{
- DagNode *node;
- DagAdjList *itA;
-
- node = dag->DagNode.first;
- while (node) {
- fprintf(stderr, "node : %s col: %i", ((ID *) node->ob)->name, node->color);
- itA = node->child;
- while (itA) {
- fprintf(stderr, "-- %s ", ((ID *) itA->node->ob)->name);
-
- itA = itA->next;
- }
- fprintf(stderr, "\n");
- node = node->next;
- }
-}
-
-/* ************************ API *********************** */
-
-/* mechanism to allow editors to be informed of depsgraph updates,
- * to do their own updates based on changes... */
-static void (*EditorsUpdateIDCb)(Main *bmain, ID *id) = NULL;
-static void (*EditorsUpdateSceneCb)(Main *bmain, Scene *scene, int updated) = NULL;
-static void (*EditorsUpdateScenePreCb)(Main *bmain, Scene *scene, bool time) = NULL;
-
-void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id),
- void (*scene_func)(Main *bmain, Scene *scene, int updated),
- void (*scene_pre_func)(Main *bmain, Scene *scene, bool time))
-{
- if (DEG_depsgraph_use_legacy()) {
- EditorsUpdateIDCb = id_func;
- EditorsUpdateSceneCb = scene_func;
- EditorsUpdateScenePreCb = scene_pre_func;
- }
- else {
- /* New dependency graph. */
- DEG_editors_set_update_cb(id_func, scene_func, scene_pre_func);
- }
-}
-
-void DAG_editors_update_pre(Main *bmain, Scene *scene, bool time)
-{
- if (DEG_depsgraph_use_legacy()) {
- if (EditorsUpdateScenePreCb != NULL) {
- EditorsUpdateScenePreCb(bmain, scene, time);
- }
- }
- else {
- DEG_editors_update_pre(bmain, scene, time);
- }
-}
-
-static void dag_editors_id_update(Main *bmain, ID *id)
-{
- if (EditorsUpdateIDCb)
- EditorsUpdateIDCb(bmain, id);
-}
-
-static void dag_editors_scene_update(Main *bmain, Scene *scene, int updated)
-{
- if (EditorsUpdateSceneCb)
- EditorsUpdateSceneCb(bmain, scene, updated);
-}
-
-/* groups with objects in this scene need to be put in the right order as well */
-static void scene_sort_groups(Main *bmain, Scene *sce)
-{
- Base *base;
- Group *group;
- GroupObject *go;
- Object *ob;
-
- /* test; are group objects all in this scene? */
- for (ob = bmain->object.first; ob; ob = ob->id.next) {
- ob->id.tag &= ~LIB_TAG_DOIT;
- }
- for (base = sce->base.first; base; base = base->next)
- base->object->id.tag |= LIB_TAG_DOIT;
-
- for (group = bmain->group.first; group; group = group->id.next) {
- for (go = group->gobject.first; go; go = go->next) {
- if ((go->ob->id.tag & LIB_TAG_DOIT) == 0)
- break;
- }
- /* this group is entirely in this scene */
- if (go == NULL) {
- ListBase listb = {NULL, NULL};
-
- for (go = group->gobject.first; go; go = go->next)
- go->ob->id.newid = (ID *)go;
-
- /* in order of sorted bases we reinsert group objects */
- for (base = sce->base.first; base; base = base->next) {
-
- if (base->object->id.newid) {
- go = (GroupObject *)base->object->id.newid;
- base->object->id.newid = NULL;
- BLI_remlink(&group->gobject, go);
- BLI_addtail(&listb, go);
- }
- }
- /* copy the newly sorted listbase */
- group->gobject = listb;
- }
- }
-
- /* newid abused for GroupObject, cleanup. */
- for (ob = bmain->object.first; ob; ob = ob->id.next) {
- ob->id.newid = NULL;
- }
-}
-
-static void dag_scene_tag_rebuild(Scene *sce)
-{
- if (sce->theDag) {
- sce->theDag->need_update = true;
- }
-}
-
-/* free the depency graph */
-static void dag_scene_free(Scene *sce)
-{
- if (sce->theDag) {
- free_forest(sce->theDag);
- MEM_freeN(sce->theDag);
- sce->theDag = NULL;
- }
-}
-
-/* Check whether object data needs to be evaluated before it
- * might be used by others.
- *
- * Means that mesh object needs to have proper derivedFinal,
- * curves-typed objects are to have proper curve cache.
- *
- * Other objects or objects which are tagged for data update are
- * not considered to be in need of evaluation.
- */
-static bool check_object_needs_evaluation(Object *object)
-{
- if (object->recalc & OB_RECALC_ALL) {
- /* Object is tagged for update anyway, no need to re-tag it. */
- return false;
- }
-
- if (object->type == OB_MESH) {
- return object->derivedFinal == NULL;
- }
- else if (ELEM(object->type, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
- return object->curve_cache == NULL;
- }
-
- return false;
-}
-
-/* Check whether object data is tagged for update. */
-static bool check_object_tagged_for_update(Object *object)
-{
- if (object->recalc & OB_RECALC_ALL) {
- return true;
- }
-
- if (ELEM(object->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
- ID *data_id = object->data;
- return (data_id->tag & (LIB_TAG_ID_RECALC_DATA | LIB_TAG_ID_RECALC)) != 0;
- }
-
- return false;
-}
-
-/* Flush changes from tagged objects in the scene to their
- * dependencies which are not evaluated yet.
- *
- * This is needed to ensure all the dependencies are met
- * before objects gets handled by object_handle_update(),
- *
- * This is needed when visible layers are changed or changing
- * scene graph layout which involved usage of objects which
- * aren't in the scene or weren't visible yet.
- */
-static void dag_invisible_dependencies_flush(Scene *scene)
-{
- DagNode *root_node = scene->theDag->DagNode.first, *node;
- DagNodeQueue *queue;
-
- for (node = root_node; node != NULL; node = node->next) {
- node->color = DAG_WHITE;
- }
-
- queue = queue_create(DAGQUEUEALLOC);
-
- for (node = root_node; node != NULL; node = node->next) {
- if (node->color == DAG_WHITE) {
- push_stack(queue, node);
- node->color = DAG_GRAY;
-
- while (queue->count) {
- DagNode *current_node = get_top_node_queue(queue);
- DagAdjList *itA;
- bool skip = false;
-
- for (itA = current_node->child; itA; itA = itA->next) {
- if (itA->node->color == DAG_WHITE) {
- itA->node->color = DAG_GRAY;
- push_stack(queue, itA->node);
- skip = true;
- break;
- }
- }
-
- if (!skip) {
- current_node = pop_queue(queue);
-
- if (current_node->type == ID_OB) {
- Object *current_object = current_node->ob;
- if (check_object_needs_evaluation(current_object)) {
- for (itA = current_node->child; itA; itA = itA->next) {
- if (itA->node->type == ID_OB) {
- Object *object = itA->node->ob;
- if (check_object_tagged_for_update(object)) {
- current_object->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
- }
- }
- }
- }
- }
- node->color = DAG_BLACK;
- }
- }
- }
- }
-
- queue_delete(queue);
-}
-
-static void dag_invisible_dependencies_check_flush(Main *bmain, Scene *scene)
-{
- if (DAG_id_type_tagged(bmain, ID_OB) ||
- DAG_id_type_tagged(bmain, ID_ME) || /* Mesh */
- DAG_id_type_tagged(bmain, ID_CU) || /* Curve */
- DAG_id_type_tagged(bmain, ID_MB) || /* MetaBall */
- DAG_id_type_tagged(bmain, ID_LT)) /* Lattice */
- {
- dag_invisible_dependencies_flush(scene);
- }
-}
-
-/* sort the base list on dependency order */
-static void dag_scene_build(Main *bmain, Scene *sce)
-{
- DagNode *node, *rootnode;
- DagNodeQueue *nqueue;
- DagAdjList *itA;
- int time;
- int skip = 0;
- ListBase tempbase;
- Base *base;
-
- BLI_listbase_clear(&tempbase);
-
- build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA);
-
- dag_check_cycle(sce->theDag);
-
- nqueue = queue_create(DAGQUEUEALLOC);
-
- for (node = sce->theDag->DagNode.first; node; node = node->next) {
- node->color = DAG_WHITE;
- }
-
- time = 1;
-
- rootnode = sce->theDag->DagNode.first;
- rootnode->color = DAG_GRAY;
- time++;
- push_stack(nqueue, rootnode);
-
- while (nqueue->count) {
-
- skip = 0;
- node = get_top_node_queue(nqueue);
-
- itA = node->child;
- while (itA != NULL) {
- if (itA->node->color == DAG_WHITE) {
- itA->node->DFS_dvtm = time;
- itA->node->color = DAG_GRAY;
-
- time++;
- push_stack(nqueue, itA->node);
- skip = 1;
- break;
- }
- itA = itA->next;
- }
-
- if (!skip) {
- if (node) {
- node = pop_queue(nqueue);
- if (node->ob == sce) /* we are done */
- break;
- node->color = DAG_BLACK;
-
- time++;
- base = sce->base.first;
- while (base && base->object != node->ob)
- base = base->next;
- if (base) {
- BLI_remlink(&sce->base, base);
- BLI_addhead(&tempbase, base);
- }
- }
- }
- }
-
- /* temporal correction for circular dependencies */
- base = sce->base.first;
- while (base) {
- BLI_remlink(&sce->base, base);
- BLI_addhead(&tempbase, base);
- //if (G.debug & G_DEBUG)
- printf("cyclic %s\n", base->object->id.name);
- base = sce->base.first;
- }
-
- sce->base = tempbase;
- queue_delete(nqueue);
-
- /* all groups with objects in this scene gets resorted too */
- scene_sort_groups(bmain, sce);
-
- if (G.debug & G_DEBUG) {
- printf("\nordered\n");
- for (base = sce->base.first; base; base = base->next) {
- printf(" %s\n", base->object->id.name);
- }
- }
-
- /* Make sure that new dependencies which came from invisible layers
- * are tagged for update (if they're needed for objects which were
- * tagged for update).
- */
- dag_invisible_dependencies_check_flush(bmain, sce);
-}
-
-/* clear all dependency graphs */
-void DAG_relations_tag_update(Main *bmain)
-{
- if (DEG_depsgraph_use_legacy()) {
- Scene *sce;
- for (sce = bmain->scene.first; sce; sce = sce->id.next) {
- dag_scene_tag_rebuild(sce);
- }
- }
- else {
- /* New dependency graph. */
- DEG_relations_tag_update(bmain);
- }
-}
-
-/* rebuild dependency graph only for a given scene */
-void DAG_scene_relations_rebuild(Main *bmain, Scene *sce)
-{
- if (DEG_depsgraph_use_legacy()) {
- dag_scene_free(sce);
- DAG_scene_relations_update(bmain, sce);
- }
- else {
- /* New dependency graph. */
- DEG_scene_relations_rebuild(bmain, sce);
- }
-}
-
-/* create dependency graph if it was cleared or didn't exist yet */
-void DAG_scene_relations_update(Main *bmain, Scene *sce)
-{
- if (DEG_depsgraph_use_legacy()) {
- if (!sce->theDag || sce->theDag->need_update)
- dag_scene_build(bmain, sce);
- }
- else {
- /* New dependency graph. */
- DEG_scene_relations_update(bmain, sce);
- }
-}
-
-void DAG_scene_relations_validate(Main *bmain, Scene *sce)
-{
- if (!DEG_depsgraph_use_legacy()) {
- DEG_debug_scene_relations_validate(bmain, sce);
- }
-}
-
-void DAG_scene_free(Scene *sce)
-{
- if (DEG_depsgraph_use_legacy()) {
- if (sce->theDag) {
- free_forest(sce->theDag);
- MEM_freeN(sce->theDag);
- sce->theDag = NULL;
- }
- }
- else {
- if (sce->depsgraph) {
- DEG_graph_free(sce->depsgraph);
- sce->depsgraph = NULL;
- }
- }
-}
-
-static void lib_id_recalc_tag(Main *bmain, ID *id)
-{
- id->tag |= LIB_TAG_ID_RECALC;
- DAG_id_type_tag(bmain, GS(id->name));
-}
-
-static void lib_id_recalc_data_tag(Main *bmain, ID *id)
-{
- id->tag |= LIB_TAG_ID_RECALC_DATA;
- DAG_id_type_tag(bmain, GS(id->name));
-}
-
-/* node was checked to have lasttime != curtime and is if type ID_OB */
-static void flush_update_node(Main *bmain, DagNode *node, unsigned int layer, int curtime)
-{
- DagAdjList *itA;
- Object *ob, *obc;
- int oldflag;
- bool changed = false;
- unsigned int all_layer;
-
- node->lasttime = curtime;
-
- ob = node->ob;
- if (ob && (ob->recalc & OB_RECALC_ALL)) {
- all_layer = node->scelay;
-
- /* got an object node that changes, now check relations */
- for (itA = node->child; itA; itA = itA->next) {
- all_layer |= itA->lay;
- /* the relationship is visible */
- if ((itA->lay & layer)) { // XXX || (itA->node->ob == obedit)
- if (itA->node->type == ID_OB) {
- obc = itA->node->ob;
- oldflag = obc->recalc;
-
- /* got a ob->obc relation, now check if flag needs flush */
- if (ob->recalc & OB_RECALC_OB) {
- if (itA->type & DAG_RL_OB_OB) {
- //printf("ob %s changes ob %s\n", ob->id.name, obc->id.name);
- obc->recalc |= OB_RECALC_OB;
- lib_id_recalc_tag(bmain, &obc->id);
- }
- if (itA->type & DAG_RL_OB_DATA) {
- //printf("ob %s changes obdata %s\n", ob->id.name, obc->id.name);
- obc->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obc->id);
- }
- }
- if (ob->recalc & OB_RECALC_DATA) {
- if (itA->type & DAG_RL_DATA_OB) {
- //printf("obdata %s changes ob %s\n", ob->id.name, obc->id.name);
- obc->recalc |= OB_RECALC_OB;
- lib_id_recalc_tag(bmain, &obc->id);
- }
- if (itA->type & DAG_RL_DATA_DATA) {
- //printf("obdata %s changes obdata %s\n", ob->id.name, obc->id.name);
- obc->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obc->id);
- }
- }
- if (oldflag != obc->recalc) changed = 1;
- }
- }
- }
- /* even nicer, we can clear recalc flags... */
- if ((all_layer & layer) == 0) { // XXX && (ob != obedit)) {
- /* but existing displaylists or derivedmesh should be freed */
- if (ob->recalc & OB_RECALC_DATA)
- BKE_object_free_derived_caches(ob);
-
- ob->recalc &= ~OB_RECALC_ALL;
- }
- }
-
- /* check case where child changes and parent forcing obdata to change */
- /* should be done regardless if this ob has recalc set */
- /* could merge this in with loop above...? (ton) */
- for (itA = node->child; itA; itA = itA->next) {
- /* the relationship is visible */
- if ((itA->lay & layer)) { // XXX || (itA->node->ob == obedit)
- if (itA->node->type == ID_OB) {
- obc = itA->node->ob;
- /* child moves */
- if ((obc->recalc & OB_RECALC_ALL) == OB_RECALC_OB) {
- /* parent has deforming info */
- if (itA->type & (DAG_RL_OB_DATA | DAG_RL_DATA_DATA)) {
- // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name);
- obc->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obc->id);
- }
- }
- }
- }
- }
-
- /* we only go deeper if node not checked or something changed */
- for (itA = node->child; itA; itA = itA->next) {
- if (changed || itA->node->lasttime != curtime)
- flush_update_node(bmain, itA->node, layer, curtime);
- }
-
-}
-
-/* node was checked to have lasttime != curtime, and is of type ID_OB */
-static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
-{
- DagAdjList *itA;
-
- node->lasttime = curtime;
- node->lay = node->scelay;
-
- for (itA = node->child; itA; itA = itA->next) {
- if (itA->node->type == ID_OB) {
- if (itA->node->lasttime != curtime) {
- itA->lay = flush_layer_node(sce, itA->node, curtime); /* lay is only set once for each relation */
- }
- else {
- itA->lay = itA->node->lay;
- }
-
- node->lay |= itA->lay;
- }
- }
-
- return node->lay;
-}
-
-/* node was checked to have lasttime != curtime, and is of type ID_OB */
-static void flush_pointcache_reset(Main *bmain, Scene *scene, DagNode *node,
- int curtime, unsigned int lay, bool reset)
-{
- DagAdjList *itA;
- Object *ob;
-
- node->lasttime = curtime;
-
- for (itA = node->child; itA; itA = itA->next) {
- if (itA->node->type == ID_OB) {
- if (itA->node->lasttime != curtime) {
- ob = (Object *)(itA->node->ob);
-
- if (reset || (ob->recalc & OB_RECALC_ALL)) {
- if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) {
- /* Don't tag nodes which are on invisible layer. */
- if (itA->node->lay & lay) {
- ob->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &ob->id);
- }
- }
-
- flush_pointcache_reset(bmain, scene, itA->node, curtime, lay, true);
- }
- else
- flush_pointcache_reset(bmain, scene, itA->node, curtime, lay, false);
- }
- }
- }
-}
-
-/* flush layer flags to dependencies */
-static void dag_scene_flush_layers(Scene *sce, int lay)
-{
- DagNode *node, *firstnode;
- DagAdjList *itA;
- Base *base;
- int lasttime;
-
- firstnode = sce->theDag->DagNode.first; /* always scene node */
-
- for (itA = firstnode->child; itA; itA = itA->next)
- itA->lay = 0;
-
- sce->theDag->time++; /* so we know which nodes were accessed */
- lasttime = sce->theDag->time;
-
- /* update layer flags in nodes */
- for (base = sce->base.first; base; base = base->next) {
- node = dag_get_node(sce->theDag, base->object);
- node->scelay = base->object->lay;
- }
-
- /* ensure cameras are set as if they are on a visible layer, because
- * they ared still used for rendering or setting the camera view
- *
- * XXX, this wont work for local view / unlocked camera's */
- if (sce->camera) {
- node = dag_get_node(sce->theDag, sce->camera);
- node->scelay |= lay;
- }
-
-#ifdef DURIAN_CAMERA_SWITCH
- {
- TimeMarker *m;
-
- for (m = sce->markers.first; m; m = m->next) {
- if (m->camera) {
- node = dag_get_node(sce->theDag, m->camera);
- node->scelay |= lay;
- }
- }
- }
-#endif
-
- /* flush layer nodes to dependencies */
- for (itA = firstnode->child; itA; itA = itA->next)
- if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
- flush_layer_node(sce, itA->node, lasttime);
-}
-
-static void dag_tag_renderlayers(Scene *sce, unsigned int lay)
-{
- if (sce->nodetree) {
- bNode *node;
- Base *base;
- unsigned int lay_changed = 0;
-
- for (base = sce->base.first; base; base = base->next)
- if (base->lay & lay)
- if (base->object->recalc)
- lay_changed |= base->lay;
-
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->id == (ID *)sce) {
- SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
- if (srl && (srl->lay & lay_changed))
- nodeUpdate(sce->nodetree, node);
- }
- }
- }
-}
-
-/* flushes all recalc flags in objects down the dependency tree */
-void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const short time)
-{
- DagNode *firstnode;
- DagAdjList *itA;
- Object *ob;
- int lasttime;
-
- if (!DEG_depsgraph_use_legacy()) {
- return;
- }
-
- if (sce->theDag == NULL || sce->theDag->need_update) {
- printf("DAG zero... not allowed to happen!\n");
- DAG_scene_relations_update(bmain, sce);
- }
-
- firstnode = sce->theDag->DagNode.first; /* always scene node */
-
- /* first we flush the layer flags */
- dag_scene_flush_layers(sce, lay);
-
- /* then we use the relationships + layer info to flush update events */
- sce->theDag->time++; /* so we know which nodes were accessed */
- lasttime = sce->theDag->time;
- for (itA = firstnode->child; itA; itA = itA->next)
- if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
- flush_update_node(bmain, itA->node, lay, lasttime);
-
- /* if update is not due to time change, do pointcache clears */
- if (!time) {
- sce->theDag->time++; /* so we know which nodes were accessed */
- lasttime = sce->theDag->time;
- for (itA = firstnode->child; itA; itA = itA->next) {
- if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) {
- ob = (Object *)(itA->node->ob);
-
- if (ob->recalc & OB_RECALC_ALL) {
- if (BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) {
- ob->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &ob->id);
- }
-
- flush_pointcache_reset(bmain, sce, itA->node, lasttime,
- lay, true);
- }
- else
- flush_pointcache_reset(bmain, sce, itA->node, lasttime,
- lay, false);
- }
- }
- }
-
- dag_tag_renderlayers(sce, lay);
-}
-
-static bool modifier_nlastrips_use_time(ListBase *strips)
-{
- NlaStrip *strip;
-
- if (strips) {
- for (strip = strips->first; strip; strip = strip->next) {
- if (modifier_nlastrips_use_time(&strip->strips)) {
- return true;
- }
- else if (strip->act) {
- FCurve *fcu;
-
- for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
- if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-static bool object_modifiers_use_time(Object *ob)
-{
- ModifierData *md;
-
- /* check if a modifier in modifier stack needs time input */
- for (md = ob->modifiers.first; md; md = md->next) {
- if (modifier_dependsOnTime(md))
- return true;
- }
-
- /* check whether any modifiers are animated */
- if (ob->adt) {
- AnimData *adt = ob->adt;
- NlaTrack *nlt;
- FCurve *fcu;
-
- /* action - check for F-Curves with paths containing 'modifiers[' */
- if (adt->action) {
- for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
- if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
- return true;
- }
- }
-
- /* This here allows modifier properties to get driven and still update properly
- *
- * Workaround to get [#26764] (e.g. subsurf levels not updating when animated/driven)
- * working, without the updating problems ([#28525] [#28690] [#28774] [#28777]) caused
- * by the RNA updates cache introduced in r.38649
- */
- for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
- if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
- return true;
- }
-
- /* Also check NLA Strips... [#T45938] */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- if (modifier_nlastrips_use_time(&nlt->strips))
- return true;
- }
- }
-
- return false;
-}
-
-static short animdata_use_time(AnimData *adt)
-{
- NlaTrack *nlt;
-
- if (adt == NULL) return 0;
-
- /* check action - only if assigned, and it has anim curves */
- if (adt->action && adt->action->curves.first)
- return 1;
-
- /* check NLA tracks + strips */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- if (nlt->strips.first)
- return 1;
- }
-
- /* If we have drivers, more likely than not, on a frame change
- * they'll need updating because their owner changed
- *
- * This is kindof a hack to get around a whole host of problems
- * involving drivers using non-object datablock data (which the
- * depsgraph currently has no way of representing let alone correctly
- * dependency sort+tagging). By doing this, at least we ensure that
- * some commonly attempted drivers (such as scene -> current frame;
- * see "Driver updates fail" thread on Bf-committers dated July 2)
- * will work correctly, and that other non-object datablocks will have
- * their drivers update at least on frame change.
- *
- * -- Aligorith, July 4 2011
- */
- if (adt->drivers.first)
- return 1;
-
- return 0;
-}
-
-static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob)
-{
- if (ob->constraints.first) {
- bConstraint *con;
- for (con = ob->constraints.first; con; con = con->next) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
- ListBase targets = {NULL, NULL};
- bConstraintTarget *ct;
-
- if (cti) {
- /* special case for camera tracking -- it doesn't use targets to define relations */
- if (ELEM(cti->type,
- CONSTRAINT_TYPE_FOLLOWTRACK,
- CONSTRAINT_TYPE_CAMERASOLVER,
- CONSTRAINT_TYPE_OBJECTSOLVER,
- CONSTRAINT_TYPE_TRANSFORM_CACHE))
- {
- ob->recalc |= OB_RECALC_OB;
- }
- else if (cti->get_constraint_targets) {
- cti->get_constraint_targets(con, &targets);
-
- for (ct = targets.first; ct; ct = ct->next) {
- if (ct->tar) {
- ob->recalc |= OB_RECALC_OB;
- break;
- }
- }
-
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(con, &targets, 1);
- }
-
- }
- }
- }
-
- if (ob->parent) {
- /* motion path or bone child */
- if (ob->parent->type == OB_CURVE || ob->parent->type == OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
- }
-
-#if 0 // XXX old animation system
- if (ob->nlastrips.first) {
- if (ob->dup_group) {
- bActionStrip *strip;
- /* this case is for groups with nla, whilst nla target has no action or nla */
- for (strip = ob->nlastrips.first; strip; strip = strip->next) {
- if (strip->object)
- strip->object->recalc |= OB_RECALC_ALL;
- }
- }
- }
-#endif // XXX old animation system
-
- if (animdata_use_time(ob->adt)) {
- ob->recalc |= OB_RECALC_OB;
- ob->adt->recalc |= ADT_RECALC_ANIM;
- }
-
- if ((ob->adt) && (ob->type == OB_ARMATURE)) ob->recalc |= OB_RECALC_DATA;
-
- if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
- if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
-
- // XXX: scene here may not be the scene that contains the rigidbody world affecting this!
- if (ob->rigidbody_object && BKE_scene_check_rigidbody_active(scene))
- ob->recalc |= OB_RECALC_OB;
-
- {
- AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
- Mesh *me;
- Curve *cu;
- Lattice *lt;
-
- switch (ob->type) {
- case OB_MESH:
- me = ob->data;
- if (me->key) {
- if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
- ob->recalc |= OB_RECALC_DATA;
- }
- }
- if (ob->particlesystem.first)
- ob->recalc |= OB_RECALC_DATA;
- break;
- case OB_CURVE:
- case OB_SURF:
- cu = ob->data;
- if (cu->key) {
- if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
- ob->recalc |= OB_RECALC_DATA;
- }
- }
- break;
- case OB_FONT:
- cu = ob->data;
- if (BLI_listbase_is_empty(&cu->nurb) && cu->str && cu->vfont)
- ob->recalc |= OB_RECALC_DATA;
- break;
- case OB_LATTICE:
- lt = ob->data;
- if (lt->key) {
- if (!(ob->shapeflag & OB_SHAPE_LOCK)) {
- ob->recalc |= OB_RECALC_DATA;
- }
- }
- break;
- case OB_MBALL:
- if (ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
- break;
- case OB_EMPTY:
- /* update animated images */
- if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data)
- if (BKE_image_is_animated(ob->data))
- ob->recalc |= OB_RECALC_DATA;
- break;
- }
-
- if (animdata_use_time(adt)) {
- ob->recalc |= OB_RECALC_DATA;
- adt->recalc |= ADT_RECALC_ANIM;
- }
-
- if (ob->particlesystem.first) {
- ParticleSystem *psys = ob->particlesystem.first;
-
- for (; psys; psys = psys->next) {
- if (psys_check_enabled(ob, psys, G.is_rendering)) {
- ob->recalc |= OB_RECALC_DATA;
- break;
- }
- }
- }
- }
-
- if (ob->recalc & OB_RECALC_OB)
- lib_id_recalc_tag(bmain, &ob->id);
- if (ob->recalc & OB_RECALC_DATA)
- lib_id_recalc_data_tag(bmain, &ob->id);
-
-}
-
-/* recursively update objects in groups, each group is done at most once */
-static void dag_group_update_flags(Main *bmain, Scene *scene, Group *group, const bool do_time)
-{
- GroupObject *go;
-
- if (group->id.tag & LIB_TAG_DOIT)
- return;
-
- group->id.tag |= LIB_TAG_DOIT;
-
- for (go = group->gobject.first; go; go = go->next) {
- if (do_time)
- dag_object_time_update_flags(bmain, scene, go->ob);
- if (go->ob->dup_group)
- dag_group_update_flags(bmain, scene, go->ob->dup_group, do_time);
- }
-}
-
-/* flag all objects that need recalc, for changes in time for example */
-/* do_time: make this optional because undo resets objects to their animated locations without this */
-void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const bool do_time, const bool do_invisible_flush)
-{
- Base *base;
- Object *ob;
- Group *group;
- GroupObject *go;
- Scene *sce_iter;
-
- BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);
-
- /* set ob flags where animated systems are */
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
-
- if (do_time) {
- /* now if DagNode were part of base, the node->lay could be checked... */
- /* we do all now, since the scene_flush checks layers and clears recalc flags even */
-
- /* NOTE: "sce_iter" not "scene" so that rigidbodies in background scenes work
- * (i.e. muting + rbw availability can be checked and tagged properly) [#33970]
- */
- dag_object_time_update_flags(bmain, sce_iter, ob);
- }
-
- /* recursively tag groups with LIB_TAG_DOIT, and update flags for objects */
- if (ob->dup_group)
- dag_group_update_flags(bmain, scene, ob->dup_group, do_time);
- }
-
- for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
- DAG_scene_flush_update(bmain, sce_iter, lay, 1);
-
- if (do_time) {
- /* test: set time flag, to disable baked systems to update */
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
- if (ob->recalc & OB_RECALC_ALL)
- ob->recalc |= OB_RECALC_TIME;
- }
-
- /* hrmf... an exception to look at once, for invisible camera object we do it over */
- if (scene->camera)
- dag_object_time_update_flags(bmain, scene, scene->camera);
- }
-
- /* and store the info in groupobject */
- for (group = bmain->group.first; group; group = group->id.next) {
- if (group->id.tag & LIB_TAG_DOIT) {
- for (go = group->gobject.first; go; go = go->next) {
- go->recalc = go->ob->recalc;
- // printf("ob %s recalc %d\n", go->ob->id.name, go->recalc);
- }
- group->id.tag &= ~LIB_TAG_DOIT;
- }
- }
-
- if (do_invisible_flush) {
- dag_invisible_dependencies_check_flush(bmain, scene);
- }
-}
-
-/* struct returned by DagSceneLayer */
-typedef struct DagSceneLayer {
- struct DagSceneLayer *next, *prev;
- Scene *scene;
- unsigned int layer;
-} DagSceneLayer;
-
-/* returns visible scenes with valid DAG */
-static void dag_current_scene_layers(Main *bmain, ListBase *lb)
-{
- wmWindowManager *wm;
- wmWindow *win;
-
- BLI_listbase_clear(lb);
-
- /* if we have a windowmanager, look into windows */
- if ((wm = bmain->wm.first)) {
-
- BKE_main_id_flag_listbase(&bmain->scene, LIB_TAG_DOIT, 1);
-
- for (win = wm->windows.first; win; win = win->next) {
- if (win->screen && win->screen->scene->theDag) {
- Scene *scene = win->screen->scene;
- DagSceneLayer *dsl;
-
- if (scene->id.tag & LIB_TAG_DOIT) {
- dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
-
- BLI_addtail(lb, dsl);
-
- dsl->scene = scene;
- dsl->layer = BKE_screen_visible_layers(win->screen, scene);
-
- scene->id.tag &= ~LIB_TAG_DOIT;
- }
- else {
- /* It is possible that multiple windows shares the same scene
- * and have different layers visible.
- *
- * Here we deal with such cases by squashing layers bits from
- * multiple windoew to the DagSceneLayer.
- *
- * TODO(sergey): Such a lookup could be optimized perhaps,
- * however should be fine for now since we usually have only
- * few open windows.
- */
- for (dsl = lb->first; dsl; dsl = dsl->next) {
- if (dsl->scene == scene) {
- dsl->layer |= BKE_screen_visible_layers(win->screen, scene);
- break;
- }
- }
- }
- }
- }
- }
- else {
- /* if not, use the first sce */
- DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
-
- BLI_addtail(lb, dsl);
-
- dsl->scene = bmain->scene.first;
- dsl->layer = dsl->scene->lay;
-
- /* XXX for background mode, we should get the scene
- * from somewhere, for the -S option, but it's in
- * the context, how to get it here? */
- }
-}
-
-static void dag_group_on_visible_update(Scene *scene, Group *group)
-{
- GroupObject *go;
-
- if (group->id.tag & LIB_TAG_DOIT)
- return;
-
- group->id.tag |= LIB_TAG_DOIT;
-
- for (go = group->gobject.first; go; go = go->next) {
- if (ELEM(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
- go->ob->recalc |= OB_RECALC_DATA;
- go->ob->id.tag |= LIB_TAG_DOIT;
- lib_id_recalc_tag(G.main, &go->ob->id);
- }
- if (go->ob->proxy_from) {
- go->ob->recalc |= OB_RECALC_OB;
- go->ob->id.tag |= LIB_TAG_DOIT;
- lib_id_recalc_tag(G.main, &go->ob->id);
- }
-
- if (go->ob->dup_group)
- dag_group_on_visible_update(scene, go->ob->dup_group);
- }
-}
-
-void DAG_on_visible_update(Main *bmain, const bool do_time)
-{
- ListBase listbase;
- DagSceneLayer *dsl;
-
- if (!DEG_depsgraph_use_legacy()) {
- /* Inform new dependnecy graphs about visibility changes. */
- DEG_on_visible_update(bmain, do_time);
- return;
- }
-
- /* get list of visible scenes and layers */
- dag_current_scene_layers(bmain, &listbase);
-
- for (dsl = listbase.first; dsl; dsl = dsl->next) {
- Scene *scene = dsl->scene;
- Scene *sce_iter;
- Base *base;
- Object *ob;
- DagNode *node;
- unsigned int lay = dsl->layer, oblay;
-
- /* derivedmeshes and displists are not saved to file so need to be
- * remade, tag them so they get remade in the scene update loop,
- * note armature poses or object matrices are preserved and do not
- * require updates, so we skip those */
- for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
- dag_scene_flush_layers(sce_iter, lay);
-
- BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);
-
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
- node = (sce_iter->theDag) ? dag_get_node(sce_iter->theDag, ob) : NULL;
- oblay = (node) ? node->lay : ob->lay;
-
- if ((oblay & lay) & ~scene->lay_updated) {
- /* TODO(sergey): Why do we need armature here now but didn't need before? */
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE, OB_ARMATURE)) {
- ob->recalc |= OB_RECALC_DATA;
- lib_id_recalc_tag(bmain, &ob->id);
- }
- /* This should not be needed here, but in some cases, like after a redo, we can end up with
- * a wrong final matrix (see T42472).
- * Quoting Sergey, this comes from BKE_object_handle_update_ex, which is calling
- * BKE_object_where_is_calc_ex when it shouldn't, but that issue is not easily fixable.
- */
- else {
- ob->recalc |= OB_RECALC_OB;
- lib_id_recalc_tag(bmain, &ob->id);
- }
- if (ob->proxy && (ob->proxy_group == NULL)) {
- ob->proxy->recalc |= OB_RECALC_DATA;
- lib_id_recalc_tag(bmain, &ob->id);
- }
- if (ob->dup_group)
- dag_group_on_visible_update(scene, ob->dup_group);
- }
- }
-
- BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);
-
- /* now tag update flags, to ensure deformers get calculated on redraw */
- DAG_scene_update_flags(bmain, scene, lay, do_time, true);
- scene->lay_updated |= lay;
- }
-
- BLI_freelistN(&listbase);
-
- /* hack to get objects updating on layer changes */
- DAG_id_type_tag(bmain, ID_OB);
-
- /* so masks update on load */
- if (bmain->mask.first) {
- Mask *mask;
-
- for (mask = bmain->mask.first; mask; mask = mask->id.next) {
- DAG_id_tag_update(&mask->id, 0);
- }
- }
-}
-
-static void dag_id_flush_update__isDependentTexture(
- void *userData, Object *UNUSED(ob), ID **idpoin, int UNUSED(cb_flag))
-{
- struct { ID *id; bool is_dependent; } *data = userData;
-
- if (*idpoin && GS((*idpoin)->name) == ID_TE) {
- if (data->id == (*idpoin))
- data->is_dependent = 1;
- }
-}
-
-static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
-{
- Object *obt, *ob = NULL;
- short idtype;
-
- /* here we flush a few things before actual scene wide flush, mostly
- * due to only objects and not other datablocks being in the depsgraph */
-
- /* set flags & pointcache for object */
- if (GS(id->name) == ID_OB) {
- ob = (Object *)id;
- BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
-
- /* So if someone tagged object recalc directly,
- * id_tag_update bit-field stays relevant
- */
- if (ob->recalc & OB_RECALC_ALL) {
- DAG_id_type_tag(bmain, GS(id->name));
- }
-
- if (ob->recalc & OB_RECALC_DATA) {
- /* all users of this ob->data should be checked */
- id = ob->data;
-
- /* no point in trying in this cases */
- if (id && id->us <= 1) {
- dag_editors_id_update(bmain, id);
- id = NULL;
- }
- }
- }
-
- /* set flags & pointcache for object data */
- if (id) {
- idtype = GS(id->name);
-
-
- if (OB_DATA_SUPPORT_ID(idtype)) {
- for (obt = bmain->object.first; obt; obt = obt->id.next) {
- if (!(ob && obt == ob) && obt->data == id) {
- obt->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obt->id);
- BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- }
- }
- }
- else if (idtype == ID_VF) {
- for (obt = bmain->object.first; obt; obt = obt->id.next) {
- if (obt->type == OB_FONT) {
- Curve *cu = obt->data;
- if (ELEM((struct VFont *)id, CURVE_VFONT_ANY(cu))) {
- obt->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obt->id);
- }
- }
- }
- }
-
- /* set flags based on textures - can influence depgraph via modifiers */
- if (idtype == ID_TE) {
- for (obt = bmain->object.first; obt; obt = obt->id.next) {
- struct { ID *id; bool is_dependent; } data;
- data.id = id;
- data.is_dependent = 0;
-
- modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data);
- if (data.is_dependent) {
- obt->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obt->id);
- }
-
- /* particle settings can use the texture as well */
- if (obt->particlesystem.first) {
- ParticleSystem *psys = obt->particlesystem.first;
- MTex **mtexp, *mtex;
- int a;
- for (; psys; psys = psys->next) {
- mtexp = psys->part->mtex;
- for (a = 0; a < MAX_MTEX; a++, mtexp++) {
- mtex = *mtexp;
- if (mtex && mtex->tex == (Tex *)id) {
- obt->recalc |= OB_RECALC_DATA;
- lib_id_recalc_data_tag(bmain, &obt->id);
-
- if (mtex->mapto & PAMAP_INIT)
- psys->recalc |= PSYS_RECALC_RESET;
- if (mtex->mapto & PAMAP_CHILD)
- psys->recalc |= PSYS_RECALC_CHILD;
-
- BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- }
- }
- }
- }
- }
- }
-
- /* set flags based on ShapeKey */
- if (idtype == ID_KE) {
- for (obt = bmain->object.first; obt; obt = obt->id.next) {
- Key *key = BKE_key_from_object(obt);
- if (!(ob && obt == ob) && ((ID *)key == id)) {
- obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA);
- lib_id_recalc_tag(bmain, &obt->id);
- lib_id_recalc_data_tag(bmain, &obt->id);
- BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- }
- }
- }
-
- /* set flags based on particle settings */
- if (idtype == ID_PA) {
- ParticleSystem *psys;
- for (obt = bmain->object.first; obt; obt = obt->id.next)
- for (psys = obt->particlesystem.first; psys; psys = psys->next)
- if (&psys->part->id == id)
- BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- }
-
- if (ELEM(idtype, ID_MA, ID_TE)) {
- obt = sce->basact ? sce->basact->object : NULL;
- if (obt && obt->mode & OB_MODE_TEXTURE_PAINT) {
- BKE_texpaint_slots_refresh_object(sce, obt);
- BKE_paint_proj_mesh_data_check(sce, obt, NULL, NULL, NULL, NULL);
- GPU_drawobject_free(obt->derivedFinal);
- }
- }
-
- if (idtype == ID_MC) {
- MovieClip *clip = (MovieClip *) id;
-
- BKE_tracking_dopesheet_tag_update(&clip->tracking);
-
- for (obt = bmain->object.first; obt; obt = obt->id.next) {
- bConstraint *con;
- for (con = obt->constraints.first; con; con = con->next) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
- if (ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
- CONSTRAINT_TYPE_OBJECTSOLVER))
- {
- obt->recalc |= OB_RECALC_OB;
- lib_id_recalc_tag(bmain, &obt->id);
- break;
- }
- }
- }
-
- if (sce->nodetree) {
- bNode *node;
-
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- nodeUpdate(sce->nodetree, node);
- }
- }
- }
- }
-
- /* Not pretty to iterate all the nodes here, but it's as good as it
- * could be with the current depsgraph design/
- */
- if (idtype == ID_IM) {
- FOREACH_NODETREE(bmain, ntree, parent_id) {
- if (ntree->type == NTREE_SHADER) {
- bNode *node;
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- lib_id_recalc_tag(bmain, &ntree->id);
- break;
- }
- }
- }
- } FOREACH_NODETREE_END
- }
-
- if (idtype == ID_MSK) {
- if (sce->nodetree) {
- bNode *node;
-
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- nodeUpdate(sce->nodetree, node);
- }
- }
- }
- }
-
- /* camera's matrix is used to orient reconstructed stuff,
- * so it should happen tracking-related constraints recalculation
- * when camera is changing (sergey) */
- if (sce->camera && &sce->camera->id == id) {
- MovieClip *clip = BKE_object_movieclip_get(sce, sce->camera, true);
-
- if (clip)
- dag_id_flush_update(bmain, sce, &clip->id);
- }
-
- /* update editors */
- dag_editors_id_update(bmain, id);
- }
-}
-
-void DAG_ids_flush_tagged(Main *bmain)
-{
- ListBase listbase;
- DagSceneLayer *dsl;
- ListBase *lbarray[MAX_LIBARRAY];
- int a;
- bool do_flush = false;
-
- if (!DEG_depsgraph_use_legacy()) {
- DEG_ids_flush_tagged(bmain);
- return;
- }
-
- /* get list of visible scenes and layers */
- dag_current_scene_layers(bmain, &listbase);
-
- if (BLI_listbase_is_empty(&listbase))
- return;
-
- /* loop over all ID types */
- a = set_listbasepointers(bmain, lbarray);
-
- while (a--) {
- ListBase *lb = lbarray[a];
- ID *id = lb->first;
-
- if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
- for (; id; id = id->next) {
- if (id->tag & (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA)) {
-
- for (dsl = listbase.first; dsl; dsl = dsl->next)
- dag_id_flush_update(bmain, dsl->scene, id);
-
- do_flush = true;
- }
- }
- }
- }
-
- /* flush changes to other objects */
- if (do_flush) {
- for (dsl = listbase.first; dsl; dsl = dsl->next)
- DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, 0);
- }
-
- BLI_freelistN(&listbase);
-}
-
-void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
-{
- ListBase *lbarray[MAX_LIBARRAY];
- int a;
- bool updated = false;
-
- if (!DEG_depsgraph_use_legacy()) {
- DEG_ids_check_recalc(bmain, scene, time);
- return;
- }
-
- /* loop over all ID types */
- a = set_listbasepointers(bmain, lbarray);
-
- while (a--) {
- ListBase *lb = lbarray[a];
- ID *id = lb->first;
-
- if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
- updated = true;
- break;
- }
- }
-
- dag_editors_scene_update(bmain, scene, (updated || time));
-}
-
-/* It is possible that scene_update_post and frame_update_post handlers
- * will modify objects. The issue is that DAG_ids_clear_recalc is called
- * just after callbacks, which leaves objects with recalc flags but no
- * corresponding bit in ID recalc bitfield. This leads to some kind of
- * regression when using ID type tag fields to check whether there objects
- * to be updated internally comparing threaded DAG with legacy one.
- *
- * For now let's have a workaround which will preserve tag for ID_OB
- * if there're objects with OB_RECALC_ALL bits. This keeps behavior
- * unchanged comparing with 2.69 release.
- *
- * TODO(sergey): Need to get rid of such a workaround.
- *
- * - sergey -
- */
-
-#define POST_UPDATE_HANDLER_WORKAROUND
-
-void DAG_ids_clear_recalc(Main *bmain)
-{
- ListBase *lbarray[MAX_LIBARRAY];
- bNodeTree *ntree;
- int a;
-
-#ifdef POST_UPDATE_HANDLER_WORKAROUND
- bool have_updated_objects = false;
-
- if (DAG_id_type_tagged(bmain, ID_OB)) {
- ListBase listbase;
- DagSceneLayer *dsl;
-
- /* We need to check all visible scenes, otherwise resetting
- * OB_ID changed flag will only work fine for first scene of
- * multiple visible and all the rest will skip update.
- *
- * This could also lead to wrong behavior scene update handlers
- * because of missing ID datablock changed flags.
- *
- * This is a bit of a bummer to allocate list here, but likely
- * it wouldn't become too much bad because it only happens when
- * objects were actually changed.
- */
- dag_current_scene_layers(bmain, &listbase);
-
- for (dsl = listbase.first; dsl; dsl = dsl->next) {
- Scene *scene = dsl->scene;
- DagNode *node;
- for (node = scene->theDag->DagNode.first;
- node != NULL && have_updated_objects == false;
- node = node->next)
- {
- if (node->type == ID_OB) {
- Object *object = (Object *) node->ob;
- if (object->recalc & OB_RECALC_ALL) {
- have_updated_objects = true;
- break;
- }
- }
- }
- }
-
- BLI_freelistN(&listbase);
- }
-#endif
-
- /* loop over all ID types */
- a = set_listbasepointers(bmain, lbarray);
-
- while (a--) {
- ListBase *lb = lbarray[a];
- ID *id = lb->first;
-
- if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
- for (; id; id = id->next) {
- if (id->tag & (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA))
- id->tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
-
- /* some ID's contain semi-datablock nodetree */
- ntree = ntreeFromID(id);
- if (ntree && (ntree->id.tag & (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA)))
- ntree->id.tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
- }
- }
- }
-
- memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
-
-#ifdef POST_UPDATE_HANDLER_WORKAROUND
- if (have_updated_objects) {
- DAG_id_type_tag(bmain, ID_OB);
- }
-#endif
-}
-
-void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
-{
- if (!DEG_depsgraph_use_legacy()) {
- DEG_id_tag_update_ex(bmain, id, flag);
- return;
- }
-
- if (id == NULL) return;
-
- if (G.debug & G_DEBUG_DEPSGRAPH) {
- printf("%s: id=%s flag=%d\n", __func__, id->name, flag);
- }
-
- /* tag ID for update */
- if (flag) {
- if (flag & OB_RECALC_OB)
- lib_id_recalc_tag(bmain, id);
- if (flag & (OB_RECALC_DATA | PSYS_RECALC))
- lib_id_recalc_data_tag(bmain, id);
- }
- else
- lib_id_recalc_tag(bmain, id);
-
- /* flag is for objects and particle systems */
- if (flag) {
- Object *ob;
- short idtype = GS(id->name);
-
- if (idtype == ID_OB) {
- /* only quick tag */
- ob = (Object *)id;
- ob->recalc |= (flag & OB_RECALC_ALL);
- }
- else if (idtype == ID_PA) {
- ParticleSystem *psys;
- /* this is weak still, should be done delayed as well */
- for (ob = bmain->object.first; ob; ob = ob->id.next) {
- for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- if (&psys->part->id == id) {
- ob->recalc |= (flag & OB_RECALC_ALL);
- psys->recalc |= (flag & PSYS_RECALC);
- lib_id_recalc_tag(bmain, &ob->id);
- lib_id_recalc_data_tag(bmain, &ob->id);
- }
- }
- }
- }
- else {
- /* disable because this is called on various ID types automatically.
- * where printing warning is not useful. for now just ignore */
- /* BLI_assert(!"invalid flag for this 'idtype'"); */
- }
- }
- else if (GS(id->name) == ID_CF) {
- for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
- ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
-
- if (md) {
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
-
- if (mcmd->cache_file && (&mcmd->cache_file->id == id)) {
- ob->recalc |= OB_RECALC_ALL;
- continue;
- }
- }
-
- for (bConstraint *con = ob->constraints.first; con; con = con->next) {
- if (con->type != CONSTRAINT_TYPE_TRANSFORM_CACHE) {
- continue;
- }
-
- bTransformCacheConstraint *data = con->data;
-
- if (data->cache_file && (&data->cache_file->id == id)) {
- ob->recalc |= OB_RECALC_ALL;
- break;
- }
- }
- }
- }
-}
-
-void DAG_id_tag_update(ID *id, short flag)
-{
- DAG_id_tag_update_ex(G.main, id, flag);
-}
-
-void DAG_id_type_tag(Main *bmain, short idtype)
-{
- if (idtype == ID_NT) {
- /* stupid workaround so parent datablocks of nested nodetree get looped
- * over when we loop over tagged datablock types */
- DAG_id_type_tag(bmain, ID_MA);
- DAG_id_type_tag(bmain, ID_TE);
- DAG_id_type_tag(bmain, ID_LA);
- DAG_id_type_tag(bmain, ID_WO);
- DAG_id_type_tag(bmain, ID_SCE);
- }
-
- atomic_fetch_and_or_uint8((uint8_t *)&bmain->id_tag_update[BKE_idcode_to_index(idtype)], 1);
-}
-
-int DAG_id_type_tagged(Main *bmain, short idtype)
-{
- return bmain->id_tag_update[BKE_idcode_to_index(idtype)];
-}
-
-#if 0 // UNUSED
-/* recursively descends tree, each node only checked once */
-/* node is checked to be of type object */
-static int parent_check_node(DagNode *node, int curtime)
-{
- DagAdjList *itA;
-
- node->lasttime = curtime;
-
- if (node->color == DAG_GRAY)
- return DAG_GRAY;
-
- for (itA = node->child; itA; itA = itA->next) {
- if (itA->node->type == ID_OB) {
-
- if (itA->node->color == DAG_GRAY)
- return DAG_GRAY;
-
- /* descend if not done */
- if (itA->node->lasttime != curtime) {
- itA->node->color = parent_check_node(itA->node, curtime);
-
- if (itA->node->color == DAG_GRAY)
- return DAG_GRAY;
- }
- }
- }
-
- return DAG_WHITE;
-}
-#endif
-
-/* ******************* DAG FOR ARMATURE POSE ***************** */
-
-/* we assume its an armature with pose */
-void DAG_pose_sort(Object *ob)
-{
- bPose *pose = ob->pose;
- bPoseChannel *pchan;
- bConstraint *con;
- DagNode *node;
- DagNode *node2, *node3;
- DagNode *rootnode;
- DagForest *dag;
- DagNodeQueue *nqueue;
- DagAdjList *itA;
- ListBase tempbase;
- int skip = 0;
-
- dag = dag_init();
- dag->ugly_hack_sorry = false; /* no ID structs */
-
- rootnode = dag_add_node(dag, NULL); /* node->ob becomes NULL */
-
- /* we add the hierarchy and the constraints */
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- int addtoroot = 1;
-
- node = dag_get_node(dag, pchan);
-
- if (pchan->parent) {
- node2 = dag_get_node(dag, pchan->parent);
- dag_add_relation(dag, node2, node, 0, "Parent Relation");
- addtoroot = 0;
- }
- for (con = pchan->constraints.first; con; con = con->next) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
- ListBase targets = {NULL, NULL};
- bConstraintTarget *ct;
-
- if (cti && cti->get_constraint_targets) {
- cti->get_constraint_targets(con, &targets);
-
- for (ct = targets.first; ct; ct = ct->next) {
- if (ct->tar == ob && ct->subtarget[0]) {
- bPoseChannel *target = BKE_pose_channel_find_name(ob->pose, ct->subtarget);
- if (target) {
- node2 = dag_get_node(dag, target);
- dag_add_relation(dag, node2, node, 0, "Pose Constraint");
-
- if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
- bKinematicConstraint *data = (bKinematicConstraint *)con->data;
- bPoseChannel *parchan;
- int segcount = 0;
-
- /* exclude tip from chain? */
- if (!(data->flag & CONSTRAINT_IK_TIP))
- parchan = pchan->parent;
- else
- parchan = pchan;
-
- /* Walk to the chain's root */
- while (parchan) {
- node3 = dag_get_node(dag, parchan);
- dag_add_relation(dag, node2, node3, 0, "IK Constraint");
-
- segcount++;
- if (segcount == data->rootbone || segcount > 255) break; /* 255 is weak */
- parchan = parchan->parent;
- }
- }
- }
- }
- }
-
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(con, &targets, 1);
- }
- }
- if (addtoroot == 1) {
- dag_add_relation(dag, rootnode, node, 0, "Root Bone Relation");
- }
- }
-
- dag_check_cycle(dag);
-
- /* now we try to sort... */
- BLI_listbase_clear(&tempbase);
-
- nqueue = queue_create(DAGQUEUEALLOC);
-
- /* tag nodes unchecked */
- for (node = dag->DagNode.first; node; node = node->next)
- node->color = DAG_WHITE;
-
- rootnode->color = DAG_GRAY;
- push_stack(nqueue, rootnode);
-
- while (nqueue->count) {
-
- skip = 0;
- node = get_top_node_queue(nqueue);
-
- itA = node->child;
- while (itA != NULL) {
- if (itA->node->color == DAG_WHITE) {
- itA->node->color = DAG_GRAY;
- push_stack(nqueue, itA->node);
- skip = 1;
- break;
- }
- itA = itA->next;
- }
-
- if (!skip) {
- if (node) {
- node = pop_queue(nqueue);
- if (node->ob == NULL) /* we are done */
- break;
- node->color = DAG_BLACK;
-
- /* put node in new list */
- BLI_remlink(&pose->chanbase, node->ob);
- BLI_addhead(&tempbase, node->ob);
- }
- }
- }
-
- /* temporal correction for circular dependencies */
- while (pose->chanbase.first) {
- pchan = pose->chanbase.first;
- BLI_remlink(&pose->chanbase, pchan);
- BLI_addhead(&tempbase, pchan);
-
- printf("cyclic %s\n", pchan->name);
- }
-
- pose->chanbase = tempbase;
- queue_delete(nqueue);
-
-// printf("\nordered\n");
-// for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
-// printf(" %s\n", pchan->name);
-// }
-
- free_forest(dag);
- MEM_freeN(dag);
-}
-
-/* ************************ DAG FOR THREADED UPDATE ********************* */
-
-/* Initialize run-time data in the graph needed for traversing it
- * from multiple threads and start threaded tree traversal by adding
- * the root node to the queue.
- *
- * This will mark DAG nodes as object/non-object and will calculate
- * num_pending_parents of nodes (which is how many non-updated parents node
- * have, which helps a lot checking whether node could be scheduled
- * already or not).
- */
-void DAG_threaded_update_begin(Scene *scene,
- void (*func)(void *node, void *user_data),
- void *user_data)
-{
- DagNode *node;
-
- /* We reset num_pending_parents to zero first and tag node as not scheduled yet... */
- for (node = scene->theDag->DagNode.first; node; node = node->next) {
- node->num_pending_parents = 0;
- node->scheduled = false;
- }
-
- /* ... and then iterate over all the nodes and
- * increase num_pending_parents for node childs.
- */
- for (node = scene->theDag->DagNode.first; node; node = node->next) {
- DagAdjList *itA;
-
- for (itA = node->child; itA; itA = itA->next) {
- if (itA->node != node) {
- itA->node->num_pending_parents++;
- }
- }
- }
-
- /* Add root nodes to the queue. */
- BLI_spin_lock(&threaded_update_lock);
- for (node = scene->theDag->DagNode.first; node; node = node->next) {
- if (node->num_pending_parents == 0) {
- node->scheduled = true;
- func(node, user_data);
- }
- }
- BLI_spin_unlock(&threaded_update_lock);
-}
-
-/* This function is called when handling node is done.
- *
- * This function updates num_pending_parents for all childs and
- * schedules them if they're ready.
- */
-void DAG_threaded_update_handle_node_updated(void *node_v,
- void (*func)(void *node, void *user_data),
- void *user_data)
-{
- DagNode *node = node_v;
- DagAdjList *itA;
-
- for (itA = node->child; itA; itA = itA->next) {
- DagNode *child_node = itA->node;
- if (child_node != node) {
- atomic_sub_and_fetch_uint32(&child_node->num_pending_parents, 1);
-
- if (child_node->num_pending_parents == 0) {
- bool need_schedule;
-
- BLI_spin_lock(&threaded_update_lock);
- need_schedule = child_node->scheduled == false;
- child_node->scheduled = true;
- BLI_spin_unlock(&threaded_update_lock);
-
- if (need_schedule) {
- func(child_node, user_data);
- }
- }
- }
- }
-}
-
-/* ************************ DAG DEBUGGING ********************* */
-
-void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob)
-{
- /* utility for debugging dependencies */
- dag_print_dependencies = 1;
-
- if (ob && (ob->mode & OB_MODE_POSE)) {
- printf("\nDEPENDENCY RELATIONS for %s\n\n", ob->id.name + 2);
- DAG_pose_sort(ob);
- }
- else {
- printf("\nDEPENDENCY RELATIONS for %s\n\n", scene->id.name + 2);
- DAG_scene_relations_rebuild(bmain, scene);
- }
-
- dag_print_dependencies = 0;
-}
-
-/* ************************ DAG querying ********************* */
-
-/* Will return Object ID if node represents Object,
- * and will return NULL otherwise.
- */
-Object *DAG_get_node_object(void *node_v)
-{
- DagNode *node = node_v;
-
- if (node->type == ID_OB) {
- return node->ob;
- }
-
- return NULL;
-}
-
-/* Returns node name, used for debug output only, atm. */
-const char *DAG_get_node_name(Scene *scene, void *node_v)
-{
- DagNode *node = node_v;
-
- return dag_node_name(scene->theDag, node);
-}
-
-short DAG_get_eval_flags_for_object(Scene *scene, void *object)
-{
- DagNode *node;
-
- if (!DEG_depsgraph_use_legacy()) {
- return DEG_get_eval_flags_for_id(scene->depsgraph, (ID *)object);
- }
-
- if (scene->theDag == NULL) {
- /* Happens when converting objects to mesh from a python script
- * after modifying scene graph.
- *
- * Currently harmless because it's only called for temporary
- * objects which are out of the DAG anyway.
- */
- return 0;
- }
-
- node = dag_find_node(scene->theDag, object);
-
- if (node) {
- return node->eval_flags;
- }
- else {
- /* Happens when external render engine exports temporary objects
- * which are not in the DAG.
- */
-
- /* TODO(sergey): Doublecheck objects with Curve Deform exports all fine. */
-
- /* TODO(sergey): Weak but currently we can't really access proper DAG from
- * the modifiers stack. This is because in most cases modifier is to use
- * the foreground scene, but to access evaluation flags we need to know
- * active background scene, which we don't know.
- */
- if (scene->set) {
- return DAG_get_eval_flags_for_object(scene->set, object);
- }
- return 0;
- }
-}
-
-bool DAG_is_acyclic(Scene *scene)
-{
- return scene->theDag->is_acyclic;
-}
-
-#else
-
-/* *********************************************************************
- * Stubs to avoid linking issues and make sure legacy crap is not used *
- * *********************************************************************
- */
-
-DagNodeQueue *queue_create(int UNUSED(slots))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-void queue_raz(DagNodeQueue *UNUSED(queue))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void queue_delete(DagNodeQueue *UNUSED(queue))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void push_queue(DagNodeQueue *UNUSED(queue), DagNode *UNUSED(node))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void push_stack(DagNodeQueue *UNUSED(queue), DagNode *UNUSED(node))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-DagNode *pop_queue(DagNodeQueue *UNUSED(queue))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-DagNode *get_top_node_queue(DagNodeQueue *UNUSED(queue))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-DagForest *dag_init(void)
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-DagForest *build_dag(Main *UNUSED(bmain),
- Scene *UNUSED(sce),
- short UNUSED(mask))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-void free_forest(DagForest *UNUSED(Dag))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-DagNode *dag_find_node(DagForest *UNUSED(forest), void *UNUSED(fob))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-DagNode *dag_add_node(DagForest *UNUSED(forest), void *UNUSED(fob))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-DagNode *dag_get_node(DagForest *UNUSED(forest), void *UNUSED(fob))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-DagNode *dag_get_sub_node(DagForest *UNUSED(forest), void *UNUSED(fob))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-void dag_add_relation(DagForest *UNUSED(forest),
- DagNode *UNUSED(fob1),
- DagNode *UNUSED(fob2),
- short UNUSED(rel),
- const char *UNUSED(name))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-/* debug test functions */
-
-void graph_print_queue(DagNodeQueue *UNUSED(nqueue))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void graph_print_queue_dist(DagNodeQueue *UNUSED(nqueue))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void graph_print_adj_list(DagForest *UNUSED(dag))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void DAG_scene_flush_update(Main *UNUSED(bmain),
- Scene *UNUSED(sce),
- unsigned int UNUSED(lay),
- const short UNUSED(time))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-void DAG_scene_update_flags(Main *UNUSED(bmain),
- Scene *UNUSED(scene),
- unsigned int UNUSED(lay),
- const bool UNUSED(do_time),
- const bool UNUSED(do_invisible_flush))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-/* ******************* DAG FOR ARMATURE POSE ***************** */
-
-void DAG_pose_sort(Object *UNUSED(ob))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
-}
-
-/* ************************ DAG FOR THREADED UPDATE ********************* */
-
-void DAG_threaded_update_begin(Scene *UNUSED(scene),
- void (*func)(void *node, void *user_data),
- void *UNUSED(user_data))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- (void)func;
-}
-
-void DAG_threaded_update_handle_node_updated(void *UNUSED(node_v),
- void (*func)(void *node, void *user_data),
- void *UNUSED(user_data))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- (void)func;
-}
-
-/* ************************ DAG querying ********************* */
-
-Object *DAG_get_node_object(void *UNUSED(node_v))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return NULL;
-}
-
-const char *DAG_get_node_name(Scene *UNUSED(scene), void *UNUSED(node_v))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return "INVALID";
-}
-
-bool DAG_is_acyclic(Scene *UNUSED(scene))
-{
- BLI_assert(!"Should not be used with new dependnecy graph");
- return false;
-}
+/* ************************ DAG ********************* */
/* ************************************
* This functions are to be supported *
@@ -3696,5 +165,3 @@ void DAG_print_dependencies(Main *UNUSED(bmain),
{
DEG_debug_graphviz(scene->depsgraph, stdout, "Depsgraph", false);
}
-
-#endif
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 2a300cbe47b..44f284d043e 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -48,7 +48,6 @@
#include "BLI_utildefines.h"
#include "BKE_global.h"
-#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_object.h"
@@ -63,6 +62,9 @@
#include "BLI_sys_types.h" // for intptr_t support
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
static void boundbox_displist_object(Object *ob);
void BKE_displist_elem_free(DispList *dl)
@@ -1739,7 +1741,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
if (!for_orco) {
if ((cu->flag & CU_PATH) ||
- DAG_get_eval_flags_for_object(scene, ob) & DAG_EVAL_NEED_CURVE_PATH)
+ DEG_get_eval_flags_for_id(scene->depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH)
{
calc_curvepath(ob, &nubase);
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 1db69d23607..fb5ef403218 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -486,7 +486,7 @@ static void scene_setSubframe(Scene *scene, float subframe)
scene->r.subframe = subframe;
}
-static int surface_getBrushFlags(DynamicPaintSurface *surface, const Scene *scene)
+static int surface_getBrushFlags(DynamicPaintSurface *surface, const SceneLayer *sl)
{
Base *base = NULL;
GroupObject *go = NULL;
@@ -498,7 +498,7 @@ static int surface_getBrushFlags(DynamicPaintSurface *surface, const Scene *scen
if (surface->brush_group)
go = surface->brush_group->gobject.first;
else
- base = scene->base.first;
+ base = FIRSTBASE_NEW;
while (base || go) {
brushObj = NULL;
@@ -1973,7 +1973,7 @@ static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMe
/*
* Updates derived mesh copy and processes dynamic paint step / caches.
*/
-static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm)
{
if (pmd->canvas) {
DynamicPaintCanvasSettings *canvas = pmd->canvas;
@@ -2036,7 +2036,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
else if (can_simulate) {
/* calculate surface frame */
canvas->flags |= MOD_DPAINT_BAKING;
- dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
+ dynamicPaint_calculateFrame(surface, scene, sl, ob, current_frame);
canvas->flags &= ~MOD_DPAINT_BAKING;
/* restore canvas derivedmesh if required */
@@ -2055,7 +2055,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
}
/* Modifier call. Processes dynamic paint modifier step. */
-DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm)
{
if (pmd->canvas) {
DerivedMesh *ret;
@@ -2064,7 +2064,7 @@ DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scen
DM_ensure_looptri(dm);
/* Update canvas data for a new frame */
- dynamicPaint_frameUpdate(pmd, scene, ob, dm);
+ dynamicPaint_frameUpdate(pmd, scene, sl, ob, dm);
/* Return output mesh */
ret = dynamicPaint_Modifier_apply(pmd, ob, dm);
@@ -2076,7 +2076,7 @@ DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scen
DM_ensure_looptri(dm);
/* Update canvas data for a new frame */
- dynamicPaint_frameUpdate(pmd, scene, ob, dm);
+ dynamicPaint_frameUpdate(pmd, scene, sl, ob, dm);
/* Return output mesh */
return dynamicPaint_Modifier_apply(pmd, ob, dm);
@@ -5638,7 +5638,7 @@ static void dynamic_paint_generate_bake_data_cb(void *userdata, const int index)
}
}
-static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const Scene *scene, Object *ob)
+static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const SceneLayer *sl, Object *ob)
{
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
@@ -5646,7 +5646,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const Sce
int index;
bool new_bdata = false;
const bool do_velocity_data = ((surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) ||
- (surface_getBrushFlags(surface, scene) & BRUSH_USES_VELOCITY));
+ (surface_getBrushFlags(surface, sl) & BRUSH_USES_VELOCITY));
const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0;
int canvasNumOfVerts = dm->getNumVerts(dm);
@@ -5758,7 +5758,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const Sce
/*
* Do Dynamic Paint step. Paints scene brush objects of current state/frame to the surface.
*/
-static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
+static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
{
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
@@ -5791,7 +5791,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
if (surface->brush_group)
go = surface->brush_group->gobject.first;
else
- base = scene->base.first;
+ base = FIRSTBASE_NEW;
while (base || go) {
brushObj = NULL;
@@ -5844,8 +5844,6 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
dynamicPaint_updateBrushMaterials(brushObj, brush->mat, scene, &bMats);
/* Apply brush on the surface depending on it's collision type */
- /* Particle brush: */
- if (brush->collision == MOD_DPAINT_COL_PSYS) {
if (brush->psys && brush->psys->part &&
ELEM(brush->psys->part->type, PART_EMITTER, PART_FLUID) &&
psys_check_enabled(brushObj, brush->psys, G.is_rendering))
@@ -5855,9 +5853,8 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
BKE_scene_frame_get(scene), ADT_RECALC_ANIM);
dynamicPaint_paintParticles(surface, brush->psys, brush, timescale);
}
- }
/* Object center distance: */
- else if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) {
+ if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) {
dynamicPaint_paintSinglePoint(surface, brushObj->loc, brush, brushObj, &bMats, scene, timescale);
}
/* Mesh volume/proximity: */
@@ -5931,7 +5928,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
/*
* Calculate a single frame and included subframes for surface
*/
-int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Object *cObject, int frame)
+int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, SceneLayer *sl, Object *cObject, int frame)
{
float timescale = 1.0f;
@@ -5940,7 +5937,7 @@ int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Obje
dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm);
/* update bake data */
- dynamicPaint_generateBakeData(surface, scene, cObject);
+ dynamicPaint_generateBakeData(surface, sl, cObject);
/* don't do substeps for first frame */
if (surface->substeps && (frame != surface->start_frame)) {
@@ -5949,10 +5946,10 @@ int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Obje
for (st = 1; st <= surface->substeps; st++) {
float subframe = ((float) st) / (surface->substeps + 1);
- if (!dynamicPaint_doStep(scene, cObject, surface, timescale, subframe))
+ if (!dynamicPaint_doStep(scene, sl, cObject, surface, timescale, subframe))
return 0;
}
}
- return dynamicPaint_doStep(scene, cObject, surface, timescale, 0.0f);
+ return dynamicPaint_doStep(scene, sl, cObject, surface, timescale, 0.0f);
}
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 4a45bf1534c..c8ae3598097 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -50,6 +50,7 @@
#include "BKE_mesh.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_bvh.h"
+#include "BKE_editmesh_tangent.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -240,383 +241,29 @@ static void emDM_calcLoopNormalsSpaceArray(
#endif
}
-
-/** \name Tangent Space Calculation
- * \{ */
-
-/* Necessary complexity to handle looptri's as quads for correct tangents */
-#define USE_LOOPTRI_DETECT_QUADS
-
-typedef struct {
- const float (*precomputedFaceNormals)[3];
- const float (*precomputedLoopNormals)[3];
- const BMLoop *(*looptris)[3];
- int cd_loop_uv_offset; /* texture coordinates */
- const float (*orco)[3];
- float (*tangent)[4]; /* destination */
- int numTessFaces;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- /* map from 'fake' face index to looptri,
- * quads will point to the first looptri of the quad */
- const int *face_as_quad_map;
- int num_face_as_quad_map;
-#endif
-
-} SGLSLEditMeshToTangent;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-/* seems weak but only used on quads */
-static const BMLoop *bm_loop_at_face_index(const BMFace *f, int vert_index)
-{
- const BMLoop *l = BM_FACE_FIRST_LOOP(f);
- while (vert_index--) {
- l = l->next;
- }
- return l;
-}
-#endif
-
-/* interface */
-#include "mikktspace.h"
-
-static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
-{
- SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- return pMesh->num_face_as_quad_map;
-#else
- return pMesh->numTessFaces;
-#endif
-}
-
-static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
-{
-#ifdef USE_LOOPTRI_DETECT_QUADS
- SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- if (pMesh->face_as_quad_map) {
- const BMLoop **lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- return 4;
- }
- }
- return 3;
-#else
- UNUSED_VARS(pContext, face_num);
- return 3;
-#endif
-}
-
-static void emdm_ts_GetPosition(
- const SMikkTSpaceContext *pContext, float r_co[3],
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- const BMLoop **lt;
- const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
-#else
- lt = pMesh->looptris[face_num];
-#endif
- l = lt[vert_index];
-
- const float *co;
-
-finally:
- co = l->v->co;
- copy_v3_v3(r_co, co);
-}
-
-static void emdm_ts_GetTextureCoordinate(
- const SMikkTSpaceContext *pContext, float r_uv[2],
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- const BMLoop **lt;
- const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
-#else
- lt = pMesh->looptris[face_num];
-#endif
- l = lt[vert_index];
-
-finally:
- if (pMesh->cd_loop_uv_offset != -1) {
- const float *uv = BM_ELEM_CD_GET_VOID_P(l, pMesh->cd_loop_uv_offset);
- copy_v2_v2(r_uv, uv);
- }
- else {
- const float *orco = pMesh->orco[BM_elem_index_get(l->v)];
- map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
- }
-}
-
-static void emdm_ts_GetNormal(
- const SMikkTSpaceContext *pContext, float r_no[3],
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- const BMLoop **lt;
- const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
-#else
- lt = pMesh->looptris[face_num];
-#endif
- l = lt[vert_index];
-
-finally:
- if (pMesh->precomputedLoopNormals) {
- copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(l)]);
- }
- else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
- if (pMesh->precomputedFaceNormals) {
- copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(l->f)]);
- }
- else {
- copy_v3_v3(r_no, l->f->no);
- }
- }
- else {
- copy_v3_v3(r_no, l->v->no);
- }
-}
-
-static void emdm_ts_SetTSpace(
- const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign,
- const int face_num, const int vert_index)
-{
- //assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- const BMLoop **lt;
- const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
-#else
- lt = pMesh->looptris[face_num];
-#endif
- l = lt[vert_index];
-
- float *pRes;
-
-finally:
- pRes = pMesh->tangent[BM_elem_index_get(l)];
- copy_v3_v3(pRes, fvTangent);
- pRes[3] = fSign;
-}
-
-static void emDM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
-{
- struct SGLSLEditMeshToTangent *mesh2tangent = taskdata;
- /* new computation method */
- {
- SMikkTSpaceContext sContext = {NULL};
- SMikkTSpaceInterface sInterface = {NULL};
- sContext.m_pUserData = mesh2tangent;
- sContext.m_pInterface = &sInterface;
- sInterface.m_getNumFaces = emdm_ts_GetNumFaces;
- sInterface.m_getNumVerticesOfFace = emdm_ts_GetNumVertsOfFace;
- sInterface.m_getPosition = emdm_ts_GetPosition;
- sInterface.m_getTexCoord = emdm_ts_GetTextureCoordinate;
- sInterface.m_getNormal = emdm_ts_GetNormal;
- sInterface.m_setTSpaceBasic = emdm_ts_SetTSpace;
- /* 0 if failed */
- genTangSpaceDefault(&sContext);
- }
-}
-
-/**
- * \see #DM_calc_loop_tangents, same logic but used arrays instead of #BMesh data.
- *
- * \note This function is not so normal, its using `bm->ldata` as input, but output's to `dm->loopData`.
- * This is done because #CD_TANGENT is cache data used only for drawing.
- */
-
static void emDM_calc_loop_tangents(
DerivedMesh *dm, bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME], int tangent_names_count)
+ const char (*tangent_names)[MAX_NAME], int tangent_names_len)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMEditMesh *em = bmdm->em;
- BMesh *bm = bmdm->em->bm;
- if (CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV) == 0)
- return;
-
- int act_uv_n = -1;
- int ren_uv_n = -1;
- bool calc_act = false;
- bool calc_ren = false;
- char act_uv_name[MAX_NAME];
- char ren_uv_name[MAX_NAME];
- char tangent_mask = 0;
-
- DM_calc_loop_tangents_step_0(
- &bm->ldata, calc_active_tangent, tangent_names, tangent_names_count,
- &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
-
- if ((dm->tangent_mask | tangent_mask) != dm->tangent_mask) {
- for (int i = 0; i < tangent_names_count; i++)
- if (tangent_names[i][0])
- DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, tangent_names[i]);
- if (calc_act && act_uv_name[0])
- DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, act_uv_name);
- if (calc_ren && ren_uv_name[0])
- DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, ren_uv_name);
- int totface = em->tottri;
-#ifdef USE_LOOPTRI_DETECT_QUADS
- int num_face_as_quad_map;
- int *face_as_quad_map = NULL;
-
- /* map faces to quads */
- if (bmdm->em->tottri != bm->totface) {
- /* over alloc, since we dont know how many ngon or quads we have */
-
- /* map fake face index to looptri */
- face_as_quad_map = MEM_mallocN(sizeof(int) * totface, __func__);
- int i, j;
- for (i = 0, j = 0; j < totface; i++, j++) {
- face_as_quad_map[i] = j;
- /* step over all quads */
- if (em->looptris[j][0]->f->len == 4) {
- j++; /* skips the nest looptri */
- }
- }
- num_face_as_quad_map = i;
- }
- else {
- num_face_as_quad_map = totface;
- }
-#endif
- /* Calculation */
- {
- TaskScheduler *scheduler = BLI_task_scheduler_get();
- TaskPool *task_pool;
- task_pool = BLI_task_pool_create(scheduler, NULL);
-
- dm->tangent_mask = 0;
- /* Calculate tangent layers */
- SGLSLEditMeshToTangent data_array[MAX_MTFACE];
- int index = 0;
- int n = 0;
- CustomData_update_typemap(&dm->loopData);
- const int tangent_layer_num = CustomData_number_of_layers(&dm->loopData, CD_TANGENT);
- for (n = 0; n < tangent_layer_num; n++) {
- index = CustomData_get_layer_index_n(&dm->loopData, CD_TANGENT, n);
- BLI_assert(n < MAX_MTFACE);
- SGLSLEditMeshToTangent *mesh2tangent = &data_array[n];
- mesh2tangent->numTessFaces = em->tottri;
-#ifdef USE_LOOPTRI_DETECT_QUADS
- mesh2tangent->face_as_quad_map = face_as_quad_map;
- mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
-#endif
- mesh2tangent->precomputedFaceNormals = bmdm->polyNos; /* dm->getPolyDataArray(dm, CD_NORMAL) */
- /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
- * have to check this is valid...
- */
- mesh2tangent->precomputedLoopNormals = CustomData_get_layer(&dm->loopData, CD_NORMAL);
- mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, n);
-
- /* needed for indexing loop-tangents */
- int htype_index = BM_LOOP;
- if (mesh2tangent->cd_loop_uv_offset == -1) {
- mesh2tangent->orco = dm->getVertDataArray(dm, CD_ORCO);
- if (!mesh2tangent->orco)
- continue;
- /* needed for orco lookups */
- htype_index |= BM_VERT;
- }
- if (mesh2tangent->precomputedFaceNormals) {
- /* needed for face normal lookups */
- htype_index |= BM_FACE;
- }
- BM_mesh_elem_index_ensure(bm, htype_index);
-
- mesh2tangent->looptris = (const BMLoop *(*)[3])em->looptris;
- mesh2tangent->tangent = dm->loopData.layers[index].data;
-
- /* Fill the resulting tangent_mask */
- int uv_ind = CustomData_get_named_layer_index(&bm->ldata, CD_MLOOPUV, dm->loopData.layers[index].name);
- int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
- BLI_assert(uv_ind != -1 && uv_start != -1);
- BLI_assert(uv_ind - uv_start < MAX_MTFACE);
- dm->tangent_mask |= 1 << (uv_ind - uv_start);
- BLI_task_pool_push(task_pool, emDM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
- }
- BLI_assert(dm->tangent_mask == tangent_mask);
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
- }
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (face_as_quad_map) {
- MEM_freeN(face_as_quad_map);
- }
-#undef USE_LOOPTRI_DETECT_QUADS
-#endif
+ if (CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV) == 0) {
+ return;
}
- /* Update active layer index */
- int uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n);
- int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name);
- CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index);
- /* Update render layer index */
- uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n);
- tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name);
- CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index);
+ const float (*poly_normals)[3] = bmdm->polyNos;
+ const float (*loop_normals)[3] = CustomData_get_layer(&dm->loopData, CD_NORMAL);
+ const float (*vert_orco)[3] = dm->getVertDataArray(dm, CD_ORCO); /* can be NULL */
+ BKE_editmesh_loop_tangent_calc(
+ em, calc_active_tangent,
+ tangent_names, tangent_names_len,
+ poly_normals, loop_normals,
+ vert_orco,
+ &dm->loopData, dm->numLoopData,
+ &dm->tangent_mask);
}
-/** \} */
-
static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
{
@@ -812,39 +459,6 @@ static void emDM_drawMappedEdgesInterp(
}
}
-static void emDM_drawUVEdges(DerivedMesh *dm)
-{
- EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
- BMesh *bm = bmdm->em->bm;
- BMFace *efa;
- BMIter iter;
-
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
- if (UNLIKELY(cd_loop_uv_offset == -1)) {
- return;
- }
-
- glBegin(GL_LINES);
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BMLoop *l_iter, *l_first;
- const float *uv, *uv_prev;
-
- if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
- continue;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
- uv_prev = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter->prev, cd_loop_uv_offset))->uv;
- do {
- uv = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv;
- glVertex2fv(uv);
- glVertex2fv(uv_prev);
- uv_prev = uv;
- } while ((l_iter = l_iter->next) != l_first);
- }
- glEnd();
-}
-
static void emDM_foreachMappedLoop(
DerivedMesh *dm,
void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
@@ -1193,20 +807,6 @@ static void emDM_drawMappedFaces(
}
}
-static void bmdm_get_tri_uv(BMLoop *ltri[3], MLoopUV *luv[3], const int cd_loop_uv_offset)
-{
- luv[0] = BM_ELEM_CD_GET_VOID_P(ltri[0], cd_loop_uv_offset);
- luv[1] = BM_ELEM_CD_GET_VOID_P(ltri[1], cd_loop_uv_offset);
- luv[2] = BM_ELEM_CD_GET_VOID_P(ltri[2], cd_loop_uv_offset);
-}
-
-static void bmdm_get_tri_col(BMLoop *ltri[3], MLoopCol *lcol[3], const int cd_loop_color_offset)
-{
- lcol[0] = BM_ELEM_CD_GET_VOID_P(ltri[0], cd_loop_color_offset);
- lcol[1] = BM_ELEM_CD_GET_VOID_P(ltri[1], cd_loop_color_offset);
- lcol[2] = BM_ELEM_CD_GET_VOID_P(ltri[2], cd_loop_color_offset);
-}
-
static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4])
{
lcol[0] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[0]->v)];
@@ -1214,204 +814,6 @@ static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned c
lcol[2] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[2]->v)];
}
-static void emDM_drawFacesTex_common(
- DerivedMesh *dm,
- DMSetDrawOptionsTex drawParams,
- DMSetDrawOptionsMappedTex drawParamsMapped,
- DMCompareDrawOptions compareDrawOptions,
- void *userData)
-{
- EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
- BMEditMesh *em = bmdm->em;
- BMesh *bm = em->bm;
- struct BMLoop *(*looptris)[3] = em->looptris;
- BMFace *efa;
- const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
- MLoopUV *luv[3], dummyluv = {{0}};
- MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
- const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
- unsigned char(*color_vert_array)[4] = em->derivedVertColor;
- bool has_uv = (cd_loop_uv_offset != -1);
- bool has_vcol_preview = (color_vert_array != NULL);
- bool has_vcol = (cd_loop_color_offset != -1) && (has_vcol_preview == false);
- bool has_vcol_any = (has_vcol_preview || has_vcol);
- int i;
-
- (void) compareDrawOptions;
-
- luv[0] = luv[1] = luv[2] = &dummyluv;
-
- // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; /* UNUSED */
-
- /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
- BM_mesh_elem_index_ensure(bm, BM_FACE);
-
- /* call again below is ok */
- if (has_vcol_preview) {
- BM_mesh_elem_index_ensure(bm, BM_VERT);
- }
-
- if (bmdm->vertexCos) {
- /* add direct access */
- const float (*vertexCos)[3] = bmdm->vertexCos;
- const float (*vertexNos)[3];
- const float (*polyNos)[3];
-
- emDM_ensureVertNormals(bmdm);
- emDM_ensurePolyNormals(bmdm);
- vertexNos = bmdm->vertexNos;
- polyNos = bmdm->polyNos;
-
- BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
-
- for (i = 0; i < em->tottri; i++) {
- BMLoop **ltri = looptris[i];
- MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
- /*unsigned char *cp = NULL;*/ /*UNUSED*/
- int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
- DMDrawOption draw_option;
-
- efa = ltri[0]->f;
-
- if (drawParams) {
- draw_option = drawParams(tp, has_vcol, efa->mat_nr);
- }
- else if (drawParamsMapped)
- draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), efa->mat_nr);
- else
- draw_option = DM_DRAW_OPTION_NORMAL;
-
- if (draw_option != DM_DRAW_OPTION_SKIP) {
-
- if (has_uv) bmdm_get_tri_uv(ltri, luv, cd_loop_uv_offset);
- if (has_vcol) bmdm_get_tri_col(ltri, lcol, cd_loop_color_offset);
- else if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
-
- glBegin(GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(polyNos[BM_elem_index_get(efa)]);
-
- glTexCoord2fv(luv[0]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
-
- glTexCoord2fv(luv[1]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
-
- glTexCoord2fv(luv[2]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
- }
- else {
- glTexCoord2fv(luv[0]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
- else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
- glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
-
- glTexCoord2fv(luv[1]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
- else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
- glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
-
- glTexCoord2fv(luv[2]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
- else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
- glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
- }
- glEnd();
- }
- }
- }
- else {
- BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
-
- for (i = 0; i < em->tottri; i++) {
- BMLoop **ltri = looptris[i];
- MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
- /*unsigned char *cp = NULL;*/ /*UNUSED*/
- int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
- DMDrawOption draw_option;
-
- efa = ltri[0]->f;
-
- if (drawParams)
- draw_option = drawParams(tp, has_vcol, efa->mat_nr);
- else if (drawParamsMapped)
- draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), efa->mat_nr);
- else
- draw_option = DM_DRAW_OPTION_NORMAL;
-
- if (draw_option != DM_DRAW_OPTION_SKIP) {
-
- if (has_uv) bmdm_get_tri_uv(ltri, luv, cd_loop_uv_offset);
- if (has_vcol) bmdm_get_tri_col(ltri, lcol, cd_loop_color_offset);
- else if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
-
- glBegin(GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(efa->no);
-
- glTexCoord2fv(luv[0]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- glVertex3fv(ltri[0]->v->co);
-
- glTexCoord2fv(luv[1]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- glVertex3fv(ltri[1]->v->co);
-
- glTexCoord2fv(luv[2]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- glVertex3fv(ltri[2]->v->co);
- }
- else {
- glTexCoord2fv(luv[0]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
- else glNormal3fv(ltri[0]->v->no);
- glVertex3fv(ltri[0]->v->co);
-
- glTexCoord2fv(luv[1]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
- else glNormal3fv(ltri[1]->v->no);
- glVertex3fv(ltri[1]->v->co);
-
- glTexCoord2fv(luv[2]->uv);
- if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
- else glNormal3fv(ltri[2]->v->no);
- glVertex3fv(ltri[2]->v->co);
- }
- glEnd();
- }
- }
- }
-}
-
-static void emDM_drawFacesTex(
- DerivedMesh *dm,
- DMSetDrawOptionsTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag UNUSED(flag))
-{
- emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
-}
-
-static void emDM_drawMappedFacesTex(
- DerivedMesh *dm,
- DMSetDrawOptionsMappedTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag UNUSED(flag))
-{
- emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
-}
-
/**
* \note
*
@@ -2057,14 +1459,8 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
if (type == CD_MTFACE || type == CD_MCOL) {
const char *bmdata;
char *data;
- bool has_type_source = false;
- if (type == CD_MTFACE) {
- has_type_source = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
- }
- else {
- has_type_source = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
- }
+ bool has_type_source = CustomData_has_layer(&bm->ldata, (type == CD_MTFACE) ? CD_MLOOPUV : CD_MLOOPCOL);
if (has_type_source) {
/* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
@@ -2080,15 +1476,8 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
if (type == CD_MTFACE) {
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
for (i = 0; i < bmdm->em->tottri; i++, data += size) {
- BMFace *efa = looptris[i][0]->f;
-
- // bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
- bmdata = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- ME_MTEXFACE_CPY(((MTFace *)data), ((const MTexPoly *)bmdata));
for (j = 0; j < 3; j++) {
// bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPUV);
bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_uv_offset);
@@ -2282,12 +1671,9 @@ DerivedMesh *getEditDerivedBMesh(
bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
- bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
- bmdm->dm.drawFacesTex = emDM_drawFacesTex;
bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
- bmdm->dm.drawUVEdges = emDM_drawUVEdges;
bmdm->dm.release = emDM_release;
diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c
index fea3c24d322..c95da3b2569 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.c
@@ -165,26 +165,6 @@ void BKE_editmesh_tessface_calc(BMEditMesh *em)
#endif
}
-void BKE_editmesh_update_linked_customdata(BMEditMesh *em)
-{
- BMesh *bm = em->bm;
- int act;
-
- if (CustomData_has_layer(&bm->pdata, CD_MTEXPOLY)) {
- act = CustomData_get_active_layer(&bm->pdata, CD_MTEXPOLY);
- CustomData_set_layer_active(&bm->ldata, CD_MLOOPUV, act);
-
- act = CustomData_get_render_layer(&bm->pdata, CD_MTEXPOLY);
- CustomData_set_layer_render(&bm->ldata, CD_MLOOPUV, act);
-
- act = CustomData_get_clone_layer(&bm->pdata, CD_MTEXPOLY);
- CustomData_set_layer_clone(&bm->ldata, CD_MLOOPUV, act);
-
- act = CustomData_get_stencil_layer(&bm->pdata, CD_MTEXPOLY);
- CustomData_set_layer_stencil(&bm->ldata, CD_MLOOPUV, act);
- }
-}
-
void BKE_editmesh_free_derivedmesh(BMEditMesh *em)
{
if (em->derivedCage) {
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c
new file mode 100644
index 00000000000..b04fc753f7a
--- /dev/null
+++ b/source/blender/blenkernel/intern/editmesh_tangent.c
@@ -0,0 +1,420 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/editmesh_tangent.c
+ * \ingroup bke
+ */
+
+#include "BLI_math.h"
+#include "BLI_task.h"
+
+#include "BKE_DerivedMesh.h"
+
+#include "BKE_mesh.h"
+#include "BKE_mesh_tangent.h" /* for utility functions */
+#include "BKE_editmesh.h"
+#include "BKE_editmesh_tangent.h"
+
+#include "MEM_guardedalloc.h"
+
+/* interface */
+#include "mikktspace.h"
+
+/** \name Tangent Space Calculation
+ * \{ */
+
+/* Necessary complexity to handle looptri's as quads for correct tangents */
+#define USE_LOOPTRI_DETECT_QUADS
+
+typedef struct {
+ const float (*precomputedFaceNormals)[3];
+ const float (*precomputedLoopNormals)[3];
+ const BMLoop *(*looptris)[3];
+ int cd_loop_uv_offset; /* texture coordinates */
+ const float (*orco)[3];
+ float (*tangent)[4]; /* destination */
+ int numTessFaces;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ /* map from 'fake' face index to looptri,
+ * quads will point to the first looptri of the quad */
+ const int *face_as_quad_map;
+ int num_face_as_quad_map;
+#endif
+
+} SGLSLEditMeshToTangent;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+/* seems weak but only used on quads */
+static const BMLoop *bm_loop_at_face_index(const BMFace *f, int vert_index)
+{
+ const BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ while (vert_index--) {
+ l = l->next;
+ }
+ return l;
+}
+#endif
+
+static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
+{
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ return pMesh->num_face_as_quad_map;
+#else
+ return pMesh->numTessFaces;
+#endif
+}
+
+static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
+{
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+ if (pMesh->face_as_quad_map) {
+ const BMLoop **lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ return 4;
+ }
+ }
+ return 3;
+#else
+ UNUSED_VARS(pContext, face_num);
+ return 3;
+#endif
+}
+
+static void emdm_ts_GetPosition(
+ const SMikkTSpaceContext *pContext, float r_co[3],
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+ const float *co;
+
+finally:
+ co = l->v->co;
+ copy_v3_v3(r_co, co);
+}
+
+static void emdm_ts_GetTextureCoordinate(
+ const SMikkTSpaceContext *pContext, float r_uv[2],
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+finally:
+ if (pMesh->cd_loop_uv_offset != -1) {
+ const float *uv = BM_ELEM_CD_GET_VOID_P(l, pMesh->cd_loop_uv_offset);
+ copy_v2_v2(r_uv, uv);
+ }
+ else {
+ const float *orco = pMesh->orco[BM_elem_index_get(l->v)];
+ map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
+ }
+}
+
+static void emdm_ts_GetNormal(
+ const SMikkTSpaceContext *pContext, float r_no[3],
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+finally:
+ if (pMesh->precomputedLoopNormals) {
+ copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(l)]);
+ }
+ else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
+ if (pMesh->precomputedFaceNormals) {
+ copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(l->f)]);
+ }
+ else {
+ copy_v3_v3(r_no, l->f->no);
+ }
+ }
+ else {
+ copy_v3_v3(r_no, l->v->no);
+ }
+}
+
+static void emdm_ts_SetTSpace(
+ const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign,
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+ float *pRes;
+
+finally:
+ pRes = pMesh->tangent[BM_elem_index_get(l)];
+ copy_v3_v3(pRes, fvTangent);
+ pRes[3] = fSign;
+}
+
+static void emDM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ struct SGLSLEditMeshToTangent *mesh2tangent = taskdata;
+ /* new computation method */
+ {
+ SMikkTSpaceContext sContext = {NULL};
+ SMikkTSpaceInterface sInterface = {NULL};
+ sContext.m_pUserData = mesh2tangent;
+ sContext.m_pInterface = &sInterface;
+ sInterface.m_getNumFaces = emdm_ts_GetNumFaces;
+ sInterface.m_getNumVerticesOfFace = emdm_ts_GetNumVertsOfFace;
+ sInterface.m_getPosition = emdm_ts_GetPosition;
+ sInterface.m_getTexCoord = emdm_ts_GetTextureCoordinate;
+ sInterface.m_getNormal = emdm_ts_GetNormal;
+ sInterface.m_setTSpaceBasic = emdm_ts_SetTSpace;
+ /* 0 if failed */
+ genTangSpaceDefault(&sContext);
+ }
+}
+
+/**
+ * \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data.
+ *
+ * \note This function is not so normal, its using `bm->ldata` as input, but output's to `dm->loopData`.
+ * This is done because #CD_TANGENT is cache data used only for drawing.
+ */
+void BKE_editmesh_loop_tangent_calc(
+ BMEditMesh *em, bool calc_active_tangent,
+ const char (*tangent_names)[MAX_NAME], int tangent_names_len,
+ const float (*poly_normals)[3],
+ const float (*loop_normals)[3],
+ const float (*vert_orco)[3],
+ /* result */
+ CustomData *loopdata_out,
+ const uint loopdata_out_len,
+ char *tangent_mask_curr_p)
+{
+ BMesh *bm = em->bm;
+
+ BLI_assert(CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV) != 0);
+
+ int act_uv_n = -1;
+ int ren_uv_n = -1;
+ bool calc_act = false;
+ bool calc_ren = false;
+ char act_uv_name[MAX_NAME];
+ char ren_uv_name[MAX_NAME];
+ char tangent_mask = 0;
+ char tangent_mask_curr = *tangent_mask_curr_p;
+
+ BKE_mesh_calc_loop_tangent_step_0(
+ &bm->ldata, calc_active_tangent, tangent_names, tangent_names_len,
+ &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
+
+ if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
+ for (int i = 0; i < tangent_names_len; i++)
+ if (tangent_names[i][0])
+ BKE_mesh_add_loop_tangent_named_layer_for_uv(&bm->ldata, loopdata_out, loopdata_out_len, tangent_names[i]);
+ if (calc_act && act_uv_name[0])
+ BKE_mesh_add_loop_tangent_named_layer_for_uv(&bm->ldata, loopdata_out, loopdata_out_len, act_uv_name);
+ if (calc_ren && ren_uv_name[0])
+ BKE_mesh_add_loop_tangent_named_layer_for_uv(&bm->ldata, loopdata_out, loopdata_out_len, ren_uv_name);
+ int totface = em->tottri;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ int num_face_as_quad_map;
+ int *face_as_quad_map = NULL;
+
+ /* map faces to quads */
+ if (em->tottri != bm->totface) {
+ /* over alloc, since we dont know how many ngon or quads we have */
+
+ /* map fake face index to looptri */
+ face_as_quad_map = MEM_mallocN(sizeof(int) * totface, __func__);
+ int i, j;
+ for (i = 0, j = 0; j < totface; i++, j++) {
+ face_as_quad_map[i] = j;
+ /* step over all quads */
+ if (em->looptris[j][0]->f->len == 4) {
+ j++; /* skips the nest looptri */
+ }
+ }
+ num_face_as_quad_map = i;
+ }
+ else {
+ num_face_as_quad_map = totface;
+ }
+#endif
+ /* Calculation */
+ {
+ TaskScheduler *scheduler = BLI_task_scheduler_get();
+ TaskPool *task_pool;
+ task_pool = BLI_task_pool_create(scheduler, NULL);
+
+ tangent_mask_curr = 0;
+ /* Calculate tangent layers */
+ SGLSLEditMeshToTangent data_array[MAX_MTFACE];
+ int index = 0;
+ int n = 0;
+ CustomData_update_typemap(loopdata_out);
+ const int tangent_layer_num = CustomData_number_of_layers(loopdata_out, CD_TANGENT);
+ for (n = 0; n < tangent_layer_num; n++) {
+ index = CustomData_get_layer_index_n(loopdata_out, CD_TANGENT, n);
+ BLI_assert(n < MAX_MTFACE);
+ SGLSLEditMeshToTangent *mesh2tangent = &data_array[n];
+ mesh2tangent->numTessFaces = em->tottri;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ mesh2tangent->face_as_quad_map = face_as_quad_map;
+ mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
+#endif
+ mesh2tangent->precomputedFaceNormals = poly_normals; /* dm->getPolyDataArray(dm, CD_NORMAL) */
+ /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
+ * have to check this is valid...
+ */
+ mesh2tangent->precomputedLoopNormals = loop_normals;
+ mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, n);
+
+ /* needed for indexing loop-tangents */
+ int htype_index = BM_LOOP;
+ if (mesh2tangent->cd_loop_uv_offset == -1) {
+ mesh2tangent->orco = vert_orco;
+ if (!mesh2tangent->orco)
+ continue;
+ /* needed for orco lookups */
+ htype_index |= BM_VERT;
+ }
+ if (mesh2tangent->precomputedFaceNormals) {
+ /* needed for face normal lookups */
+ htype_index |= BM_FACE;
+ }
+ BM_mesh_elem_index_ensure(bm, htype_index);
+
+ mesh2tangent->looptris = (const BMLoop *(*)[3])em->looptris;
+ mesh2tangent->tangent = loopdata_out->layers[index].data;
+
+ /* Fill the resulting tangent_mask */
+ int uv_ind = CustomData_get_named_layer_index(
+ &bm->ldata, CD_MLOOPUV, loopdata_out->layers[index].name);
+ int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
+ BLI_assert(uv_ind != -1 && uv_start != -1);
+ BLI_assert(uv_ind - uv_start < MAX_MTFACE);
+ tangent_mask_curr |= 1 << (uv_ind - uv_start);
+ BLI_task_pool_push(task_pool, emDM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
+ }
+
+ BLI_assert(tangent_mask_curr == tangent_mask);
+ BLI_task_pool_work_and_wait(task_pool);
+ BLI_task_pool_free(task_pool);
+ }
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (face_as_quad_map) {
+ MEM_freeN(face_as_quad_map);
+ }
+#undef USE_LOOPTRI_DETECT_QUADS
+#endif
+ }
+
+ *tangent_mask_curr_p = tangent_mask_curr;
+
+ /* Update active layer index */
+ int uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n);
+ int tan_index = CustomData_get_named_layer_index(loopdata_out, CD_TANGENT, bm->ldata.layers[uv_index].name);
+ CustomData_set_layer_active_index(loopdata_out, CD_TANGENT, tan_index);
+
+ /* Update render layer index */
+ uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n);
+ tan_index = CustomData_get_named_layer_index(loopdata_out, CD_TANGENT, bm->ldata.layers[uv_index].name);
+ CustomData_set_layer_render_index(loopdata_out, CD_TANGENT, tan_index);
+}
+
+/** \} */ \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 4eee24b378f..4b5548c48d4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -64,6 +64,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -209,6 +210,7 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
EffectorWeights *weights, bool for_simulation)
{
+ SceneLayer *sl = BKE_scene_layer_context_active(scene); /* Can't get sl from the calling modifiers yet */
Base *base;
unsigned int layer= ob_src->lay;
ListBase *effectors = NULL;
@@ -231,17 +233,15 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
}
}
else {
- for (base = scene->base.first; base; base= base->next) {
- if ( (base->lay & layer) ) {
- if ( base->object->pd && base->object->pd->forcefield )
- add_object_to_effectors(&effectors, scene, weights, base->object, ob_src, for_simulation);
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if ( base->object->pd && base->object->pd->forcefield )
+ add_object_to_effectors(&effectors, scene, weights, base->object, ob_src, for_simulation);
- if ( base->object->particlesystem.first ) {
- ParticleSystem *psys= base->object->particlesystem.first;
+ if ( base->object->particlesystem.first ) {
+ ParticleSystem *psys= base->object->particlesystem.first;
- for ( ; psys; psys=psys->next )
- add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src, for_simulation);
- }
+ for ( ; psys; psys=psys->next )
+ add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src, for_simulation);
}
}
}
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 414802dd250..f969c932333 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -45,8 +45,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_icons.h"
@@ -132,18 +130,11 @@ static bool group_object_add_internal(Group *group, Object *ob)
return true;
}
-bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base)
+bool BKE_group_object_add(Group *group, Object *object)
{
if (group_object_add_internal(group, object)) {
if ((object->flag & OB_FROMGROUP) == 0) {
-
- if (scene && base == NULL)
- base = BKE_scene_base_find(scene, object);
-
object->flag |= OB_FROMGROUP;
-
- if (base)
- base->flag |= OB_FROMGROUP;
}
return true;
}
@@ -210,18 +201,12 @@ bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
return group_object_cyclic_check_internal(object, group);
}
-bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
+bool BKE_group_object_unlink(Group *group, Object *object)
{
if (group_object_unlink_internal(group, object)) {
/* object can be NULL */
if (object && BKE_group_object_find(NULL, object) == NULL) {
- if (scene && base == NULL)
- base = BKE_scene_base_find(scene, object);
-
object->flag &= ~OB_FROMGROUP;
-
- if (base)
- base->flag &= ~OB_FROMGROUP;
}
return true;
}
@@ -329,7 +314,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
* you can draw everything, leaves tags in objects to signal it needs further updating */
/* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */
-void BKE_group_handle_recalc_and_update(EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
+void BKE_group_handle_recalc_and_update(struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
{
GroupObject *go;
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 7669c4ba112..70cf0d5a445 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -42,6 +42,7 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "DNA_brush_types.h"
@@ -252,6 +253,7 @@ PreviewImage **BKE_previewimg_id_get_p(ID *id)
ID_PRV_CASE(ID_OB, Object);
ID_PRV_CASE(ID_GR, Group);
ID_PRV_CASE(ID_SCE, Scene);
+ ID_PRV_CASE(ID_SCR, bScreen);
#undef ID_PRV_CASE
}
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index e98181be444..a3bd15252cb 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -474,6 +474,7 @@ static IDProperty *IDP_CopyGroup(const IDProperty *prop)
BLI_assert(prop->type == IDP_GROUP);
newp = idp_generic_copy(prop);
newp->len = prop->len;
+ newp->subtype = prop->subtype;
for (link = prop->data.group.first; link; link = link->next) {
BLI_addtail(&newp->data.group, IDP_CopyProperty(link));
@@ -600,6 +601,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
/**
* If a property is missing in \a dest, add it.
+ * Do it recursively.
*/
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite)
{
@@ -610,13 +612,29 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
if (do_overwrite) {
for (prop = src->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_GROUP) {
+ IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
+
+ if (prop_exist != NULL) {
+ IDP_MergeGroup(prop_exist, prop, do_overwrite);
+ continue;
+ }
+ }
+
IDProperty *copy = IDP_CopyProperty(prop);
IDP_ReplaceInGroup(dest, copy);
}
}
else {
for (prop = src->data.group.first; prop; prop = prop->next) {
- if (IDP_GetPropertyFromGroup(dest, prop->name) == NULL) {
+ IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
+ if (prop_exist != NULL) {
+ if (prop->type == IDP_GROUP) {
+ IDP_MergeGroup(prop_exist, prop, do_overwrite);
+ continue;
+ }
+ }
+ else {
IDProperty *copy = IDP_CopyProperty(prop);
dest->len++;
BLI_addtail(&dest->data.group, copy);
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 54cfae620a1..c03aa0cd155 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -53,7 +53,6 @@
#include "BKE_anim.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_key.h"
@@ -307,6 +306,8 @@ void BKE_lattice_free(Lattice *lt)
{
BKE_animdata_free(&lt->id, false);
+ BKE_lattice_batch_cache_free(lt);
+
MEM_SAFE_FREE(lt->def);
if (lt->dvert) {
BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
@@ -1227,8 +1228,24 @@ void BKE_lattice_translate(Lattice *lt, float offset[3], bool do_keys)
/* **** Depsgraph evaluation **** */
-void BKE_lattice_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_lattice_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx),
Lattice *UNUSED(latt))
{
}
+/* Draw Engine */
+void (*BKE_lattice_batch_cache_dirty_cb)(Lattice *lt, int mode) = NULL;
+void (*BKE_lattice_batch_cache_free_cb)(Lattice *lt) = NULL;
+
+void BKE_lattice_batch_cache_dirty(Lattice *lt, int mode)
+{
+ if (lt->batch_cache) {
+ BKE_lattice_batch_cache_dirty_cb(lt, mode);
+ }
+}
+void BKE_lattice_batch_cache_free(Lattice *lt)
+{
+ if (lt->batch_cache) {
+ BKE_lattice_batch_cache_free_cb(lt);
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
new file mode 100644
index 00000000000..d2fa09fa9e9
--- /dev/null
+++ b/source/blender/blenkernel/intern/layer.c
@@ -0,0 +1,1837 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/layer.c
+ * \ingroup bke
+ */
+
+#include <string.h>
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_string_utils.h"
+#include "BLT_translation.h"
+
+#include "BKE_collection.h"
+#include "BKE_global.h"
+#include "BKE_idprop.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+
+#include "DNA_ID.h"
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
+
+#include "DRW_engine.h"
+
+#include "MEM_guardedalloc.h"
+
+#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
+
+/* prototype */
+struct EngineSettingsCB_Type;
+static void layer_collection_free(SceneLayer *sl, LayerCollection *lc);
+static LayerCollection *layer_collection_add(SceneLayer *sl, LayerCollection *parent, SceneCollection *sc);
+static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc);
+static IDProperty *collection_engine_settings_create(struct EngineSettingsCB_Type *ces_type, const bool populate);
+static IDProperty *collection_engine_get(IDProperty *root, const int type, const char *engine_name);
+static void collection_engine_settings_init(IDProperty *root, const bool populate);
+static void layer_engine_settings_init(IDProperty *root, const bool populate);
+static void object_bases_Iterator_next(BLI_Iterator *iter, const int flag);
+
+/* RenderLayer */
+
+/**
+ * Returns the SceneLayer to be used for rendering
+ * Most of the time BKE_scene_layer_context_active should be used instead
+ */
+SceneLayer *BKE_scene_layer_render_active(const Scene *scene)
+{
+ SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer);
+ BLI_assert(sl);
+ return sl;
+}
+
+/**
+ * Returns the SceneLayer to be used for drawing, outliner, and
+ * other context related areas.
+ */
+SceneLayer *BKE_scene_layer_context_active(const Scene *scene)
+{
+ /* waiting for workspace to get the layer from context*/
+ TODO_LAYER_CONTEXT;
+ return BKE_scene_layer_render_active(scene);
+}
+
+/**
+ * Add a new renderlayer
+ * by default, a renderlayer has the master collection
+ */
+SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
+{
+ if (!name) {
+ name = DATA_("Render Layer");
+ }
+
+ IDPropertyTemplate val = {0};
+ SceneLayer *sl = MEM_callocN(sizeof(SceneLayer), "Scene Layer");
+ sl->flag |= SCENE_LAYER_RENDER;
+
+ sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ layer_engine_settings_init(sl->properties, false);
+
+ BLI_addtail(&scene->render_layers, sl);
+
+ /* unique name */
+ BLI_strncpy_utf8(sl->name, name, sizeof(sl->name));
+ BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
+
+ SceneCollection *sc = BKE_collection_master(scene);
+ layer_collection_add(sl, NULL, sc);
+
+ return sl;
+}
+
+bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl)
+{
+ const int act = BLI_findindex(&scene->render_layers, sl);
+
+ if (act == -1) {
+ return false;
+ }
+ else if ( (scene->render_layers.first == scene->render_layers.last) &&
+ (scene->render_layers.first == sl))
+ {
+ /* ensure 1 layer is kept */
+ return false;
+ }
+
+ BLI_remlink(&scene->render_layers, sl);
+
+ BKE_scene_layer_free(sl);
+ MEM_freeN(sl);
+
+ scene->active_layer = 0;
+ /* TODO WORKSPACE: set active_layer to 0 */
+
+ for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
+ if (sce->nodetree) {
+ BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Free (or release) any data used by this SceneLayer (does not free the SceneLayer itself).
+ */
+void BKE_scene_layer_free(SceneLayer *sl)
+{
+ sl->basact = NULL;
+
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (base->collection_properties) {
+ IDP_FreeProperty(base->collection_properties);
+ MEM_freeN(base->collection_properties);
+ }
+ }
+ BLI_freelistN(&sl->object_bases);
+
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ layer_collection_free(NULL, lc);
+ }
+ BLI_freelistN(&sl->layer_collections);
+
+ if (sl->properties) {
+ IDP_FreeProperty(sl->properties);
+ MEM_freeN(sl->properties);
+ }
+
+ if (sl->properties_evaluated) {
+ IDP_FreeProperty(sl->properties_evaluated);
+ MEM_freeN(sl->properties_evaluated);
+ }
+
+ for (SceneLayerEngineData *sled = sl->drawdata.first; sled; sled = sled->next) {
+ if (sled->storage) {
+ if (sled->free) {
+ sled->free(sled->storage);
+ }
+ MEM_freeN(sled->storage);
+ }
+ }
+ BLI_freelistN(&sl->drawdata);
+
+ MEM_SAFE_FREE(sl->stats);
+}
+
+/**
+ * Set the render engine of a renderlayer
+ */
+void BKE_scene_layer_engine_set(SceneLayer *sl, const char *engine)
+{
+ BLI_strncpy_utf8(sl->engine, engine, sizeof(sl->engine));
+}
+
+/**
+ * Tag all the selected objects of a renderlayer
+ */
+void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag)
+{
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ base->object->flag |= tag;
+ }
+ else {
+ base->object->flag &= ~tag;
+ }
+ }
+}
+
+static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
+{
+ for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
+ if (lcn == lc) {
+ return true;
+ }
+ if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Find the SceneLayer a LayerCollection belongs to
+ */
+SceneLayer *BKE_scene_layer_find_from_collection(const Scene *scene, LayerCollection *lc)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
+ return sl;
+ }
+ }
+ return NULL;
+}
+
+/* Base */
+
+Base *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
+{
+ return BLI_findptr(&sl->object_bases, ob, offsetof(Base, object));
+}
+
+void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
+{
+ Base *base;
+
+ for (base = sl->object_bases.first; base; base = base->next) {
+ base->flag &= ~BASE_SELECTED;
+ }
+}
+
+void BKE_scene_layer_base_select(struct SceneLayer *sl, Base *selbase)
+{
+ sl->basact = selbase;
+ if ((selbase->flag & BASE_SELECTABLED) != 0) {
+ selbase->flag |= BASE_SELECTED;
+ }
+}
+
+static void scene_layer_object_base_unref(SceneLayer *sl, Base *base)
+{
+ base->refcount--;
+
+ /* It only exists in the RenderLayer */
+ if (base->refcount == 0) {
+ if (sl->basact == base) {
+ sl->basact = NULL;
+ }
+
+ if (base->collection_properties) {
+ IDP_FreeProperty(base->collection_properties);
+ MEM_freeN(base->collection_properties);
+ }
+
+ BLI_remlink(&sl->object_bases, base);
+ MEM_freeN(base);
+ }
+}
+
+/**
+ * Return the base if existent, or create it if necessary
+ * Always bump the refcount
+ */
+static Base *object_base_add(SceneLayer *sl, Object *ob)
+{
+ Base *base;
+ base = BKE_scene_layer_base_find(sl, ob);
+
+ if (base == NULL) {
+ base = MEM_callocN(sizeof(Base), "Object Base");
+
+ /* Do not bump user count, leave it for SceneCollections. */
+ base->object = ob;
+ BLI_addtail(&sl->object_bases, base);
+
+ IDPropertyTemplate val = {0};
+ base->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ }
+
+ base->refcount++;
+ return base;
+}
+
+/* LayerCollection */
+
+/**
+ * When freeing the entire SceneLayer at once we don't bother with unref
+ * otherwise SceneLayer is passed to keep the syncing of the LayerCollection tree
+ */
+static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
+{
+ if (sl) {
+ for (LinkData *link = lc->object_bases.first; link; link = link->next) {
+ scene_layer_object_base_unref(sl, link->data);
+ }
+ }
+
+ BLI_freelistN(&lc->object_bases);
+ BLI_freelistN(&lc->overrides);
+
+ if (lc->properties) {
+ IDP_FreeProperty(lc->properties);
+ MEM_freeN(lc->properties);
+ }
+
+ if (lc->properties_evaluated) {
+ IDP_FreeProperty(lc->properties_evaluated);
+ MEM_freeN(lc->properties_evaluated);
+ }
+
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ layer_collection_free(sl, nlc);
+ }
+
+ BLI_freelistN(&lc->layer_collections);
+}
+
+/**
+ * Free (or release) LayerCollection from SceneLayer
+ * (does not free the LayerCollection itself).
+ */
+void BKE_layer_collection_free(SceneLayer *sl, LayerCollection *lc)
+{
+ layer_collection_free(sl, lc);
+}
+
+/* LayerCollection */
+
+/**
+ * Recursively get the collection for a given index
+ */
+static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (*i == number) {
+ return lc;
+ }
+
+ (*i)++;
+
+ LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
+ if (lc_nested) {
+ return lc_nested;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Get the active collection
+ */
+LayerCollection *BKE_layer_collection_get_active(SceneLayer *sl)
+{
+ int i = 0;
+ return collection_from_index(&sl->layer_collections, sl->active_collection, &i);
+}
+
+
+/**
+ * Return layer collection to add new object(s).
+ * Create one if none exists.
+ */
+LayerCollection *BKE_layer_collection_get_active_ensure(Scene *scene, SceneLayer *sl)
+{
+ LayerCollection *lc = BKE_layer_collection_get_active(sl);
+
+ if (lc == NULL) {
+ BLI_assert(BLI_listbase_is_empty(&sl->layer_collections));
+ /* When there is no collection linked to this SceneLayer, create one. */
+ SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
+ lc = BKE_collection_link(sl, sc);
+ }
+
+ return lc;
+}
+
+/**
+ * Recursively get the count of collections
+ */
+static int collection_count(ListBase *lb)
+{
+ int i = 0;
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ i += collection_count(&lc->layer_collections) + 1;
+ }
+ return i;
+}
+
+/**
+ * Get the total number of collections
+ * (including all the nested collections)
+ */
+int BKE_layer_collection_count(SceneLayer *sl)
+{
+ return collection_count(&sl->layer_collections);
+}
+
+/**
+ * Recursively get the index for a given collection
+ */
+static int index_from_collection(ListBase *lb, const LayerCollection *lc, int *i)
+{
+ for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
+ if (lcol == lc) {
+ return *i;
+ }
+
+ (*i)++;
+
+ int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
+ if (i_nested != -1) {
+ return i_nested;
+ }
+ }
+ return -1;
+}
+
+/**
+ * Return -1 if not found
+ */
+int BKE_layer_collection_findindex(SceneLayer *sl, const LayerCollection *lc)
+{
+ int i = 0;
+ return index_from_collection(&sl->layer_collections, lc, &i);
+}
+
+/**
+ * Lookup the listbase that contains \a lc.
+ */
+static ListBase *layer_collection_listbase_find(ListBase *lb, LayerCollection *lc)
+{
+ for (LayerCollection *lc_iter = lb->first; lc_iter; lc_iter = lc_iter->next) {
+ if (lc_iter == lc) {
+ return lb;
+ }
+
+ ListBase *lb_child_result;
+ if ((lb_child_result = layer_collection_listbase_find(&lc_iter->layer_collections, lc))) {
+ return lb_child_result;
+ }
+ }
+
+ return NULL;
+}
+
+#if 0
+/**
+ * Lookup the listbase that contains \a sc.
+ */
+static ListBase *scene_collection_listbase_find(ListBase *lb, SceneCollection *sc)
+{
+ for (SceneCollection *sc_iter = lb->first; sc_iter; sc_iter = sc_iter->next) {
+ if (sc_iter == sc) {
+ return lb;
+ }
+
+ ListBase *lb_child_result;
+ if ((lb_child_result = scene_collection_listbase_find(&sc_iter->scene_collections, sc))) {
+ return lb_child_result;
+ }
+ }
+
+ return NULL;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+/* Outliner drag and drop */
+
+/**
+ * Nest a LayerCollection into another one
+ * Both collections must be from the same SceneLayer, return true if succeded.
+ *
+ * The LayerCollection will effectively be moved into the
+ * new (nested) position. So all the settings, overrides, ... go with it, and
+ * if the collection was directly linked to the SceneLayer it's then unlinked.
+ *
+ * For the other SceneLayers we simply resync the tree, without changing directly
+ * linked collections (even if they link to the same SceneCollection)
+ *
+ * \param lc_src LayerCollection to nest into \a lc_dst
+ * \param lc_dst LayerCollection to have \a lc_src inserted into
+ */
+
+static void layer_collection_swap(
+ SceneLayer *sl, ListBase *lb_a, ListBase *lb_b,
+ LayerCollection *lc_a, LayerCollection *lc_b)
+{
+ if (lb_a == NULL) {
+ lb_a = layer_collection_listbase_find(&sl->layer_collections, lc_a);
+ }
+
+ if (lb_b == NULL) {
+ lb_b = layer_collection_listbase_find(&sl->layer_collections, lc_b);
+ }
+
+ BLI_assert(lb_a);
+ BLI_assert(lb_b);
+
+ BLI_listbases_swaplinks(lb_a, lb_b, lc_a, lc_b);
+}
+
+/**
+ * Move \a lc_src into \a lc_dst. Both have to be stored in \a sl.
+ * If \a lc_src is directly linked to the SceneLayer it's unlinked
+ */
+bool BKE_layer_collection_move_into(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc_src);
+ bool is_directly_linked = false;
+
+ if ((!sl) || (sl != BKE_scene_layer_find_from_collection(scene, lc_dst))) {
+ return false;
+ }
+
+ /* We can't nest the collection into itself */
+ if (lc_src->scene_collection == lc_dst->scene_collection) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (lc_dst->layer_collections.last == lc_src) {
+ return false;
+ }
+
+ /* Collection is already where we want it to be in the scene tree
+ * but we want to swap it in the layer tree still */
+ if (lc_dst->scene_collection->scene_collections.last == lc_src->scene_collection) {
+ LayerCollection *lc_swap = lc_dst->layer_collections.last;
+ layer_collection_swap(sl, &lc_dst->layer_collections, NULL, lc_dst->layer_collections.last, lc_src);
+
+ if (BLI_findindex(&sl->layer_collections, lc_swap) != -1) {
+ BKE_collection_unlink(sl, lc_swap);
+ }
+ return true;
+ }
+ else {
+ LayerCollection *lc_temp;
+ is_directly_linked = BLI_findindex(&sl->layer_collections, lc_src) != -1;
+
+ if (!is_directly_linked) {
+ /* lc_src will be invalid after BKE_collection_move_into!
+ * so we swap it with lc_temp to preserve its settings */
+ lc_temp = BKE_collection_link(sl, lc_src->scene_collection);
+ layer_collection_swap(sl, &sl->layer_collections, NULL, lc_temp, lc_src);
+ }
+
+ if (!BKE_collection_move_into(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!is_directly_linked) {
+ /* Swap back and remove */
+ layer_collection_swap(sl, NULL, NULL, lc_temp, lc_src);
+ BKE_collection_unlink(sl, lc_temp);
+ }
+ return false;
+ }
+ }
+
+ LayerCollection *lc_new = BLI_findptr(&lc_dst->layer_collections, lc_src->scene_collection, offsetof(LayerCollection, scene_collection));
+ BLI_assert(lc_new);
+ layer_collection_swap(sl, &lc_dst->layer_collections, NULL, lc_new, lc_src);
+
+ /* If it's directly linked, unlink it after the swap */
+ if (BLI_findindex(&sl->layer_collections, lc_new) != -1) {
+ BKE_collection_unlink(sl, lc_new);
+ }
+
+ return true;
+}
+
+/**
+ * Move \a lc_src above \a lc_dst. Both have to be stored in \a sl.
+ * If \a lc_src is directly linked to the SceneLayer it's unlinked
+ */
+bool BKE_layer_collection_move_above(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc_src);
+ const bool is_directly_linked_src = BLI_findindex(&sl->layer_collections, lc_src) != -1;
+ const bool is_directly_linked_dst = BLI_findindex(&sl->layer_collections, lc_dst) != -1;
+
+ if ((!sl) || (sl != BKE_scene_layer_find_from_collection(scene, lc_dst))) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (lc_dst->prev == lc_src) {
+ return false;
+ }
+
+ /* Collection is already where we want it to be in the scene tree
+ * but we want to swap it in the layer tree still */
+ if (lc_dst->prev && lc_dst->prev->scene_collection == lc_src->scene_collection) {
+ LayerCollection *lc_swap = lc_dst->prev;
+ layer_collection_swap(sl, NULL, NULL, lc_dst->prev, lc_src);
+
+ if (BLI_findindex(&sl->layer_collections, lc_swap) != -1) {
+ BKE_collection_unlink(sl, lc_swap);
+ }
+ return true;
+ }
+ /* We don't allow to move above/below a directly linked collection
+ * unless the source collection is also directly linked */
+ else if (is_directly_linked_dst) {
+ /* Both directly linked to the SceneLayer, just need to swap */
+ if (is_directly_linked_src) {
+ BLI_remlink(&sl->layer_collections, lc_src);
+ BLI_insertlinkbefore(&sl->layer_collections, lc_dst, lc_src);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ LayerCollection *lc_temp;
+
+ if (!is_directly_linked_src) {
+ /* lc_src will be invalid after BKE_collection_move_into!
+ * so we swap it with lc_temp to preserve its settings */
+ lc_temp = BKE_collection_link(sl, lc_src->scene_collection);
+ layer_collection_swap(sl, &sl->layer_collections, NULL, lc_temp, lc_src);
+ }
+
+ if (!BKE_collection_move_above(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!is_directly_linked_src) {
+ /* Swap back and remove */
+ layer_collection_swap(sl, NULL, NULL, lc_temp, lc_src);
+ BKE_collection_unlink(sl, lc_temp);
+ }
+ return false;
+ }
+ }
+
+ LayerCollection *lc_new = lc_dst->prev;
+ BLI_assert(lc_new);
+ layer_collection_swap(sl, NULL, NULL, lc_new, lc_src);
+
+ /* If it's directly linked, unlink it after the swap */
+ if (BLI_findindex(&sl->layer_collections, lc_new) != -1) {
+ BKE_collection_unlink(sl, lc_new);
+ }
+
+ return true;
+}
+
+/**
+ * Move \a lc_src below \a lc_dst. Both have to be stored in \a sl.
+ * If \a lc_src is directly linked to the SceneLayer it's unlinked
+ */
+bool BKE_layer_collection_move_below(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc_src);
+ const bool is_directly_linked_src = BLI_findindex(&sl->layer_collections, lc_src) != -1;
+ const bool is_directly_linked_dst = BLI_findindex(&sl->layer_collections, lc_dst) != -1;
+
+ if ((!sl) || (sl != BKE_scene_layer_find_from_collection(scene, lc_dst))) {
+ return false;
+ }
+
+ /* Collection is already where we wanted it to be */
+ if (lc_dst->next == lc_src) {
+ return false;
+ }
+
+ /* Collection is already where we want it to be in the scene tree
+ * but we want to swap it in the layer tree still */
+ if (lc_dst->next && lc_dst->next->scene_collection == lc_src->scene_collection) {
+ LayerCollection *lc_swap = lc_dst->next;
+ layer_collection_swap(sl, NULL, NULL, lc_dst->next, lc_src);
+
+ if (BLI_findindex(&sl->layer_collections, lc_swap) != -1) {
+ BKE_collection_unlink(sl, lc_swap);
+ }
+ return true;
+ }
+ /* We don't allow to move above/below a directly linked collection
+ * unless the source collection is also directly linked */
+ else if (is_directly_linked_dst) {
+ /* Both directly linked to the SceneLayer, just need to swap */
+ if (is_directly_linked_src) {
+ BLI_remlink(&sl->layer_collections, lc_src);
+ BLI_insertlinkafter(&sl->layer_collections, lc_dst, lc_src);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ LayerCollection *lc_temp;
+
+ if (!is_directly_linked_src) {
+ /* lc_src will be invalid after BKE_collection_move_into!
+ * so we swap it with lc_temp to preserve its settings */
+ lc_temp = BKE_collection_link(sl, lc_src->scene_collection);
+ layer_collection_swap(sl, &sl->layer_collections, NULL, lc_temp, lc_src);
+ }
+
+ if (!BKE_collection_move_below(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!is_directly_linked_src) {
+ /* Swap back and remove */
+ layer_collection_swap(sl, NULL, NULL, lc_temp, lc_src);
+ BKE_collection_unlink(sl, lc_temp);
+ }
+ return false;
+ }
+ }
+
+ LayerCollection *lc_new = lc_dst->next;
+ BLI_assert(lc_new);
+ layer_collection_swap(sl, NULL, NULL, lc_new, lc_src);
+
+ /* If it's directly linked, unlink it after the swap */
+ if (BLI_findindex(&sl->layer_collections, lc_new) != -1) {
+ BKE_collection_unlink(sl, lc_new);
+ }
+
+ return true;
+}
+
+static bool layer_collection_resync(SceneLayer *sl, LayerCollection *lc, const SceneCollection *sc)
+{
+ if (lc->scene_collection == sc) {
+ ListBase collections = {NULL};
+ BLI_movelisttolist(&collections, &lc->layer_collections);
+
+ for (SceneCollection *sc_nested = sc->scene_collections.first; sc_nested; sc_nested = sc_nested->next) {
+ LayerCollection *lc_nested = BLI_findptr(&collections, sc_nested, offsetof(LayerCollection, scene_collection));
+ if (lc_nested) {
+ BLI_remlink(&collections, lc_nested);
+ BLI_addtail(&lc->layer_collections, lc_nested);
+ }
+ else {
+ layer_collection_add(sl, lc, sc_nested);
+ }
+ }
+
+ for (LayerCollection *lc_nested = collections.first; lc_nested; lc_nested = lc_nested->next) {
+ layer_collection_free(sl, lc_nested);
+ }
+ BLI_freelistN(&collections);
+
+ BLI_assert(BLI_listbase_count(&lc->layer_collections) ==
+ BLI_listbase_count(&sc->scene_collections));
+
+ return true;
+ }
+
+ for (LayerCollection *lc_nested = lc->layer_collections.first; lc_nested; lc_nested = lc_nested->next) {
+ if (layer_collection_resync(sl, lc_nested, sc)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Update the scene layers so that any LayerCollection that points
+ * to \a sc is re-synced again
+ */
+void BKE_layer_collection_resync(const Scene *scene, const SceneCollection *sc)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ layer_collection_resync(sl, lc, sc);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+/**
+ * Link a collection to a renderlayer
+ * The collection needs to be created separately
+ */
+LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
+{
+ LayerCollection *lc = layer_collection_add(sl, NULL, sc);
+ sl->active_collection = BKE_layer_collection_findindex(sl, lc);
+ return lc;
+}
+
+/**
+ * Unlink a collection base from a renderlayer
+ * The corresponding collection is not removed from the master collection
+ */
+void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc)
+{
+ BKE_layer_collection_free(sl, lc);
+ BLI_remlink(&sl->layer_collections, lc);
+ MEM_freeN(lc);
+ sl->active_collection = 0;
+}
+
+static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Object *ob)
+{
+ Base *base = object_base_add(sl, ob);
+
+ /* Only add an object once - prevent SceneCollection->objects and
+ * SceneCollection->filter_objects to add the same object. */
+
+ if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data))) {
+ return;
+ }
+
+ bool is_visible = (lc->flag & COLLECTION_VISIBLE) != 0;
+ bool is_selectable = is_visible && ((lc->flag & COLLECTION_SELECTABLE) != 0);
+
+ if (is_visible) {
+ base->flag |= BASE_VISIBLED;
+ }
+
+ if (is_selectable) {
+ base->flag |= BASE_SELECTABLED;
+ }
+
+ BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
+}
+
+static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob)
+{
+ Base *base;
+ base = BKE_scene_layer_base_find(sl, ob);
+
+ LinkData *link = BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data));
+ BLI_remlink(&lc->object_bases, link);
+ MEM_freeN(link);
+
+ scene_layer_object_base_unref(sl, base);
+}
+
+static void layer_collection_objects_populate(SceneLayer *sl, LayerCollection *lc, ListBase *objects)
+{
+ for (LinkData *link = objects->first; link; link = link->next) {
+ layer_collection_object_add(sl, lc, link->data);
+ }
+}
+
+static void layer_collection_populate(SceneLayer *sl, LayerCollection *lc, SceneCollection *sc)
+{
+ layer_collection_objects_populate(sl, lc, &sc->objects);
+ layer_collection_objects_populate(sl, lc, &sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ layer_collection_add(sl, lc, nsc);
+ }
+}
+
+static LayerCollection *layer_collection_add(SceneLayer *sl, LayerCollection *parent, SceneCollection *sc)
+{
+ IDPropertyTemplate val = {0};
+ LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
+
+ lc->scene_collection = sc;
+ lc->flag = COLLECTION_VISIBLE | COLLECTION_SELECTABLE;
+
+ lc->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ collection_engine_settings_init(lc->properties, false);
+
+ if (parent != NULL) {
+ BLI_addtail(&parent->layer_collections, lc);
+ }
+ else {
+ BLI_addtail(&sl->layer_collections, lc);
+ }
+
+ layer_collection_populate(sl, lc, sc);
+
+ return lc;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/**
+ * See if render layer has the scene collection linked directly, or indirectly (nested)
+ */
+bool BKE_scene_layer_has_collection(SceneLayer *sl, const SceneCollection *sc)
+{
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ if (find_layer_collection_by_scene_collection(lc, sc) != NULL) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * See if the object is in any of the scene layers of the scene
+ */
+bool BKE_scene_has_object(Scene *scene, Object *ob)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+ if (base) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/* ---------------------------------------------------------------------- */
+/* Syncing */
+
+static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc)
+{
+ if (lc->scene_collection == sc) {
+ return lc;
+ }
+
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ LayerCollection *found = find_layer_collection_by_scene_collection(nlc, sc);
+ if (found) {
+ return found;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Add a new LayerCollection for all the SceneLayers that have sc_parent
+ */
+void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc_parent, SceneCollection *sc)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
+ if (lc_parent) {
+ layer_collection_add(sl, lc_parent, sc);
+ }
+ }
+ }
+}
+
+/**
+ * Add a corresponding ObjectBase to all the equivalent LayerCollection
+ */
+void BKE_layer_sync_object_link(const Scene *scene, SceneCollection *sc, Object *ob)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
+ if (found) {
+ layer_collection_object_add(sl, found, ob);
+ }
+ }
+ }
+}
+
+/**
+ * Remove the equivalent object base to all layers that have this collection
+ * also remove all reference to ob in the filter_objects
+ */
+void BKE_layer_sync_object_unlink(const Scene *scene, SceneCollection *sc, Object *ob)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
+ if (found) {
+ layer_collection_object_remove(sl, found, ob);
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/* Override */
+
+/**
+ * Add a new datablock override
+ */
+void BKE_collection_override_datablock_add(LayerCollection *UNUSED(lc), const char *UNUSED(data_path), ID *UNUSED(id))
+{
+ TODO_LAYER_OVERRIDE;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Engine Settings */
+
+ListBase R_layer_collection_engines_settings_callbacks = {NULL, NULL};
+ListBase R_scene_layer_engines_settings_callbacks = {NULL, NULL};
+
+typedef struct EngineSettingsCB_Type {
+ struct EngineSettingsCB_Type *next, *prev;
+
+ char name[MAX_NAME]; /* engine name */
+
+ EngineSettingsCB callback;
+
+} EngineSettingsCB_Type;
+
+static void create_engine_settings_scene(IDProperty *root, EngineSettingsCB_Type *es_type)
+{
+ if (collection_engine_get(root, COLLECTION_MODE_NONE, es_type->name)) {
+ return;
+ }
+
+ IDProperty *props = collection_engine_settings_create(es_type, true);
+ IDP_AddToGroup(root, props);
+}
+
+static void create_layer_collection_engine_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type)
+{
+ create_engine_settings_scene(scene->collection_properties, es_type);
+}
+
+static void create_scene_layer_engine_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type)
+{
+ create_engine_settings_scene(scene->layer_properties, es_type);
+}
+
+static void create_layer_collection_engine_settings_collection(LayerCollection *lc, EngineSettingsCB_Type *es_type)
+{
+ if (BKE_layer_collection_engine_collection_get(lc, COLLECTION_MODE_NONE, es_type->name)) {
+ return;
+ }
+
+ IDProperty *props = collection_engine_settings_create(es_type, false);
+ IDP_AddToGroup(lc->properties, props);
+
+ for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
+ create_layer_collection_engine_settings_collection(lcn, es_type);
+ }
+}
+
+static void create_layer_collection_engines_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type)
+{
+ /* Populate the scene with the new settings. */
+ create_layer_collection_engine_settings_scene(scene, es_type);
+
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ create_layer_collection_engine_settings_collection(lc, es_type);
+ }
+ }
+}
+
+static void create_scene_layer_engines_settings_scene(Scene *scene, EngineSettingsCB_Type *es_type)
+{
+ /* Populate the scene with the new settings. */
+ create_scene_layer_engine_settings_scene(scene, es_type);
+}
+
+static void create_scene_layer_engines_settings_layer(SceneLayer *sl, EngineSettingsCB_Type *es_type)
+{
+ if (BKE_scene_layer_engine_layer_get(sl, COLLECTION_MODE_NONE, es_type->name)) {
+ return;
+ }
+
+ IDProperty *props = collection_engine_settings_create(es_type, false);
+ IDP_AddToGroup(sl->properties, props);
+}
+
+static EngineSettingsCB_Type *engine_settings_callback_register(const char *engine_name, EngineSettingsCB func, ListBase *lb)
+{
+ EngineSettingsCB_Type *es_type;
+
+ /* Cleanup in case it existed. */
+ es_type = BLI_findstring(lb, engine_name, offsetof(EngineSettingsCB_Type, name));
+
+ if (es_type) {
+ BLI_remlink(lb, es_type);
+ MEM_freeN(es_type);
+ }
+
+ es_type = MEM_callocN(sizeof(EngineSettingsCB_Type), __func__);
+ BLI_strncpy_utf8(es_type->name, engine_name, sizeof(es_type->name));
+ es_type->callback = func;
+ BLI_addtail(lb, es_type);
+
+ return es_type;
+}
+
+void BKE_layer_collection_engine_settings_callback_register(
+ Main *bmain, const char *engine_name, EngineSettingsCB func)
+{
+ EngineSettingsCB_Type *es_type =
+ engine_settings_callback_register(engine_name, func, &R_layer_collection_engines_settings_callbacks);
+
+ if (bmain) {
+ /* Populate all of the collections of the scene with those settings. */
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+ create_layer_collection_engines_settings_scene(scene, es_type);
+ }
+ }
+}
+
+void BKE_scene_layer_engine_settings_callback_register(
+ Main *bmain, const char *engine_name, EngineSettingsCB func)
+{
+ EngineSettingsCB_Type *es_type =
+ engine_settings_callback_register(engine_name, func, &R_scene_layer_engines_settings_callbacks);
+
+ if (bmain) {
+ /* Populate all of the collections of the scene with those settings. */
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+ create_scene_layer_engines_settings_scene(scene, es_type);
+
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ create_scene_layer_engines_settings_layer(sl, es_type);
+ }
+ }
+ }
+}
+
+void BKE_layer_collection_engine_settings_callback_free(void)
+{
+ BLI_freelistN(&R_layer_collection_engines_settings_callbacks);
+}
+
+void BKE_scene_layer_engine_settings_callback_free(void)
+{
+ BLI_freelistN(&R_scene_layer_engines_settings_callbacks);
+}
+
+/**
+ * Create a root IDProperty for this engine
+ *
+ * \param populate whether we want to pre-fill the collection with the default properties
+ */
+static IDProperty *collection_engine_settings_create(EngineSettingsCB_Type *es_type, const bool populate)
+{
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, es_type->name);
+ props->subtype = IDP_GROUP_SUB_ENGINE_RENDER;
+
+ /* properties */
+ if (populate) {
+ es_type->callback(NULL, props);
+ }
+
+ return props;
+}
+
+static void layer_collection_create_mode_settings_object(IDProperty *root, const bool populate)
+{
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "ObjectMode");
+ props->subtype = IDP_GROUP_SUB_MODE_OBJECT;
+
+ /* properties */
+ if (populate) {
+ OBJECT_collection_settings_create(props);
+ }
+
+ IDP_AddToGroup(root, props);
+}
+
+static void layer_collection_create_mode_settings_edit(IDProperty *root, const bool populate)
+{
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "EditMode");
+ props->subtype = IDP_GROUP_SUB_MODE_EDIT;
+
+ /* properties */
+ if (populate) {
+ EDIT_MESH_collection_settings_create(props);
+ }
+
+ IDP_AddToGroup(root, props);
+}
+
+static void layer_collection_create_mode_settings_paint_weight(IDProperty *root, const bool populate)
+{
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "WeightPaintMode");
+ props->subtype = IDP_GROUP_SUB_MODE_PAINT_WEIGHT;
+
+ /* properties */
+ if (populate) {
+ PAINT_WEIGHT_collection_settings_create(props);
+ }
+
+ IDP_AddToGroup(root, props);
+}
+
+static void layer_collection_create_mode_settings_paint_vertex(IDProperty *root, const bool populate)
+{
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "VertexPaintMode");
+ props->subtype = IDP_GROUP_SUB_MODE_PAINT_VERTEX;
+
+ /* properties */
+ if (populate) {
+ PAINT_VERTEX_collection_settings_create(props);
+ }
+
+ IDP_AddToGroup(root, props);
+}
+
+static void layer_collection_create_render_settings(IDProperty *root, const bool populate)
+{
+ EngineSettingsCB_Type *es_type;
+ for (es_type = R_layer_collection_engines_settings_callbacks.first; es_type; es_type = es_type->next) {
+ IDProperty *props = collection_engine_settings_create(es_type, populate);
+ IDP_AddToGroup(root, props);
+ }
+}
+
+static void scene_layer_create_render_settings(IDProperty *root, const bool populate)
+{
+ EngineSettingsCB_Type *es_type;
+ for (es_type = R_scene_layer_engines_settings_callbacks.first; es_type; es_type = es_type->next) {
+ IDProperty *props = collection_engine_settings_create(es_type, populate);
+ IDP_AddToGroup(root, props);
+ }
+}
+
+static void collection_create_mode_settings(IDProperty *root, const bool populate)
+{
+ /* XXX TODO: put all those engines in the R_engines_settings_callbacks
+ * and have IDP_AddToGroup outside the callbacks */
+ layer_collection_create_mode_settings_object(root, populate);
+ layer_collection_create_mode_settings_edit(root, populate);
+ layer_collection_create_mode_settings_paint_weight(root, populate);
+ layer_collection_create_mode_settings_paint_vertex(root, populate);
+}
+
+static void layer_create_mode_settings(IDProperty *root, const bool populate)
+{
+ TODO_LAYER; /* XXX like collection_create_mode_settings */
+ UNUSED_VARS(root, populate);
+}
+
+static int idproperty_group_subtype(const int mode_type)
+{
+ int idgroup_type;
+
+ switch (mode_type) {
+ case COLLECTION_MODE_OBJECT:
+ idgroup_type = IDP_GROUP_SUB_MODE_OBJECT;
+ break;
+ case COLLECTION_MODE_EDIT:
+ idgroup_type = IDP_GROUP_SUB_MODE_EDIT;
+ break;
+ case COLLECTION_MODE_PAINT_WEIGHT:
+ idgroup_type = IDP_GROUP_SUB_MODE_PAINT_WEIGHT;
+ break;
+ case COLLECTION_MODE_PAINT_VERTEX:
+ idgroup_type = IDP_GROUP_SUB_MODE_PAINT_VERTEX;
+ break;
+ default:
+ case COLLECTION_MODE_NONE:
+ return IDP_GROUP_SUB_ENGINE_RENDER;
+ break;
+ }
+
+ return idgroup_type;
+}
+
+/**
+ * Return collection enginne settings for either Object s of LayerCollection s
+ */
+static IDProperty *collection_engine_get(
+ IDProperty *root, const int type, const char *engine_name)
+{
+ const int subtype = idproperty_group_subtype(type);
+
+ if (subtype == IDP_GROUP_SUB_ENGINE_RENDER) {
+ return IDP_GetPropertyFromGroup(root, engine_name);
+ }
+ else {
+ IDProperty *prop;
+ for (prop = root->data.group.first; prop; prop = prop->next) {
+ if (prop->subtype == subtype) {
+ return prop;
+ }
+ }
+ }
+
+ BLI_assert(false);
+ return NULL;
+}
+
+/**
+ * Return collection engine settings from Object for specified engine of mode
+ */
+IDProperty *BKE_layer_collection_engine_evaluated_get(Object *ob, const int type, const char *engine_name)
+{
+ return collection_engine_get(ob->base_collection_properties, type, engine_name);
+}
+/**
+ * Return layer collection engine settings for specified engine
+ */
+IDProperty *BKE_layer_collection_engine_collection_get(LayerCollection *lc, const int type, const char *engine_name)
+{
+ return collection_engine_get(lc->properties, type, engine_name);
+}
+
+/**
+ * Return layer collection engine settings for specified engine in the scene
+ */
+IDProperty *BKE_layer_collection_engine_scene_get(Scene *scene, const int type, const char *engine_name)
+{
+ return collection_engine_get(scene->collection_properties, type, engine_name);
+}
+
+/**
+ * Return scene layer engine settings for specified engine in the scene
+ */
+IDProperty *BKE_scene_layer_engine_scene_get(Scene *scene, const int type, const char *engine_name)
+{
+ return collection_engine_get(scene->layer_properties, type, engine_name);
+}
+
+/**
+ * Return scene layer engine settings for specified engine
+ */
+IDProperty *BKE_scene_layer_engine_layer_get(SceneLayer *sl, const int type, const char *engine_name)
+{
+ return collection_engine_get(sl->properties, type, engine_name);
+}
+
+/**
+ * Return scene layer evaluated engine settings for specified engine
+ */
+IDProperty *BKE_scene_layer_engine_evaluated_get(SceneLayer *sl, const int type, const char *engine_name)
+{
+ return collection_engine_get(sl->properties_evaluated, type, engine_name);
+}
+
+/* ---------------------------------------------------------------------- */
+/* Engine Settings Properties */
+
+void BKE_collection_engine_property_add_float(IDProperty *props, const char *name, float value)
+{
+ IDPropertyTemplate val = {0};
+ val.f = value;
+ IDP_AddToGroup(props, IDP_New(IDP_FLOAT, &val, name));
+}
+
+void BKE_collection_engine_property_add_float_array(
+ IDProperty *props, const char *name, const float *values, const int array_length)
+{
+ IDPropertyTemplate val = {0};
+ val.array.len = array_length;
+ val.array.type = IDP_FLOAT;
+
+ IDProperty *idprop= IDP_New(IDP_ARRAY, &val, name);
+ memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
+ IDP_AddToGroup(props, idprop);
+}
+
+void BKE_collection_engine_property_add_int(IDProperty *props, const char *name, int value)
+{
+ IDPropertyTemplate val = {0};
+ val.i = value;
+ IDP_AddToGroup(props, IDP_New(IDP_INT, &val, name));
+}
+
+void BKE_collection_engine_property_add_bool(IDProperty *props, const char *name, bool value)
+{
+ IDPropertyTemplate val = {0};
+ val.i = value;
+ IDP_AddToGroup(props, IDP_New(IDP_INT, &val, name));
+}
+
+int BKE_collection_engine_property_value_get_int(IDProperty *props, const char *name)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? IDP_Int(idprop) : 0;
+}
+
+float BKE_collection_engine_property_value_get_float(IDProperty *props, const char *name)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? IDP_Float(idprop) : 0.0f;
+}
+
+const float *BKE_collection_engine_property_value_get_float_array(IDProperty *props, const char *name)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? IDP_Array(idprop) : NULL;
+}
+
+bool BKE_collection_engine_property_value_get_bool(IDProperty *props, const char *name)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ return idprop ? IDP_Int(idprop) : 0;
+}
+
+void BKE_collection_engine_property_value_set_int(IDProperty *props, const char *name, int value)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ IDP_Int(idprop) = value;
+}
+
+void BKE_collection_engine_property_value_set_float(IDProperty *props, const char *name, float value)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ IDP_Float(idprop) = value;
+}
+
+void BKE_collection_engine_property_value_set_float_array(IDProperty *props, const char *name, const float *values)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
+}
+
+void BKE_collection_engine_property_value_set_bool(IDProperty *props, const char *name, bool value)
+{
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, name);
+ IDP_Int(idprop) = value;
+}
+
+/* Engine Settings recalculate */
+
+/* get all the default settings defined in scene and merge them here */
+static void collection_engine_settings_init(IDProperty *root, const bool populate)
+{
+ /* render engines */
+ layer_collection_create_render_settings(root, populate);
+
+ /* mode engines */
+ collection_create_mode_settings(root, populate);
+}
+
+/* get all the default settings defined in scene and merge them here */
+static void layer_engine_settings_init(IDProperty *root, const bool populate)
+{
+ /* render engines */
+ scene_layer_create_render_settings(root, populate);
+
+ /* mode engines */
+ layer_create_mode_settings(root, populate);
+}
+
+/**
+ * Initialize the layer collection render setings
+ * It's used mainly for scenes
+ */
+void BKE_layer_collection_engine_settings_create(IDProperty *root)
+{
+ collection_engine_settings_init(root, true);
+}
+
+/**
+ * Initialize the render setings
+ * It's used mainly for scenes
+ */
+void BKE_scene_layer_engine_settings_create(IDProperty *root)
+{
+ layer_engine_settings_init(root, true);
+}
+
+/**
+ * Reference of IDProperty group scene collection settings
+ * Used when reading blendfiles, to see if there is any missing settings.
+ */
+static struct {
+ struct {
+ IDProperty *collection_properties;
+ IDProperty *render_settings;
+ } scene;
+ IDProperty *scene_layer;
+ IDProperty *layer_collection;
+} root_reference = {
+ .scene = {NULL, NULL},
+ .scene_layer = NULL,
+ .layer_collection = NULL,
+};
+
+/**
+ * Free the reference scene collection settings IDProperty group.
+ */
+static void engine_settings_validate_init(void)
+{
+ IDPropertyTemplate val = {0};
+
+ /* LayerCollection engine settings. */
+ if (root_reference.scene.collection_properties == NULL) {
+ root_reference.scene.collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ collection_engine_settings_init(root_reference.scene.collection_properties, true);
+ }
+
+ if (root_reference.layer_collection == NULL) {
+ root_reference.layer_collection = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ collection_engine_settings_init(root_reference.layer_collection, false);
+ }
+
+ /* Render engine setting. */
+ if (root_reference.scene.render_settings == NULL) {
+ root_reference.scene.render_settings = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ layer_engine_settings_init(root_reference.scene.render_settings, true);
+ }
+
+ if (root_reference.scene_layer == NULL) {
+ root_reference.scene_layer = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ layer_engine_settings_init(root_reference.scene_layer, false);
+ }
+}
+
+/**
+ * Free the reference scene collection settings IDProperty group.
+ */
+static void layer_collection_engine_settings_validate_free(void)
+{
+ IDProperty *idprops[] = {
+ root_reference.scene.render_settings,
+ root_reference.scene.collection_properties,
+ root_reference.scene_layer,
+ root_reference.layer_collection,
+ NULL,
+ };
+
+ IDProperty **idprop = &idprops[0];
+ while (*idprop) {
+ if (*idprop) {
+ IDP_FreeProperty(*idprop);
+ MEM_freeN(*idprop);
+ *idprop = NULL;
+ idprop++;
+ }
+ }
+}
+
+/**
+ * Make sure Scene has all required collection settings.
+ */
+void BKE_layer_collection_engine_settings_validate_scene(Scene *scene)
+{
+ if (root_reference.scene.collection_properties == NULL) {
+ engine_settings_validate_init();
+ }
+
+ if (scene->collection_properties == NULL) {
+ IDPropertyTemplate val = {0};
+ scene->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_layer_collection_engine_settings_create(scene->collection_properties);
+ }
+ else {
+ IDP_MergeGroup(scene->collection_properties, root_reference.scene.collection_properties, false);
+ }
+}
+
+/**
+ * Maker sure LayerCollection has all required collection settings.
+ */
+void BKE_layer_collection_engine_settings_validate_collection(LayerCollection *lc)
+{
+ if (root_reference.layer_collection == NULL) {
+ engine_settings_validate_init();
+ }
+
+ BLI_assert(lc->properties != NULL);
+ IDP_MergeGroup(lc->properties, root_reference.layer_collection, false);
+}
+
+/**
+ * Make sure Scene has all required collection settings.
+ */
+void BKE_scene_layer_engine_settings_validate_scene(Scene *scene)
+{
+ if (root_reference.scene.render_settings == NULL) {
+ engine_settings_validate_init();
+ }
+
+ if (scene->layer_properties == NULL) {
+ IDPropertyTemplate val = {0};
+ scene->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_scene_layer_engine_settings_create(scene->layer_properties);
+ }
+ else {
+ IDP_MergeGroup(scene->layer_properties, root_reference.scene.render_settings, false);
+ }
+}
+
+/**
+ * Make sure Scene has all required collection settings.
+ */
+void BKE_scene_layer_engine_settings_validate_layer(SceneLayer *sl)
+{
+ if (root_reference.scene_layer == NULL) {
+ engine_settings_validate_init();
+ }
+
+ IDP_MergeGroup(sl->properties, root_reference.scene_layer, false);
+}
+
+/* ---------------------------------------------------------------------- */
+/* Iterators */
+
+static void object_bases_Iterator_begin(BLI_Iterator *iter, void *data_in, const int flag)
+{
+ SceneLayer *sl = data_in;
+ Base *base = sl->object_bases.first;
+
+ /* when there are no objects */
+ if (base == NULL) {
+ iter->valid = false;
+ return;
+ }
+
+ iter->valid = true;
+ iter->data = base;
+
+ if ((base->flag & flag) == 0) {
+ object_bases_Iterator_next(iter, flag);
+ }
+ else {
+ iter->current = base;
+ }
+}
+
+static void object_bases_Iterator_next(BLI_Iterator *iter, const int flag)
+{
+ Base *base = ((Base *)iter->data)->next;
+
+ while (base) {
+ if ((base->flag & flag) != 0) {
+ iter->current = base;
+ iter->data = base;
+ return;
+ }
+ base = base->next;
+ }
+
+ iter->current = NULL;
+ iter->valid = false;
+}
+
+static void objects_Iterator_begin(BLI_Iterator *iter, void *data_in, const int flag)
+{
+ object_bases_Iterator_begin(iter, data_in, flag);
+
+ if (iter->valid) {
+ iter->current = ((Base *)iter->current)->object;
+ }
+}
+
+static void objects_Iterator_next(BLI_Iterator *iter, const int flag)
+{
+ object_bases_Iterator_next(iter, flag);
+
+ if (iter->valid) {
+ iter->current = ((Base *)iter->current)->object;
+ }
+}
+
+void BKE_selected_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ objects_Iterator_begin(iter, data_in, BASE_SELECTED);
+}
+
+void BKE_selected_objects_iterator_next(BLI_Iterator *iter)
+{
+ objects_Iterator_next(iter, BASE_SELECTED);
+}
+
+void BKE_selected_objects_iterator_end(BLI_Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
+
+void BKE_visible_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ objects_Iterator_begin(iter, data_in, BASE_VISIBLED);
+}
+
+void BKE_visible_objects_iterator_next(BLI_Iterator *iter)
+{
+ objects_Iterator_next(iter, BASE_VISIBLED);
+}
+
+void BKE_visible_objects_iterator_end(BLI_Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
+
+void BKE_selected_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ object_bases_Iterator_begin(iter, data_in, BASE_SELECTED);
+}
+
+void BKE_selected_bases_iterator_next(BLI_Iterator *iter)
+{
+ object_bases_Iterator_next(iter, BASE_SELECTED);
+}
+
+void BKE_selected_bases_iterator_end(BLI_Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
+
+void BKE_visible_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ object_bases_Iterator_begin(iter, data_in, BASE_VISIBLED);
+}
+
+void BKE_visible_bases_iterator_next(BLI_Iterator *iter)
+{
+ object_bases_Iterator_next(iter, BASE_VISIBLED);
+}
+
+void BKE_visible_bases_iterator_end(BLI_Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
+
+/* Evaluation */
+
+/**
+ * Reset props
+ *
+ * If props_ref is pasted, copy props from it
+ */
+static void idproperty_reset(IDProperty **props, IDProperty *props_ref)
+{
+ IDPropertyTemplate val = {0};
+
+ if (*props) {
+ IDP_FreeProperty(*props);
+ MEM_freeN(*props);
+ }
+ *props = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+
+ if (props_ref) {
+ IDP_MergeGroup(*props, props_ref, true);
+ }
+}
+
+void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *UNUSED(eval_ctx),
+ Scene *scene, SceneLayer *scene_layer)
+{
+ DEBUG_PRINT("%s on %s\n", __func__, scene_layer->name);
+ for (Base *base = scene_layer->object_bases.first; base != NULL; base = base->next) {
+ base->flag &= ~(BASE_VISIBLED | BASE_SELECTABLED);
+ idproperty_reset(&base->collection_properties, scene->collection_properties);
+ }
+
+ /* Sync properties from scene to scene layer. */
+ idproperty_reset(&scene_layer->properties_evaluated, scene->layer_properties);
+ IDP_MergeGroup(scene_layer->properties_evaluated, scene_layer->properties, true);
+
+ /* TODO(sergey): Is it always required? */
+ scene_layer->flag |= SCENE_LAYER_ENGINE_DIRTY;
+}
+
+void BKE_layer_eval_layer_collection(struct EvaluationContext *UNUSED(eval_ctx),
+ LayerCollection *layer_collection,
+ LayerCollection *parent_layer_collection)
+{
+ DEBUG_PRINT("%s on %s, parent %s\n",
+ __func__,
+ layer_collection->scene_collection->name,
+ (parent_layer_collection != NULL) ? parent_layer_collection->scene_collection->name : "NONE");
+
+ /* visibility */
+ layer_collection->flag_evaluated = layer_collection->flag;
+ bool is_visible = (layer_collection->flag & COLLECTION_VISIBLE) != 0;
+ bool is_selectable = is_visible && ((layer_collection->flag & COLLECTION_SELECTABLE) != 0);
+
+ if (parent_layer_collection != NULL) {
+ is_visible &= (parent_layer_collection->flag_evaluated & COLLECTION_VISIBLE) != 0;
+ is_selectable &= (parent_layer_collection->flag_evaluated & COLLECTION_SELECTABLE) != 0;
+ layer_collection->flag_evaluated &= parent_layer_collection->flag_evaluated;
+ }
+
+ /* overrides */
+ if (is_visible) {
+ if (parent_layer_collection == NULL) {
+ idproperty_reset(&layer_collection->properties_evaluated, layer_collection->properties);
+ }
+ else {
+ idproperty_reset(&layer_collection->properties_evaluated, parent_layer_collection->properties_evaluated);
+ IDP_MergeGroup(layer_collection->properties_evaluated, layer_collection->properties, true);
+ }
+ }
+
+ for (LinkData *link = layer_collection->object_bases.first; link != NULL; link = link->next) {
+ Base *base = link->data;
+
+ if (is_visible) {
+ IDP_MergeGroup(base->collection_properties, layer_collection->properties_evaluated, true);
+ base->flag |= BASE_VISIBLED;
+ }
+
+ if (is_selectable) {
+ base->flag |= BASE_SELECTABLED;
+ }
+ }
+}
+
+void BKE_layer_eval_layer_collection_post(struct EvaluationContext *UNUSED(eval_ctx),
+ SceneLayer *scene_layer)
+{
+ DEBUG_PRINT("%s on %s\n", __func__, scene_layer->name);
+ /* if base is not selectabled, clear select */
+ for (Base *base = scene_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTABLED) == 0) {
+ base->flag &= ~BASE_SELECTED;
+ }
+ }
+}
+
+/**
+ * Free any static allocated memory.
+ */
+void BKE_layer_exit(void)
+{
+ layer_collection_engine_settings_validate_free();
+}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c249577686e..4da2108b9d0 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -91,7 +91,6 @@
#include "BKE_cachefile.h"
#include "BKE_context.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_group.h"
@@ -779,11 +778,11 @@ void BKE_main_lib_objects_recalc_all(Main *bmain)
/* flag for full recalc */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ID_IS_LINKED_DATABLOCK(ob)) {
- DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
- DAG_id_type_tag(bmain, ID_OB);
+ DEG_id_type_tag(bmain, ID_OB);
}
/**
@@ -994,7 +993,7 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
/* alphabetic insertion: is in new_id */
BKE_main_unlock(bmain);
}
- DAG_id_type_tag(bmain, type);
+ DEG_id_type_tag(bmain, type);
return id;
}
@@ -1220,41 +1219,41 @@ void BKE_main_free(Main *mainvar)
/* errors freeing ID's can be hard to track down,
* enable this so valgrind will give the line number in its error log */
switch (a) {
- case 0: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 1: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 2: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 3: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 4: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 5: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 6: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 7: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 8: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 9: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 10: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 11: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 12: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 13: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 14: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 15: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 16: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 17: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 18: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 19: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 20: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 21: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 22: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 23: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 24: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 25: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 26: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 27: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 28: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 29: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 30: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 31: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 32: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 33: BKE_libblock_free_ex(mainvar, id, false, false); break;
- case 34: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 0: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 1: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 2: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 3: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 4: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 5: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 6: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 7: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 8: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 9: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 10: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 11: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 12: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 13: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 14: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 15: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 16: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 17: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 18: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 19: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 20: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 21: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 22: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 23: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 24: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 25: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 26: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 27: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 28: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 29: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 30: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 31: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 32: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 33: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 34: BKE_libblock_free_ex(mainvar, id, false); break;
default:
BLI_assert(0);
break;
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 931002e6bbc..0c89a5bea42 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -69,6 +69,7 @@
#include "BLI_linklist_stack.h"
#include "BKE_animsys.h"
+#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_fcurve.h"
#include "BKE_idprop.h"
@@ -403,7 +404,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
Scene *scene = (Scene *) id;
ToolSettings *toolsett = scene->toolsettings;
SceneRenderLayer *srl;
- Base *base;
+ BaseLegacy *legacy_base;
CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
@@ -461,8 +462,27 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
- for (base = scene->base.first; base; base = base->next) {
- CALLBACK_INVOKE(base->object, IDWALK_CB_USER);
+ for (legacy_base = scene->base.first; legacy_base; legacy_base = legacy_base->next) {
+ CALLBACK_INVOKE(legacy_base->object, IDWALK_CB_USER);
+ }
+
+ FOREACH_SCENE_COLLECTION(scene, sc)
+ {
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
+ }
+
+ for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
+ CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
+ }
+ }
+ FOREACH_SCENE_COLLECTION_END
+
+ SceneLayer *sl;
+ for (sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ CALLBACK_INVOKE(base->object, IDWALK_NOP);
+ }
}
for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) {
@@ -623,31 +643,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
for (i = 0; i < mesh->totcol; i++) {
CALLBACK_INVOKE(mesh->mat[i], IDWALK_CB_USER);
}
-
- /* XXX Really not happy with this - probably texface should rather use some kind of
- * 'texture slots' and just set indices in each poly/face item - would also save some memory.
- * Maybe a nice TODO for blender2.8? */
- if (mesh->mtface || mesh->mtpoly) {
- for (i = 0; i < mesh->pdata.totlayer; i++) {
- if (mesh->pdata.layers[i].type == CD_MTEXPOLY) {
- MTexPoly *txface = (MTexPoly *)mesh->pdata.layers[i].data;
-
- for (int j = 0; j < mesh->totpoly; j++, txface++) {
- CALLBACK_INVOKE(txface->tpage, IDWALK_CB_USER_ONE);
- }
- }
- }
-
- for (i = 0; i < mesh->fdata.totlayer; i++) {
- if (mesh->fdata.layers[i].type == CD_MTFACE) {
- MTFace *tface = (MTFace *)mesh->fdata.layers[i].data;
-
- for (int j = 0; j < mesh->totface; j++, tface++) {
- CALLBACK_INVOKE(tface->tpage, IDWALK_CB_USER_ONE);
- }
- }
- }
- }
break;
}
@@ -690,6 +685,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
library_foreach_ID_as_subdata_link((ID **)&material->nodetree, callback, user_data, flag, &data);
}
CALLBACK_INVOKE(material->group, IDWALK_CB_USER);
+ CALLBACK_INVOKE(material->edit_image, IDWALK_CB_USER);
break;
}
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 24626c6ead7..02128ae9c3a 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -71,8 +71,8 @@
#include "BKE_brush.h"
#include "BKE_camera.h"
#include "BKE_cachefile.h"
+#include "BKE_collection.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_font.h"
#include "BKE_group.h"
@@ -108,6 +108,9 @@
#include "BKE_texture.h"
#include "BKE_world.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#ifdef WITH_PYTHON
#include "BPY_extern.h"
#endif
@@ -219,7 +222,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
else {
if (!is_never_null) {
*id_p = new_id;
- DAG_id_tag_update_ex(id_remap_data->bmain, id_self, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update_ex(id_remap_data->bmain, id_self, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
if (cb_flag & IDWALK_CB_USER) {
id_us_min(old_id);
@@ -243,7 +246,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_base_unlink(
- IDRemap *r_id_remap_data, Scene *sce, Base *base, const bool skip_indirect, const bool is_indirect)
+ IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
{
if (skip_indirect && is_indirect) {
r_id_remap_data->skipped_indirect++;
@@ -259,6 +262,22 @@ static void libblock_remap_data_preprocess_scene_base_unlink(
}
}
+/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
+static void libblock_remap_data_preprocess_scene_object_unlink(
+ IDRemap *r_id_remap_data, Scene *sce, Object *ob, const bool skip_indirect, const bool is_indirect)
+{
+ if (skip_indirect && is_indirect) {
+ r_id_remap_data->skipped_indirect++;
+ r_id_remap_data->skipped_refcounted++;
+ }
+ else {
+ BKE_collections_object_remove(r_id_remap_data->bmain, sce, ob, false);
+ if (!is_indirect) {
+ r_id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
+ }
+ }
+}
+
static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
{
switch (GS(r_id_remap_data->id->name)) {
@@ -273,7 +292,15 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
/* In case we are unlinking... */
if (!r_id_remap_data->old_id) {
/* ... everything from scene. */
- Base *base, *base_next;
+ FOREACH_SCENE_OBJECT(sce, ob_iter)
+ {
+ libblock_remap_data_preprocess_scene_object_unlink(
+ r_id_remap_data, sce, ob_iter, skip_indirect, is_indirect);
+ }
+ FOREACH_SCENE_OBJECT_END
+
+
+ BaseLegacy *base, *base_next;
for (base = sce->base.first; base; base = base_next) {
base_next = base->next;
libblock_remap_data_preprocess_scene_base_unlink(
@@ -283,8 +310,11 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
else if (GS(r_id_remap_data->old_id->name) == ID_OB) {
/* ... a specific object from scene. */
Object *old_ob = (Object *)r_id_remap_data->old_id;
- Base *base = BKE_scene_base_find(sce, old_ob);
+ libblock_remap_data_preprocess_scene_object_unlink(
+ r_id_remap_data, sce, old_ob, skip_indirect, is_indirect);
+
+ BaseLegacy *base = BKE_scene_base_find(sce, old_ob);
if (base) {
libblock_remap_data_preprocess_scene_base_unlink(
r_id_remap_data, sce, base, skip_indirect, is_indirect);
@@ -330,7 +360,7 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
}
if (new_ob == NULL) { /* We need to remove NULL-ified groupobjects... */
for (Group *group = bmain->group.first; group; group = group->id.next) {
- BKE_group_object_unlink(group, NULL, NULL, NULL);
+ BKE_group_object_unlink(group, NULL);
}
}
else {
@@ -343,23 +373,17 @@ static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmai
{
/* Note that here we assume no object has no base (i.e. all objects are assumed instanced
* in one scene...). */
- for (Base *base = sce->base.first; base; base = base->next) {
- if (base->flag & OB_FROMGROUP) {
- Object *ob = base->object;
-
- if (ob->flag & OB_FROMGROUP) {
- Group *grp = BKE_group_object_find(NULL, ob);
-
- /* Unlinked group (old_id) is still in bmain... */
- if (grp && (&grp->id == old_id || grp->id.us == 0)) {
- grp = BKE_group_object_find(grp, ob);
- }
- if (!grp) {
- ob->flag &= ~OB_FROMGROUP;
- }
+ for (BaseLegacy *base = sce->base.first; base; base = base->next) {
+ Object *ob = base->object;
+ if (ob->flag & OB_FROMGROUP) {
+ Group *grp = BKE_group_object_find(NULL, ob);
+
+ /* Unlinked group (old_id) is still in bmain... */
+ if (grp && (&grp->id == old_id || grp->id.us == 0)) {
+ grp = BKE_group_object_find(grp, ob);
}
- if (!(ob->flag & OB_FROMGROUP)) {
- base->flag &= ~OB_FROMGROUP;
+ if (!grp) {
+ ob->flag &= ~OB_FROMGROUP;
}
}
}
@@ -577,7 +601,7 @@ void BKE_libblock_remap_locked(
BKE_main_lock(bmain);
/* Full rebuild of DAG! */
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const short remap_flags)
@@ -745,7 +769,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
short type = GS(id->name);
ListBase *lb = which_libbase(bmain, type);
- DAG_id_type_tag(bmain, type);
+ DEG_id_type_tag(bmain, type);
#ifdef WITH_PYTHON
BPY_id_release(id);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 54945242fe4..61e3ede3e8a 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -58,7 +58,6 @@
#include "BKE_animsys.h"
#include "BKE_displist.h"
#include "BKE_global.h"
-#include "BKE_depsgraph.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_library.h"
@@ -73,6 +72,8 @@
#include "BKE_editmesh.h"
#include "BKE_font.h"
+#include "DEG_depsgraph_build.h"
+
#include "GPU_material.h"
/* used in UI and render */
@@ -228,6 +229,7 @@ Material *BKE_material_copy(Main *bmain, Material *ma)
man = BKE_libblock_copy(bmain, &ma->id);
id_lib_extern((ID *)man->group);
+ id_lib_extern((ID *)man->edit_image);
for (a = 0; a < MAX_MTEX; a++) {
if (ma->mtex[a]) {
@@ -248,6 +250,8 @@ Material *BKE_material_copy(Main *bmain, Material *ma)
BLI_listbase_clear(&man->gpumaterial);
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
+
BKE_id_copy_ensure_local(bmain, &ma->id, &man->id);
return man;
@@ -279,6 +283,8 @@ Material *localize_material(Material *ma)
man->nodetree = ntreeLocalize(ma->nodetree);
BLI_listbase_clear(&man->gpumaterial);
+
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
return man;
}
@@ -426,7 +432,7 @@ void BKE_material_resize_id(Main *bmain, ID *id, short totcol, bool do_id_user)
}
*totcolp = totcol;
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
void BKE_material_append_id(Main *bmain, ID *id, Material *ma)
@@ -443,7 +449,7 @@ void BKE_material_append_id(Main *bmain, ID *id, Material *ma)
id_us_plus((ID *)ma);
test_all_objects_materials(bmain, id);
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
}
@@ -477,7 +483,7 @@ Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data
material_data_index_remove_id(id, index);
}
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
}
@@ -504,7 +510,7 @@ void BKE_material_clear_id(Main *bmain, ID *id, bool update_data)
material_data_index_clear_id(id);
}
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
}
@@ -599,7 +605,7 @@ void BKE_material_resize_object(Main *bmain, Object *ob, const short totcol, boo
if (ob->totcol && ob->actcol == 0) ob->actcol = 1;
if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
void test_object_materials(Object *ob, ID *id)
@@ -939,7 +945,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
if (needtang) ma->mode |= MA_NORMAP_TANG;
else ma->mode &= ~MA_NORMAP_TANG;
- if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
+ if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
needuv = 1;
if (r_mode & R_OSA) ma->texco |= TEXCO_OSA; /* for texfaces */
}
@@ -1300,6 +1306,14 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
bool use_nodes = BKE_scene_use_new_shading_nodes(scene);
bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene);
+
+ /* XXX, for 2.8 testing & development its useful to have non Cycles/BI engines use material nodes
+ * In the future we may have some way to check this which each engine can define.
+ * For now use material slots for Clay/Eevee.
+ * - Campbell */
+ if (!(use_nodes || is_bi)) {
+ is_bi = true;
+ }
if (!ma)
return;
@@ -1698,6 +1712,7 @@ void copy_matcopybuf(Material *ma)
matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, G.main, false);
matcopybuf.preview = NULL;
BLI_listbase_clear(&matcopybuf.gpumaterial);
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
matcopied = 1;
}
@@ -1753,501 +1768,30 @@ void paste_matcopybuf(Material *ma)
ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, G.main, false);
}
-
-/*********************** texface to material convert functions **********************/
-/* encode all the TF information into a single int */
-static int encode_tfaceflag(MTFace *tf, int convertall)
-{
- /* calculate the flag */
- int flag = tf->mode;
-
- /* options that change the material offline render */
- if (!convertall) {
- flag &= ~TF_OBCOL;
- }
-
- /* clean flags that are not being converted */
- flag &= ~TF_TEX;
- flag &= ~TF_SHAREDVERT;
- flag &= ~TF_SHAREDCOL;
- flag &= ~TF_CONVERTED;
-
- /* light tface flag is ignored in GLSL mode */
- flag &= ~TF_LIGHT;
-
- /* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */
- flag |= tf->transp << 15;
-
- /* increase 1 so flag 0 is different than no flag yet */
- return flag + 1;
-}
-
-/* set the material options based in the tface flag */
-static void decode_tfaceflag(Material *ma, int flag, int convertall)
-{
- int alphablend;
- GameSettings *game = &ma->game;
-
- /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
- flag -= 1;
-
- alphablend = flag >> 15; /* encoded in the encode_tfaceflag function */
- (*game).flag = 0;
-
- /* General Material Options */
- if ((flag & TF_DYNAMIC) == 0) (*game).flag |= GEMAT_NOPHYSICS;
-
- /* Material Offline Rendering Properties */
- if (convertall) {
- if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR;
- }
-
- /* Special Face Properties */
- if ((flag & TF_TWOSIDE) == 0) (*game).flag |= GEMAT_BACKCULL;
- if (flag & TF_INVISIBLE) (*game).flag |= GEMAT_INVISIBLE;
- if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;
-
- /* Face Orientation */
- if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
- else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD;
- else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW;
-
- /* Alpha Blend */
- if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT;
- else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA;
- else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD;
- else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP;
-}
-
-/* boolean check to see if the mesh needs a material */
-static int check_tfaceneedmaterial(int flag)
-{
- /* check if the flags we have are not deprecated != than default material options
- * also if only flags are visible and collision see if all objects using this mesh have this option in physics */
-
- /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
- flag -= 1;
-
- /* deprecated flags */
- flag &= ~TF_OBCOL;
- flag &= ~TF_SHAREDVERT;
- flag &= ~TF_SHAREDCOL;
-
- /* light tface flag is ignored in GLSL mode */
- flag &= ~TF_LIGHT;
-
- /* automatic detected if tex image has alpha */
- flag &= ~(TF_ALPHA << 15);
- /* automatic detected if using texture */
- flag &= ~TF_TEX;
-
- /* settings for the default NoMaterial */
- if (flag == TF_DYNAMIC)
- return 0;
-
- else
- return 1;
-}
-
-/* return number of digits of an integer */
-/* XXX to be optmized or replaced by an equivalent blender internal function */
-static int integer_getdigits(int number)
-{
- int i = 0;
- if (number == 0) return 1;
-
- while (number != 0) {
- number = (int)(number / 10);
- i++;
- }
- return i;
-}
-
-static void calculate_tface_materialname(char *matname, char *newname, int flag)
-{
- /* if flag has only light and collision and material matches those values
- * you can do strcpy(name, mat_name);
- * otherwise do: */
- int digits = integer_getdigits(flag);
- /* clamp the old name, remove the MA prefix and add the .TF.flag suffix
- * e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */
- BLI_snprintf(newname, MAX_ID_NAME, "%.*s.TF.%0*d", MAX_ID_NAME - (digits + 5), matname, digits, flag);
-}
-
-/* returns -1 if no match */
-static short mesh_getmaterialnumber(Mesh *me, Material *ma)
-{
- short a;
-
- for (a = 0; a < me->totcol; a++) {
- if (me->mat[a] == ma) {
- return a;
- }
- }
-
- return -1;
-}
-
-/* append material */
-static short mesh_addmaterial(Mesh *me, Material *ma)
-{
- BKE_material_append_id(G.main, &me->id, NULL);
- me->mat[me->totcol - 1] = ma;
-
- id_us_plus(&ma->id);
-
- return me->totcol - 1;
-}
-
-static void set_facetexture_flags(Material *ma, Image *image)
+struct Image *BKE_object_material_edit_image_get(Object *ob, short mat_nr)
{
- if (image) {
- ma->mode |= MA_FACETEXTURE;
- /* we could check if the texture has alpha, but then more meshes sharing the same
- * material may need it. Let's make it simple. */
- if (BKE_image_has_alpha(image))
- ma->mode |= MA_FACETEXTURE_ALPHA;
- }
+ Material *ma = give_current_material(ob, mat_nr + 1);
+ return ma ? ma->edit_image : NULL;
}
-/* returns material number */
-static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
+struct Image **BKE_object_material_edit_image_get_array(Object *ob)
{
- Material *ma;
- char idname[MAX_ID_NAME];
- short mat_nr = -1;
-
- /* new material, the name uses the flag*/
- BLI_snprintf(idname, sizeof(idname), "MAMaterial.TF.%0*d", integer_getdigits(flag), flag);
-
- if ((ma = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
- mat_nr = mesh_getmaterialnumber(me, ma);
- /* assign the material to the mesh */
- if (mat_nr == -1) mat_nr = mesh_addmaterial(me, ma);
-
- /* if needed set "Face Textures [Alpha]" Material options */
- set_facetexture_flags(ma, tf->tpage);
- }
- /* create a new material */
- else {
- ma = BKE_material_add(main, idname + 2);
-
- if (ma) {
- printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
- mat_nr = mesh_addmaterial(me, ma);
-
- /* if needed set "Face Textures [Alpha]" Material options */
- set_facetexture_flags(ma, tf->tpage);
-
- decode_tfaceflag(ma, flag, 1);
- /* the final decoding will happen after, outside the main loop
- * for now store the flag into the material and change light/tex/collision
- * store the flag as a negative number */
- ma->game.flag = -flag;
- id_us_min((ID *)ma);
- }
- else {
- printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
- }
+ Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__);
+ for (int i = 0; i < ob->totcol; i++) {
+ image_array[i] = BKE_object_material_edit_image_get(ob, i);
}
-
- /* set as converted, no need to go bad to this face */
- tf->mode |= TF_CONVERTED;
- return mat_nr;
+ return image_array;
}
-/* Function to fully convert materials */
-static void convert_tfacematerial(Main *main, Material *ma)
+bool BKE_object_material_edit_image_set(Object *ob, short mat_nr, Image *image)
{
- Mesh *me;
- Material *mat_new;
- MFace *mf;
- MTFace *tf;
- int flag, index;
- int a;
- short mat_nr;
- CustomDataLayer *cdl;
- char idname[MAX_ID_NAME];
-
- for (me = main->mesh.first; me; me = me->id.next) {
- /* check if this mesh uses this material */
- for (a = 0; a < me->totcol; a++)
- if (me->mat[a] == ma) break;
-
- /* no material found */
- if (a == me->totcol) continue;
-
- /* get the active tface layer */
- index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
- cdl = (index == -1) ? NULL : &me->fdata.layers[index];
- if (!cdl) continue;
-
- /* loop over all the faces and stop at the ones that use the material*/
- for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
- if (me->mat[mf->mat_nr] != ma) continue;
-
- /* texface data for this face */
- tf = ((MTFace *)cdl->data) + a;
- flag = encode_tfaceflag(tf, 1);
-
- /* the name of the new material */
- calculate_tface_materialname(ma->id.name, (char *)&idname, flag);
-
- if ((mat_new = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
- /* material already existent, see if the mesh has it */
- mat_nr = mesh_getmaterialnumber(me, mat_new);
- /* material is not in the mesh, add it */
- if (mat_nr == -1) mat_nr = mesh_addmaterial(me, mat_new);
- }
- /* create a new material */
- else {
- mat_new = BKE_material_copy(main, ma);
- if (mat_new) {
- /* rename the material*/
- BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
- id_us_min((ID *)mat_new);
-
- mat_nr = mesh_addmaterial(me, mat_new);
- decode_tfaceflag(mat_new, flag, 1);
- }
- else {
- printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname + 2, me->id.name + 2);
- mat_nr = mf->mat_nr;
- continue;
- }
- }
-
- /* if the material has a texture but no texture channel
- * set "Face Textures [Alpha]" Material options
- * actually we need to run it always, because of old behavior
- * of using face texture if any texture channel was present (multitex) */
- //if ((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex))
- set_facetexture_flags(mat_new, tf->tpage);
-
- /* set the material number to the face*/
- mf->mat_nr = mat_nr;
- }
- /* remove material from mesh */
- for (a = 0; a < me->totcol; ) {
- if (me->mat[a] == ma) {
- BKE_material_pop_id(main, &me->id, a, true);
- }
- else {
- a++;
- }
- }
- }
-}
-
-
-#define MAT_BGE_DISPUTED -99999
-
-int do_version_tface(Main *main)
-{
- Mesh *me;
- Material *ma;
- MFace *mf;
- MTFace *tf;
- CustomDataLayer *cdl;
- int a;
- int flag;
- int index;
-
- /* Operator in help menu has been removed for 2.7x */
- int fileload = 1;
-
- /* sometimes mesh has no materials but will need a new one. In those
- * cases we need to ignore the mf->mat_nr and only look at the face
- * mode because it can be zero as uninitialized or the 1st created material
- */
- int nomaterialslots;
-
- /* alert to user to check the console */
- int nowarning = 1;
-
- /* mark all the materials to conversion with a flag
- * if there is tface create a complete flag for that storing in flag
- * if there is tface and flag > 0: creates a new flag based on this face
- * if flags are different set flag to -1
- */
-
- /* 1st part: marking mesh materials to update */
- for (me = main->mesh.first; me; me = me->id.next) {
- if (ID_IS_LINKED_DATABLOCK(me)) continue;
-
- /* get the active tface layer */
- index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
- cdl = (index == -1) ? NULL : &me->fdata.layers[index];
- if (!cdl) continue;
-
- nomaterialslots = (me->totcol == 0 ? 1 : 0);
-
- /* loop over all the faces*/
- for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
- /* texface data for this face */
- tf = ((MTFace *)cdl->data) + a;
-
- /* conversion should happen only once */
- if (fileload)
- tf->mode &= ~TF_CONVERTED;
- else {
- if ((tf->mode & TF_CONVERTED)) continue;
- else tf->mode |= TF_CONVERTED;
- }
-
- /* no material slots */
- if (nomaterialslots) {
- flag = encode_tfaceflag(tf, 1);
-
- /* create/find a new material and assign to the face */
- if (check_tfaceneedmaterial(flag)) {
- mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
- }
- /* else mark them as no-material to be reverted to 0 later */
- else {
- mf->mat_nr = -1;
- }
- }
- else if (mf->mat_nr < me->totcol) {
- ma = me->mat[mf->mat_nr];
-
- /* no material create one if necessary */
- if (!ma) {
- /* find a new material and assign to the face */
- flag = encode_tfaceflag(tf, 1);
-
- /* create/find a new material and assign to the face */
- if (check_tfaceneedmaterial(flag))
- mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
-
- continue;
- }
-
- /* we can't read from this if it comes from a library,
- * at doversion time: direct_link might not have happened on it,
- * so ma->mtex is not pointing to valid memory yet.
- * later we could, but it's better not */
- else if (ID_IS_LINKED_DATABLOCK(ma))
- continue;
-
- /* material already marked as disputed */
- else if (ma->game.flag == MAT_BGE_DISPUTED)
- continue;
-
- /* found a material */
- else {
- flag = encode_tfaceflag(tf, ((fileload) ? 0 : 1));
-
- /* first time changing this material */
- if (ma->game.flag == 0)
- ma->game.flag = -flag;
-
- /* mark material as disputed */
- else if (ma->game.flag != -flag) {
- ma->game.flag = MAT_BGE_DISPUTED;
- continue;
- }
-
- /* material ok so far */
- else {
- ma->game.flag = -flag;
-
- /* some people uses multitexture with TexFace by creating a texture
- * channel which not necessarily the tf->tpage image. But the game engine
- * was enabling it. Now it's required to set "Face Texture [Alpha] in the
- * material settings. */
- if (!fileload)
- set_facetexture_flags(ma, tf->tpage);
- }
- }
- }
- else {
- continue;
- }
- }
-
- /* if we didn't have material slot and now we do, we need to
- * make sure the materials are correct */
- if (nomaterialslots) {
- if (me->totcol > 0) {
- for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
- if (mf->mat_nr == -1) {
- /* texface data for this face */
- tf = ((MTFace *)cdl->data) + a;
- mf->mat_nr = convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1));
- }
- }
- }
- else {
- for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
- mf->mat_nr = 0;
- }
- }
- }
-
- }
-
- /* 2nd part - conversion */
- /* skip library files */
-
- /* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */
- for (ma = main->mat.first, a = 0; ma; ma = ma->id.next, a++) {
- if (ID_IS_LINKED_DATABLOCK(ma)) continue;
-
- /* disputed material */
- if (ma->game.flag == MAT_BGE_DISPUTED) {
- ma->game.flag = 0;
- if (fileload) {
- printf("Warning: material \"%s\" skipped.\n", ma->id.name + 2);
- nowarning = 0;
- }
- else {
- convert_tfacematerial(main, ma);
- }
- continue;
- }
-
- /* no conflicts in this material - 90% of cases
- * convert from tface system to material */
- else if (ma->game.flag < 0) {
- decode_tfaceflag(ma, -(ma->game.flag), 1);
-
- /* material is good make sure all faces using
- * this material are set to converted */
- if (fileload) {
- for (me = main->mesh.first; me; me = me->id.next) {
- /* check if this mesh uses this material */
- for (a = 0; a < me->totcol; a++)
- if (me->mat[a] == ma) break;
-
- /* no material found */
- if (a == me->totcol) continue;
-
- /* get the active tface layer */
- index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
- cdl = (index == -1) ? NULL : &me->fdata.layers[index];
- if (!cdl) continue;
-
- /* loop over all the faces and stop at the ones that use the material*/
- for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
- if (me->mat[mf->mat_nr] == ma) {
- /* texface data for this face */
- tf = ((MTFace *)cdl->data) + a;
- tf->mode |= TF_CONVERTED;
- }
- }
- }
- }
- }
- /* material is not used by faces with texface
- * set the default flag - do it only once */
- else {
- if (fileload) {
- ma->game.flag = GEMAT_BACKCULL;
- }
- }
+ Material *ma = give_current_material(ob, mat_nr + 1);
+ if (ma) {
+ /* both may be NULL */
+ id_us_min((ID *)ma->edit_image);
+ ma->edit_image = image;
+ id_us_plus((ID *)ma->edit_image);
+ return true;
}
-
- return nowarning;
+ return false;
}
-
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 97033a9555d..4bfdb7fbc61 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -57,7 +57,6 @@
#include "BKE_animsys.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_scene.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -67,6 +66,8 @@
#include "BKE_object.h"
#include "BKE_material.h"
+//#include "DEG_depsgraph.h"
+
/* Functions */
/** Free (or release) any data used by this mball (does not free the mball itself). */
@@ -316,13 +317,13 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
void BKE_mball_properties_copy(Scene *scene, Object *active_object)
{
Scene *sce_iter = scene;
- Base *base;
+ BaseLegacy *base;
Object *ob;
MetaBall *active_mball = (MetaBall *)active_object->data;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
SceneBaseIter iter;
- EvaluationContext *eval_ctx = G.main->eval_ctx;
+ struct EvaluationContext *eval_ctx = G.main->eval_ctx;
BLI_split_name_num(basisname, &basisnr, active_object->id.name + 2, '.');
@@ -359,27 +360,25 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
*/
Object *BKE_mball_basis_find(Scene *scene, Object *basis)
{
- Scene *sce_iter = scene;
- Base *base;
- Object *ob, *bob = basis;
+ Object *bob = basis;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
- SceneBaseIter iter;
- EvaluationContext *eval_ctx = G.main->eval_ctx;
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
- BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 0, NULL, NULL);
- while (BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 1, &base, &ob)) {
- if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
- if (ob != bob) {
- BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
-
- /* object ob has to be in same "group" ... it means, that it has to have same base of its name */
- if (STREQ(obname, basisname)) {
- if (obnr < basisnr) {
- basis = ob;
- basisnr = obnr;
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ Object *ob = base->object;
+ if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
+ if (ob != bob) {
+ BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
+
+ /* object ob has to be in same "group" ... it means, that it has to have same base of its name */
+ if (STREQ(obname, basisname)) {
+ if (obnr < basisnr) {
+ basis = ob;
+ basisnr = obnr;
+ }
}
}
}
@@ -533,7 +532,7 @@ void BKE_mball_select_swap(struct MetaBall *mb)
/* **** Depsgraph evaluation **** */
-void BKE_mball_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_mball_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx),
MetaBall *UNUSED(mball))
{
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index 76965176be8..d897213d362 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -48,11 +48,12 @@
#include "BKE_global.h"
-#include "BKE_depsgraph.h"
#include "BKE_scene.h"
#include "BKE_displist.h"
#include "BKE_mball_tessellate.h" /* own include */
+#include "DEG_depsgraph.h"
+
#include "BLI_strict_flags.h"
/* experimental (faster) normal calculation */
@@ -1081,7 +1082,7 @@ static void polygonize(PROCESS *process)
static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
{
Scene *sce_iter = scene;
- Base *base;
+ BaseLegacy *base;
Object *bob;
MetaBall *mb;
const MetaElem *ml;
@@ -1103,7 +1104,7 @@ static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scen
zero_size = 0;
ml = NULL;
- if (bob == ob && (base->flag & OB_FROMDUPLI) == 0) {
+ if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
mb = ob->data;
if (mb->editelems) ml = mb->editelems->first;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index c12890a354e..768ca0bd4f7 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -59,7 +59,6 @@
#include "BKE_multires.h"
#include "BKE_key.h"
#include "BKE_mball.h"
-#include "BKE_depsgraph.h"
/* these 2 are only used by conversion functions */
#include "BKE_curve.h"
/* -- */
@@ -127,7 +126,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
for (i = 0; i < c1->totlayer; i++) {
if (ELEM(c1->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i1++;
}
@@ -135,7 +134,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
for (i = 0; i < c2->totlayer; i++) {
if (ELEM(c2->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i2++;
}
@@ -149,14 +148,14 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
i1 = 0; i2 = 0;
for (i = 0; i < tot; i++) {
while (i1 < c1->totlayer && !ELEM(l1->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i1++;
l1++;
}
while (i2 < c2->totlayer && !ELEM(l2->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i2++;
l2++;
@@ -324,7 +323,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
* Callers could also check but safer to do here - campbell */
}
else {
- const int tottex_original = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+ const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
@@ -335,7 +334,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
{
BKE_mesh_tessface_clear(me);
- CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface);
+ CustomData_from_bmeshpoly(&me->fdata, &me->ldata, me->totface);
/* TODO - add some --debug-mesh option */
if (G.debug & G_DEBUG) {
@@ -344,7 +343,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
* and check if there was any data to begin with, for now just print the warning with
* some info to help troubleshoot whats going on - campbell */
printf("%s: warning! Tessellation uvs or vcol data got out of sync, "
- "had to reset!\n CD_MTFACE: %d != CD_MTEXPOLY: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
+ "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
__func__, tottex_tessface, tottex_original, totcol_tessface, totcol_original);
}
}
@@ -396,14 +395,11 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
* versions of the mesh. - campbell*/
static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
{
- if (me->edit_btmesh)
- BKE_editmesh_update_linked_customdata(me->edit_btmesh);
-
if (do_ensure_tess_cd) {
mesh_ensure_tessellation_customdata(me);
}
- CustomData_bmesh_update_active_layers(&me->fdata, &me->pdata, &me->ldata);
+ CustomData_bmesh_update_active_layers(&me->fdata, &me->ldata);
}
void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
@@ -422,7 +418,6 @@ void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
me->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
me->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
- me->mtpoly = CustomData_get_layer(&me->pdata, CD_MTEXPOLY);
me->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
me->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
}
@@ -442,6 +437,8 @@ void BKE_mesh_free(Mesh *me)
{
BKE_animdata_free(&me->id, false);
+ BKE_mesh_batch_cache_free(me);
+
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
@@ -529,6 +526,7 @@ Mesh *BKE_mesh_copy(Main *bmain, Mesh *me)
BKE_mesh_update_customdata_pointers(men, do_tessface);
men->edit_btmesh = NULL;
+ men->batch_cache = NULL;
men->mselect = MEM_dupallocN(men->mselect);
men->bb = MEM_dupallocN(men->bb);
@@ -583,24 +581,34 @@ bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int
ldata = &me->ldata;
fdata = &me->fdata;
}
- cdlp = &pdata->layers[poly_index];
+ cdlp = (poly_index != -1) ? &pdata->layers[poly_index] : NULL;
cdlu = &ldata->layers[loop_index];
cdlf = fdata && do_tessface ? &fdata->layers[face_index] : NULL;
- if (cdlp->name != new_name) {
+ if (cdlp == NULL && cdlf == NULL) {
+ return false;
+ }
+
+ if (cdlu->name != new_name) {
/* Mesh validate passes a name from the CD layer as the new name,
* Avoid memcpy from self to self in this case.
*/
- BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name));
- CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+ BLI_strncpy(cdlu->name, new_name, sizeof(cdlu->name));
+ CustomData_set_layer_unique_name(pdata, cdlu - pdata->layers);
}
/* Loop until we do have exactly the same name for all layers! */
- for (i = 1; !STREQ(cdlp->name, cdlu->name) || (cdlf && !STREQ(cdlp->name, cdlf->name)); i++) {
+ for (i = 1;
+ (cdlp && !STREQ(cdlp->name, cdlu->name)) ||
+ (cdlf && !STREQ(cdlp->name, cdlf->name));
+ i++)
+ {
switch (i % step) {
case 0:
- BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
- CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+ if (cdlp) {
+ BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
+ CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+ }
break;
case 1:
BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
@@ -608,7 +616,7 @@ bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int
break;
case 2:
if (cdlf) {
- BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
+ BLI_strncpy(cdlf->name, cdlu->name, sizeof(cdlf->name));
CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
}
break;
@@ -620,66 +628,44 @@ bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int
bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface)
{
- CustomData *pdata, *ldata, *fdata;
+ CustomData *ldata, *fdata;
if (me->edit_btmesh) {
- pdata = &me->edit_btmesh->bm->pdata;
ldata = &me->edit_btmesh->bm->ldata;
/* No tessellated data in BMesh! */
fdata = NULL;
do_tessface = false;
}
else {
- pdata = &me->pdata;
ldata = &me->ldata;
fdata = &me->fdata;
do_tessface = (do_tessface && fdata->totlayer);
}
{
- const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY);
const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV);
const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1;
- int pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name);
int lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name);
int fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1;
/* None of those cases should happen, in theory!
* Note this assume we have the same number of mtexpoly, mloopuv and mtface layers!
*/
- if (pidx == -1) {
- if (lidx == -1) {
- if (fidx == -1) {
- /* No layer found with this name! */
- return false;
- }
- else {
- lidx = fidx;
- }
- }
- pidx = lidx;
- }
- else {
- if (lidx == -1) {
- lidx = pidx;
+ if (lidx == -1) {
+ if (fidx == -1) {
+ /* No layer found with this name! */
+ return false;
}
- if (fidx == -1 && do_tessface) {
- fidx = pidx;
+ else {
+ lidx = fidx;
}
}
-#if 0
- /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */
- else if (pidx != lidx) {
- lidx = pidx;
- }
-#endif
/* Go back to absolute indices! */
- pidx += pidx_start;
lidx += lidx_start;
if (fidx != -1)
fidx += fidx_start;
- return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface);
+ return BKE_mesh_uv_cdlayer_rename_index(me, -1, lidx, fidx, new_name, do_tessface);
}
}
@@ -1379,7 +1365,6 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
if (alluv) {
const char *uvname = "Orco";
- me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
}
@@ -2676,3 +2661,20 @@ void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
BKE_mesh_texspace_calc(mesh);
}
}
+
+/* Draw Engine */
+void (*BKE_mesh_batch_cache_dirty_cb)(Mesh *me, int mode) = NULL;
+void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = NULL;
+
+void BKE_mesh_batch_cache_dirty(Mesh *me, int mode)
+{
+ if (me->batch_cache) {
+ BKE_mesh_batch_cache_dirty_cb(me, mode);
+ }
+}
+void BKE_mesh_batch_cache_free(Mesh *me)
+{
+ if (me->batch_cache) {
+ BKE_mesh_batch_cache_free_cb(me);
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 37f4477febf..2c769c3ce03 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -1665,152 +1665,6 @@ void BKE_mesh_normals_loop_to_vertex(
/* -------------------------------------------------------------------- */
-/** \name Mesh Tangent Calculations
- * \{ */
-
-/* Tangent space utils. */
-
-/* User data. */
-typedef struct {
- const MPoly *mpolys; /* faces */
- const MLoop *mloops; /* faces's vertices */
- const MVert *mverts; /* vertices */
- const MLoopUV *luvs; /* texture coordinates */
- float (*lnors)[3]; /* loops' normals */
- float (*tangents)[4]; /* output tangents */
- int num_polys; /* number of polygons */
-} BKEMeshToTangent;
-
-/* Mikktspace's API */
-static int get_num_faces(const SMikkTSpaceContext *pContext)
-{
- BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
- return p_mesh->num_polys;
-}
-
-static int get_num_verts_of_face(const SMikkTSpaceContext *pContext, const int face_idx)
-{
- BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
- return p_mesh->mpolys[face_idx].totloop;
-}
-
-static void get_position(const SMikkTSpaceContext *pContext, float r_co[3], const int face_idx, const int vert_idx)
-{
- BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
- const int loop_idx = p_mesh->mpolys[face_idx].loopstart + vert_idx;
- copy_v3_v3(r_co, p_mesh->mverts[p_mesh->mloops[loop_idx].v].co);
-}
-
-static void get_texture_coordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_idx,
- const int vert_idx)
-{
- BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
- copy_v2_v2(r_uv, p_mesh->luvs[p_mesh->mpolys[face_idx].loopstart + vert_idx].uv);
-}
-
-static void get_normal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_idx, const int vert_idx)
-{
- BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
- copy_v3_v3(r_no, p_mesh->lnors[p_mesh->mpolys[face_idx].loopstart + vert_idx]);
-}
-
-static void set_tspace(const SMikkTSpaceContext *pContext, const float fv_tangent[3], const float face_sign,
- const int face_idx, const int vert_idx)
-{
- BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
- float *p_res = p_mesh->tangents[p_mesh->mpolys[face_idx].loopstart + vert_idx];
- copy_v3_v3(p_res, fv_tangent);
- p_res[3] = face_sign;
-}
-
-/**
- * Compute simplified tangent space normals, i.e. tangent vector + sign of bi-tangent one, which combined with
- * split normals can be used to recreate the full tangent space.
- * Note: * The mesh should be made of only tris and quads!
- */
-void BKE_mesh_loop_tangents_ex(
- const MVert *mverts, const int UNUSED(numVerts), const MLoop *mloops,
- float (*r_looptangent)[4], float (*loopnors)[3], const MLoopUV *loopuvs,
- const int UNUSED(numLoops), const MPoly *mpolys, const int numPolys,
- ReportList *reports)
-{
- BKEMeshToTangent mesh_to_tangent = {NULL};
- SMikkTSpaceContext s_context = {NULL};
- SMikkTSpaceInterface s_interface = {NULL};
-
- const MPoly *mp;
- int mp_index;
-
- /* First check we do have a tris/quads only mesh. */
- for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
- if (mp->totloop > 4) {
- BKE_report(reports, RPT_ERROR, "Tangent space can only be computed for tris/quads, aborting");
- return;
- }
- }
-
- /* Compute Mikktspace's tangent normals. */
- mesh_to_tangent.mpolys = mpolys;
- mesh_to_tangent.mloops = mloops;
- mesh_to_tangent.mverts = mverts;
- mesh_to_tangent.luvs = loopuvs;
- mesh_to_tangent.lnors = loopnors;
- mesh_to_tangent.tangents = r_looptangent;
- mesh_to_tangent.num_polys = numPolys;
-
- s_context.m_pUserData = &mesh_to_tangent;
- s_context.m_pInterface = &s_interface;
- s_interface.m_getNumFaces = get_num_faces;
- s_interface.m_getNumVerticesOfFace = get_num_verts_of_face;
- s_interface.m_getPosition = get_position;
- s_interface.m_getTexCoord = get_texture_coordinate;
- s_interface.m_getNormal = get_normal;
- s_interface.m_setTSpaceBasic = set_tspace;
-
- /* 0 if failed */
- if (genTangSpaceDefault(&s_context) == false) {
- BKE_report(reports, RPT_ERROR, "Mikktspace failed to generate tangents for this mesh!");
- }
-}
-
-/**
- * Wrapper around BKE_mesh_loop_tangents_ex, which takes care of most boiling code.
- * \note
- * - There must be a valid loop's CD_NORMALS available.
- * - The mesh should be made of only tris and quads!
- */
-void BKE_mesh_loop_tangents(Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], ReportList *reports)
-{
- MLoopUV *loopuvs;
- float (*loopnors)[3];
-
- /* Check we have valid texture coordinates first! */
- if (uvmap) {
- loopuvs = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvmap);
- }
- else {
- loopuvs = CustomData_get_layer(&mesh->ldata, CD_MLOOPUV);
- }
- if (!loopuvs) {
- BKE_reportf(reports, RPT_ERROR, "Tangent space computation needs an UVMap, \"%s\" not found, aborting", uvmap);
- return;
- }
-
- loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
- if (!loopnors) {
- BKE_report(reports, RPT_ERROR, "Tangent space computation needs loop normals, none found, aborting");
- return;
- }
-
- BKE_mesh_loop_tangents_ex(mesh->mvert, mesh->totvert, mesh->mloop, r_looptangents,
- loopnors, loopuvs, mesh->totloop, mesh->mpoly, mesh->totpoly, reports);
-}
-
-/** \} */
-
-
-/* -------------------------------------------------------------------- */
-
/** \name Polygon Calculations
* \{ */
@@ -2307,12 +2161,12 @@ void BKE_mesh_calc_volume(
*/
void BKE_mesh_loops_to_mface_corners(
CustomData *fdata, CustomData *ldata,
- CustomData *pdata, unsigned int lindex[4], int findex,
- const int polyindex,
+ CustomData *UNUSED(pdata), unsigned int lindex[4], int findex,
+ const int UNUSED(polyindex),
const int mf_len, /* 3 or 4 */
/* cache values to avoid lookups every time */
- const int numTex, /* CustomData_number_of_layers(pdata, CD_MTEXPOLY) */
+ const int numUV, /* CustomData_number_of_layers(ldata, CD_MLOOPUV) */
const int numCol, /* CustomData_number_of_layers(ldata, CD_MLOOPCOL) */
const bool hasPCol, /* CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL) */
const bool hasOrigSpace, /* CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP) */
@@ -2320,17 +2174,13 @@ void BKE_mesh_loops_to_mface_corners(
)
{
MTFace *texface;
- MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
int i, j;
- for (i = 0; i < numTex; i++) {
+ for (i = 0; i < numUV; i++) {
texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
- texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
-
- ME_MTEXFACE_CPY(texface, texpoly);
for (j = 0; j < mf_len; j++) {
mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, (int)lindex[j], i);
@@ -2382,14 +2232,14 @@ void BKE_mesh_loops_to_mface_corners(
*
* \note when mface is not NULL, mface[face_index].v4 is used to test quads, else, loopindices[face_index][3] is used.
*/
-void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData *pdata, MFace *mface,
+void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, MFace *mface,
int *polyindices, unsigned int (*loopindices)[4], const int num_faces)
{
/* Note: performances are sub-optimal when we get a NULL mface, we could be ~25% quicker with dedicated code...
* Issue is, unless having two different functions with nearly the same code, there's not much ways to solve
* this. Better imho to live with it for now. :/ --mont29
*/
- const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+ const int numUV = CustomData_number_of_layers(ldata, CD_MLOOPUV);
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
@@ -2399,17 +2249,14 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData
const int *pidx;
unsigned int (*lidx)[4];
- for (i = 0; i < numTex; i++) {
+ for (i = 0; i < numUV; i++) {
MTFace *texface = CustomData_get_layer_n(fdata, CD_MTFACE, i);
- MTexPoly *texpoly = CustomData_get_layer_n(pdata, CD_MTEXPOLY, i);
MLoopUV *mloopuv = CustomData_get_layer_n(ldata, CD_MLOOPUV, i);
for (findex = 0, pidx = polyindices, lidx = loopindices;
findex < num_faces;
pidx++, lidx++, findex++, texface++)
{
- ME_MTEXFACE_CPY(texface, &texpoly[*pidx]);
-
for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
copy_v2_v2(texface->uv[j], mloopuv[(*lidx)[j]].uv);
}
@@ -2732,7 +2579,7 @@ int BKE_mesh_recalc_tessellation(
/* CD_ORIGINDEX will contain an array of indices from tessfaces to the polygons
* they are directly tessellated from */
CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_to_poly_map, totface);
- CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+ CustomData_from_bmeshpoly(fdata, ldata, totface);
if (do_face_nor_copy) {
/* If polys have a normals layer, copying that to faces can help
@@ -2753,7 +2600,7 @@ int BKE_mesh_recalc_tessellation(
* So we pass NULL as MFace pointer, and BKE_mesh_loops_to_tessdata will use the fourth loop index as quad test.
* ...
*/
- BKE_mesh_loops_to_tessdata(fdata, ldata, pdata, NULL, mface_to_poly_map, lindices, totface);
+ BKE_mesh_loops_to_tessdata(fdata, ldata, NULL, mface_to_poly_map, lindices, totface);
/* NOTE: quad detection issue - fourth vertidx vs fourth loopidx:
* ...However, most TFace code uses 'MFace->v4 == 0' test to check whether it is a tri or quad.
@@ -2932,7 +2779,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
MPoly *mp, *mpoly;
MFace *mface, *mf;
- const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+ const int numUV = CustomData_number_of_layers(ldata, CD_MLOOPUV);
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
@@ -2972,7 +2819,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
- CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+ CustomData_from_bmeshpoly(fdata, ldata, totface);
mp = mpoly;
k = 0;
@@ -2994,9 +2841,10 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
mf->v2 = mloop[mf->v2].v;
mf->v3 = mloop[mf->v3].v;
- BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
- lindex, k, i, 3,
- numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
+ BKE_mesh_loops_to_mface_corners(
+ fdata, ldata, pdata,
+ lindex, k, i, 3,
+ numUV, numCol, hasPCol, hasOrigSpace, hasLNor);
test_index_face(mf, fdata, k, 3);
}
else {
@@ -3014,9 +2862,10 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
mf->v3 = mloop[mf->v3].v;
mf->v4 = mloop[mf->v4].v;
- BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
- lindex, k, i, 4,
- numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
+ BKE_mesh_loops_to_mface_corners(
+ fdata, ldata, pdata,
+ lindex, k, i, 4,
+ numUV, numCol, hasPCol, hasOrigSpace, hasLNor);
test_index_face(mf, fdata, k, 4);
}
@@ -3031,11 +2880,11 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
#endif /* USE_BMESH_SAVE_AS_COMPAT */
-static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata,
- MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol)
+static void bm_corners_to_loops_ex(
+ ID *id, CustomData *fdata, CustomData *ldata,
+ MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol)
{
MTFace *texface;
- MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
@@ -3046,9 +2895,6 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata,
for (i = 0; i < numTex; i++) {
texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
- texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, findex, i);
-
- ME_MTEXFACE_CPY(texpoly, texface);
mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
copy_v2_v2(mloopuv->uv, texface->uv[0]); mloopuv++;
@@ -3156,7 +3002,7 @@ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh)
mesh->medge, mesh->mface,
&mesh->totloop, &mesh->totpoly, &mesh->mloop, &mesh->mpoly);
- CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->pdata, &mesh->ldata);
+ CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->ldata);
BKE_mesh_update_customdata_pointers(mesh, true);
}
@@ -3199,7 +3045,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData
CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop);
- CustomData_to_bmeshpoly(fdata, pdata, ldata, totloop, totpoly);
+ CustomData_to_bmeshpoly(fdata, ldata, totloop);
if (id) {
/* ensure external data is transferred */
@@ -3249,7 +3095,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData
# undef ML
- bm_corners_to_loops_ex(id, fdata, ldata, pdata, mface, totloop, i, mp->loopstart, numTex, numCol);
+ bm_corners_to_loops_ex(id, fdata, ldata, mface, totloop, i, mp->loopstart, numTex, numCol);
if (polyindex) {
*polyindex = i;
diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c
new file mode 100644
index 00000000000..7b953337909
--- /dev/null
+++ b/source/blender/blenkernel/intern/mesh_tangent.c
@@ -0,0 +1,684 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/mesh_tangent.c
+ * \ingroup bke
+ *
+ * Functions to evaluate mesh tangents.
+ */
+
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_stack.h"
+#include "BLI_task.h"
+
+#include "BKE_customdata.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_tangent.h"
+#include "BKE_report.h"
+
+#include "BLI_strict_flags.h"
+
+#include "atomic_ops.h"
+#include "mikktspace.h"
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Mesh Tangent Calculations (Single Layer)
+ * \{ */
+
+/* Tangent space utils. */
+
+/* User data. */
+typedef struct {
+ const MPoly *mpolys; /* faces */
+ const MLoop *mloops; /* faces's vertices */
+ const MVert *mverts; /* vertices */
+ const MLoopUV *luvs; /* texture coordinates */
+ float (*lnors)[3]; /* loops' normals */
+ float (*tangents)[4]; /* output tangents */
+ int num_polys; /* number of polygons */
+} BKEMeshToTangent;
+
+/* Mikktspace's API */
+static int get_num_faces(const SMikkTSpaceContext *pContext)
+{
+ BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
+ return p_mesh->num_polys;
+}
+
+static int get_num_verts_of_face(const SMikkTSpaceContext *pContext, const int face_idx)
+{
+ BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
+ return p_mesh->mpolys[face_idx].totloop;
+}
+
+static void get_position(const SMikkTSpaceContext *pContext, float r_co[3], const int face_idx, const int vert_idx)
+{
+ BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
+ const int loop_idx = p_mesh->mpolys[face_idx].loopstart + vert_idx;
+ copy_v3_v3(r_co, p_mesh->mverts[p_mesh->mloops[loop_idx].v].co);
+}
+
+static void get_texture_coordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_idx,
+ const int vert_idx)
+{
+ BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
+ copy_v2_v2(r_uv, p_mesh->luvs[p_mesh->mpolys[face_idx].loopstart + vert_idx].uv);
+}
+
+static void get_normal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_idx, const int vert_idx)
+{
+ BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
+ copy_v3_v3(r_no, p_mesh->lnors[p_mesh->mpolys[face_idx].loopstart + vert_idx]);
+}
+
+static void set_tspace(const SMikkTSpaceContext *pContext, const float fv_tangent[3], const float face_sign,
+ const int face_idx, const int vert_idx)
+{
+ BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
+ float *p_res = p_mesh->tangents[p_mesh->mpolys[face_idx].loopstart + vert_idx];
+ copy_v3_v3(p_res, fv_tangent);
+ p_res[3] = face_sign;
+}
+
+/**
+ * Compute simplified tangent space normals, i.e. tangent vector + sign of bi-tangent one, which combined with
+ * split normals can be used to recreate the full tangent space.
+ * Note: * The mesh should be made of only tris and quads!
+ */
+void BKE_mesh_calc_loop_tangent_single_ex(
+ const MVert *mverts, const int UNUSED(numVerts), const MLoop *mloops,
+ float (*r_looptangent)[4], float (*loopnors)[3], const MLoopUV *loopuvs,
+ const int UNUSED(numLoops), const MPoly *mpolys, const int numPolys,
+ ReportList *reports)
+{
+ BKEMeshToTangent mesh_to_tangent = {NULL};
+ SMikkTSpaceContext s_context = {NULL};
+ SMikkTSpaceInterface s_interface = {NULL};
+
+ const MPoly *mp;
+ int mp_index;
+
+ /* First check we do have a tris/quads only mesh. */
+ for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
+ if (mp->totloop > 4) {
+ BKE_report(reports, RPT_ERROR, "Tangent space can only be computed for tris/quads, aborting");
+ return;
+ }
+ }
+
+ /* Compute Mikktspace's tangent normals. */
+ mesh_to_tangent.mpolys = mpolys;
+ mesh_to_tangent.mloops = mloops;
+ mesh_to_tangent.mverts = mverts;
+ mesh_to_tangent.luvs = loopuvs;
+ mesh_to_tangent.lnors = loopnors;
+ mesh_to_tangent.tangents = r_looptangent;
+ mesh_to_tangent.num_polys = numPolys;
+
+ s_context.m_pUserData = &mesh_to_tangent;
+ s_context.m_pInterface = &s_interface;
+ s_interface.m_getNumFaces = get_num_faces;
+ s_interface.m_getNumVerticesOfFace = get_num_verts_of_face;
+ s_interface.m_getPosition = get_position;
+ s_interface.m_getTexCoord = get_texture_coordinate;
+ s_interface.m_getNormal = get_normal;
+ s_interface.m_setTSpaceBasic = set_tspace;
+
+ /* 0 if failed */
+ if (genTangSpaceDefault(&s_context) == false) {
+ BKE_report(reports, RPT_ERROR, "Mikktspace failed to generate tangents for this mesh!");
+ }
+}
+
+/**
+ * Wrapper around BKE_mesh_calc_loop_tangent_single_ex, which takes care of most boiling code.
+ * \note
+ * - There must be a valid loop's CD_NORMALS available.
+ * - The mesh should be made of only tris and quads!
+ */
+void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], ReportList *reports)
+{
+ MLoopUV *loopuvs;
+ float (*loopnors)[3];
+
+ /* Check we have valid texture coordinates first! */
+ if (uvmap) {
+ loopuvs = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvmap);
+ }
+ else {
+ loopuvs = CustomData_get_layer(&mesh->ldata, CD_MLOOPUV);
+ }
+ if (!loopuvs) {
+ BKE_reportf(reports, RPT_ERROR, "Tangent space computation needs an UVMap, \"%s\" not found, aborting", uvmap);
+ return;
+ }
+
+ loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
+ if (!loopnors) {
+ BKE_report(reports, RPT_ERROR, "Tangent space computation needs loop normals, none found, aborting");
+ return;
+ }
+
+ BKE_mesh_calc_loop_tangent_single_ex(mesh->mvert, mesh->totvert, mesh->mloop, r_looptangents,
+ loopnors, loopuvs, mesh->totloop, mesh->mpoly, mesh->totpoly, reports);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Mesh Tangent Calculations (All Layers)
+ * \{ */
+
+
+/* Necessary complexity to handle looptri's as quads for correct tangents */
+#define USE_LOOPTRI_DETECT_QUADS
+
+typedef struct {
+ const float (*precomputedFaceNormals)[3];
+ const float (*precomputedLoopNormals)[3];
+ const MLoopTri *looptri;
+ MLoopUV *mloopuv; /* texture coordinates */
+ const MPoly *mpoly; /* indices */
+ const MLoop *mloop; /* indices */
+ const MVert *mvert; /* vertices & normals */
+ const float (*orco)[3];
+ float (*tangent)[4]; /* destination */
+ int numTessFaces;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ /* map from 'fake' face index to looptri,
+ * quads will point to the first looptri of the quad */
+ const int *face_as_quad_map;
+ int num_face_as_quad_map;
+#endif
+
+} SGLSLMeshToTangent;
+
+/* interface */
+#include "mikktspace.h"
+
+static int dm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
+{
+ SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ return pMesh->num_face_as_quad_map;
+#else
+ return pMesh->numTessFaces;
+#endif
+}
+
+static int dm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
+{
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
+ if (pMesh->face_as_quad_map) {
+ const MLoopTri *lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
+ const MPoly *mp = &pMesh->mpoly[lt->poly];
+ if (mp->totloop == 4) {
+ return 4;
+ }
+ }
+ return 3;
+#else
+ UNUSED_VARS(pContext, face_num);
+ return 3;
+#endif
+}
+
+static void dm_ts_GetPosition(
+ const SMikkTSpaceContext *pContext, float r_co[3],
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
+ const MLoopTri *lt;
+ uint loop_index;
+ const float *co;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
+ const MPoly *mp = &pMesh->mpoly[lt->poly];
+ if (mp->totloop == 4) {
+ loop_index = (uint)(mp->loopstart + vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = &pMesh->looptri[face_num];
+ }
+#else
+ lt = &pMesh->looptri[face_num];
+#endif
+ loop_index = lt->tri[vert_index];
+
+finally:
+ co = pMesh->mvert[pMesh->mloop[loop_index].v].co;
+ copy_v3_v3(r_co, co);
+}
+
+static void dm_ts_GetTextureCoordinate(
+ const SMikkTSpaceContext *pContext, float r_uv[2],
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
+ const MLoopTri *lt;
+ uint loop_index;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
+ const MPoly *mp = &pMesh->mpoly[lt->poly];
+ if (mp->totloop == 4) {
+ loop_index = (uint)(mp->loopstart + vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = &pMesh->looptri[face_num];
+ }
+#else
+ lt = &pMesh->looptri[face_num];
+#endif
+ loop_index = lt->tri[vert_index];
+
+finally:
+ if (pMesh->mloopuv != NULL) {
+ const float *uv = pMesh->mloopuv[loop_index].uv;
+ copy_v2_v2(r_uv, uv);
+ }
+ else {
+ const float *orco = pMesh->orco[pMesh->mloop[loop_index].v];
+ map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
+ }
+}
+
+static void dm_ts_GetNormal(
+ const SMikkTSpaceContext *pContext, float r_no[3],
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
+ const MLoopTri *lt;
+ uint loop_index;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
+ const MPoly *mp = &pMesh->mpoly[lt->poly];
+ if (mp->totloop == 4) {
+ loop_index = (uint)(mp->loopstart + vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = &pMesh->looptri[face_num];
+ }
+#else
+ lt = &pMesh->looptri[face_num];
+#endif
+ loop_index = lt->tri[vert_index];
+
+finally:
+ if (pMesh->precomputedLoopNormals) {
+ copy_v3_v3(r_no, pMesh->precomputedLoopNormals[loop_index]);
+ }
+ else if ((pMesh->mpoly[lt->poly].flag & ME_SMOOTH) == 0) { /* flat */
+ if (pMesh->precomputedFaceNormals) {
+ copy_v3_v3(r_no, pMesh->precomputedFaceNormals[lt->poly]);
+ }
+ else {
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ const MPoly *mp = &pMesh->mpoly[lt->poly];
+ if (mp->totloop == 4) {
+ normal_quad_v3(
+ r_no,
+ pMesh->mvert[pMesh->mloop[mp->loopstart + 0].v].co,
+ pMesh->mvert[pMesh->mloop[mp->loopstart + 1].v].co,
+ pMesh->mvert[pMesh->mloop[mp->loopstart + 2].v].co,
+ pMesh->mvert[pMesh->mloop[mp->loopstart + 3].v].co);
+ }
+ else
+#endif
+ {
+ normal_tri_v3(
+ r_no,
+ pMesh->mvert[pMesh->mloop[lt->tri[0]].v].co,
+ pMesh->mvert[pMesh->mloop[lt->tri[1]].v].co,
+ pMesh->mvert[pMesh->mloop[lt->tri[2]].v].co);
+ }
+ }
+ }
+ else {
+ const short *no = pMesh->mvert[pMesh->mloop[loop_index].v].no;
+ normal_short_to_float_v3(r_no, no);
+ }
+}
+
+static void dm_ts_SetTSpace(
+ const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign,
+ const int face_num, const int vert_index)
+{
+ //assert(vert_index >= 0 && vert_index < 4);
+ SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
+ const MLoopTri *lt;
+ uint loop_index;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
+ const MPoly *mp = &pMesh->mpoly[lt->poly];
+ if (mp->totloop == 4) {
+ loop_index = (uint)(mp->loopstart + vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = &pMesh->looptri[face_num];
+ }
+#else
+ lt = &pMesh->looptri[face_num];
+#endif
+ loop_index = lt->tri[vert_index];
+
+ float *pRes;
+
+finally:
+ pRes = pMesh->tangent[loop_index];
+ copy_v3_v3(pRes, fvTangent);
+ pRes[3] = fSign;
+}
+
+static void DM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ struct SGLSLMeshToTangent *mesh2tangent = taskdata;
+ /* new computation method */
+ {
+ SMikkTSpaceContext sContext = {NULL};
+ SMikkTSpaceInterface sInterface = {NULL};
+
+ sContext.m_pUserData = mesh2tangent;
+ sContext.m_pInterface = &sInterface;
+ sInterface.m_getNumFaces = dm_ts_GetNumFaces;
+ sInterface.m_getNumVerticesOfFace = dm_ts_GetNumVertsOfFace;
+ sInterface.m_getPosition = dm_ts_GetPosition;
+ sInterface.m_getTexCoord = dm_ts_GetTextureCoordinate;
+ sInterface.m_getNormal = dm_ts_GetNormal;
+ sInterface.m_setTSpaceBasic = dm_ts_SetTSpace;
+
+ /* 0 if failed */
+ genTangSpaceDefault(&sContext);
+ }
+}
+
+void BKE_mesh_add_loop_tangent_named_layer_for_uv(
+ CustomData *uv_data, CustomData *tan_data, int numLoopData,
+ const char *layer_name)
+{
+ if (CustomData_get_named_layer_index(tan_data, CD_TANGENT, layer_name) == -1 &&
+ CustomData_get_named_layer_index(uv_data, CD_MLOOPUV, layer_name) != -1)
+ {
+ CustomData_add_layer_named(
+ tan_data, CD_TANGENT, CD_CALLOC, NULL,
+ numLoopData, layer_name);
+ }
+}
+
+/**
+ * Here we get some useful information such as active uv layer name and search if it is already in tangent_names.
+ * Also, we calculate tangent_mask that works as a descriptor of tangents state.
+ * If tangent_mask has changed, then recalculate tangents.
+ */
+void BKE_mesh_calc_loop_tangent_step_0(
+ const CustomData *loopData, bool calc_active_tangent,
+ const char (*tangent_names)[MAX_NAME], int tangent_names_count,
+ bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
+ char *ract_uv_name, char *rren_uv_name, char *rtangent_mask) {
+ /* Active uv in viewport */
+ int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV);
+ *ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV);
+ ract_uv_name[0] = 0;
+ if (*ract_uv_n != -1) {
+ strcpy(ract_uv_name, loopData->layers[*ract_uv_n + layer_index].name);
+ }
+
+ /* Active tangent in render */
+ *rren_uv_n = CustomData_get_render_layer(loopData, CD_MLOOPUV);
+ rren_uv_name[0] = 0;
+ if (*rren_uv_n != -1) {
+ strcpy(rren_uv_name, loopData->layers[*rren_uv_n + layer_index].name);
+ }
+
+ /* If active tangent not in tangent_names we take it into account */
+ *rcalc_act = false;
+ *rcalc_ren = false;
+ for (int i = 0; i < tangent_names_count; i++) {
+ if (tangent_names[i][0] == 0) {
+ calc_active_tangent = true;
+ }
+ }
+ if (calc_active_tangent) {
+ *rcalc_act = true;
+ *rcalc_ren = true;
+ for (int i = 0; i < tangent_names_count; i++) {
+ if (STREQ(ract_uv_name, tangent_names[i]))
+ *rcalc_act = false;
+ if (STREQ(rren_uv_name, tangent_names[i]))
+ *rcalc_ren = false;
+ }
+ }
+ *rtangent_mask = 0;
+
+ const int uv_layer_num = CustomData_number_of_layers(loopData, CD_MLOOPUV);
+ for (int n = 0; n < uv_layer_num; n++) {
+ const char *name = CustomData_get_layer_name(loopData, CD_MLOOPUV, n);
+ bool add = false;
+ for (int i = 0; i < tangent_names_count; i++) {
+ if (tangent_names[i][0] && STREQ(tangent_names[i], name)) {
+ add = true;
+ break;
+ }
+ }
+ if ((*rcalc_act && ract_uv_name[0] && STREQ(ract_uv_name, name)) ||
+ (*rcalc_ren && rren_uv_name[0] && STREQ(rren_uv_name, name)))
+ {
+ add = true;
+ }
+ if (add)
+ *rtangent_mask |= (char)(1 << n);
+ }
+}
+
+/**
+ * See: #BKE_editmesh_loop_tangent_calc (matching logic).
+ */
+void BKE_mesh_calc_loop_tangent_ex(
+ const MVert *mvert,
+ const MPoly *mpoly, const uint mpoly_len,
+ const MLoop *mloop,
+ const MLoopTri *looptri,
+ const uint looptri_len,
+
+ CustomData *loopdata,
+ bool calc_active_tangent,
+ const char (*tangent_names)[MAX_NAME], int tangent_names_len,
+ const float (*poly_normals)[3],
+ const float (*loop_normals)[3],
+ const float (*vert_orco)[3],
+ /* result */
+ CustomData *loopdata_out,
+ const uint loopdata_out_len,
+ char *tangent_mask_curr_p)
+{
+ BLI_assert(CustomData_number_of_layers(loopdata, CD_MLOOPUV) != 0);
+
+ int act_uv_n = -1;
+ int ren_uv_n = -1;
+ bool calc_act = false;
+ bool calc_ren = false;
+ char act_uv_name[MAX_NAME];
+ char ren_uv_name[MAX_NAME];
+ char tangent_mask = 0;
+ char tangent_mask_curr = *tangent_mask_curr_p;
+
+ BKE_mesh_calc_loop_tangent_step_0(
+ loopdata, calc_active_tangent, tangent_names, tangent_names_len,
+ &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
+ if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
+ /* Check we have all the needed layers */
+ /* Allocate needed tangent layers */
+ for (int i = 0; i < tangent_names_len; i++)
+ if (tangent_names[i][0])
+ BKE_mesh_add_loop_tangent_named_layer_for_uv(loopdata, loopdata_out, (int)loopdata_out_len, tangent_names[i]);
+ if (calc_act && act_uv_name[0])
+ BKE_mesh_add_loop_tangent_named_layer_for_uv(loopdata, loopdata_out, (int)loopdata_out_len, act_uv_name);
+ if (calc_ren && ren_uv_name[0])
+ BKE_mesh_add_loop_tangent_named_layer_for_uv(loopdata, loopdata_out, (int)loopdata_out_len, ren_uv_name);
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ int num_face_as_quad_map;
+ int *face_as_quad_map = NULL;
+
+ /* map faces to quads */
+ if (looptri_len != mpoly_len) {
+ /* over alloc, since we dont know how many ngon or quads we have */
+
+ /* map fake face index to looptri */
+ face_as_quad_map = MEM_mallocN(sizeof(int) * looptri_len, __func__);
+ int k, j;
+ for (k = 0, j = 0; j < (int)looptri_len; k++, j++) {
+ face_as_quad_map[k] = j;
+ /* step over all quads */
+ if (mpoly[looptri[j].poly].totloop == 4) {
+ j++; /* skips the nest looptri */
+ }
+ }
+ num_face_as_quad_map = k;
+ }
+ else {
+ num_face_as_quad_map = (int)looptri_len;
+ }
+#endif
+
+ /* Calculation */
+ {
+ TaskScheduler *scheduler = BLI_task_scheduler_get();
+ TaskPool *task_pool;
+ task_pool = BLI_task_pool_create(scheduler, NULL);
+
+ tangent_mask_curr = 0;
+ /* Calculate tangent layers */
+ SGLSLMeshToTangent data_array[MAX_MTFACE];
+ const int tangent_layer_num = CustomData_number_of_layers(loopdata_out, CD_TANGENT);
+ for (int n = 0; n < tangent_layer_num; n++) {
+ int index = CustomData_get_layer_index_n(loopdata_out, CD_TANGENT, n);
+ BLI_assert(n < MAX_MTFACE);
+ SGLSLMeshToTangent *mesh2tangent = &data_array[n];
+ mesh2tangent->numTessFaces = (int)looptri_len;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ mesh2tangent->face_as_quad_map = face_as_quad_map;
+ mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
+#endif
+ mesh2tangent->mvert = mvert;
+ mesh2tangent->mpoly = mpoly;
+ mesh2tangent->mloop = mloop;
+ mesh2tangent->looptri = looptri;
+ /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
+ * have to check this is valid...
+ */
+ mesh2tangent->precomputedLoopNormals = loop_normals;
+ mesh2tangent->precomputedFaceNormals = poly_normals;
+
+ mesh2tangent->orco = NULL;
+ mesh2tangent->mloopuv = CustomData_get_layer_named(loopdata, CD_MLOOPUV, loopdata->layers[index].name);
+ if (!mesh2tangent->mloopuv) {
+ mesh2tangent->orco = vert_orco;
+ if (!mesh2tangent->orco)
+ continue;
+ }
+ mesh2tangent->tangent = loopdata_out->layers[index].data;
+
+ /* Fill the resulting tangent_mask */
+ int uv_ind = CustomData_get_named_layer_index(
+ loopdata, CD_MLOOPUV, loopdata_out->layers[index].name);
+ int uv_start = CustomData_get_layer_index(loopdata, CD_MLOOPUV);
+ BLI_assert(uv_ind != -1 && uv_start != -1);
+ BLI_assert(uv_ind - uv_start < MAX_MTFACE);
+ tangent_mask_curr |= (char)(1 << (uv_ind - uv_start));
+ BLI_task_pool_push(task_pool, DM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
+ }
+
+ BLI_assert(tangent_mask_curr == tangent_mask);
+ BLI_task_pool_work_and_wait(task_pool);
+ BLI_task_pool_free(task_pool);
+ }
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (face_as_quad_map) {
+ MEM_freeN(face_as_quad_map);
+ }
+#undef USE_LOOPTRI_DETECT_QUADS
+
+#endif
+
+ *tangent_mask_curr_p = tangent_mask_curr;
+
+ int uv_index, tan_index;
+
+ /* Update active layer index */
+ uv_index = CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, act_uv_n);
+ if (uv_index != -1) {
+ tan_index = CustomData_get_named_layer_index(loopdata_out, CD_TANGENT, loopdata->layers[uv_index].name);
+ CustomData_set_layer_active_index(loopdata_out, CD_TANGENT, tan_index);
+ }
+
+ /* Update render layer index */
+ uv_index = CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, ren_uv_n);
+ if (uv_index != -1) {
+ tan_index = CustomData_get_named_layer_index(loopdata_out, CD_TANGENT, loopdata->layers[uv_index].name);
+ CustomData_set_layer_render_index(loopdata_out, CD_TANGENT, tan_index);
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 4aeddbb4c45..54de843bc64 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -43,10 +43,11 @@
#include "BLI_math_vector.h"
#include "BKE_deform.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_mesh.h"
+#include "DEG_depsgraph.h"
+
#include "MEM_guardedalloc.h"
/* loop v/e are unsigned, so using max uint_32 value as invalid marker... */
@@ -936,7 +937,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
{
bool is_valid = true;
bool is_change_v, is_change_e, is_change_l, is_change_p;
- int tot_texpoly, tot_uvloop, tot_vcolloop;
+ int tot_uvloop, tot_vcolloop;
CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0;
is_valid &= mesh_validate_customdata(vdata, mask, do_verbose, do_fixes, &is_change_v);
@@ -944,17 +945,8 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
is_valid &= mesh_validate_customdata(ldata, mask, do_verbose, do_fixes, &is_change_l);
is_valid &= mesh_validate_customdata(pdata, mask, do_verbose, do_fixes, &is_change_p);
- tot_texpoly = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV);
tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
- if (tot_texpoly != tot_uvloop) {
- PRINT_ERR("\tCustomDataLayer mismatch, tot_texpoly(%d), tot_uvloop(%d)\n",
- tot_texpoly, tot_uvloop);
- }
- if (tot_texpoly > MAX_MTFACE) {
- PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
- MAX_MTFACE, tot_texpoly - MAX_MTFACE);
- }
if (tot_uvloop > MAX_MTFACE) {
PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
MAX_MTFACE, tot_uvloop - MAX_MTFACE);
@@ -965,18 +957,10 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
}
/* check indices of clone/stencil */
- if (do_fixes && CustomData_get_clone_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) {
- CustomData_set_layer_clone(pdata, CD_MTEXPOLY, 0);
- is_change_p = true;
- }
if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0);
is_change_l = true;
}
- if (do_fixes && CustomData_get_stencil_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) {
- CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, 0);
- is_change_p = true;
- }
if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0);
is_change_l = true;
@@ -1019,7 +1003,7 @@ int BKE_mesh_validate(Mesh *me, const int do_verbose, const int cddata_check_mas
&changed);
if (changed) {
- DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&me->id, OB_RECALC_DATA);
return true;
}
else {
@@ -1028,64 +1012,6 @@ int BKE_mesh_validate(Mesh *me, const int do_verbose, const int cddata_check_mas
}
/**
- * Duplicate of BM_mesh_cd_validate() for Mesh data.
- */
-void BKE_mesh_cd_validate(Mesh *me)
-{
- int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
- int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
- int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
- int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
- int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
- int i;
-
- /* XXX For now, do not delete those, just warn they are not really usable. */
- if (UNLIKELY(totlayer_mtex > MAX_MTFACE)) {
- printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
- MAX_MTFACE, totlayer_mtex - MAX_MTFACE);
- }
- if (UNLIKELY(totlayer_uv > MAX_MTFACE)) {
- printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
- MAX_MTFACE, totlayer_uv - MAX_MTFACE);
- }
- if (UNLIKELY(totlayer_mcol > MAX_MCOL)) {
- printf("WARNING! More VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
- MAX_MCOL, totlayer_mcol - MAX_MCOL);
- }
-
- if (LIKELY(totlayer_mtex == totlayer_uv)) {
- /* pass */
- }
- else if (totlayer_mtex < totlayer_uv) {
- do {
- const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name;
- CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name);
- CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex);
- } while (totlayer_uv != ++totlayer_mtex);
- mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
- }
- else if (totlayer_uv < totlayer_mtex) {
- do {
- const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name;
- CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name);
- CustomData_set_layer_unique_name(&me->ldata, totlayer_uv);
- } while (totlayer_mtex != ++totlayer_uv);
- uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
- }
-
- BLI_assert(totlayer_mtex == totlayer_uv);
-
- /* Check uv/tex names match as well!!! */
- for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) {
- const char *name_src = me->pdata.layers[mtex_index].name;
- const char *name_dst = me->ldata.layers[uv_index].name;
- if (!STREQ(name_src, name_dst)) {
- BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false);
- }
- }
-}
-
-/**
* Check all material indices of polygons are valid, invalid ones are set to 0.
* \returns is_valid.
*/
@@ -1105,7 +1031,7 @@ int BKE_mesh_validate_material_indices(Mesh *me)
}
if (!is_valid) {
- DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&me->id, OB_RECALC_DATA);
return true;
}
else {
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 63da1b5f9e7..7c382bccfc9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3588,6 +3588,8 @@ static void registerShaderNodes(void)
register_node_type_sh_output_lamp();
register_node_type_sh_output_material();
+ register_node_type_sh_output_metallic();
+ register_node_type_sh_output_specular();
register_node_type_sh_output_world();
register_node_type_sh_output_linestyle();
@@ -3777,3 +3779,20 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
return true;
}
+
+/* -------------------------------------------------------------------- */
+/* NodeTree kernel functions */
+
+void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
+{
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
+ if (node->custom1 == layer_index) {
+ node->custom1 = 0;
+ }
+ else if (node->custom1 > layer_index) {
+ node->custom1--;
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index b65cc408ae5..c24a6d3c791 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -78,7 +78,6 @@
#include "BKE_action.h"
#include "BKE_bullet.h"
#include "BKE_deform.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_animsys.h"
#include "BKE_anim.h"
@@ -91,6 +90,7 @@
#include "BKE_icons.h"
#include "BKE_key.h"
#include "BKE_lamp.h"
+#include "BKE_layer.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -103,6 +103,7 @@
#include "BKE_multires.h"
#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_object_facemap.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -118,6 +119,10 @@
#include "BKE_camera.h"
#include "BKE_image.h"
+#include "DEG_depsgraph.h"
+
+#include "DRW_engine.h"
+
#ifdef WITH_MOD_FLUID
#include "LBM_fluidsim.h"
#endif
@@ -129,7 +134,7 @@
#include "CCGSubSurf.h"
#include "atomic_ops.h"
-#include "GPU_material.h"
+#include "GPU_lamp.h"
/* Vertex parent modifies original BMesh which is not safe for threading.
* Ideally such a modification should be handled as a separate DAG update
@@ -154,7 +159,7 @@ void BKE_object_workob_clear(Object *workob)
void BKE_object_update_base_layer(struct Scene *scene, Object *ob)
{
- Base *base = scene->base.first;
+ BaseLegacy *base = scene->base.first;
while (base) {
if (base->object == ob) base->lay = ob->lay;
@@ -401,7 +406,7 @@ void BKE_object_free_caches(Object *object)
* guaranteed to be in a known state.
*/
if (update_flag != 0) {
- DAG_id_tag_update(&object->id, update_flag);
+ DEG_id_tag_update(&object->id, update_flag);
}
}
@@ -418,6 +423,7 @@ void BKE_object_free(Object *ob)
MEM_SAFE_FREE(ob->bb);
BLI_freelistN(&ob->defbase);
+ BLI_freelistN(&ob->fmaps);
if (ob->pose) {
BKE_pose_free_ex(ob->pose, false);
ob->pose = NULL;
@@ -448,6 +454,16 @@ void BKE_object_free(Object *ob)
}
GPU_lamp_free(ob);
+ for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
+ if (oed->storage) {
+ if (oed->free) {
+ oed->free(oed->storage);
+ }
+ MEM_freeN(oed->storage);
+ }
+ }
+ BLI_freelistN(&ob->drawdata);
+
BKE_sculptsession_free(ob);
BLI_freelistN(&ob->pc_ids);
@@ -464,6 +480,9 @@ void BKE_object_free(Object *ob)
}
BKE_previewimg_free(&ob->preview);
+
+ /* don't free, let the base free it */
+ ob->base_collection_properties = NULL;
}
/* actual check for internal data, not context or flags */
@@ -683,23 +702,26 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
/* general add: to scene, with layer from area and default name */
/* creates minimum required data, but without vertices etc. */
Object *BKE_object_add(
- Main *bmain, Scene *scene,
+ Main *bmain, Scene *scene, SceneLayer *sl,
int type, const char *name)
{
Object *ob;
Base *base;
+ LayerCollection *lc;
ob = BKE_object_add_only_object(bmain, type, name);
ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
- ob->lay = scene->lay;
-
- base = BKE_scene_base_add(scene, ob);
- BKE_scene_base_deselect_all(scene);
- BKE_scene_base_select(scene, base);
- DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ lc = BKE_layer_collection_get_active_ensure(scene, sl);
+
+ BKE_collection_object_add(scene, lc->scene_collection, ob);
+ base = BKE_scene_layer_base_find(sl, ob);
+ BKE_scene_layer_base_deselect_all(sl);
+ BKE_scene_layer_base_select(sl, base);
+
+ DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
@@ -794,9 +816,9 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
return current;
}
-bool BKE_object_lod_is_usable(Object *ob, Scene *scene)
+bool BKE_object_lod_is_usable(Object *ob, SceneLayer *sl)
{
- bool active = (scene) ? ob == OBACT : false;
+ bool active = (sl) ? ob == OBACT_NEW : false;
return (ob->mode == OB_MODE_OBJECT || !active);
}
@@ -810,11 +832,11 @@ void BKE_object_lod_update(Object *ob, const float camera_position[3])
}
}
-static Object *lod_ob_get(Object *ob, Scene *scene, int flag)
+static Object *lod_ob_get(Object *ob, SceneLayer *sl, int flag)
{
LodLevel *current = ob->currentlod;
- if (!current || !BKE_object_lod_is_usable(ob, scene))
+ if (!current || !BKE_object_lod_is_usable(ob, sl))
return ob;
while (current->prev && (!(current->flags & flag) || !current->source || current->source->type != OB_MESH)) {
@@ -824,14 +846,14 @@ static Object *lod_ob_get(Object *ob, Scene *scene, int flag)
return current->source;
}
-struct Object *BKE_object_lod_meshob_get(Object *ob, Scene *scene)
+struct Object *BKE_object_lod_meshob_get(Object *ob, SceneLayer *sl)
{
- return lod_ob_get(ob, scene, OB_LOD_USE_MESH);
+ return lod_ob_get(ob, sl, OB_LOD_USE_MESH);
}
-struct Object *BKE_object_lod_matob_get(Object *ob, Scene *scene)
+struct Object *BKE_object_lod_matob_get(Object *ob, SceneLayer *sl)
{
- return lod_ob_get(ob, scene, OB_LOD_USE_MAT);
+ return lod_ob_get(ob, sl, OB_LOD_USE_MAT);
}
#endif /* WITH_GAMEENGINE */
@@ -943,6 +965,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
psysn->effectors = NULL;
psysn->tree = NULL;
psysn->bvhtree = NULL;
+ psysn->batch_cache = NULL;
BLI_listbase_clear(&psysn->pathcachebufs);
BLI_listbase_clear(&psysn->childcachebufs);
@@ -1138,6 +1161,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
BKE_pose_rebuild(obn, obn->data);
}
defgroup_copy_list(&obn->defbase, &ob->defbase);
+ BKE_object_facemap_copy_list(&obn->fmaps, &ob->fmaps);
BKE_constraints_copy(&obn->constraints, &ob->constraints, true);
obn->mode = OB_MODE_OBJECT;
@@ -1170,6 +1194,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
BLI_listbase_clear(&obn->gpulamp);
BLI_listbase_clear(&obn->pc_ids);
+ BLI_listbase_clear(&obn->drawdata);
obn->mpath = NULL;
@@ -1265,10 +1290,10 @@ static void armature_set_id_extern(Object *ob)
unsigned int lay = arm->layer_protected;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (!(pchan->bone->layer & lay))
+ if (!(pchan->bone->layer & lay)) {
id_lib_extern((ID *)pchan->custom);
+ }
}
-
}
void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
@@ -1326,8 +1351,8 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
ob->proxy_group = gob;
id_lib_extern(&target->id);
- DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
- DAG_id_tag_update(&target->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&target->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* copy transform
* - gob means this proxy comes from a group, just apply the matrix
@@ -2486,14 +2511,14 @@ void BKE_object_foreach_display_point(
}
void BKE_scene_foreach_display_point(
- Scene *scene, View3D *v3d, const short flag,
+ Scene *scene, SceneLayer *sl,
void (*func_cb)(const float[3], void *), void *user_data)
{
Base *base;
Object *ob;
- for (base = FIRSTBASE; base; base = base->next) {
- if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag & flag) == flag) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTED) != 0)) {
ob = base->object;
if ((ob->transflag & OB_DUPLI) == 0) {
@@ -3288,33 +3313,33 @@ static void obrel_list_add(LinkNode **links, Object *ob)
}
/*
- * Iterates over all objects of the given scene.
+ * Iterates over all objects of the given scene layer.
* Depending on the eObjectSet flag:
* collect either OB_SET_ALL, OB_SET_VISIBLE or OB_SET_SELECTED objects.
* If OB_SET_VISIBLE or OB_SET_SELECTED are collected,
* then also add related objects according to the given includeFilters.
*/
-LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
+LinkNode *BKE_object_relational_superset(struct SceneLayer *scene_layer, eObjectSet objectSet, eObRelationTypes includeFilter)
{
LinkNode *links = NULL;
Base *base;
/* Remove markers from all objects */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = scene_layer->object_bases.first; base; base = base->next) {
base->object->id.tag &= ~LIB_TAG_DOIT;
}
/* iterate over all selected and visible objects */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = scene_layer->object_bases.first; base; base = base->next) {
if (objectSet == OB_SET_ALL) {
/* as we get all anyways just add it */
Object *ob = base->object;
obrel_list_add(&links, ob);
}
else {
- if ((objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base)) ||
- (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base)))
+ if ((objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE_NEW(base)) ||
+ (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE_NEW(base)))
{
Object *ob = base->object;
@@ -3343,8 +3368,8 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
/* child relationship */
if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
Base *local_base;
- for (local_base = scene->base.first; local_base; local_base = local_base->next) {
- if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) {
+ for (local_base = scene_layer->object_bases.first; local_base; local_base = local_base->next) {
+ if (BASE_EDITABLE_BGMODE_NEW(local_base)) {
Object *child = local_base->object;
if (obrel_list_test(child)) {
@@ -3388,18 +3413,11 @@ struct LinkNode *BKE_object_groups(Object *ob)
return group_linknode;
}
-void BKE_object_groups_clear(Scene *scene, Base *base, Object *object)
+void BKE_object_groups_clear(Object *ob)
{
Group *group = NULL;
-
- BLI_assert((base == NULL) || (base->object == object));
-
- if (scene && base == NULL) {
- base = BKE_scene_base_find(scene, object);
- }
-
- while ((group = BKE_group_object_find(group, base->object))) {
- BKE_group_object_unlink(group, object, scene, base);
+ while ((group = BKE_group_object_find(group, ob))) {
+ BKE_group_object_unlink(group, ob);
}
}
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index ccf2aec5c7a..455c4b6352d 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -51,6 +51,7 @@
#include "BKE_editmesh.h"
#include "BKE_object_deform.h" /* own include */
#include "BKE_object.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
/** \name Misc helpers
@@ -405,6 +406,8 @@ void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
object_defgroup_remove_edit_mode(ob, defgroup);
else
object_defgroup_remove_object_mode(ob, defgroup);
+
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
}
/**
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index e9ebd397df0..844edd87c37 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -49,7 +49,6 @@
#include "BKE_animsys.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.h"
#include "BKE_font.h"
#include "BKE_group.h"
#include "BKE_global.h"
@@ -62,6 +61,7 @@
#include "BKE_editmesh.h"
#include "BKE_anim.h"
+#include "DEG_depsgraph.h"
#include "BLI_strict_flags.h"
#include "BLI_hash.h"
@@ -259,7 +259,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
else {
unsigned int lay = ctx->scene->lay;
int baseid = 0;
- Base *base;
+ BaseLegacy *base;
for (base = ctx->scene->base.first; base; base = base->next, baseid++) {
Object *ob = base->object;
diff --git a/source/blender/blenkernel/intern/object_facemap.c b/source/blender/blenkernel/intern/object_facemap.c
new file mode 100644
index 00000000000..02dedc10026
--- /dev/null
+++ b/source/blender/blenkernel/intern/object_facemap.c
@@ -0,0 +1,259 @@
+
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/object_facemap.c
+ * \ingroup bke
+ */
+
+#include <string.h>
+
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_editmesh.h"
+#include "BKE_object.h"
+#include "BKE_object_facemap.h" /* own include */
+#include "BKE_object_deform.h"
+
+#include "BKE_depsgraph.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+#include "BLI_listbase.h"
+
+#include "BLT_translation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_define.h"
+#include "RNA_access.h"
+
+static bool fmap_unique_check(void *arg, const char *name)
+{
+ struct {Object *ob; void *fm; } *data = arg;
+
+ bFaceMap *fmap;
+
+ for (fmap = data->ob->fmaps.first; fmap; fmap = fmap->next) {
+ if (data->fm != fmap) {
+ if (!strcmp(fmap->name, name)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bFaceMap *fmap_duplicate(bFaceMap *infmap)
+{
+ bFaceMap *outfmap;
+
+ if (!infmap)
+ return NULL;
+
+ outfmap = MEM_callocN(sizeof(bFaceMap), "copy facemap");
+
+ /* For now, just copy everything over. */
+ memcpy(outfmap, infmap, sizeof(bFaceMap));
+
+ outfmap->next = outfmap->prev = NULL;
+
+ return outfmap;
+}
+
+void BKE_object_facemap_copy_list(ListBase *outbase, ListBase *inbase)
+{
+ bFaceMap *fmap, *fmapn;
+
+ BLI_listbase_clear(outbase);
+
+ for (fmap = inbase->first; fmap; fmap = fmap->next) {
+ fmapn = fmap_duplicate(fmap);
+ BLI_addtail(outbase, fmapn);
+ }
+}
+
+void BKE_object_facemap_unique_name(Object *ob, bFaceMap *fmap)
+{
+ struct {Object *ob; void *fmap; } data;
+ data.ob = ob;
+ data.fmap = fmap;
+
+ BLI_uniquename_cb(fmap_unique_check, &data, DATA_("Group"), '.', fmap->name, sizeof(fmap->name));
+}
+
+bFaceMap *BKE_object_facemap_add_name(Object *ob, const char *name)
+{
+ bFaceMap *fmap;
+
+ if (!ob || ob->type != OB_MESH)
+ return NULL;
+
+ fmap = MEM_callocN(sizeof(bFaceMap), __func__);
+
+ BLI_strncpy(fmap->name, name, sizeof(fmap->name));
+
+ BLI_addtail(&ob->fmaps, fmap);
+
+ ob->actfmap = BLI_listbase_count(&ob->fmaps);
+
+ BKE_object_facemap_unique_name(ob, fmap);
+
+ return fmap;
+}
+
+bFaceMap *BKE_object_facemap_add(Object *ob)
+{
+ return BKE_object_facemap_add_name(ob, DATA_("FaceMap"));
+}
+
+
+static void object_fmap_remove_edit_mode(Object *ob, bFaceMap *fmap, bool do_selected, bool purge)
+{
+ const int fmap_nr = BLI_findindex(&ob->fmaps, fmap);
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (me->edit_btmesh) {
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
+
+ if (cd_fmap_offset != -1) {
+ BMFace *efa;
+ BMIter iter;
+ int *map;
+
+ if (purge) {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (map) {
+ if (*map == fmap_nr)
+ *map = -1;
+ else if (*map > fmap_nr)
+ *map -= 1;
+ }
+ }
+ }
+ else {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (map && *map == fmap_nr && (!do_selected || BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
+ *map = -1;
+ }
+ }
+ }
+ }
+
+ if (ob->actfmap == BLI_listbase_count(&ob->fmaps))
+ ob->actfmap--;
+
+ BLI_remlink(&ob->fmaps, fmap);
+ MEM_freeN(fmap);
+ }
+ }
+}
+
+static void object_fmap_remove_object_mode(Object *ob, bFaceMap *fmap, bool purge)
+{
+ const int fmap_nr = BLI_findindex(&ob->fmaps, fmap);
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+ int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+ int i;
+
+ if (map) {
+ for (i = 0; i < me->totpoly; i++) {
+ if (map[i] == fmap_nr)
+ map[i] = -1;
+ else if (purge && map[i] > fmap_nr)
+ map[i]--;
+ }
+ }
+ }
+
+ if (ob->actfmap == BLI_listbase_count(&ob->fmaps))
+ ob->actfmap--;
+
+ BLI_remlink(&ob->fmaps, fmap);
+ MEM_freeN(fmap);
+ }
+}
+
+static void fmap_remove_exec(Object *ob, bFaceMap *fmap, const bool is_edit_mode, const bool purge)
+{
+ if (is_edit_mode)
+ object_fmap_remove_edit_mode(ob, fmap, false, purge);
+ else
+ object_fmap_remove_object_mode(ob, fmap, purge);
+}
+
+void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
+{
+ fmap_remove_exec(ob, fmap, BKE_object_is_in_editmode(ob), true);
+}
+
+void BKE_object_facemap_clear(Object *ob)
+{
+ bFaceMap *fmap = (bFaceMap *)ob->fmaps.first;
+
+ if (fmap) {
+ const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
+
+ while (fmap) {
+ bFaceMap *next_fmap = fmap->next;
+ fmap_remove_exec(ob, fmap, edit_mode, false);
+ fmap = next_fmap;
+ }
+ }
+ /* remove all face-maps */
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ CustomData_free_layer(&me->pdata, CD_FACEMAP, me->totpoly, 0);
+ }
+ ob->actfmap = 0;
+}
+
+int BKE_object_facemap_name_index(Object *ob, const char *name)
+{
+ return (name) ? BLI_findstringindex(&ob->fmaps, name, offsetof(bFaceMap, name)) : -1;
+}
+
+bFaceMap *BKE_object_facemap_find_name(Object *ob, const char *name)
+{
+ return BLI_findstring(&ob->fmaps, name, offsetof(bFaceMap, name));
+}
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index a531466294e..b4cf9b16247 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -43,7 +43,7 @@
#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_constraint.h"
-#include "BKE_depsgraph.h"
+#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
#include "BKE_animsys.h"
#include "BKE_displist.h"
@@ -57,15 +57,12 @@
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_material.h"
+#include "BKE_mesh.h"
#include "BKE_image.h"
#include "DEG_depsgraph.h"
-#ifdef WITH_LEGACY_DEPSGRAPH
-# define DEBUG_PRINT if (!DEG_depsgraph_use_legacy() && G.debug & G_DEBUG_DEPSGRAPH) printf
-#else
-# define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
-#endif
+#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
static ThreadMutex material_lock = BLI_MUTEX_INITIALIZER;
@@ -346,6 +343,20 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
BLI_assert(ob->type != OB_ARMATURE);
BKE_object_handle_data_update(eval_ctx, scene, ob);
+ switch (ob->type) {
+ case OB_MESH:
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+ break;
+ case OB_LATTICE:
+ BKE_lattice_batch_cache_dirty(ob->data, BKE_LATTICE_BATCH_DIRTY_ALL);
+ break;
+ case OB_CURVE:
+ case OB_FONT:
+ case OB_SURF:
+ BKE_curve_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_ALL);
+ break;
+ }
+
ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
}
diff --git a/source/blender/blenkernel/intern/outliner_treehash.c b/source/blender/blenkernel/intern/outliner_treehash.c
index f31ba34a984..3e99dbe37ca 100644
--- a/source/blender/blenkernel/intern/outliner_treehash.c
+++ b/source/blender/blenkernel/intern/outliner_treehash.c
@@ -27,6 +27,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "BKE_outliner_treehash.h"
@@ -56,7 +57,7 @@ static TseGroup *tse_group_create(void)
return tse_group;
}
-static void tse_group_add(TseGroup *tse_group, TreeStoreElem *elem)
+static void tse_group_add_element(TseGroup *tse_group, TreeStoreElem *elem)
{
if (UNLIKELY(tse_group->size == tse_group->allocated)) {
tse_group->allocated *= 2;
@@ -66,6 +67,26 @@ static void tse_group_add(TseGroup *tse_group, TreeStoreElem *elem)
tse_group->size++;
}
+static void tse_group_remove_element(TseGroup *tse_group, TreeStoreElem *elem)
+{
+ int min_allocated = MAX2(1, tse_group->allocated / 2);
+ BLI_assert(tse_group->allocated == 1 || (tse_group->allocated % 2) == 0);
+
+ tse_group->size--;
+ BLI_assert(tse_group->size >= 0);
+ for (int i = 0; i < tse_group->size; i++) {
+ if (tse_group->elems[i] == elem) {
+ memcpy(tse_group->elems[i], tse_group->elems[i + 1], (tse_group->size - (i + 1)) * sizeof(TreeStoreElem *));
+ break;
+ }
+ }
+
+ if (UNLIKELY(tse_group->size > 0 && tse_group->size <= min_allocated)) {
+ tse_group->allocated = min_allocated;
+ tse_group->elems = MEM_reallocN(tse_group->elems, sizeof(TreeStoreElem *) * tse_group->allocated);
+ }
+}
+
static void tse_group_free(TseGroup *tse_group)
{
MEM_freeN(tse_group->elems);
@@ -140,7 +161,21 @@ void BKE_outliner_treehash_add_element(void *treehash, TreeStoreElem *elem)
*val_p = tse_group_create();
}
group = *val_p;
- tse_group_add(group, elem);
+ tse_group_add_element(group, elem);
+}
+
+void BKE_outliner_treehash_remove_element(void *treehash, TreeStoreElem *elem)
+{
+ TseGroup *group = BLI_ghash_lookup(treehash, elem);
+
+ BLI_assert(group != NULL);
+ if (group->size <= 1) {
+ /* one element -> remove group completely */
+ BLI_ghash_remove(treehash, elem, NULL, free_treehash_group);
+ }
+ else {
+ tse_group_remove_element(group, elem);
+ }
}
static TseGroup *BKE_outliner_treehash_lookup_group(GHash *th, short type, short nr, struct ID *id)
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 6b954f060d3..5a85637755d 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -52,7 +52,6 @@
#include "BKE_main.h"
#include "BKE_context.h"
#include "BKE_crazyspace.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_key.h"
@@ -64,6 +63,8 @@
#include "BKE_pbvh.h"
#include "BKE_subsurf.h"
+#include "DEG_depsgraph.h"
+
#include "bmesh.h"
const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
@@ -73,9 +74,9 @@ const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
static OverlayControlFlags overlay_flags = 0;
-void BKE_paint_invalidate_overlay_tex(Scene *scene, const Tex *tex)
+void BKE_paint_invalidate_overlay_tex(Scene *scene, SceneLayer *sl, const Tex *tex)
{
- Paint *p = BKE_paint_get_active(scene);
+ Paint *p = BKE_paint_get_active(scene, sl);
Brush *br = p->brush;
if (!br)
@@ -87,9 +88,9 @@ void BKE_paint_invalidate_overlay_tex(Scene *scene, const Tex *tex)
overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY;
}
-void BKE_paint_invalidate_cursor_overlay(Scene *scene, CurveMapping *curve)
+void BKE_paint_invalidate_cursor_overlay(Scene *scene, SceneLayer *sl, CurveMapping *curve)
{
- Paint *p = BKE_paint_get_active(scene);
+ Paint *p = BKE_paint_get_active(scene, sl);
Brush *br = p->brush;
if (br && br->curve == curve)
@@ -155,13 +156,13 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode)
return NULL;
}
-Paint *BKE_paint_get_active(Scene *sce)
+Paint *BKE_paint_get_active(Scene *sce, SceneLayer *sl)
{
- if (sce) {
+ if (sce && sl) {
ToolSettings *ts = sce->toolsettings;
- if (sce->basact && sce->basact->object) {
- switch (sce->basact->object->mode) {
+ if (sl->basact && sl->basact->object) {
+ switch (sl->basact->object->mode) {
case OB_MODE_SCULPT:
return &ts->sculpt->paint;
case OB_MODE_VERTEX_PAINT:
@@ -187,14 +188,15 @@ Paint *BKE_paint_get_active(Scene *sce)
Paint *BKE_paint_get_active_from_context(const bContext *C)
{
Scene *sce = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
SpaceImage *sima;
- if (sce) {
+ if (sce && sl) {
ToolSettings *ts = sce->toolsettings;
Object *obact = NULL;
- if (sce->basact && sce->basact->object)
- obact = sce->basact->object;
+ if (sl->basact && sl->basact->object)
+ obact = sl->basact->object;
if ((sima = CTX_wm_space_image(C)) != NULL) {
if (obact && obact->mode == OB_MODE_EDIT) {
@@ -237,14 +239,15 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
{
Scene *sce = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
SpaceImage *sima;
- if (sce) {
+ if (sce && sl) {
ToolSettings *ts = sce->toolsettings;
Object *obact = NULL;
- if (sce->basact && sce->basact->object)
- obact = sce->basact->object;
+ if (sl->basact && sl->basact->object)
+ obact = sl->basact->object;
if ((sima = CTX_wm_space_image(C)) != NULL) {
if (obact && obact->mode == OB_MODE_EDIT) {
@@ -681,7 +684,7 @@ void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
sculptsession_bm_to_me_update_data_only(ob, reorder);
/* ensure the objects DerivedMesh mesh doesn't hold onto arrays now realloc'd in the mesh [#34473] */
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index bb5cea9dcc7..7901dff129e 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -78,7 +78,6 @@
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
-#include "BKE_depsgraph.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_cdderivedmesh.h"
@@ -86,6 +85,9 @@
#include "BKE_scene.h"
#include "BKE_deform.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#include "RE_render_ext.h"
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
@@ -601,6 +603,8 @@ void psys_free(Object *ob, ParticleSystem *psys)
MEM_freeN(psys->pdd);
}
+ BKE_particle_batch_cache_free(psys);
+
MEM_freeN(psys);
}
}
@@ -3153,8 +3157,8 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
psys->flag = PSYS_CURRENT;
psys->cfra = BKE_scene_frame_get_from_ctime(scene, CFRA + 1);
- DAG_relations_tag_update(G.main);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(G.main);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
return md;
}
@@ -3199,8 +3203,8 @@ void object_remove_particle_system(Scene *UNUSED(scene), Object *ob)
else
ob->mode &= ~OB_MODE_PARTICLE_EDIT;
- DAG_relations_tag_update(G.main);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(G.main);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
static void default_particle_settings(ParticleSettings *part)
@@ -3285,6 +3289,7 @@ static void default_particle_settings(ParticleSettings *part)
part->omat = 1;
part->use_modifier_stack = false;
+ part->draw_size = 4;
}
@@ -4305,3 +4310,22 @@ void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
psys->flag |= PSYS_EDITED;
}
}
+
+
+
+/* Draw Engine */
+void (*BKE_particle_batch_cache_dirty_cb)(ParticleSystem *psys, int mode) = NULL;
+void (*BKE_particle_batch_cache_free_cb)(ParticleSystem *psys) = NULL;
+
+void BKE_particle_batch_cache_dirty(ParticleSystem *psys, int mode)
+{
+ if (psys->batch_cache) {
+ BKE_particle_batch_cache_dirty_cb(psys, mode);
+ }
+}
+void BKE_particle_batch_cache_free(ParticleSystem *psys)
+{
+ if (psys->batch_cache) {
+ BKE_particle_batch_cache_free_cb(psys);
+ }
+}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 943dc781246..2da0b6aeb4f 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -78,6 +78,7 @@
#include "BKE_particle.h"
#include "BKE_global.h"
+#include "BKE_collection.h"
#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
#include "BKE_material.h"
@@ -88,7 +89,6 @@
#include "BKE_modifier.h"
#include "BKE_scene.h"
#include "BKE_bvhutils.h"
-#include "BKE_depsgraph.h"
#include "PIL_time.h"
@@ -2896,7 +2896,6 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
- Base *base;
int distr=0, alloc=0, skip=0;
if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
@@ -2941,8 +2940,9 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
/* particle instance modifier with "path" option need cached paths even if particle system doesn't */
- for (base = sim->scene->base.first; base; base= base->next) {
- ModifierData *md = modifiers_findByType(base->object, eModifierType_ParticleInstance);
+ FOREACH_SCENE_OBJECT(sim->scene, ob)
+ {
+ ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleInstance);
if (md) {
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
if (pimd->flag & eParticleInstanceFlag_Path && pimd->ob == sim->ob && pimd->psys == (psys - (ParticleSystem*)sim->ob->particlesystem.first)) {
@@ -2951,6 +2951,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
}
}
}
+ FOREACH_SCENE_OBJECT_END
if (!skip) {
psys_cache_paths(sim, cfra, use_render_params);
@@ -4320,6 +4321,8 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons
/* save matrix for duplicators, at rendertime the actual dupliobject's matrix is used so don't update! */
if (psys->renderdata==0)
invert_m4_m4(psys->imat, ob->obmat);
+
+ BKE_particle_batch_cache_dirty(psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
}
/* ID looper */
@@ -4350,7 +4353,7 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
/* **** Depsgraph evaluation **** */
-void BKE_particle_system_eval(EvaluationContext *UNUSED(eval_ctx),
+void BKE_particle_system_eval(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
ParticleSystem *psys)
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index dacaad8d703..33901d3c0d0 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -40,6 +40,7 @@
#include "BKE_paint.h"
#include "GPU_buffers.h"
+#include "GPU_immediate.h"
#include "bmesh.h"
@@ -1158,15 +1159,16 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
static void pbvh_draw_BB(PBVH *bvh)
{
- GPU_pbvh_BB_draw_init();
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
for (int a = 0; a < bvh->totnode; a++) {
PBVHNode *node = &bvh->nodes[a];
- GPU_pbvh_BB_draw(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0));
+ GPU_pbvh_BB_draw(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0), pos);
}
- GPU_pbvh_BB_draw_end();
+ immUnbindProgram();
}
static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
@@ -1739,24 +1741,6 @@ void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
{
PBVHNodeDrawData *data = data_v;
-#if 0
- /* XXX: Just some quick code to show leaf nodes in different colors */
- float col[3];
- float spec[3] = {0.0f, 0.0f, 0.0f};
-
- if (0) { //is_partial) {
- col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
- }
- else {
- srand((long long)node);
- for (int i = 0; i < 3; ++i)
- col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
- }
-
- GPU_basic_shader_colors(col, spec, 0, 1.0f);
- glColor3f(1, 0, 0);
-#endif
-
if (!(node->flag & PBVH_FullyHidden)) {
GPU_pbvh_buffers_draw(node->draw_buffers,
data->setMaterial,
@@ -1863,6 +1847,67 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*fnors)[3],
pbvh_draw_BB(bvh);
}
+struct PBVHNodeDrawCallbackData {
+
+ void (*draw_fn)(void *user_data, Batch *batch);
+ void *user_data;
+ bool fast;
+};
+
+static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
+{
+ struct PBVHNodeDrawCallbackData *data = data_v;
+
+ if (!(node->flag & PBVH_FullyHidden)) {
+ Batch *triangles = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast);
+ if (triangles != NULL) {
+ data->draw_fn(data->user_data, triangles);
+ }
+ }
+}
+
+/**
+ * Version of #BKE_pbvh_draw that runs a callback.
+ */
+void BKE_pbvh_draw_cb(
+ PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast,
+ void (*draw_fn)(void *user_data, Batch *batch), void *user_data)
+{
+ struct PBVHNodeDrawCallbackData draw_data = {
+ .fast = fast,
+ .draw_fn = draw_fn,
+ .user_data = user_data,
+ };
+ PBVHNode **nodes;
+ int totnode;
+
+ for (int a = 0; a < bvh->totnode; a++)
+ pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
+
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
+ &nodes, &totnode);
+
+ pbvh_update_normals(bvh, nodes, totnode, fnors);
+ pbvh_update_draw_buffers(bvh, nodes, totnode);
+
+ if (nodes) MEM_freeN(nodes);
+
+ if (planes) {
+ BKE_pbvh_search_callback(
+ bvh, BKE_pbvh_node_planes_contain_AABB,
+ planes, pbvh_node_draw_cb, &draw_data);
+ }
+ else {
+ BKE_pbvh_search_callback(
+ bvh, NULL,
+ NULL, pbvh_node_draw_cb, &draw_data);
+ }
+#if 0
+ if (G.debug_value == 14)
+ pbvh_draw_BB(bvh);
+#endif
+}
+
void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces,
DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
{
@@ -2072,22 +2117,22 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
}
-void pbvh_show_diffuse_color_set(PBVH *bvh, bool show_diffuse_color)
+bool pbvh_has_mask(PBVH *bvh)
{
- bool has_mask = false;
-
switch (bvh->type) {
case PBVH_GRIDS:
- has_mask = (bvh->gridkey.has_mask != 0);
- break;
+ return (bvh->gridkey.has_mask != 0);
case PBVH_FACES:
- has_mask = (bvh->vdata && CustomData_get_layer(bvh->vdata,
- CD_PAINT_MASK));
- break;
+ return (bvh->vdata && CustomData_get_layer(bvh->vdata,
+ CD_PAINT_MASK));
case PBVH_BMESH:
- has_mask = (bvh->bm && (CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK) != -1));
- break;
+ return (bvh->bm && (CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK) != -1));
}
- bvh->show_diffuse_color = !has_mask || show_diffuse_color;
+ return false;
+}
+
+void pbvh_show_diffuse_color_set(PBVH *bvh, bool show_diffuse_color)
+{
+ bvh->show_diffuse_color = !pbvh_has_mask(bvh) || show_diffuse_color;
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index a7e00a8103a..0b152534dcb 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -3652,7 +3652,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
stime = ptime = PIL_check_seconds_timer();
for (int fr = CFRA; fr <= endframe; fr += baker->quick_step, CFRA = fr) {
- BKE_scene_update_for_newframe(G.main->eval_ctx, bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(G.main->eval_ctx, bmain, scene);
if (baker->update_progress) {
float progress = ((float)(CFRA - startframe)/(float)(endframe - startframe));
@@ -3738,7 +3738,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
CFRA = cfrao;
if (bake) { /* already on cfra unless baking */
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
}
/* TODO: call redraw all windows somehow */
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index b3a36bfb089..aec635feffa 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -55,7 +55,6 @@
#include "DNA_scene_types.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_depsgraph.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -1589,7 +1588,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
}
/* advance simulation, we can only step one frame forward */
- if (can_simulate) {
+ if (ctime == rbw->ltime + 1) {
/* write cache for first frame when on second frame */
if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
BKE_ptcache_write(&pid, startframe);
@@ -1652,7 +1651,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
/* -------------------- */
/* Depsgraph evaluation */
-void BKE_rigidbody_rebuild_sim(EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_rebuild_sim(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene)
{
float ctime = BKE_scene_frame_get(scene);
@@ -1667,7 +1666,7 @@ void BKE_rigidbody_rebuild_sim(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_rigidbody_eval_simulation(EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_eval_simulation(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene)
{
float ctime = BKE_scene_frame_get(scene);
@@ -1682,7 +1681,7 @@ void BKE_rigidbody_eval_simulation(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_rigidbody_object_sync_transforms(EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_object_sync_transforms(struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5933aaccd66..9de3ab5a93b 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -67,8 +67,8 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_cachefile.h"
+#include "BKE_collection.h"
#include "BKE_colortools.h"
-#include "BKE_depsgraph.h"
#include "BKE_editmesh.h"
#include "BKE_fcurve.h"
#include "BKE_freestyle.h"
@@ -78,6 +78,7 @@
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_linestyle.h"
@@ -95,6 +96,8 @@
#include "BKE_world.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "RE_engine.h"
@@ -107,6 +110,8 @@
const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER";
const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME";
+const char *RE_engine_id_BLENDER_CLAY = "BLENDER_CLAY";
+const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
const char *RE_engine_id_CYCLES = "CYCLES";
void free_avicodecdata(AviCodecData *acd)
@@ -154,13 +159,66 @@ static void remove_sequencer_fcurves(Scene *sce)
}
}
+/* copy SceneCollection tree but keep pointing to the same objects */
+static void scene_collection_copy(SceneCollection *scn, SceneCollection *sc)
+{
+ BLI_duplicatelist(&scn->objects, &sc->objects);
+ for (LinkData *link = scn->objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
+
+ BLI_duplicatelist(&scn->filter_objects, &sc->filter_objects);
+ for (LinkData *link = scn->filter_objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
+
+ BLI_duplicatelist(&scn->scene_collections, &sc->scene_collections);
+ SceneCollection *nscn = scn->scene_collections.first; /* nested SceneCollection new */
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ scene_collection_copy(nscn, nsc);
+ nscn = nscn->next;
+ }
+}
+
+/* Find the equivalent SceneCollection in the new tree */
+static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *scn, SceneCollection *sc)
+{
+ if (sc == sc_reference) {
+ return scn;
+ }
+
+ SceneCollection *nscn = scn->scene_collections.first; /* nested master collection new */
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+
+ SceneCollection *found = scene_collection_from_new_tree(sc_reference, nscn, nsc);
+ if (found) {
+ return found;
+ }
+ nscn = nscn->next;
+ }
+ return NULL;
+}
+
+/* recreate the LayerCollection tree */
+static void layer_collections_recreate(SceneLayer *sl, ListBase *lb, SceneCollection *mcn, SceneCollection *mc)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+
+ SceneCollection *sc = scene_collection_from_new_tree(lc->scene_collection, mcn, mc);
+ BLI_assert(sc);
+
+ /* instead of syncronizing both trees we simply re-create it */
+ BKE_collection_link(sl, sc);
+ }
+}
+
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
{
Scene *scen;
SceneRenderLayer *srl, *new_srl;
FreestyleLineSet *lineset;
ToolSettings *ts;
- Base *base, *obase;
+ BaseLegacy *legacy_base, *olegacy_base;
if (type == SCE_COPY_EMPTY) {
ListBase rl, rv;
@@ -196,7 +254,6 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
scen->theDag = NULL;
scen->depsgraph = NULL;
scen->obedit = NULL;
- scen->stats = NULL;
scen->fps_info = NULL;
if (sce->rigidbody_world)
@@ -214,14 +271,14 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
BKE_libblock_relink_ex(bmain, scen->nodetree, &sce->id, &scen->id, false);
}
- obase = sce->base.first;
- base = scen->base.first;
- while (base) {
- id_us_plus(&base->object->id);
- if (obase == sce->basact) scen->basact = base;
+ olegacy_base = sce->base.first;
+ legacy_base = scen->base.first;
+ while (legacy_base) {
+ id_us_plus(&legacy_base->object->id);
+ if (olegacy_base == sce->basact) scen->basact = legacy_base;
- obase = obase->next;
- base = base->next;
+ olegacy_base = olegacy_base->next;
+ legacy_base = legacy_base->next;
}
/* copy action and remove animation used by sequencer */
@@ -247,6 +304,44 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
}
new_srl = new_srl->next;
}
+
+ /* layers and collections */
+ scen->collection = MEM_dupallocN(sce->collection);
+ SceneCollection *mcn = BKE_collection_master(scen);
+ SceneCollection *mc = BKE_collection_master(sce);
+
+ /* recursively creates a new SceneCollection tree */
+ scene_collection_copy(mcn, mc);
+
+ IDPropertyTemplate val = {0};
+ BLI_duplicatelist(&scen->render_layers, &sce->render_layers);
+ SceneLayer *new_sl = scen->render_layers.first;
+ for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+ new_sl->stats = NULL;
+ new_sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ new_sl->properties_evaluated = NULL;
+
+ /* we start fresh with no overrides and no visibility flags set
+ * instead of syncing both trees we simply unlink and relink the scene collection */
+ BLI_listbase_clear(&new_sl->layer_collections);
+ BLI_listbase_clear(&new_sl->object_bases);
+ layer_collections_recreate(new_sl, &sl->layer_collections, mcn, mc);
+
+
+ if (sl->basact) {
+ Object *active_ob = sl->basact->object;
+ for (Base *base = new_sl->object_bases.first; base; base = base->next) {
+ if (base->object == active_ob) {
+ new_sl->basact = base;
+ break;
+ }
+ }
+ }
+ new_sl = new_sl->next;
+ }
+
+ scen->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ scen->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
}
/* copy color management settings */
@@ -360,6 +455,15 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
BKE_previewimg_id_copy(&scen->id, &sce->id);
+ if (type != SCE_COPY_NEW) {
+ if (sce->collection_properties) {
+ IDP_MergeGroup(scen->collection_properties, sce->collection_properties, true);
+ }
+ if (sce->layer_properties) {
+ IDP_MergeGroup(scen->layer_properties, sce->layer_properties, true);
+ }
+ }
+
return scen;
}
@@ -465,11 +569,10 @@ void BKE_scene_free(Scene *sce)
sce->toolsettings = NULL;
}
- DAG_scene_free(sce);
+ DEG_scene_graph_free(sce);
if (sce->depsgraph)
DEG_graph_free(sce->depsgraph);
-
- MEM_SAFE_FREE(sce->stats);
+
MEM_SAFE_FREE(sce->fps_info);
BKE_sound_destroy_scene(sce);
@@ -478,6 +581,30 @@ void BKE_scene_free(Scene *sce)
BKE_previewimg_free(&sce->preview);
curvemapping_free_data(&sce->r.mblur_shutter_curve);
+
+ for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+ BKE_scene_layer_free(sl);
+ }
+ BLI_freelistN(&sce->render_layers);
+
+ /* Master Collection */
+ BKE_collection_master_free(sce);
+ MEM_freeN(sce->collection);
+ sce->collection = NULL;
+
+ /* LayerCollection engine settings. */
+ if (sce->collection_properties) {
+ IDP_FreeProperty(sce->collection_properties);
+ MEM_freeN(sce->collection_properties);
+ sce->collection_properties = NULL;
+ }
+
+ /* Render engine setting. */
+ if (sce->layer_properties) {
+ IDP_FreeProperty(sce->layer_properties);
+ MEM_freeN(sce->layer_properties);
+ sce->layer_properties = NULL;
+ }
}
void BKE_scene_init(Scene *sce)
@@ -733,7 +860,7 @@ void BKE_scene_init(Scene *sce)
sce->gm.angulardeactthreshold = 1.0f;
sce->gm.deactivationtime = 0.0f;
- sce->gm.flag = GAME_DISPLAY_LISTS;
+ sce->gm.flag = 0;
sce->gm.matmode = GAME_MAT_MULTITEX;
sce->gm.obstacleSimulation = OBSTSIMULATION_NONE;
@@ -827,6 +954,20 @@ void BKE_scene_init(Scene *sce)
sce->toolsettings->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
sce->toolsettings->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
sce->toolsettings->gpencil_ima_align = GP_PROJECT_VIEWSPACE;
+
+ /* Master Collection */
+ sce->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
+ BLI_strncpy(sce->collection->name, "Master Collection", sizeof(sce->collection->name));
+
+ /* Engine settings */
+ IDPropertyTemplate val = {0};
+ sce->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_layer_collection_engine_settings_create(sce->collection_properties);
+
+ sce->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_scene_layer_engine_settings_create(sce->layer_properties);
+
+ BKE_scene_layer_add(sce, "Render Layer");
}
Scene *BKE_scene_add(Main *bmain, const char *name)
@@ -842,9 +983,9 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
return sce;
}
-Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
+BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
{
- Base *base;
+ BaseLegacy *base;
for (base = scene->base.first; base; base = base->next) {
if (STREQ(base->object->id.name + 2, name)) {
@@ -855,9 +996,9 @@ Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
return base;
}
-Base *BKE_scene_base_find(Scene *scene, Object *ob)
+BaseLegacy *BKE_scene_base_find(Scene *scene, Object *ob)
{
- return BLI_findptr(&scene->base, ob, offsetof(Base, object));
+ return BLI_findptr(&scene->base, ob, offsetof(BaseLegacy, object));
}
/**
@@ -868,11 +1009,10 @@ Base *BKE_scene_base_find(Scene *scene, Object *ob)
void BKE_scene_set_background(Main *bmain, Scene *scene)
{
Scene *sce;
- Base *base;
+ BaseLegacy *base;
Object *ob;
Group *group;
GroupObject *go;
- int flag;
/* check for cyclic sets, for reading old files but also for definite security (py?) */
BKE_scene_validate_setscene(bmain, scene);
@@ -896,7 +1036,7 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
/* sort baselist for scene and sets */
for (sce = scene; sce; sce = sce->set)
- DAG_scene_relations_rebuild(bmain, sce);
+ DEG_scene_relations_rebuild(bmain, sce);
/* copy layers and flags from bases to objects */
for (base = scene->base.first; base; base = base->next) {
@@ -904,13 +1044,7 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
ob->lay = base->lay;
/* group patch... */
- base->flag &= ~(OB_FROMGROUP);
- flag = ob->flag & (OB_FROMGROUP);
- base->flag |= flag;
-
- /* not too nice... for recovering objects with lost data */
- //if (ob->pose == NULL) base->flag &= ~OB_POSEMODE;
- ob->flag = base->flag;
+ BKE_scene_base_flag_sync_from_base(base);
}
/* no full animation update, this to enable render code to work (render code calls own animation updates) */
}
@@ -931,7 +1065,7 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
- Scene **scene, int val, Base **base, Object **ob)
+ Scene **scene, int val, BaseLegacy **base, Object **ob)
{
bool run_again = true;
@@ -1013,7 +1147,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
}
/* handle dupli's */
if (iter->dupob) {
- (*base)->flag |= OB_FROMDUPLI;
+ (*base)->flag_legacy |= OB_FROMDUPLI;
*ob = iter->dupob->ob;
iter->phase = F_DUPLI;
@@ -1032,7 +1166,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
}
else if (iter->phase == F_DUPLI) {
iter->phase = F_SCENE;
- (*base)->flag &= ~OB_FROMDUPLI;
+ (*base)->flag_legacy &= ~OB_FROMDUPLI;
if (iter->dupli_refob) {
/* Restore last object's real matrix. */
@@ -1057,9 +1191,22 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
return iter->phase;
}
+Scene *BKE_scene_find_from_collection(const Main *bmain, const SceneCollection *scene_collection)
+{
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+ for (SceneLayer *layer = scene->render_layers.first; layer; layer = layer->next) {
+ if (BKE_scene_layer_has_collection(layer, scene_collection)) {
+ return scene;
+ }
+ }
+ }
+
+ return NULL;
+}
+
Object *BKE_scene_camera_find(Scene *sc)
{
- Base *base;
+ BaseLegacy *base;
for (base = sc->base.first; base; base = base->next)
if (base->object->type == OB_CAMERA)
@@ -1161,47 +1308,54 @@ char *BKE_scene_find_last_marker_name(Scene *scene, int frame)
return best_marker ? best_marker->name : NULL;
}
+void BKE_scene_remove_rigidbody_object(Scene *scene, Object *ob)
+{
+ /* remove rigid body constraint from world before removing object */
+ if (ob->rigidbody_constraint)
+ BKE_rigidbody_remove_constraint(scene, ob);
+ /* remove rigid body object from world before removing object */
+ if (ob->rigidbody_object)
+ BKE_rigidbody_remove_object(scene, ob);
+}
-Base *BKE_scene_base_add(Scene *sce, Object *ob)
+BaseLegacy *BKE_scene_base_add(Scene *sce, Object *ob)
{
- Base *b = MEM_callocN(sizeof(*b), __func__);
+ BaseLegacy *b = MEM_callocN(sizeof(*b), __func__);
BLI_addhead(&sce->base, b);
b->object = ob;
- b->flag = ob->flag;
+ b->flag_legacy = ob->flag;
b->lay = ob->lay;
return b;
}
-void BKE_scene_base_unlink(Scene *sce, Base *base)
+void BKE_scene_base_unlink(Scene *sce, BaseLegacy *base)
{
- /* remove rigid body constraint from world before removing object */
- if (base->object->rigidbody_constraint)
- BKE_rigidbody_remove_constraint(sce, base->object);
- /* remove rigid body object from world before removing object */
- if (base->object->rigidbody_object)
- BKE_rigidbody_remove_object(sce, base->object);
-
+ BKE_scene_remove_rigidbody_object(sce, base->object);
+
BLI_remlink(&sce->base, base);
if (sce->basact == base)
sce->basact = NULL;
}
+/* deprecated, use BKE_scene_layer_base_deselect_all */
void BKE_scene_base_deselect_all(Scene *sce)
{
- Base *b;
+ BaseLegacy *b;
for (b = sce->base.first; b; b = b->next) {
- b->flag &= ~SELECT;
- b->object->flag = b->flag;
+ b->flag_legacy &= ~SELECT;
+ int flag = b->object->flag & (OB_FROMGROUP);
+ b->object->flag = b->flag_legacy;
+ b->object->flag |= flag;
}
}
-void BKE_scene_base_select(Scene *sce, Base *selbase)
+void BKE_scene_base_select(Scene *sce, BaseLegacy *selbase)
{
- selbase->flag |= SELECT;
- selbase->object->flag = selbase->flag;
+ selbase->flag_legacy |= SELECT;
+ selbase->object->flag = selbase->flag_legacy;
sce->basact = selbase;
}
@@ -1255,109 +1409,6 @@ void BKE_scene_frame_set(struct Scene *scene, double cfra)
scene->r.cfra = (int)intpart;
}
-#ifdef WITH_LEGACY_DEPSGRAPH
-/* drivers support/hacks
- * - this method is called from scene_update_tagged_recursive(), so gets included in viewport + render
- * - these are always run since the depsgraph can't handle non-object data
- * - these happen after objects are all done so that we can read in their final transform values,
- * though this means that objects can't refer to scene info for guidance...
- */
-static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
-{
- SceneRenderLayer *srl;
- float ctime = BKE_scene_frame_get(scene);
-
- /* scene itself */
- if (scene->adt && scene->adt->drivers.first) {
- BKE_animsys_evaluate_animdata(scene, &scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
- }
-
- /* world */
- /* TODO: what about world textures? but then those have nodes too... */
- if (scene->world) {
- ID *wid = (ID *)scene->world;
- AnimData *adt = BKE_animdata_from_id(wid);
-
- if (adt && adt->drivers.first)
- BKE_animsys_evaluate_animdata(scene, wid, adt, ctime, ADT_RECALC_DRIVERS);
- }
-
- /* nodes */
- if (scene->nodetree) {
- ID *nid = (ID *)scene->nodetree;
- AnimData *adt = BKE_animdata_from_id(nid);
-
- if (adt && adt->drivers.first)
- BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS);
- }
-
- /* world nodes */
- if (scene->world && scene->world->nodetree) {
- ID *nid = (ID *)scene->world->nodetree;
- AnimData *adt = BKE_animdata_from_id(nid);
-
- if (adt && adt->drivers.first)
- BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS);
- }
-
- /* freestyle */
- for (srl = scene->r.layers.first; srl; srl = srl->next) {
- FreestyleConfig *config = &srl->freestyleConfig;
- FreestyleLineSet *lineset;
-
- for (lineset = config->linesets.first; lineset; lineset = lineset->next) {
- if (lineset->linestyle) {
- ID *lid = &lineset->linestyle->id;
- AnimData *adt = BKE_animdata_from_id(lid);
-
- if (adt && adt->drivers.first)
- BKE_animsys_evaluate_animdata(scene, lid, adt, ctime, ADT_RECALC_DRIVERS);
- }
- }
- }
-}
-
-/* deps hack - do extra recalcs at end */
-static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent)
-{
- Base *base;
-
- scene->customdata_mask = scene_parent->customdata_mask;
-
- /* sets first, we allow per definition current scene to have
- * dependencies on sets, but not the other way around. */
- if (scene->set)
- scene_depsgraph_hack(eval_ctx, scene->set, scene_parent);
-
- for (base = scene->base.first; base; base = base->next) {
- Object *ob = base->object;
-
- if (ob->depsflag) {
- int recalc = 0;
- // printf("depshack %s\n", ob->id.name + 2);
-
- if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC)
- recalc |= OB_RECALC_OB;
- if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC)
- recalc |= OB_RECALC_DATA;
-
- ob->recalc |= recalc;
- BKE_object_handle_update(eval_ctx, scene_parent, ob);
-
- if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) {
- GroupObject *go;
-
- for (go = ob->dup_group->gobject.first; go; go = go->next) {
- if (go->ob)
- go->ob->recalc |= recalc;
- }
- BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, ob, ob->dup_group);
- }
- }
- }
-}
-#endif /* WITH_LEGACY_DEPSGRAPH */
-
/* That's like really a bummer, because currently animation data for armatures
* might want to use pose, and pose might be missing on the object.
* This happens when changing visible layers, which leads to situations when
@@ -1373,7 +1424,7 @@ static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scen
static void scene_armature_depsgraph_workaround(Main *bmain)
{
Object *ob;
- if (BLI_listbase_is_empty(&bmain->armature) || !DAG_id_type_tagged(bmain, ID_OB)) {
+ if (BLI_listbase_is_empty(&bmain->armature) || !DEG_id_type_tagged(bmain, ID_OB)) {
return;
}
for (ob = bmain->object.first; ob; ob = ob->id.next) {
@@ -1386,372 +1437,25 @@ static void scene_armature_depsgraph_workaround(Main *bmain)
}
#endif
-#ifdef WITH_LEGACY_DEPSGRAPH
-static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
-{
- if (scene->set)
- scene_rebuild_rbw_recursive(scene->set, ctime);
-
- if (BKE_scene_check_rigidbody_active(scene))
- BKE_rigidbody_rebuild_world(scene, ctime);
-}
-
-static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
-{
- if (scene->set)
- scene_do_rb_simulation_recursive(scene->set, ctime);
-
- if (BKE_scene_check_rigidbody_active(scene))
- BKE_rigidbody_do_simulation(scene, ctime);
-}
-#endif
-
-/* Used to visualize CPU threads activity during threaded object update,
- * would pollute STDERR with whole bunch of timing information which then
- * could be parsed and nicely visualized.
- */
-#ifdef WITH_LEGACY_DEPSGRAPH
-# undef DETAILED_ANALYSIS_OUTPUT
-#else
-/* ALWAYS KEEY DISABLED! */
-# undef DETAILED_ANALYSIS_OUTPUT
-#endif
-
-/* Mballs evaluation uses BKE_scene_base_iter_next which calls
- * duplilist for all objects in the scene. This leads to conflict
- * accessing and writing same data from multiple threads.
- *
- * Ideally Mballs shouldn't do such an iteration and use DAG
- * queries instead. For the time being we've got new DAG
- * let's keep it simple and update mballs in a single thread.
- */
-#define MBALL_SINGLETHREAD_HACK
-
-#ifdef WITH_LEGACY_DEPSGRAPH
-typedef struct StatisicsEntry {
- struct StatisicsEntry *next, *prev;
- Object *object;
- double start_time;
- double duration;
-} StatisicsEntry;
-
-typedef struct ThreadedObjectUpdateState {
- /* TODO(sergey): We might want this to be per-thread object. */
- EvaluationContext *eval_ctx;
- Scene *scene;
- Scene *scene_parent;
- double base_time;
-
-#ifdef MBALL_SINGLETHREAD_HACK
- bool has_mballs;
-#endif
-
- /* Execution statistics */
- bool has_updated_objects;
- ListBase *statistics;
-} ThreadedObjectUpdateState;
-
-static void scene_update_object_add_task(void *node, void *user_data);
-
-static void scene_update_all_bases(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent)
-{
- Base *base;
-
- for (base = scene->base.first; base; base = base->next) {
- Object *object = base->object;
-
- BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, true);
-
- if (object->dup_group && (object->transflag & OB_DUPLIGROUP))
- BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, object, object->dup_group);
-
- /* always update layer, so that animating layers works (joshua july 2010) */
- /* XXX commented out, this has depsgraph issues anyway - and this breaks setting scenes
- * (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */
- // base->lay = ob->lay;
- }
-}
-
-static void scene_update_object_func(TaskPool * __restrict pool, void *taskdata, int threadid)
-{
-/* Disable print for now in favor of summary statistics at the end of update. */
-#define PRINT if (false) printf
-
- ThreadedObjectUpdateState *state = (ThreadedObjectUpdateState *) BLI_task_pool_userdata(pool);
- void *node = taskdata;
- Object *object = DAG_get_node_object(node);
- EvaluationContext *eval_ctx = state->eval_ctx;
- Scene *scene = state->scene;
- Scene *scene_parent = state->scene_parent;
-
-#ifdef MBALL_SINGLETHREAD_HACK
- if (object && object->type == OB_MBALL) {
- state->has_mballs = true;
- }
- else
-#endif
- if (object) {
- double start_time = 0.0;
- bool add_to_stats = false;
-
- if (G.debug & G_DEBUG_DEPSGRAPH) {
- if (object->recalc & OB_RECALC_ALL) {
- printf("Thread %d: update object %s\n", threadid, object->id.name);
- }
-
- start_time = PIL_check_seconds_timer();
-
- if (object->recalc & OB_RECALC_ALL) {
- state->has_updated_objects = true;
- add_to_stats = true;
- }
- }
-
- /* We only update object itself here, dupli-group will be updated
- * separately from main thread because of we've got no idea about
- * dependencies inside the group.
- */
- BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, false);
-
- /* Calculate statistics. */
- if (add_to_stats) {
- StatisicsEntry *entry;
-
- entry = MEM_mallocN(sizeof(StatisicsEntry), "update thread statistics");
- entry->object = object;
- entry->start_time = start_time;
- entry->duration = PIL_check_seconds_timer() - start_time;
-
- BLI_addtail(&state->statistics[threadid], entry);
- }
- }
- else {
- PRINT("Threda %d: update node %s\n", threadid,
- DAG_get_node_name(scene, node));
- }
-
- /* Update will decrease child's valency and schedule child with zero valency. */
- DAG_threaded_update_handle_node_updated(node, scene_update_object_add_task, pool);
-
-#undef PRINT
-}
-
-static void scene_update_object_add_task(void *node, void *user_data)
-{
- TaskPool *task_pool = user_data;
-
- BLI_task_pool_push(task_pool, scene_update_object_func, node, false, TASK_PRIORITY_LOW);
-}
-
-static void print_threads_statistics(ThreadedObjectUpdateState *state)
-{
- int i, tot_thread;
- double finish_time;
-
- if ((G.debug & G_DEBUG_DEPSGRAPH) == 0) {
- return;
- }
-
-#ifdef DETAILED_ANALYSIS_OUTPUT
- if (state->has_updated_objects) {
- tot_thread = BLI_system_thread_count();
-
- fprintf(stderr, "objects update base time %f\n", state->base_time);
-
- for (i = 0; i < tot_thread; i++) {
- StatisicsEntry *entry;
- for (entry = state->statistics[i].first;
- entry;
- entry = entry->next)
- {
- fprintf(stderr, "thread %d object %s start_time %f duration %f\n",
- i, entry->object->id.name + 2,
- entry->start_time, entry->duration);
- }
- BLI_freelistN(&state->statistics[i]);
- }
- }
-#else
- finish_time = PIL_check_seconds_timer();
- tot_thread = BLI_system_thread_count();
- int total_objects = 0;
-
- for (i = 0; i < tot_thread; i++) {
- int thread_total_objects = 0;
- double thread_total_time = 0.0;
- StatisicsEntry *entry;
-
- if (state->has_updated_objects) {
- /* Don't pollute output if no objects were updated. */
- for (entry = state->statistics[i].first;
- entry;
- entry = entry->next)
- {
- thread_total_objects++;
- thread_total_time += entry->duration;
- }
-
- printf("Thread %d: total %d objects in %f sec.\n",
- i,
- thread_total_objects,
- thread_total_time);
-
- for (entry = state->statistics[i].first;
- entry;
- entry = entry->next)
- {
- printf(" %s in %f sec\n", entry->object->id.name + 2, entry->duration);
- }
-
- total_objects += thread_total_objects;
- }
-
- BLI_freelistN(&state->statistics[i]);
- }
- if (state->has_updated_objects) {
- printf("Scene updated %d objects in %f sec\n",
- total_objects,
- finish_time - state->base_time);
- }
-#endif
-}
-
-static bool scene_need_update_objects(Main *bmain)
-{
- return
- /* Object datablocks themselves (for OB_RECALC_OB) */
- DAG_id_type_tagged(bmain, ID_OB) ||
-
- /* Objects data datablocks (for OB_RECALC_DATA) */
- DAG_id_type_tagged(bmain, ID_ME) || /* Mesh */
- DAG_id_type_tagged(bmain, ID_CU) || /* Curve */
- DAG_id_type_tagged(bmain, ID_MB) || /* MetaBall */
- DAG_id_type_tagged(bmain, ID_LA) || /* Lamp */
- DAG_id_type_tagged(bmain, ID_LT) || /* Lattice */
- DAG_id_type_tagged(bmain, ID_CA) || /* Camera */
- DAG_id_type_tagged(bmain, ID_KE) || /* KE */
- DAG_id_type_tagged(bmain, ID_SPK) || /* Speaker */
- DAG_id_type_tagged(bmain, ID_AR); /* Armature */
-}
-
-static void scene_update_objects(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Scene *scene_parent)
-{
- TaskScheduler *task_scheduler;
- TaskPool *task_pool;
- ThreadedObjectUpdateState state;
- bool need_singlethread_pass;
- bool need_free_scheduler;
-
- /* Early check for whether we need to invoke all the task-based
- * things (spawn new ppol, traverse dependency graph and so on).
- *
- * Basically if there's no ID datablocks tagged for update which
- * corresponds to object->recalc flags (which are checked in
- * BKE_object_handle_update() then we do nothing here.
- */
- if (!scene_need_update_objects(bmain)) {
- return;
- }
-
- state.eval_ctx = eval_ctx;
- state.scene = scene;
- state.scene_parent = scene_parent;
-
- if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) {
- task_scheduler = BLI_task_scheduler_create(1);
- need_free_scheduler = true;
- }
- else {
- task_scheduler = BLI_task_scheduler_get();
- need_free_scheduler = false;
- }
-
- /* Those are only needed when blender is run with --debug argument. */
- if (G.debug & G_DEBUG_DEPSGRAPH) {
- const int tot_thread = BLI_task_scheduler_num_threads(task_scheduler);
- state.statistics = MEM_callocN(tot_thread * sizeof(*state.statistics),
- "scene update objects stats");
- state.has_updated_objects = false;
- state.base_time = PIL_check_seconds_timer();
- }
-
-#ifdef MBALL_SINGLETHREAD_HACK
- state.has_mballs = false;
-#endif
-
- task_pool = BLI_task_pool_create(task_scheduler, &state);
-
- DAG_threaded_update_begin(scene, scene_update_object_add_task, task_pool);
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
-
- if (G.debug & G_DEBUG_DEPSGRAPH) {
- print_threads_statistics(&state);
- MEM_freeN(state.statistics);
- }
-
- /* We do single thread pass to update all the objects which are in cyclic dependency.
- * Such objects can not be handled by a generic DAG traverse and it's really tricky
- * to detect whether cycle could be solved or not.
- *
- * In this situation we simply update all remaining objects in a single thread and
- * it'll happen in the same exact order as it was in single-threaded DAG.
- *
- * We couldn't use threaded update for objects which are in cycle because they might
- * access data of each other which is being re-evaluated.
- *
- * Also, as was explained above, for now we also update all the mballs in single thread.
- *
- * - sergey -
- */
- need_singlethread_pass = DAG_is_acyclic(scene) == false;
-#ifdef MBALL_SINGLETHREAD_HACK
- need_singlethread_pass |= state.has_mballs;
-#endif
-
- if (need_singlethread_pass) {
- scene_update_all_bases(eval_ctx, scene, scene_parent);
- }
-
- if (need_free_scheduler) {
- BLI_task_scheduler_free(task_scheduler);
- }
-}
-
-static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Scene *scene_parent)
-{
- scene->customdata_mask = scene_parent->customdata_mask;
-
- /* sets first, we allow per definition current scene to have
- * dependencies on sets, but not the other way around. */
- if (scene->set)
- scene_update_tagged_recursive(eval_ctx, bmain, scene->set, scene_parent);
-
- /* scene objects */
- scene_update_objects(eval_ctx, bmain, scene, scene_parent);
-
- /* scene drivers... */
- scene_update_drivers(bmain, scene);
-
- /* update masking curves */
- BKE_mask_update_scene(bmain, scene);
-
-}
-#endif /* WITH_LEGACY_DEPSGRAPH */
-
static bool check_rendered_viewport_visible(Main *bmain)
{
wmWindowManager *wm = bmain->wm.first;
wmWindow *window;
for (window = wm->windows.first; window != NULL; window = window->next) {
bScreen *screen = window->screen;
+ Scene *scene = screen->scene;
ScrArea *area;
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ if ((type->draw_engine != NULL) || (type->render_to_view == NULL)) {
+ continue;
+ }
+ const bool use_legacy = (type->flag & RE_USE_LEGACY_PIPELINE) != 0;
for (area = screen->areabase.first; area != NULL; area = area->next) {
View3D *v3d = area->spacedata.first;
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
- if (v3d->drawtype == OB_RENDER) {
+ if (v3d->drawtype == OB_RENDER || !use_legacy) {
return true;
}
}
@@ -1780,7 +1484,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
if (check_rendered_viewport_visible(bmain)) {
BMesh *bm = mesh->edit_btmesh->bm;
BM_mesh_bm_to_me(bm, mesh, (&(struct BMeshToMeshParams){0}));
- DAG_id_tag_update(&mesh->id, 0);
+ DEG_id_tag_update(&mesh->id, 0);
}
}
}
@@ -1789,24 +1493,13 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *scene)
{
Scene *sce_iter;
-#ifdef WITH_LEGACY_DEPSGRAPH
- bool use_new_eval = !DEG_depsgraph_use_legacy();
-#endif
-
- /* keep this first */
- BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
/* (re-)build dependency graph if needed */
for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set) {
- DAG_scene_relations_update(bmain, sce_iter);
+ DEG_scene_relations_update(bmain, sce_iter);
/* Uncomment this to check if graph was properly tagged for update. */
#if 0
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (use_new_eval)
-#endif
- {
- DAG_scene_relations_validate(bmain, sce_iter);
- }
+ DEG_scene_relations_validate(bmain, sce_iter);
#endif
}
@@ -1814,7 +1507,7 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
prepare_mesh_for_viewport_render(bmain, scene);
/* flush recalc flags to dependencies */
- DAG_ids_flush_tagged(bmain);
+ DEG_ids_flush_tagged(bmain);
/* removed calls to quick_cache, see pointcache.c */
@@ -1829,17 +1522,9 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
*
* in the future this should handle updates for all datablocks, not
* only objects and scenes. - brecht */
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!use_new_eval) {
- scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
- }
- else
-#endif
- {
- DEG_evaluate_on_refresh(eval_ctx, scene->depsgraph, scene);
- /* TODO(sergey): This is to beocme a node in new depsgraph. */
- BKE_mask_update_scene(bmain, scene);
- }
+ DEG_evaluate_on_refresh(eval_ctx, scene->depsgraph, scene);
+ /* TODO(sergey): This is to beocme a node in new depsgraph. */
+ BKE_mask_update_scene(bmain, scene);
/* update sound system animation (TODO, move to depsgraph) */
BKE_sound_update_scene(bmain, scene);
@@ -1853,110 +1538,35 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0);
}
- /* Extra call here to recalc material animation.
- *
- * Need to do this so changing material settings from the graph/dopesheet
- * will update stuff in the viewport.
- */
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!use_new_eval && DAG_id_type_tagged(bmain, ID_MA)) {
- Material *material;
- float ctime = BKE_scene_frame_get(scene);
-
- for (material = bmain->mat.first;
- material;
- material = material->id.next)
- {
- AnimData *adt = BKE_animdata_from_id(&material->id);
- if (adt && (adt->recalc & ADT_RECALC_ANIM))
- BKE_animsys_evaluate_animdata(scene, &material->id, adt, ctime, 0);
- }
- }
-
- /* Also do the same for node trees. */
- if (!use_new_eval && DAG_id_type_tagged(bmain, ID_NT)) {
- float ctime = BKE_scene_frame_get(scene);
-
- FOREACH_NODETREE(bmain, ntree, id)
- {
- AnimData *adt = BKE_animdata_from_id(&ntree->id);
- if (adt && (adt->recalc & ADT_RECALC_ANIM))
- BKE_animsys_evaluate_animdata(scene, &ntree->id, adt, ctime, 0);
- }
- FOREACH_NODETREE_END
- }
-#endif
-
- /* notify editors and python about recalc */
- BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
-
/* Inform editors about possible changes. */
- DAG_ids_check_recalc(bmain, scene, false);
+ DEG_ids_check_recalc(bmain, scene, false);
/* clear recalc flags */
- DAG_ids_clear_recalc(bmain);
+ DEG_ids_clear_recalc(bmain);
}
/* applies changes right away, does all sets too */
-void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay)
-{
- BKE_scene_update_for_newframe_ex(eval_ctx, bmain, sce, lay, false);
-}
-
-void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay, bool do_invisible_flush)
+void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce)
{
float ctime = BKE_scene_frame_get(sce);
Scene *sce_iter;
-#ifdef DETAILED_ANALYSIS_OUTPUT
- double start_time = PIL_check_seconds_timer();
-#endif
-#ifdef WITH_LEGACY_DEPSGRAPH
- bool use_new_eval = !DEG_depsgraph_use_legacy();
-#else
- /* TODO(sergey): Pass to evaluation routines instead of storing layer in the graph? */
- (void) do_invisible_flush;
-#endif
- DAG_editors_update_pre(bmain, sce, true);
+ DEG_editors_update_pre(bmain, sce, true);
/* keep this first */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
- BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
/* update animated image textures for particles, modifiers, gpu, etc,
* call this at the start so modifiers with textures don't lag 1 frame */
BKE_image_update_frame(bmain, sce->r.cfra);
-
-#ifdef WITH_LEGACY_DEPSGRAPH
- /* rebuild rigid body worlds before doing the actual frame update
- * this needs to be done on start frame but animation playback usually starts one frame later
- * we need to do it here to avoid rebuilding the world on every simulation change, which can be very expensive
- */
- if (!use_new_eval) {
- scene_rebuild_rbw_recursive(sce, ctime);
- }
-#endif
-
+
BKE_sound_set_cfra(sce->r.cfra);
-
+
/* clear animation overrides */
/* XXX TODO... */
for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set)
- DAG_scene_relations_update(bmain, sce_iter);
-
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!use_new_eval) {
- /* flush recalc flags to dependencies, if we were only changing a frame
- * this would not be necessary, but if a user or a script has modified
- * some datablock before BKE_scene_update_tagged was called, we need the flush */
- DAG_ids_flush_tagged(bmain);
-
- /* Following 2 functions are recursive
- * so don't call within 'scene_update_tagged_recursive' */
- DAG_scene_update_flags(bmain, sce, lay, true, do_invisible_flush); // only stuff that moves or needs display still
- }
-#endif
+ DEG_scene_relations_update(bmain, sce_iter);
BKE_mask_evaluate_all_masks(bmain, ctime, true);
@@ -1967,67 +1577,26 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
scene_armature_depsgraph_workaround(bmain);
#endif
- /* All 'standard' (i.e. without any dependencies) animation is handled here,
- * with an 'local' to 'macro' order of evaluation. This should ensure that
- * settings stored nestled within a hierarchy (i.e. settings in a Texture block
- * can be overridden by settings from Scene, which owns the Texture through a hierarchy
- * such as Scene->World->MTex/Texture) can still get correctly overridden.
- */
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!use_new_eval) {
- BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
- /*...done with recursive funcs */
- }
-#endif
-
/* clear "LIB_TAG_DOIT" flag from all materials, to prevent infinite recursion problems later
* when trying to find materials with drivers that need evaluating [#32017]
*/
BKE_main_id_tag_idcode(bmain, ID_MA, LIB_TAG_DOIT, false);
BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false);
- /* run rigidbody sim */
- /* NOTE: current position is so that rigidbody sim affects other objects, might change in the future */
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!use_new_eval) {
- scene_do_rb_simulation_recursive(sce, ctime);
- }
-#endif
-
/* BKE_object_handle_update() on all objects, groups and sets */
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (use_new_eval) {
- DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
- }
- else {
- scene_update_tagged_recursive(eval_ctx, bmain, sce, sce);
- }
-#else
- DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
-#endif
+ DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime);
/* update sound system animation (TODO, move to depsgraph) */
BKE_sound_update_scene(bmain, sce);
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!use_new_eval) {
- scene_depsgraph_hack(eval_ctx, sce, sce);
- }
-#endif
-
/* notify editors and python about recalc */
- BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
/* Inform editors about possible changes. */
- DAG_ids_check_recalc(bmain, sce, true);
+ DEG_ids_check_recalc(bmain, sce, true);
/* clear recalc flags */
- DAG_ids_clear_recalc(bmain);
-
-#ifdef DETAILED_ANALYSIS_OUTPUT
- fprintf(stderr, "frame update start_time %f duration %f\n", start_time, PIL_check_seconds_timer() - start_time);
-#endif
+ DEG_ids_clear_recalc(bmain);
}
/* return default layer, also used to patch old files */
@@ -2082,15 +1651,7 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree) {
- bNode *node;
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
- if (node->custom1 == act)
- node->custom1 = 0;
- else if (node->custom1 > act)
- node->custom1--;
- }
- }
+ BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
}
}
@@ -2177,21 +1738,37 @@ float get_render_aosss_error(const RenderData *r, float error)
return error;
}
-/* helper function for the SETLOOPER macro */
+/**
+ * Helper function for the SETLOOPER macro
+ *
+ * It iterates over the bases of the active layer and then the bases
+ * of the active layer of the background (set) scenes recursively.
+ */
Base *_setlooper_base_step(Scene **sce_iter, Base *base)
{
if (base && base->next) {
/* common case, step to the next */
return base->next;
}
- else if (base == NULL && (*sce_iter)->base.first) {
+ else if (base == NULL) {
/* first time looping, return the scenes first base */
- return (Base *)(*sce_iter)->base.first;
+
+ /* for the first loop we should get the layer from context */
+ SceneLayer *sl = BKE_scene_layer_context_active((*sce_iter));
+
+ if (sl->object_bases.first) {
+ return (Base *)sl->object_bases.first;
+ }
+ /* no base on this scene layer */
+ goto next_set;
}
else {
+next_set:
/* reached the end, get the next base in the set */
while ((*sce_iter = (*sce_iter)->set)) {
- base = (Base *)(*sce_iter)->base.first;
+ SceneLayer *sl = BKE_scene_layer_render_active((*sce_iter));
+ base = (Base *)sl->object_bases.first;
+
if (base) {
return base;
}
@@ -2236,23 +1813,60 @@ bool BKE_scene_uses_blender_game(const Scene *scene)
return STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME);
}
-void BKE_scene_base_flag_to_objects(struct Scene *scene)
+bool BKE_scene_uses_blender_eevee(const Scene *scene)
+{
+ return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE);
+}
+
+void BKE_scene_base_flag_to_objects(SceneLayer *sl)
{
- Base *base = scene->base.first;
+ Base *base = sl->object_bases.first;
while (base) {
- base->object->flag = base->flag;
+ BKE_scene_object_base_flag_sync_from_base(base);
base = base->next;
}
}
-void BKE_scene_base_flag_from_objects(struct Scene *scene)
+void BKE_scene_base_flag_sync_from_base(BaseLegacy *base)
{
- Base *base = scene->base.first;
+ BKE_scene_object_base_flag_sync_from_base(base);
+}
- while (base) {
- base->flag = base->object->flag;
- base = base->next;
+void BKE_scene_base_flag_sync_from_object(BaseLegacy *base)
+{
+ BKE_scene_object_base_flag_sync_from_object(base);
+}
+
+void BKE_scene_object_base_flag_sync_from_base(Base *base)
+{
+ Object *ob = base->object;
+
+ /* keep the object only flags untouched */
+ int flag = ob->flag & OB_FROMGROUP;
+
+ ob->flag = base->flag;
+ ob->flag |= flag;
+
+ if ((base->flag & BASE_SELECTED) != 0) {
+ ob->flag |= SELECT;
+ }
+ else {
+ ob->flag &= ~SELECT;
+ }
+}
+
+void BKE_scene_object_base_flag_sync_from_object(Base *base)
+{
+ Object *ob = base->object;
+ base->flag = ob->flag;
+
+ if ((ob->flag & SELECT) != 0) {
+ base->flag |= BASE_SELECTED;
+ BLI_assert((base->flag & BASE_SELECTABLED) != 0);
+ }
+ else {
+ base->flag &= ~BASE_SELECTED;
}
}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 857bd5447c8..c5d00d63b6d 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -50,6 +50,7 @@
#include "BLI_utildefines.h"
#include "BLI_rect.h"
+#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_screen.h"
@@ -180,6 +181,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
BLI_listbase_clear(&newar->panels_category_active);
BLI_listbase_clear(&newar->ui_lists);
newar->swinid = 0;
+ newar->manipulator_map = NULL;
newar->regiontimer = NULL;
/* use optional regiondata callback */
@@ -288,6 +290,17 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
}
}
+
+/**
+ * Avoid bad-level calls to #WM_manipulatormap_delete.
+ */
+static void (*region_free_manipulatormap_callback)(struct wmManipulatorMap *) = NULL;
+
+void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *))
+{
+ region_free_manipulatormap_callback = callback;
+}
+
/* not region itself */
void BKE_area_region_free(SpaceType *st, ARegion *ar)
{
@@ -337,6 +350,8 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
MEM_freeN(uilst->properties);
}
}
+
+ region_free_manipulatormap_callback(ar->manipulator_map);
BLI_freelistN(&ar->ui_lists);
BLI_freelistN(&ar->ui_previews);
BLI_freelistN(&ar->panels_category);
@@ -380,6 +395,8 @@ void BKE_screen_free(bScreen *sc)
BLI_freelistN(&sc->vertbase);
BLI_freelistN(&sc->edgebase);
BLI_freelistN(&sc->areabase);
+
+ BKE_previewimg_free(&sc->preview);
}
/* for depsgraph */
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 5bb765d012e..2df601ee4f5 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -63,9 +63,9 @@
#include "BLT_translation.h"
#include "BKE_animsys.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_movieclip.h"
@@ -75,6 +75,8 @@
#include "BKE_library.h"
#include "BKE_idprop.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#include "RE_pipeline.h"
@@ -3301,10 +3303,10 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
context->scene->r.seq_prev_type = 3 /* == OB_SOLID */;
/* opengl offscreen render */
- BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
ibuf = sequencer_view3d_cb(
/* set for OpenGL render (NULL when scrubbing) */
- scene, camera, width, height, IB_rect,
+ scene, BKE_scene_layer_render_active(scene), camera, width, height, IB_rect,
context->scene->r.seq_prev_type,
(context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0,
use_gpencil, use_background, scene->r.alphamode,
@@ -3334,7 +3336,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
if (re == NULL)
re = RE_NewRender(scene->id.name);
- BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
RE_BlenderFrame(re, context->bmain, scene, NULL, camera, scene->lay, frame, false);
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
@@ -3394,7 +3396,7 @@ finally:
scene->r.subframe = orig_data.subframe;
if (is_frame_update) {
- BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
}
#ifdef DURIAN_CAMERA_SWITCH
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index d0ef5cfc092..667f8d1e8c7 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -126,7 +126,7 @@ void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(s
void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity),
int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color),
float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {}
-struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; }
+struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), SceneLayer *UNUSED(sl), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; }
float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; }
#endif /* WITH_SMOKE */
@@ -693,16 +693,16 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData
#ifdef WITH_SMOKE
// forward decleration
-static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene);
+static void smoke_calc_transparency(SmokeDomainSettings *sds, SceneLayer *sl);
static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
-static int get_lamp(Scene *scene, float *light)
+static int get_lamp(SceneLayer *sl, float *light)
{
Base *base_tmp = NULL;
int found_lamp = 0;
// try to find a lamp, preferably local
- for (base_tmp = scene->base.first; base_tmp; base_tmp = base_tmp->next) {
+ for (base_tmp = FIRSTBASE_NEW; base_tmp; base_tmp = base_tmp->next) {
if (base_tmp->object->type == OB_LAMP) {
Lamp *la = base_tmp->object->data;
@@ -2683,7 +2683,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob)
return result;
}
-static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
+static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm)
{
if ((smd->type & MOD_SMOKE_TYPE_FLOW))
{
@@ -2810,7 +2810,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *
}
// create shadows before writing cache so they get stored
- smoke_calc_transparency(sds, scene);
+ smoke_calc_transparency(sds, sl);
if (sds->wt && sds->total_cells > 1) {
smoke_turbulence_step(sds->wt, sds->fluid);
@@ -2827,13 +2827,13 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *
}
}
-struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
+struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm)
{
/* lock so preview render does not read smoke data while it gets modified */
if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
BLI_rw_mutex_lock(smd->domain->fluid_mutex, THREAD_LOCK_WRITE);
- smokeModifier_process(smd, scene, ob, dm);
+ smokeModifier_process(smd, scene, sl, ob, dm);
if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
BLI_rw_mutex_unlock(smd->domain->fluid_mutex);
@@ -2948,7 +2948,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
cb(result, input, res, pixel, tRay, correct);
}
-static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene)
+static void smoke_calc_transparency(SmokeDomainSettings *sds, SceneLayer *sl)
{
float bv[6] = {0};
float light[3];
@@ -2956,7 +2956,7 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene)
float *density = smoke_get_density(sds->fluid);
float correct = -7.0f * sds->dx;
- if (!get_lamp(scene, light)) return;
+ if (!get_lamp(sl, light)) return;
/* convert light pos to sim cell space */
mul_m4_v3(sds->imat, light);
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 4f73e153074..11c692077c0 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -512,7 +512,7 @@ static void ccd_build_deflector_hash_single(GHash *hash, Object *ob)
/**
* \note group overrides scene when not NULL.
*/
-static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
+static void ccd_build_deflector_hash(SceneLayer *sl, Group *group, Object *vertexowner, GHash *hash)
{
Object *ob;
@@ -530,10 +530,10 @@ static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexo
}
}
else {
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
/*Only proceed for mesh object in same layer */
- if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
- ob= base->object;
+ if (base->object->type == OB_MESH) {
+ ob = base->object;
if ((vertexowner) && (ob == vertexowner)) {
/* if vertexowner is given we don't want to check collision with owner object */
continue;
@@ -558,7 +558,7 @@ static void ccd_update_deflector_hash_single(GHash *hash, Object *ob)
/**
* \note group overrides scene when not NULL.
*/
-static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
+static void ccd_update_deflector_hash(SceneLayer *sl, Group *group, Object *vertexowner, GHash *hash)
{
Object *ob;
@@ -576,10 +576,10 @@ static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertex
}
}
else {
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
/*Only proceed for mesh object in same layer */
- if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
- ob= base->object;
+ if (base->object->type == OB_MESH) {
+ ob = base->object;
if (ob == vertexowner) {
/* if vertexowner is given we don't want to check collision with owner object */
continue;
@@ -977,7 +977,7 @@ static void free_softbody_intern(SoftBody *sb)
/**
* \note group overrides scene when not NULL.
*/
-static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
+static bool are_there_deflectors(SceneLayer *sl, Group *group)
{
if (group) {
for (GroupObject *go = group->gobject.first; go; go = go->next) {
@@ -986,8 +986,8 @@ static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
}
}
else {
- for (Base *base = scene->base.first; base; base= base->next) {
- if ( (base->lay & layer) && base->object->pd) {
+ for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ if (base->object->pd) {
if (base->object->pd->deflect)
return 1;
}
@@ -997,9 +997,9 @@ static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
return 0;
}
-static int query_external_colliders(Scene *scene, Group *group, Object *me)
+static int query_external_colliders(SceneLayer *sl, Group *group)
{
- return(are_there_deflectors(scene, group, me->lay));
+ return(are_there_deflectors(sl, group));
}
/* --- dependency information functions*/
@@ -2233,7 +2233,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
MEM_freeN(sb_threads);
}
-static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow)
+static void softbody_calc_forcesEx(Scene *scene, SceneLayer *sl, Object *ob, float forcetime, float timenow)
{
/* rule we never alter free variables :bp->vec bp->pos in here !
* this will ruin adaptive stepsize AKA heun! (BM)
@@ -2249,7 +2249,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
/* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */
/* check conditions for various options */
- do_deflector= query_external_colliders(scene, sb->collision_group, ob);
+ do_deflector= query_external_colliders(sl, sb->collision_group);
/* do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); */ /* UNUSED */
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2278,11 +2278,11 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
}
-static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, float timenow)
+static void softbody_calc_forces(Scene *scene, SceneLayer *sl, Object *ob, float forcetime, float timenow)
{
/* redirection to the new threaded Version */
if (!(G.debug_value & 0x10)) { // 16
- softbody_calc_forcesEx(scene, ob, forcetime, timenow);
+ softbody_calc_forcesEx(scene, sl, ob, forcetime, timenow);
return;
}
else {
@@ -2313,7 +2313,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
/* check conditions for various options */
- do_deflector= query_external_colliders(scene, sb->collision_group, ob);
+ do_deflector= query_external_colliders(sl, sb->collision_group);
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -3510,7 +3510,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
}
}
-static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
+static void softbody_step(Scene *scene, SceneLayer *sl, Object *ob, SoftBody *sb, float dtime)
{
/* the simulator */
float forcetime;
@@ -3524,11 +3524,11 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
*/
if (dtime < 0 || dtime > 10.5f) return;
- ccd_update_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
+ ccd_update_deflector_hash(sl, sb->collision_group, ob, sb->scratch->colliderhash);
if (sb->scratch->needstobuildcollider) {
- if (query_external_colliders(scene, sb->collision_group, ob)) {
- ccd_build_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
+ if (query_external_colliders(sl, sb->collision_group)) {
+ ccd_build_deflector_hash(sl, sb->collision_group, ob, sb->scratch->colliderhash);
}
sb->scratch->needstobuildcollider=0;
}
@@ -3558,12 +3558,12 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
sb->scratch->flag &= ~SBF_DOFUZZY;
/* do predictive euler step */
- softbody_calc_forces(scene, ob, forcetime, timedone/dtime);
+ softbody_calc_forces(scene, sl, ob, forcetime, timedone/dtime);
softbody_apply_forces(ob, forcetime, 1, NULL, mid_flags);
/* crop new slope values to do averaged slope step */
- softbody_calc_forces(scene, ob, forcetime, timedone/dtime);
+ softbody_calc_forces(scene, sl, ob, forcetime, timedone/dtime);
softbody_apply_forces(ob, forcetime, 2, &err, mid_flags);
softbody_apply_goalsnap(ob);
@@ -3644,7 +3644,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
}
/* simulates one step. framenr is in frames */
-void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
+void sbObjectStep(Scene *scene, SceneLayer *sl, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
{
SoftBody *sb= ob->soft;
PointCache *cache;
@@ -3652,7 +3652,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
float dtime, timescale;
int framedelta, framenr, startframe, endframe;
int cache_result;
-
cache= sb->pointcache;
framenr= (int)cfra;
@@ -3721,7 +3720,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
}
/* try to read from cache */
- bool can_simulate = (framenr == sb->last_frame+1) && !(cache->flag & PTCACHE_BAKED);
+ bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED);
cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, can_simulate);
@@ -3760,7 +3759,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
dtime = framedelta*timescale;
/* do simulation */
- softbody_step(scene, ob, sb, dtime);
+ softbody_step(scene, sl, ob, sb, dtime);
softbody_to_object(ob, vertexCos, numVerts, 0);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index c4665c40ec4..1f72744bdee 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1901,7 +1901,8 @@ static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
no[1] = b_dZ * a_cX - b_dX * a_cZ;
no[2] = b_dX * a_cY - b_dY * a_cX;
- /* don't normalize, GL_NORMALIZE is enabled */
+ normalize_v3(no); /* we no longer rely on GL_NORMALIZE */
+
glNormal3fv(no);
}
@@ -3409,261 +3410,6 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
#undef PASSATTRIB
}
-static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
- DMSetDrawOptionsTex drawParams,
- DMSetDrawOptionsMappedTex drawParamsMapped,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int colType;
- const MLoopCol *mloopcol = NULL;
- MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- DMDrawOption draw_option;
- int i, totpoly;
- bool flush;
- const bool use_tface = (flag & DM_DRAW_USE_ACTIVE_UV) != 0;
- const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0;
- unsigned int next_actualFace;
- unsigned int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
- int mat_index;
- int tot_element, start_element, tot_drawn;
-
- if (use_colors) {
- colType = CD_TEXTURE_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- if (!mloopcol) {
- colType = CD_PREVIEW_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- }
- if (!mloopcol) {
- colType = CD_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- }
- }
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- const int active_uv_layer = CustomData_get_active_layer_index(&dm->loopData, CD_MLOOPUV);
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, active_uv_layer) == false)) {
- return;
- }
- if (drawParams == NULL) {
- ccgSubSurf_drawGLMesh(ss, true, -1, -1);
- return;
- }
- const int level = ccgSubSurf_getSubdivisionLevels(ss);
- const int face_side = 1 << level;
- const int grid_side = 1 << (level - 1);
- const int face_patches = face_side * face_side;
- const int grid_patches = grid_side * grid_side;
- const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
- int current_patch = 0;
- int mat_nr = -1;
- int start_draw_patch = 0, num_draw_patches = 0;
- bool draw_smooth = false;
- for (i = 0; i < num_base_faces; ++i) {
- const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
- const int num_patches = (num_face_verts == 4) ? face_patches
- : num_face_verts * grid_patches;
- if (faceFlags) {
- mat_nr = faceFlags[i].mat_nr;
- draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
- }
- else {
- mat_nr = 0;
- draw_smooth = false;
- }
-
- if (drawParams != NULL) {
- MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[i] : NULL;
- draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
- }
- else {
- draw_option = (drawParamsMapped)
- ? drawParamsMapped(userData, i, mat_nr)
- : DM_DRAW_OPTION_NORMAL;
- }
-
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1);
-
- const int next_face = min_ii(i + 1, num_base_faces - 1);
- if (!flush && compareDrawOptions) {
- flush |= compareDrawOptions(userData, i, next_face) == 0;
- }
- if (!flush && faceFlags) {
- bool new_draw_smooth = (faceFlags[next_face].flag & ME_SMOOTH);
- flush |= (new_draw_smooth != draw_smooth);
- }
-
- current_patch += num_patches;
-
- if (flush) {
- if (draw_option != DM_DRAW_OPTION_SKIP) {
- num_draw_patches += num_patches;
- }
- if (num_draw_patches != 0) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- start_draw_patch = current_patch;
- num_draw_patches = 0;
- }
- else {
- num_draw_patches += num_patches;
- }
- }
- glShadeModel(GL_SMOOTH);
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgdm_pbvh_update(ccgdm);
-
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- GPU_triangle_setup(dm);
- if (flag & DM_DRAW_USE_TEXPAINT_UV)
- GPU_texpaint_uv_setup(dm);
- else
- GPU_uv_setup(dm);
- if (mloopcol) {
- GPU_color_setup(dm, colType);
- }
-
- next_actualFace = 0;
-
- /* lastFlag = 0; */ /* UNUSED */
- for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
- GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
- next_actualFace = bufmat->polys[0];
- totpoly = bufmat->totpolys;
-
- tot_element = 0;
- tot_drawn = 0;
- start_element = 0;
-
- for (i = 0; i < totpoly; i++) {
- int polyindex = bufmat->polys[i];
- CCGFace *f = ccgdm->faceMap[polyindex].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- int index = ccgDM_getFaceMapIndex(ss, f);
- int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int mat_nr;
- int facequads = numVerts * gridFaces * gridFaces;
- int actualFace = ccgdm->faceMap[polyindex].startFace;
-
- if (i != totpoly - 1) {
- polyindex = bufmat->polys[i + 1];
- next_actualFace = ccgdm->faceMap[polyindex].startFace;
- }
-
- if (faceFlags) {
- mat_nr = faceFlags[orig_index].mat_nr;
- }
- else {
- mat_nr = 0;
- }
-
- if (drawParams) {
- MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[actualFace] : NULL;
- draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
- }
- else if (index != ORIGINDEX_NONE)
- draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
- else
- draw_option = DM_DRAW_OPTION_NORMAL;
-
- /* flush buffer if current triangle isn't drawable or it's last triangle */
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 1);
-
- if (!flush && compareDrawOptions) {
- /* also compare draw options and flush buffer if they're different
- * need for face selection highlight in edit mode */
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- tot_element += facequads * 6;
-
- if (flush) {
- if (draw_option != DM_DRAW_OPTION_SKIP)
- tot_drawn += facequads * 6;
-
- if (tot_drawn) {
- if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
- GPU_color_switch(1);
- else
- GPU_color_switch(0);
-
- GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn);
- tot_drawn = 0;
- }
-
- start_element = tot_element;
- }
- else {
- tot_drawn += facequads * 6;
- }
- }
- }
-
-
- GPU_buffers_unbind();
-}
-
-static void ccgDM_drawFacesTex(DerivedMesh *dm,
- DMSetDrawOptionsTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
-}
-
-static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptionsMappedTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
-}
-
-/* same as cdDM_drawUVEdges */
-static void ccgDM_drawUVEdges(DerivedMesh *dm)
-{
- MPoly *mpoly = dm->getPolyArray(dm);
- int totpoly = dm->getNumPolys(dm);
- int prevstart = 0;
- bool prevdraw = true;
- int curpos = 0;
- int i;
-
- GPU_uvedge_setup(dm);
- for (i = 0; i < totpoly; i++, mpoly++) {
- const bool draw = (mpoly->flag & ME_HIDE) == 0;
-
- if (prevdraw != draw) {
- if (prevdraw && (curpos != prevstart)) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- prevstart = curpos;
- }
-
- curpos += 2 * mpoly->totloop;
- prevdraw = draw;
- }
- if (prevdraw && (curpos != prevstart)) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- GPU_buffers_unbind();
-}
-
static void ccgDM_drawMappedFaces(DerivedMesh *dm,
DMSetDrawOptions setDrawOptions,
DMSetMaterial setMaterial,
@@ -4583,13 +4329,10 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
ccgdm->dm.drawEdges = ccgDM_drawEdges;
ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
- ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
- ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
- ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
@@ -5044,8 +4787,7 @@ static bool subsurf_use_gpu_backend(SubsurfFlags flags)
*/
return
(flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
- (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE) &&
- (openSubdiv_supportGPUDisplay());
+ (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
#else
(void)flags;
return false;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 298790a9e9b..9a6db855694 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -58,7 +58,6 @@
#include "DNA_node_types.h"
#include "DNA_material_types.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
diff --git a/source/blender/blenlib/BLI_callbacks.h b/source/blender/blenlib/BLI_callbacks.h
index fdffbeb4c8d..be53d1f603b 100644
--- a/source/blender/blenlib/BLI_callbacks.h
+++ b/source/blender/blenlib/BLI_callbacks.h
@@ -49,8 +49,6 @@ typedef enum {
BLI_CB_EVT_LOAD_POST,
BLI_CB_EVT_SAVE_PRE,
BLI_CB_EVT_SAVE_POST,
- BLI_CB_EVT_SCENE_UPDATE_PRE,
- BLI_CB_EVT_SCENE_UPDATE_POST,
BLI_CB_EVT_GAME_PRE,
BLI_CB_EVT_GAME_POST,
BLI_CB_EVT_VERSION_UPDATE,
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 7cf3e97bdc9..8bf5c3da90d 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -32,6 +32,7 @@
* \ingroup bli
*/
+#include "BLI_blenlib.h"
#include "BLI_sys_types.h" /* for bool */
#include "BLI_compiler_attrs.h"
diff --git a/source/blender/blenlib/BLI_iterator.h b/source/blender/blenlib/BLI_iterator.h
new file mode 100644
index 00000000000..a2ec21d89b3
--- /dev/null
+++ b/source/blender/blenlib/BLI_iterator.h
@@ -0,0 +1,55 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_ITERATOR_H__
+#define __BLI_ITERATOR_H__
+
+/** \file BLI_iterator.h
+ * \ingroup bli
+ */
+
+typedef struct BLI_Iterator {
+ void *current; /* current pointer we iterate over */
+ void *data; /* stored data required for this iterator */
+ bool valid;
+} BLI_Iterator;
+
+typedef void (*IteratorCb)(BLI_Iterator *iter);
+typedef void (*IteratorBeginCb)(BLI_Iterator *iter, void *data_in);
+
+#define ITER_BEGIN(callback_begin, callback_next, callback_end, _data_in, _type, _instance) \
+{ \
+ _type _instance; \
+ IteratorCb callback_end_func = callback_end; \
+ BLI_Iterator iter_macro; \
+ for (callback_begin(&iter_macro, (_data_in)); \
+ iter_macro.valid; \
+ callback_next(&iter_macro)) \
+ { \
+ _instance = (_type ) iter_macro.current;
+
+#define ITER_END \
+ } \
+ callback_end_func(&iter_macro); \
+}
+
+#endif /* __BLI_ITERATOR_H__ */
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index b06944e4985..c1e28d5ebc3 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -77,6 +77,7 @@ int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2);
+void BLI_listbases_swaplinks(struct ListBase *listbasea, struct ListBase *listbaseb, void *vlinka, void *vlinkb) ATTR_NONNULL(2, 3);
void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2);
void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2);
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 5e6b1256d30..34fc52c12c0 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -141,7 +141,11 @@ MINLINE void float_to_byte_dither_v3(unsigned char b[3], const float f[3], float
#define rgba_char_args_set_fl(col, r, g, b, a) \
rgba_char_args_set(col, (r) * 255, (g) * 255, (b) * 255, (a) * 255)
+#define rgba_float_args_set_ch(col, r, g, b, a) \
+ rgba_float_args_set(col, (r) / 255.0f, (g) / 255.0f, (b) / 255.0f, (a) / 255.0f)
+
MINLINE void rgba_char_args_set(char col[4], const char r, const char g, const char b, const char a);
+MINLINE void rgba_float_args_set(float col[4], const float r, const float g, const float b, const float a);
MINLINE void rgba_char_args_test_set(char col[4], const char r, const char g, const char b, const char a);
MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack);
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index d0dfad2a02f..90aff1fcbbc 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -46,31 +46,43 @@ void unit_m2(float R[2][2]);
void unit_m3(float R[3][3]);
void unit_m4(float R[4][4]);
-void copy_m2_m2(float R[2][2], float A[2][2]);
-void copy_m3_m3(float R[3][3], float A[3][3]);
-void copy_m4_m4(float R[4][4], float A[4][4]);
-void copy_m3_m4(float R[3][3], float A[4][4]);
-void copy_m4_m3(float R[4][4], float A[3][3]);
+void copy_m2_m2(float R[2][2], const float A[2][2]);
+void copy_m3_m3(float R[3][3], const float A[3][3]);
+void copy_m4_m4(float R[4][4], const float A[4][4]);
+void copy_m3_m4(float R[3][3], const float A[4][4]);
+void copy_m4_m3(float R[4][4], const float A[3][3]);
/* double->float */
-void copy_m3_m3d(float R[3][3], double A[3][3]);
+void copy_m3_m3d(float R[3][3], const double A[3][3]);
void swap_m3m3(float A[3][3], float B[3][3]);
void swap_m4m4(float A[4][4], float B[4][4]);
/******************************** Arithmetic *********************************/
-void add_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
-void add_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
+void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]);
+void add_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]);
-void sub_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
-void sub_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
+void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]);
+void sub_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]);
-void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
-void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]);
-void mul_m4_m4m3(float R[4][4], float A[4][4], float B[3][3]);
-void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
-void mul_m3_m3m4(float R[3][3], float A[4][4], float B[3][3]);
+void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]);
+void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4]);
+void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3]);
+void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]);
+void mul_m3_m3m4(float R[3][3], const float A[4][4], const float B[3][3]);
+
+/* special matrix multiplies
+ * uniq: R <-- AB, R is neither A nor B
+ * pre: R <-- AR
+ * post: R <-- RB
+ */
+void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]);
+void mul_m3_m3_pre(float R[3][3], const float A[3][3]);
+void mul_m3_m3_post(float R[3][3], const float B[3][3]);
+void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]);
+void mul_m4_m4_pre(float R[4][4], const float A[4][4]);
+void mul_m4_m4_post(float R[4][4], const float B[4][4]);
/* mul_m3_series */
void _va_mul_m3_series_3(float R[3][3], float M1[3][3], float M2[3][3]) ATTR_NONNULL();
@@ -100,27 +112,28 @@ void _va_mul_m4_series_9(float R[4][4], float M1[4][4], float M2[4][4], float M3
#define mul_m3_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m3_series_, __VA_ARGS__)
#define mul_m4_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m4_series_, __VA_ARGS__)
-void mul_m4_v3(float M[4][4], float r[3]);
-void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
-void mul_v2_m4v3(float r[2], float M[4][4], const float v[3]);
-void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
-void mul_m2v2(float M[2][2], float v[2]);
-void mul_mat3_m4_v3(float M[4][4], float r[3]);
-void mul_v3_mat3_m4v3(float r[3], float M[4][4], const float v[3]);
-void mul_m4_v4(float M[4][4], float r[4]);
-void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
-void mul_project_m4_v3(float M[4][4], float vec[3]);
-void mul_v3_project_m4_v3(float r[3], float mat[4][4], const float vec[3]);
-void mul_v2_project_m4_v3(float r[2], float M[4][4], const float vec[3]);
-
-void mul_m3_v2(float m[3][3], float r[2]);
-void mul_v2_m3v2(float r[2], float m[3][3], float v[2]);
-void mul_m3_v3(float M[3][3], float r[3]);
-void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]);
-void mul_v2_m3v3(float r[2], float M[3][3], const float a[3]);
-void mul_transposed_m3_v3(float M[3][3], float r[3]);
-void mul_transposed_mat3_m4_v3(float M[4][4], float r[3]);
-void mul_m3_v3_double(float M[3][3], double r[3]);
+void mul_m4_v3(const float M[4][4], float r[3]);
+void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3]);
+void mul_v2_m4v3(float r[2], const float M[4][4], const float v[3]);
+void mul_v2_m2v2(float r[2], const float M[2][2], const float v[2]);
+void mul_m2v2(const float M[2][2], float v[2]);
+void mul_mat3_m4_v3(const float M[4][4], float r[3]);
+void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3]);
+void mul_m4_v4(const float M[4][4], float r[4]);
+void mul_v4_m4v4(float r[4], const float M[4][4], const float v[4]);
+void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3]); /* v has implicit w = 1.0f */
+void mul_project_m4_v3(const float M[4][4], float vec[3]);
+void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3]);
+void mul_v2_project_m4_v3(float r[2], const float M[4][4], const float vec[3]);
+
+void mul_m3_v2(const float m[3][3], float r[2]);
+void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2]);
+void mul_m3_v3(const float M[3][3], float r[3]);
+void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3]);
+void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3]);
+void mul_transposed_m3_v3(const float M[3][3], float r[3]);
+void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3]);
+void mul_m3_v3_double(const float M[3][3], double r[3]);
void mul_m3_fl(float R[3][3], float f);
void mul_m4_fl(float R[4][4], float f);
@@ -131,102 +144,103 @@ void negate_mat3_m4(float R[4][4]);
void negate_m4(float R[4][4]);
bool invert_m3_ex(float m[3][3], const float epsilon);
-bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon);
+bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon);
bool invert_m3(float R[3][3]);
-bool invert_m3_m3(float R[3][3], float A[3][3]);
+bool invert_m3_m3(float R[3][3], const float A[3][3]);
bool invert_m4(float R[4][4]);
-bool invert_m4_m4(float R[4][4], float A[4][4]);
+bool invert_m4_m4(float R[4][4], const float A[4][4]);
/* double arithmetic (mixed float/double) */
-void mul_m4_v4d(float M[4][4], double r[4]);
-void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
+void mul_m4_v4d(const float M[4][4], double r[4]);
+void mul_v4d_m4v4d(double r[4], const float M[4][4], const double v[4]);
/* double matrix functions (no mixing types) */
-void mul_v3_m3v3_db(double r[3], double M[3][3], const double a[3]);
-void mul_m3_v3_db(double M[3][3], double r[3]);
+void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3]);
+void mul_m3_v3_db(const double M[3][3], double r[3]);
/****************************** Linear Algebra *******************************/
void transpose_m3(float R[3][3]);
-void transpose_m3_m3(float R[3][3], float A[3][3]);
-void transpose_m3_m4(float R[3][3], float A[4][4]);
+void transpose_m3_m3(float R[3][3], const float A[3][3]);
+void transpose_m3_m4(float R[3][3], const float A[4][4]);
void transpose_m4(float R[4][4]);
-void transpose_m4_m4(float R[4][4], float A[4][4]);
+void transpose_m4_m4(float R[4][4], const float A[4][4]);
-int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
+int compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit);
void normalize_m3_ex(float R[3][3], float r_scale[3]) ATTR_NONNULL();
void normalize_m3(float R[3][3]) ATTR_NONNULL();
-void normalize_m3_m3_ex(float R[3][3], float A[3][3], float r_scale[3]) ATTR_NONNULL();
-void normalize_m3_m3(float R[3][3], float A[3][3]) ATTR_NONNULL();
+void normalize_m3_m3_ex(float R[3][3], const float A[3][3], float r_scale[3]) ATTR_NONNULL();
+void normalize_m3_m3(float R[3][3], const float A[3][3]) ATTR_NONNULL();
void normalize_m4_ex(float R[4][4], float r_scale[3]) ATTR_NONNULL();
void normalize_m4(float R[4][4]) ATTR_NONNULL();
-void normalize_m4_m4_ex(float R[4][4], float A[4][4], float r_scale[3]) ATTR_NONNULL();
-void normalize_m4_m4(float R[4][4], float A[4][4]) ATTR_NONNULL();
+void normalize_m4_m4_ex(float R[4][4], const float A[4][4], float r_scale[3]) ATTR_NONNULL();
+void normalize_m4_m4(float R[4][4],const float A[4][4]) ATTR_NONNULL();
void orthogonalize_m3(float R[3][3], int axis);
void orthogonalize_m4(float R[4][4], int axis);
-bool is_orthogonal_m3(float mat[3][3]);
-bool is_orthogonal_m4(float mat[4][4]);
-bool is_orthonormal_m3(float mat[3][3]);
-bool is_orthonormal_m4(float mat[4][4]);
+bool is_orthogonal_m3(const float mat[3][3]);
+bool is_orthogonal_m4(const float mat[4][4]);
+bool is_orthonormal_m3(const float mat[3][3]);
+bool is_orthonormal_m4(const float mat[4][4]);
-bool is_uniform_scaled_m3(float mat[3][3]);
-bool is_uniform_scaled_m4(float m[4][4]);
+bool is_uniform_scaled_m3(const float mat[3][3]);
+bool is_uniform_scaled_m4(const float m[4][4]);
/* Note: 'adjoint' here means the adjugate (adjunct, "classical adjoint") matrix!
* Nowadays 'adjoint' usually refers to the conjugate transpose,
* which for real-valued matrices is simply the transpose.
*/
-void adjoint_m2_m2(float R[2][2], float A[2][2]);
-void adjoint_m3_m3(float R[3][3], float A[3][3]);
-void adjoint_m4_m4(float R[4][4], float A[4][4]);
+void adjoint_m2_m2(float R[2][2], const float A[2][2]);
+void adjoint_m3_m3(float R[3][3], const float A[3][3]);
+void adjoint_m4_m4(float R[4][4], const float A[4][4]);
float determinant_m2(float a, float b,
float c, float d);
float determinant_m3(float a, float b, float c,
float d, float e, float f,
float g, float h, float i);
-float determinant_m3_array(float m[3][3]);
-float determinant_m4(float A[4][4]);
+float determinant_m3_array(const float m[3][3]);
+float determinant_m4(const float A[4][4]);
#define PSEUDOINVERSE_EPSILON 1e-8f
void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
-void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon);
-void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
+void pseudoinverse_m4_m4(float Ainv[4][4], const float A[4][4], float epsilon);
+void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon);
-bool has_zero_axis_m4(float matrix[4][4]);
+bool has_zero_axis_m4(const float matrix[4][4]);
-void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
+void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]);
/****************************** Transformations ******************************/
void scale_m3_fl(float R[3][3], float scale);
void scale_m4_fl(float R[4][4], float scale);
-float mat3_to_scale(float M[3][3]);
-float mat4_to_scale(float M[4][4]);
+float mat3_to_scale(const float M[3][3]);
+float mat4_to_scale(const float M[4][4]);
+float mat4_to_xy_scale(const float M[4][4]);
void size_to_mat3(float R[3][3], const float size[3]);
void size_to_mat4(float R[4][4], const float size[3]);
-void mat3_to_size(float r[3], float M[3][3]);
-void mat4_to_size(float r[3], float M[4][4]);
+void mat3_to_size(float r[3], const float M[3][3]);
+void mat4_to_size(float r[3], const float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle);
void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
-void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
-void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
-void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]);
-void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]);
+void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]);
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4]);
+void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4]);
+void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4]);
-void mat3_polar_decompose(float mat3[3][3], float r_U[3][3], float r_P[3][3]);
+void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]);
void loc_eul_size_to_mat4(float R[4][4],
const float loc[3], const float eul[3], const float size[3]);
@@ -237,20 +251,20 @@ void loc_quat_size_to_mat4(float R[4][4],
void loc_axisangle_size_to_mat4(float R[4][4],
const float loc[3], const float axis[4], const float angle, const float size[3]);
-void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
-void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
+void blend_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t);
+void blend_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t);
-void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
-void interp_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
+void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t);
+void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t);
-bool is_negative_m3(float mat[3][3]);
-bool is_negative_m4(float mat[4][4]);
+bool is_negative_m3(const float mat[3][3]);
+bool is_negative_m4(const float mat[4][4]);
-bool is_zero_m3(float mat[3][3]);
-bool is_zero_m4(float mat[4][4]);
+bool is_zero_m3(const float mat[3][3]);
+bool is_zero_m4(const float mat[4][4]);
-bool equals_m3m3(float mat1[3][3], float mat2[3][3]);
-bool equals_m4m4(float mat1[4][4], float mat2[4][4]);
+bool equals_m3m3(const float mat1[3][3], const float mat2[3][3]);
+bool equals_m4m4(const float mat1[4][4], const float mat2[4][4]);
/* SpaceTransform helper */
typedef struct SpaceTransform {
@@ -259,8 +273,8 @@ typedef struct SpaceTransform {
} SpaceTransform;
-void BLI_space_transform_from_matrices(struct SpaceTransform *data, float local[4][4], float target[4][4]);
-void BLI_space_transform_global_from_matrices(struct SpaceTransform *data, float local[4][4], float target[4][4]);
+void BLI_space_transform_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4]);
+void BLI_space_transform_global_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4]);
void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3]);
void BLI_space_transform_invert(const struct SpaceTransform *data, float co[3]);
void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3]);
@@ -271,8 +285,8 @@ void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float
/*********************************** Other ***********************************/
-void print_m3(const char *str, float M[3][3]);
-void print_m4(const char *str, float M[4][4]);
+void print_m3(const char *str, const float M[3][3]);
+void print_m4(const char *str, const float M[4][4]);
#define print_m3_id(M) print_m3(STRINGIFY(M), M)
#define print_m4_id(M) print_m4(STRINGIFY(M), M)
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 8e0884ba347..c1e5c1177cc 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -123,7 +123,7 @@ MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2]);
MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]);
-MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
@@ -151,6 +151,7 @@ MINLINE void negate_v3_short(short r[3]);
MINLINE void negate_v3_db(double r[3]);
MINLINE void invert_v2(float r[2]);
+MINLINE void invert_v3(float r[3]);
MINLINE void abs_v2(float r[2]);
MINLINE void abs_v2_v2(float r[2], const float a[2]);
@@ -305,6 +306,7 @@ void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]);
void ortho_v3_v3(float out[3], const float v[3]);
void ortho_v2_v2(float out[2], const float v[2]);
void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
+void rotate_v2_v2fl(float r[2], const float p[2], const float angle);
void rotate_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle);
void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], const float angle);
@@ -320,6 +322,7 @@ void print_vn(const char *str, const float v[], const int n);
#define print_v4_id(v) print_v4(STRINGIFY(v), v)
#define print_vn_id(v, n) print_vn(STRINGIFY(v), v, n)
+MINLINE void normal_float_to_short_v2(short r[2], const float n[2]);
MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 746eb922c65..72ac6bd0080 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -674,6 +674,9 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
# define BLI_STATIC_ASSERT(a, msg)
#endif
+#define BLI_STATIC_ASSERT_ALIGN(st, align) \
+ BLI_STATIC_ASSERT((sizeof(st) % (align) == 0), "Structure must be strictly aligned")
+
/* hints for branch prediction, only use in code that runs a _lot_ where */
#ifdef __GNUC__
# define LIKELY(x) __builtin_expect(!!(x), 1)
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index fcb02a86a84..dc81ce000ea 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -156,6 +156,7 @@ set(SRC
BLI_hash_md5.h
BLI_hash_mm2a.h
BLI_heap.h
+ BLI_iterator.h
BLI_jitter.h
BLI_kdopbvh.h
BLI_kdtree.h
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 46dcee48eda..0a6d575c7d6 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -170,6 +170,34 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
}
/**
+ * Swaps \a vlinka and \a vlinkb from their respective lists. Assumes they are both already in their lista!
+ */
+void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb)
+{
+ Link *linka = vlinka;
+ Link *linkb = vlinkb;
+ Link linkc = {NULL};
+
+ if (!linka || !linkb) {
+ return;
+ }
+
+ /* Temporary link to use as placeholder of the links positions */
+ BLI_insertlinkafter(listbasea, linka, &linkc);
+
+ /* Bring linka into linkb position */
+ BLI_remlink(listbasea, linka);
+ BLI_insertlinkafter(listbaseb, linkb, linka);
+
+ /* Bring linkb into linka position */
+ BLI_remlink(listbaseb, linkb);
+ BLI_insertlinkafter(listbasea, &linkc, linkb);
+
+ /* Remove temporary link */
+ BLI_remlink(listbasea, &linkc);
+}
+
+/**
* Removes the head from \a listbase and returns it.
*/
void *BLI_pophead(ListBase *listbase)
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 6d7d24c79c3..cb39134af45 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -359,8 +359,10 @@ void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b, int
}
}
-/* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
- * for that reason it is sensitive for endianness... with this function it works correctly
+/**
+ * We define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
+ * for that reason it is sensitive for endianness... with this function it works correctly.
+ * \see #imm_cpack
*/
unsigned int hsv_to_cpack(float h, float s, float v)
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 01a805a09b6..bc3a1ee3e90 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -239,6 +239,14 @@ MINLINE void rgba_char_args_set(char col[4], const char r, const char g, const c
col[3] = a;
}
+MINLINE void rgba_float_args_set(float col[4], const float r, const float g, const float b, const float a)
+{
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = a;
+}
+
MINLINE void rgba_char_args_test_set(char col[4], const char r, const char g, const char b, const char a)
{
if (col[3] == 0) {
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 9a60c670ec7..1883b62f532 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -74,23 +74,23 @@ void unit_m4(float m[4][4])
m[3][0] = m[3][1] = m[3][2] = 0.0f;
}
-void copy_m2_m2(float m1[2][2], float m2[2][2])
+void copy_m2_m2(float m1[2][2], const float m2[2][2])
{
memcpy(m1, m2, sizeof(float[2][2]));
}
-void copy_m3_m3(float m1[3][3], float m2[3][3])
+void copy_m3_m3(float m1[3][3], const float m2[3][3])
{
/* destination comes first: */
memcpy(m1, m2, sizeof(float[3][3]));
}
-void copy_m4_m4(float m1[4][4], float m2[4][4])
+void copy_m4_m4(float m1[4][4], const float m2[4][4])
{
memcpy(m1, m2, sizeof(float[4][4]));
}
-void copy_m3_m4(float m1[3][3], float m2[4][4])
+void copy_m3_m4(float m1[3][3], const float m2[4][4])
{
m1[0][0] = m2[0][0];
m1[0][1] = m2[0][1];
@@ -105,7 +105,7 @@ void copy_m3_m4(float m1[3][3], float m2[4][4])
m1[2][2] = m2[2][2];
}
-void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */
+void copy_m4_m3(float m1[4][4], const float m2[3][3]) /* no clear */
{
m1[0][0] = m2[0][0];
m1[0][1] = m2[0][1];
@@ -131,7 +131,7 @@ void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */
}
-void copy_m3_m3d(float R[3][3], double A[3][3])
+void copy_m3_m3d(float R[3][3], const double A[3][3])
{
/* Keep it stupid simple for better data flow in CPU. */
R[0][0] = (float)A[0][0];
@@ -177,64 +177,107 @@ void swap_m4m4(float m1[4][4], float m2[4][4])
/******************************** Arithmetic *********************************/
-void mul_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4])
+void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
{
- float m2[4][4], m3[4][4];
+ if (A == R)
+ mul_m4_m4_post(R, B);
+ else if (B == R)
+ mul_m4_m4_pre(R, A);
+ else
+ mul_m4_m4m4_uniq(R, A, B);
+}
- /* copy so it works when m1 is the same pointer as m2 or m3 */
- copy_m4_m4(m2, m2_);
- copy_m4_m4(m3, m3_);
+void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4])
+{
+ BLI_assert(R != A && R != B);
- /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0] + m2[0][3] * m3[3][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1] + m2[0][3] * m3[3][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2] + m2[0][3] * m3[3][2];
- m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3] + m2[0][3] * m3[3][3];
+ /* matrix product: R[j][k] = A[j][i] . B[i][k] */
+ R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
+ R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
+ R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2];
+ R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3];
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0] + m2[1][3] * m3[3][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1] + m2[1][3] * m3[3][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2] + m2[1][3] * m3[3][2];
- m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3] + m2[1][3] * m3[3][3];
+ R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0];
+ R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1];
+ R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2];
+ R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3];
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0] + m2[2][3] * m3[3][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1] + m2[2][3] * m3[3][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2] + m2[2][3] * m3[3][2];
- m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3] + m2[2][3] * m3[3][3];
+ R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0];
+ R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1];
+ R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2];
+ R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3];
- m1[3][0] = m2[3][0] * m3[0][0] + m2[3][1] * m3[1][0] + m2[3][2] * m3[2][0] + m2[3][3] * m3[3][0];
- m1[3][1] = m2[3][0] * m3[0][1] + m2[3][1] * m3[1][1] + m2[3][2] * m3[2][1] + m2[3][3] * m3[3][1];
- m1[3][2] = m2[3][0] * m3[0][2] + m2[3][1] * m3[1][2] + m2[3][2] * m3[2][2] + m2[3][3] * m3[3][2];
- m1[3][3] = m2[3][0] * m3[0][3] + m2[3][1] * m3[1][3] + m2[3][2] * m3[2][3] + m2[3][3] * m3[3][3];
+ R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0];
+ R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1];
+ R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2];
+ R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3];
+}
+void mul_m4_m4_pre(float R[4][4], const float A[4][4])
+{
+ BLI_assert(A != R);
+ float B[4][4];
+ copy_m4_m4(B, R);
+ mul_m4_m4m4_uniq(R, A, B);
}
-void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3])
+void mul_m4_m4_post(float R[4][4], const float B[4][4])
{
- float m2[3][3], m3[3][3];
+ BLI_assert(B != R);
+ float A[4][4];
+ copy_m4_m4(A, R);
+ mul_m4_m4m4_uniq(R, A, B);
+}
- /* copy so it works when m1 is the same pointer as m2 or m3 */
- copy_m3_m3(m2, m2_);
- copy_m3_m3(m3, m3_);
+void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
+{
+ if (A == R)
+ mul_m3_m3_post(R, B);
+ else if (B == R)
+ mul_m3_m3_pre(R, A);
+ else
+ mul_m3_m3m3_uniq(R, A, B);
+}
- /* m1[i][j] = m2[i][k] * m3[k][j], args are flipped! */
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+void mul_m3_m3_pre(float R[3][3], const float A[3][3])
+{
+ BLI_assert(A != R);
+ float B[3][3];
+ copy_m3_m3(B, R);
+ mul_m3_m3m3_uniq(R, A, B);
+}
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+void mul_m3_m3_post(float R[3][3], const float B[3][3])
+{
+ BLI_assert(B != R);
+ float A[3][3];
+ copy_m3_m3(A, R);
+ mul_m3_m3m3_uniq(R, A, B);
+}
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3])
+{
+ BLI_assert(R != A && R != B);
+
+ R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0];
+ R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1];
+ R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2];
+
+ R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0];
+ R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1];
+ R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2];
+
+ R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0];
+ R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1];
+ R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2];
}
-void mul_m4_m4m3(float m1[4][4], float m3_[4][4], float m2_[3][3])
+void mul_m4_m4m3(float m1[4][4], const float m3_[4][4], const float m2_[3][3])
{
float m2[3][3], m3[4][4];
/* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
copy_m3_m3(m2, m2_);
copy_m4_m4(m3, m3_);
@@ -250,11 +293,12 @@ void mul_m4_m4m3(float m1[4][4], float m3_[4][4], float m2_[3][3])
}
/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */
-void mul_m3_m3m4(float m1[3][3], float m3_[4][4], float m2_[3][3])
+void mul_m3_m3m4(float m1[3][3], const float m3_[4][4], const float m2_[3][3])
{
float m2[3][3], m3[4][4];
/* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
copy_m3_m3(m2, m2_);
copy_m4_m4(m3, m3_);
@@ -272,11 +316,12 @@ void mul_m3_m3m4(float m1[3][3], float m3_[4][4], float m2_[3][3])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4])
+void mul_m4_m3m4(float m1[4][4], const float m3_[3][3], const float m2_[4][4])
{
float m2[4][4], m3[3][3];
/* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
copy_m4_m4(m2, m2_);
copy_m3_m3(m3, m3_);
@@ -434,7 +479,7 @@ void _va_mul_m4_series_9(
}
/** \} */
-void mul_v2_m3v2(float r[2], float m[3][3], float v[2])
+void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2])
{
float temp[3], warped[3];
@@ -447,12 +492,12 @@ void mul_v2_m3v2(float r[2], float m[3][3], float v[2])
r[1] = warped[1] / warped[2];
}
-void mul_m3_v2(float m[3][3], float r[2])
+void mul_m3_v2(const float m[3][3], float r[2])
{
mul_v2_m3v2(r, m, r);
}
-void mul_m4_v3(float mat[4][4], float vec[3])
+void mul_m4_v3(const float mat[4][4], float vec[3])
{
const float x = vec[0];
const float y = vec[1];
@@ -462,7 +507,7 @@ void mul_m4_v3(float mat[4][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
-void mul_v3_m4v3(float r[3], float mat[4][4], const float vec[3])
+void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
{
const float x = vec[0];
const float y = vec[1];
@@ -472,7 +517,7 @@ void mul_v3_m4v3(float r[3], float mat[4][4], const float vec[3])
r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
-void mul_v2_m4v3(float r[2], float mat[4][4], const float vec[3])
+void mul_v2_m4v3(float r[2], const float mat[4][4], const float vec[3])
{
const float x = vec[0];
@@ -480,7 +525,7 @@ void mul_v2_m4v3(float r[2], float mat[4][4], const float vec[3])
r[1] = x * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
}
-void mul_v2_m2v2(float r[2], float mat[2][2], const float vec[2])
+void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
{
const float x = vec[0];
@@ -488,13 +533,13 @@ void mul_v2_m2v2(float r[2], float mat[2][2], const float vec[2])
r[1] = mat[0][1] * x + mat[1][1] * vec[1];
}
-void mul_m2v2(float mat[2][2], float vec[2])
+void mul_m2v2(const float mat[2][2], float vec[2])
{
mul_v2_m2v2(vec, mat, vec);
}
/* same as mul_m4_v3() but doesnt apply translation component */
-void mul_mat3_m4_v3(float mat[4][4], float vec[3])
+void mul_mat3_m4_v3(const float mat[4][4], float vec[3])
{
const float x = vec[0];
const float y = vec[1];
@@ -504,7 +549,7 @@ void mul_mat3_m4_v3(float mat[4][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
}
-void mul_v3_mat3_m4v3(float r[3], float mat[4][4], const float vec[3])
+void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
{
const float x = vec[0];
const float y = vec[1];
@@ -514,7 +559,7 @@ void mul_v3_mat3_m4v3(float r[3], float mat[4][4], const float vec[3])
r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
}
-void mul_project_m4_v3(float mat[4][4], float vec[3])
+void mul_project_m4_v3(const float mat[4][4], float vec[3])
{
/* absolute value to not flip the frustum upside down behind the camera */
const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
@@ -525,7 +570,7 @@ void mul_project_m4_v3(float mat[4][4], float vec[3])
vec[2] /= w;
}
-void mul_v3_project_m4_v3(float r[3], float mat[4][4], const float vec[3])
+void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3])
{
const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
mul_v3_m4v3(r, mat, vec);
@@ -535,7 +580,7 @@ void mul_v3_project_m4_v3(float r[3], float mat[4][4], const float vec[3])
r[2] /= w;
}
-void mul_v2_project_m4_v3(float r[2], float mat[4][4], const float vec[3])
+void mul_v2_project_m4_v3(float r[2], const float mat[4][4], const float vec[3])
{
const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
mul_v2_m4v3(r, mat, vec);
@@ -544,7 +589,7 @@ void mul_v2_project_m4_v3(float r[2], float mat[4][4], const float vec[3])
r[1] /= w;
}
-void mul_v4_m4v4(float r[4], float mat[4][4], const float v[4])
+void mul_v4_m4v4(float r[4], const float mat[4][4], const float v[4])
{
const float x = v[0];
const float y = v[1];
@@ -556,12 +601,12 @@ void mul_v4_m4v4(float r[4], float mat[4][4], const float v[4])
r[3] = x * mat[0][3] + y * mat[1][3] + z * mat[2][3] + mat[3][3] * v[3];
}
-void mul_m4_v4(float mat[4][4], float r[4])
+void mul_m4_v4(const float mat[4][4], float r[4])
{
mul_v4_m4v4(r, mat, r);
}
-void mul_v4d_m4v4d(double r[4], float mat[4][4], double v[4])
+void mul_v4d_m4v4d(double r[4], const float mat[4][4], const double v[4])
{
const double x = v[0];
const double y = v[1];
@@ -573,12 +618,21 @@ void mul_v4d_m4v4d(double r[4], float mat[4][4], double v[4])
r[3] = x * (double)mat[0][3] + y * (double)mat[1][3] + z * (double)mat[2][3] + (double)mat[3][3] * v[3];
}
-void mul_m4_v4d(float mat[4][4], double r[4])
+void mul_m4_v4d(const float mat[4][4], double r[4])
{
mul_v4d_m4v4d(r, mat, r);
}
-void mul_v3_m3v3(float r[3], float M[3][3], const float a[3])
+void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3])
+{
+ /* v has implicit w = 1.0f */
+ r[0] = v[0] * M[0][0] + v[1] * M[1][0] + M[2][0] * v[2] + M[3][0];
+ r[1] = v[0] * M[0][1] + v[1] * M[1][1] + M[2][1] * v[2] + M[3][1];
+ r[2] = v[0] * M[0][2] + v[1] * M[1][2] + M[2][2] * v[2] + M[3][2];
+ r[3] = v[0] * M[0][3] + v[1] * M[1][3] + M[2][3] * v[2] + M[3][3];
+}
+
+void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
{
BLI_assert(r != a);
@@ -587,7 +641,7 @@ void mul_v3_m3v3(float r[3], float M[3][3], const float a[3])
r[2] = M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
-void mul_v3_m3v3_db(double r[3], double M[3][3], const double a[3])
+void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3])
{
BLI_assert(r != a);
@@ -596,7 +650,7 @@ void mul_v3_m3v3_db(double r[3], double M[3][3], const double a[3])
r[2] = M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
-void mul_v2_m3v3(float r[2], float M[3][3], const float a[3])
+void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
{
BLI_assert(r != a);
@@ -604,17 +658,17 @@ void mul_v2_m3v3(float r[2], float M[3][3], const float a[3])
r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
}
-void mul_m3_v3(float M[3][3], float r[3])
+void mul_m3_v3(const float M[3][3], float r[3])
{
mul_v3_m3v3(r, M, (const float[3]){UNPACK3(r)});
}
-void mul_m3_v3_db(double M[3][3], double r[3])
+void mul_m3_v3_db(const double M[3][3], double r[3])
{
mul_v3_m3v3_db(r, M, (const double[3]){UNPACK3(r)});
}
-void mul_transposed_m3_v3(float mat[3][3], float vec[3])
+void mul_transposed_m3_v3(const float mat[3][3], float vec[3])
{
const float x = vec[0];
const float y = vec[1];
@@ -624,7 +678,7 @@ void mul_transposed_m3_v3(float mat[3][3], float vec[3])
vec[2] = x * mat[2][0] + y * mat[2][1] + mat[2][2] * vec[2];
}
-void mul_transposed_mat3_m4_v3(float mat[4][4], float vec[3])
+void mul_transposed_mat3_m4_v3(const float mat[4][4], float vec[3])
{
const float x = vec[0];
const float y = vec[1];
@@ -688,7 +742,7 @@ void negate_m4(float m[4][4])
m[i][j] *= -1.0f;
}
-void mul_m3_v3_double(float mat[3][3], double vec[3])
+void mul_m3_v3_double(const float mat[3][3], double vec[3])
{
const double x = vec[0];
const double y = vec[1];
@@ -698,7 +752,7 @@ void mul_m3_v3_double(float mat[3][3], double vec[3])
vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2];
}
-void add_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
+void add_m3_m3m3(float m1[3][3], const float m2[3][3], const float m3[3][3])
{
int i, j;
@@ -707,7 +761,7 @@ void add_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
m1[i][j] = m2[i][j] + m3[i][j];
}
-void add_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
+void add_m4_m4m4(float m1[4][4], const float m2[4][4], const float m3[4][4])
{
int i, j;
@@ -716,7 +770,7 @@ void add_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
m1[i][j] = m2[i][j] + m3[i][j];
}
-void sub_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
+void sub_m3_m3m3(float m1[3][3], const float m2[3][3], const float m3[3][3])
{
int i, j;
@@ -725,7 +779,7 @@ void sub_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
m1[i][j] = m2[i][j] - m3[i][j];
}
-void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
+void sub_m4_m4m4(float m1[4][4], const float m2[4][4], const float m3[4][4])
{
int i, j;
@@ -734,7 +788,7 @@ void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
m1[i][j] = m2[i][j] - m3[i][j];
}
-float determinant_m3_array(float m[3][3])
+float determinant_m3_array(const float m[3][3])
{
return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
@@ -750,7 +804,7 @@ bool invert_m3_ex(float m[3][3], const float epsilon)
return success;
}
-bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon)
+bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
{
float det;
int a, b;
@@ -786,7 +840,7 @@ bool invert_m3(float m[3][3])
return success;
}
-bool invert_m3_m3(float m1[3][3], float m2[3][3])
+bool invert_m3_m3(float m1[3][3], const float m2[3][3])
{
float det;
int a, b;
@@ -830,7 +884,7 @@ bool invert_m4(float m[4][4])
* Mark Segal - 1992
*/
-bool invert_m4_m4(float inverse[4][4], float mat[4][4])
+bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
{
int i, j, k;
double temp;
@@ -908,7 +962,7 @@ void transpose_m3(float mat[3][3])
mat[2][1] = t;
}
-void transpose_m3_m3(float rmat[3][3], float mat[3][3])
+void transpose_m3_m3(float rmat[3][3], const float mat[3][3])
{
BLI_assert(rmat != mat);
@@ -924,7 +978,7 @@ void transpose_m3_m3(float rmat[3][3], float mat[3][3])
}
/* seems obscure but in-fact a common operation */
-void transpose_m3_m4(float rmat[3][3], float mat[4][4])
+void transpose_m3_m4(float rmat[3][3], const float mat[4][4])
{
BLI_assert(&rmat[0][0] != &mat[0][0]);
@@ -965,7 +1019,7 @@ void transpose_m4(float mat[4][4])
mat[3][2] = t;
}
-void transpose_m4_m4(float rmat[4][4], float mat[4][4])
+void transpose_m4_m4(float rmat[4][4], const float mat[4][4])
{
BLI_assert(rmat != mat);
@@ -987,7 +1041,8 @@ void transpose_m4_m4(float rmat[4][4], float mat[4][4])
rmat[3][3] = mat[3][3];
}
-int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit)
+/* TODO: return bool */
+int compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit)
{
if (compare_v4v4(mat1[0], mat2[0], limit))
if (compare_v4v4(mat1[1], mat2[1], limit))
@@ -1165,7 +1220,7 @@ void orthogonalize_m4(float mat[4][4], int axis)
mul_v3_fl(mat[2], size[2]);
}
-bool is_orthogonal_m3(float m[3][3])
+bool is_orthogonal_m3(const float m[3][3])
{
int i, j;
@@ -1179,7 +1234,7 @@ bool is_orthogonal_m3(float m[3][3])
return true;
}
-bool is_orthogonal_m4(float m[4][4])
+bool is_orthogonal_m4(const float m[4][4])
{
int i, j;
@@ -1194,7 +1249,7 @@ bool is_orthogonal_m4(float m[4][4])
return true;
}
-bool is_orthonormal_m3(float m[3][3])
+bool is_orthonormal_m3(const float m[3][3])
{
if (is_orthogonal_m3(m)) {
int i;
@@ -1209,7 +1264,7 @@ bool is_orthonormal_m3(float m[3][3])
return false;
}
-bool is_orthonormal_m4(float m[4][4])
+bool is_orthonormal_m4(const float m[4][4])
{
if (is_orthogonal_m4(m)) {
int i;
@@ -1224,7 +1279,7 @@ bool is_orthonormal_m4(float m[4][4])
return false;
}
-bool is_uniform_scaled_m3(float m[3][3])
+bool is_uniform_scaled_m3(const float m[3][3])
{
const float eps = 1e-7f;
float t[3][3];
@@ -1252,7 +1307,7 @@ bool is_uniform_scaled_m3(float m[3][3])
return false;
}
-bool is_uniform_scaled_m4(float m[4][4])
+bool is_uniform_scaled_m4(const float m[4][4])
{
float t[3][3];
copy_m3_m4(t, m);
@@ -1274,14 +1329,14 @@ void normalize_m3(float mat[3][3])
}
}
-void normalize_m3_m3_ex(float rmat[3][3], float mat[3][3], float r_scale[3])
+void normalize_m3_m3_ex(float rmat[3][3], const float mat[3][3], float r_scale[3])
{
int i;
for (i = 0; i < 3; i++) {
r_scale[i] = normalize_v3_v3(rmat[i], mat[i]);
}
}
-void normalize_m3_m3(float rmat[3][3], float mat[3][3])
+void normalize_m3_m3(float rmat[3][3], const float mat[3][3])
{
int i;
for (i = 0; i < 3; i++) {
@@ -1310,7 +1365,7 @@ void normalize_m4(float mat[4][4])
}
}
-void normalize_m4_m4_ex(float rmat[4][4], float mat[4][4], float r_scale[3])
+void normalize_m4_m4_ex(float rmat[4][4], const float mat[4][4], float r_scale[3])
{
int i;
for (i = 0; i < 3; i++) {
@@ -1319,7 +1374,7 @@ void normalize_m4_m4_ex(float rmat[4][4], float mat[4][4], float r_scale[3])
}
copy_v4_v4(rmat[3], mat[3]);
}
-void normalize_m4_m4(float rmat[4][4], float mat[4][4])
+void normalize_m4_m4(float rmat[4][4], const float mat[4][4])
{
int i;
for (i = 0; i < 3; i++) {
@@ -1329,7 +1384,7 @@ void normalize_m4_m4(float rmat[4][4], float mat[4][4])
copy_v4_v4(rmat[3], mat[3]);
}
-void adjoint_m2_m2(float m1[2][2], float m[2][2])
+void adjoint_m2_m2(float m1[2][2], const float m[2][2])
{
BLI_assert(m1 != m);
m1[0][0] = m[1][1];
@@ -1338,7 +1393,7 @@ void adjoint_m2_m2(float m1[2][2], float m[2][2])
m1[1][1] = m[0][0];
}
-void adjoint_m3_m3(float m1[3][3], float m[3][3])
+void adjoint_m3_m3(float m1[3][3], const float m[3][3])
{
BLI_assert(m1 != m);
m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1];
@@ -1354,7 +1409,7 @@ void adjoint_m3_m3(float m1[3][3], float m[3][3])
m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
-void adjoint_m4_m4(float out[4][4], float in[4][4]) /* out = ADJ(in) */
+void adjoint_m4_m4(float out[4][4], const float in[4][4]) /* out = ADJ(in) */
{
float a1, a2, a3, a4, b1, b2, b3, b4;
float c1, c2, c3, c4, d1, d2, d3, d4;
@@ -1420,7 +1475,7 @@ float determinant_m3(float a1, float a2, float a3,
return ans;
}
-float determinant_m4(float m[4][4])
+float determinant_m4(const float m[4][4])
{
float ans;
float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
@@ -1488,14 +1543,14 @@ void size_to_mat4(float mat[4][4], const float size[3])
mat[3][3] = 1.0f;
}
-void mat3_to_size(float size[3], float mat[3][3])
+void mat3_to_size(float size[3], const float mat[3][3])
{
size[0] = len_v3(mat[0]);
size[1] = len_v3(mat[1]);
size[2] = len_v3(mat[2]);
}
-void mat4_to_size(float size[3], float mat[4][4])
+void mat4_to_size(float size[3], const float mat[4][4])
{
size[0] = len_v3(mat[0]);
size[1] = len_v3(mat[1]);
@@ -1505,7 +1560,7 @@ void mat4_to_size(float size[3], float mat[4][4])
/* this gets the average scale of a matrix, only use when your scaling
* data that has no idea of scale axis, examples are bone-envelope-radius
* and curve radius */
-float mat3_to_scale(float mat[3][3])
+float mat3_to_scale(const float mat[3][3])
{
/* unit length vector */
float unit_vec[3];
@@ -1514,7 +1569,7 @@ float mat3_to_scale(float mat[3][3])
return len_v3(unit_vec);
}
-float mat4_to_scale(float mat[4][4])
+float mat4_to_scale(const float mat[4][4])
{
/* unit length vector */
float unit_vec[3];
@@ -1523,7 +1578,16 @@ float mat4_to_scale(float mat[4][4])
return len_v3(unit_vec);
}
-void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
+/** Return 2D scale (in XY plane) of given mat4. */
+float mat4_to_xy_scale(const float M[4][4])
+{
+ /* unit length vector in xy plane */
+ float unit_vec[3] = {(float)M_SQRT1_2, (float)M_SQRT1_2, 0.0f};
+ mul_mat3_m4_v3(M, unit_vec);
+ return len_v3(unit_vec);
+}
+
+void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
{
/* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
size[0] = normalize_v3_v3(rot[0], mat3[0]);
@@ -1535,7 +1599,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
}
}
-void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4])
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
{
float mat3[3][3]; /* wmat -> 3x3 */
@@ -1546,7 +1610,7 @@ void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wm
copy_v3_v3(loc, wmat[3]);
}
-void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4])
+void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
{
float mat3[3][3];
float mat3_n[3][3]; /* normalized mat3 */
@@ -1564,7 +1628,7 @@ void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4])
copy_v3_v3(loc, wmat[3]);
}
-void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4])
+void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
{
float rot[3][3];
mat4_to_loc_rot_size(loc, rot, size, wmat);
@@ -1581,7 +1645,7 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]
* See https://en.wikipedia.org/wiki/Polar_decomposition for more.
*/
#ifndef MATH_STANDALONE
-void mat3_polar_decompose(float mat3[3][3], float r_U[3][3], float r_P[3][3])
+void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3])
{
/* From svd decomposition (M = WSV*), we have:
* U = WV*
@@ -1625,6 +1689,7 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
}
+/* TODO: enum for axis? */
/**
* Rotate a matrix in-place.
*
@@ -1688,7 +1753,7 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
mul_m4_m4m4(mat, mat, tmat);
}
-void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
+void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
float squat[4], dquat[4], fquat[4];
@@ -1711,7 +1776,7 @@ void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const floa
mul_m3_m3m3(out, rmat, smat);
}
-void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const float srcweight)
+void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4], const float srcweight)
{
float sloc[3], dloc[3], floc[3];
float srot[3][3], drot[3][3];
@@ -1749,7 +1814,7 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa
* @param B the intput matrix which is totally effective with \a t = 1.0.
* @param t the interpolation factor.
*/
-void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t)
+void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t)
{
/* 'Rotation' component ('U' part of polar decomposition, the closest orthogonal matrix to M3 rot/scale
* transformation matrix), spherically interpolated. */
@@ -1784,7 +1849,7 @@ void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t)
* @param B the intput matrix which is totally effective with \a t = 1.0.
* @param t the interpolation factor.
*/
-void interp_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t)
+void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t)
{
float A3[3][3], B3[3][3], R3[3][3];
@@ -1805,27 +1870,27 @@ void interp_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t)
}
#endif /* MATH_STANDALONE */
-bool is_negative_m3(float mat[3][3])
+bool is_negative_m3(const float mat[3][3])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
-bool is_negative_m4(float mat[4][4])
+bool is_negative_m4(const float mat[4][4])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
-bool is_zero_m3(float mat[3][3])
+bool is_zero_m3(const float mat[3][3])
{
return (is_zero_v3(mat[0]) &&
is_zero_v3(mat[1]) &&
is_zero_v3(mat[2]));
}
-bool is_zero_m4(float mat[4][4])
+bool is_zero_m4(const float mat[4][4])
{
return (is_zero_v4(mat[0]) &&
is_zero_v4(mat[1]) &&
@@ -1833,14 +1898,14 @@ bool is_zero_m4(float mat[4][4])
is_zero_v4(mat[3]));
}
-bool equals_m3m3(float mat1[3][3], float mat2[3][3])
+bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
{
return (equals_v3v3(mat1[0], mat2[0]) &&
equals_v3v3(mat1[1], mat2[1]) &&
equals_v3v3(mat1[2], mat2[2]));
}
-bool equals_m4m4(float mat1[4][4], float mat2[4][4])
+bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
{
return (equals_v4v4(mat1[0], mat2[0]) &&
equals_v4v4(mat1[1], mat2[1]) &&
@@ -1931,7 +1996,7 @@ void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float
/*********************************** Other ***********************************/
-void print_m3(const char *str, float m[3][3])
+void print_m3(const char *str, const float m[3][3])
{
printf("%s\n", str);
printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
@@ -1940,7 +2005,7 @@ void print_m3(const char *str, float m[3][3])
printf("\n");
}
-void print_m4(const char *str, float m[4][4])
+void print_m4(const char *str, const float m[4][4])
{
printf("%s\n", str);
printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
@@ -2394,7 +2459,7 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
}
}
-void pseudoinverse_m4_m4(float Ainv[4][4], float A_[4][4], float epsilon)
+void pseudoinverse_m4_m4(float Ainv[4][4], const float A_[4][4], float epsilon)
{
/* compute Moore-Penrose pseudo inverse of matrix, singular values
* below epsilon are ignored for stability (truncated SVD) */
@@ -2415,7 +2480,7 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A_[4][4], float epsilon)
mul_m4_series(Ainv, U, Wm, V);
}
-void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon)
+void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
{
/* try regular inverse when possible, otherwise fall back to slow svd */
if (!invert_m3_m3(Ainv, A)) {
@@ -2427,14 +2492,14 @@ void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon)
}
}
-bool has_zero_axis_m4(float matrix[4][4])
+bool has_zero_axis_m4(const float matrix[4][4])
{
return len_squared_v3(matrix[0]) < FLT_EPSILON ||
len_squared_v3(matrix[1]) < FLT_EPSILON ||
len_squared_v3(matrix[2]) < FLT_EPSILON;
}
-void invert_m4_m4_safe(float Ainv[4][4], float A[4][4])
+void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
{
if (!invert_m4_m4(Ainv, A)) {
float Atemp[4][4];
@@ -2482,7 +2547,7 @@ void invert_m4_m4_safe(float Ainv[4][4], float A[4][4])
* this defines a transform matrix TM such that (x', y', z') = TM * (x, y, z)
* where (x', y', z') are the coordinates of P' in target space such that it keeps (X, Y, Z) coordinates in global space.
*/
-void BLI_space_transform_from_matrices(SpaceTransform *data, float local[4][4], float target[4][4])
+void BLI_space_transform_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4])
{
float itarget[4][4];
invert_m4_m4(itarget, target);
@@ -2500,7 +2565,7 @@ void BLI_space_transform_from_matrices(SpaceTransform *data, float local[4][4],
* this defines a transform matrix TM such that (X', Y', Z') = TM * (X, Y, Z)
* where (X', Y', Z') are the coordinates of p' in global space such that it keeps (x, y, z) coordinates in target space.
*/
-void BLI_space_transform_global_from_matrices(SpaceTransform *data, float local[4][4], float target[4][4])
+void BLI_space_transform_global_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4])
{
float ilocal[4][4];
invert_m4_m4(ilocal, local);
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 37897e2cd32..b45137fd7f7 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -794,6 +794,20 @@ void ortho_v2_v2(float out[2], const float v[2])
}
/**
+ * Rotate a point \a p by \a angle around origin (0, 0)
+ */
+void rotate_v2_v2fl(float r[2], const float p[2], const float angle)
+{
+ const float co = cosf(angle);
+ const float si = sinf(angle);
+
+ BLI_assert(r != p);
+
+ r[0] = co * p[0] - si * p[1];
+ r[1] = si * p[0] + co * p[1];
+}
+
+/**
* Rotate a point \a p by \a angle around an arbitrary unit length \a axis.
* http://local.wasp.uwa.edu.au/~pbourke/geometry/
*/
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index ee5e8651bd3..4f658ef015f 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -491,7 +491,7 @@ MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
* return co_4d[3];
* \endcode
*/
-MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
+MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
{
return (mat[0][3] * co[0]) +
(mat[1][3] * co[1]) +
@@ -658,6 +658,14 @@ MINLINE void invert_v2(float r[2])
r[1] = 1.0f / r[1];
}
+MINLINE void invert_v3(float r[3])
+{
+ BLI_assert(!ELEM(0.0f, r[0], r[1], r[2]));
+ r[0] = 1.0f / r[0];
+ r[1] = 1.0f / r[1];
+ r[2] = 1.0f / r[2];
+}
+
MINLINE void abs_v2(float r[2])
{
r[0] = fabsf(r[0]);
@@ -960,6 +968,12 @@ MINLINE float normalize_v3(float n[3])
return normalize_v3_v3(n, n);
}
+MINLINE void normal_float_to_short_v2(short out[2], const float in[2])
+{
+ out[0] = (short) (in[0] * 32767.0f);
+ out[1] = (short) (in[1] * 32767.0f);
+}
+
MINLINE void normal_short_to_float_v3(float out[3], const short in[3])
{
out[0] = in[0] * (1.0f / 32767.0f);
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 3b6ab99ae86..ef1df479f13 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -95,20 +95,6 @@ void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx)
}
#endif
-#if 0
-void BLI_scanfill_view3d_dump(ScanFillContext *sf_ctx)
-{
- ScanFillEdge *eed;
-
- bl_debug_draw_quad_clear();
- bl_debug_color_set(0x0000ff);
-
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- bl_debug_draw_edge_add(eed->v1->co, eed->v2->co);
- }
-}
-#endif
-
static ListBase *edge_isect_ls_ensure(GHash *isect_hash, ScanFillEdge *eed)
{
ListBase *e_ls;
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index e6fc4703248..0213a4ee997 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -43,6 +43,7 @@ struct Main;
struct MemFile;
struct ReportList;
struct Scene;
+struct SceneLayer;
struct UserDef;
struct View3D;
struct bContext;
@@ -114,9 +115,9 @@ struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, con
struct ID *BLO_library_link_named_part_ex(
struct Main *mainl, BlendHandle **bh,
const short idcode, const char *name, const short flag,
- struct Scene *scene, struct View3D *v3d,
+ struct Scene *scene, struct SceneLayer *sl,
const bool use_placeholders, const bool force_indirect);
-void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d);
+void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct SceneLayer *sl);
void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh);
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index 3d2e8a306de..0a678cfe6f8 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../blenkernel
../blenlib
../blentranslation
+ ../depsgraph
../imbuf
../makesdna
../makesrna
@@ -53,6 +54,7 @@ set(SRC
intern/versioning_250.c
intern/versioning_260.c
intern/versioning_270.c
+ intern/versioning_280.c
intern/versioning_defaults.c
intern/versioning_legacy.c
intern/writefile.c
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 01951b0266f..d22af275469 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -72,6 +72,7 @@
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_layer_types.h"
#include "DNA_lamp_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_meta_types.h"
@@ -120,11 +121,11 @@
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_global.h" // for G
#include "BKE_group.h"
+#include "BKE_layer.h"
#include "BKE_library.h" // for which_libbase
#include "BKE_library_idmap.h"
#include "BKE_library_query.h"
@@ -149,6 +150,8 @@
#include "BKE_sound.h"
#include "BKE_colortools.h"
+#include "DEG_depsgraph.h"
+
#include "NOD_common.h"
#include "NOD_socket.h"
@@ -238,7 +241,6 @@ typedef struct OldNewMap {
/* local prototypes */
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
-static void convert_tface_mt(FileData *fd, Main *main);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
@@ -3339,7 +3341,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
if (rebuild) {
- DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_pose_tag_recalc(bmain, pose);
}
}
@@ -3862,6 +3864,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
cu->editnurb = NULL;
cu->editfont = NULL;
+ cu->batch_cache = NULL;
for (nu = cu->nurb.first; nu; nu = nu->next) {
nu->bezt = newdataadr(fd, nu->bezt);
@@ -4368,55 +4371,14 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
psys->tree = NULL;
psys->bvhtree = NULL;
+
+ psys->batch_cache = NULL;
}
return;
}
/* ************ READ MESH ***************** */
-static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
-{
- MTFace *tf= mtface;
- int i;
-
- /* Add pseudo-references (not fake users!) to images used by texface. A
- * little bogus; it would be better if each mesh consistently added one ref
- * to each image it used. - z0r */
- for (i = 0; i < totface; i++, tf++) {
- tf->tpage = newlibadr_real_us(fd, me->id.lib, tf->tpage);
- }
-}
-
-static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface)
-{
- int i;
- for (i = 0; i < fdata->totlayer; i++) {
- CustomDataLayer *layer = &fdata->layers[i];
-
- if (layer->type == CD_MTFACE)
- lib_link_mtface(fd, me, layer->data, totface);
- }
-
-}
-
-static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata, int totface)
-{
- int i;
-
- for (i=0; i < pdata->totlayer; i++) {
- CustomDataLayer *layer = &pdata->layers[i];
-
- if (layer->type == CD_MTEXPOLY) {
- MTexPoly *tf= layer->data;
- int j;
-
- for (j = 0; j < totface; j++, tf++) {
- tf->tpage = newlibadr_real_us(fd, me->id.lib, tf->tpage);
- }
- }
- }
-}
-
static void lib_link_mesh(FileData *fd, Main *main)
{
Mesh *me;
@@ -4443,19 +4405,9 @@ static void lib_link_mesh(FileData *fd, Main *main)
me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys
me->key = newlibadr_us(fd, me->id.lib, me->key);
me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh);
-
- lib_link_customdata_mtface(fd, me, &me->fdata, me->totface);
- lib_link_customdata_mtpoly(fd, me, &me->pdata, me->totpoly);
- if (me->mr && me->mr->levels.first) {
- lib_link_customdata_mtface(fd, me, &me->mr->fdata,
- ((MultiresLevel*)me->mr->levels.first)->totface);
- }
}
}
- /* convert texface options to material */
- convert_tface_mt(fd, main);
-
for (me = main->mesh.first; me; me = me->id.next) {
if (me->id.tag & LIB_TAG_NEED_LINK) {
/*check if we need to convert mfaces to mpolys*/
@@ -4611,7 +4563,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->dvert = newdataadr(fd, mesh->dvert);
mesh->mloopcol = newdataadr(fd, mesh->mloopcol);
mesh->mloopuv = newdataadr(fd, mesh->mloopuv);
- mesh->mtpoly = newdataadr(fd, mesh->mtpoly);
mesh->mselect = newdataadr(fd, mesh->mselect);
/* animdata */
@@ -4630,18 +4581,13 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->bb = NULL;
mesh->edit_btmesh = NULL;
+ mesh->batch_cache = NULL;
/* happens with old files */
if (mesh->mselect == NULL) {
mesh->totselect = 0;
}
- if (mesh->mloopuv || mesh->mtpoly) {
- /* for now we have to ensure texpoly and mloopuv layers are aligned
- * in the future we may allow non-aligned layers */
- BKE_mesh_cd_validate(mesh);
- }
-
/* Multires data */
mesh->mr= newdataadr(fd, mesh->mr);
if (mesh->mr) {
@@ -4721,6 +4667,7 @@ static void direct_link_latt(FileData *fd, Lattice *lt)
direct_link_dverts(fd, lt->pntsu*lt->pntsv*lt->pntsw, lt->dvert);
lt->editlatt = NULL;
+ lt->batch_cache = NULL;
lt->adt = newdataadr(fd, lt->adt);
direct_link_animdata(fd, lt->adt);
@@ -5069,6 +5016,8 @@ static void direct_link_pose(FileData *fd, bPose *pose)
/* in case this value changes in future, clamp else we get undefined behavior */
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
+
+ pchan->draw_data = NULL;
}
pose->ikdata = NULL;
if (pose->ikparam != NULL) {
@@ -5443,6 +5392,7 @@ static void direct_link_object(FileData *fd, Object *ob)
direct_link_motionpath(fd, ob->mpath);
link_list(fd, &ob->defbase);
+ link_list(fd, &ob->fmaps);
// XXX deprecated - old animation system <<<
direct_link_nlastrips(fd, &ob->nlastrips);
link_list(fd, &ob->constraintChannels);
@@ -5629,6 +5579,7 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->derivedDeform = NULL;
ob->derivedFinal = NULL;
BLI_listbase_clear(&ob->gpulamp);
+ BLI_listbase_clear(&ob->drawdata);
link_list(fd, &ob->pc_ids);
/* Runtime curve data */
@@ -5645,6 +5596,8 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->currentlod = ob->lodlevels.first;
ob->preview = direct_link_preview_image(fd, ob->preview);
+
+ ob->base_collection_properties = NULL;
}
/* ************ READ SCENE ***************** */
@@ -5709,6 +5662,23 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
}
#endif
+static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ link->data = newlibadr_us(fd, lib, link->data);
+ BLI_assert(link->data);
+ }
+
+ for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
+ link->data = newlibadr_us(fd, lib, link->data);
+ BLI_assert(link->data);
+ }
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ lib_link_scene_collection(fd, lib, nsc);
+ }
+}
+
static void lib_link_scene(FileData *fd, Main *main)
{
#ifdef USE_SETSCENE_CHECK
@@ -5756,17 +5726,17 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object);
- for (Base *next, *base = sce->base.first; base; base = next) {
- next = base->next;
+ for (BaseLegacy *base_legacy_next, *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy_next) {
+ base_legacy_next = base_legacy->next;
- base->object = newlibadr_us(fd, sce->id.lib, base->object);
+ base_legacy->object = newlibadr_us(fd, sce->id.lib, base_legacy->object);
- if (base->object == NULL) {
+ if (base_legacy->object == NULL) {
blo_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB: object lost from scene: '%s'"),
sce->id.name + 2);
- BLI_remlink(&sce->base, base);
- if (base == sce->basact) sce->basact = NULL;
- MEM_freeN(base);
+ BLI_remlink(&sce->base, base_legacy);
+ if (base_legacy == sce->basact) sce->basact = NULL;
+ MEM_freeN(base_legacy);
}
}
@@ -5855,6 +5825,19 @@ static void lib_link_scene(FileData *fd, Main *main)
/* Motion Tracking */
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
+ lib_link_scene_collection(fd, sce->id.lib, sce->collection);
+
+ for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+ /* tag scene layer to update for collection tree evaluation */
+ sl->flag |= SCENE_LAYER_ENGINE_DIRTY;
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ /* we only bump the use count for the collection objects */
+ base->object = newlibadr(fd, sce->id.lib, base->object);
+ base->flag |= BASE_DIRTY_ENGINE_SETTINGS;
+ base->collection_properties = NULL;
+ }
+ }
+
#ifdef USE_SETSCENE_CHECK
if (sce->set != NULL) {
/* link flag for scenes with set would be reset later,
@@ -5958,18 +5941,54 @@ static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *vi
direct_link_curvemapping(fd, view_settings->curve_mapping);
}
+static void direct_link_scene_collection(FileData *fd, SceneCollection *sc)
+{
+ link_list(fd, &sc->objects);
+ link_list(fd, &sc->filter_objects);
+ link_list(fd, &sc->scene_collections);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ direct_link_scene_collection(fd, nsc);
+ }
+}
+
+static void direct_link_layer_collections(FileData *fd, ListBase *lb)
+{
+ link_list(fd, lb);
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ lc->scene_collection = newdataadr(fd, lc->scene_collection);
+
+ link_list(fd, &lc->object_bases);
+
+ for (LinkData *link = lc->object_bases.first; link; link = link->next) {
+ link->data = newdataadr(fd, link->data);
+ }
+
+ link_list(fd, &lc->overrides);
+
+ if (lc->properties) {
+ lc->properties = newdataadr(fd, lc->properties);
+ IDP_DirectLinkGroup_OrFree(&lc->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ BKE_layer_collection_engine_settings_validate_collection(lc);
+ }
+ lc->properties_evaluated = NULL;
+
+ direct_link_layer_collections(fd, &lc->layer_collections);
+ }
+}
+
static void direct_link_scene(FileData *fd, Scene *sce)
{
Editing *ed;
Sequence *seq;
MetaStack *ms;
RigidBodyWorld *rbw;
+ SceneLayer *sl;
SceneRenderLayer *srl;
sce->theDag = NULL;
sce->depsgraph = NULL;
sce->obedit = NULL;
- sce->stats = NULL;
sce->fps_info = NULL;
sce->customdata_mask_modal = 0;
sce->lay_updated = 0;
@@ -6001,6 +6020,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->toolsettings->imapaint.paintcursor = NULL;
sce->toolsettings->particle.paintcursor = NULL;
sce->toolsettings->particle.scene = NULL;
+ sce->toolsettings->particle.scene_layer = NULL;
sce->toolsettings->particle.object = NULL;
sce->toolsettings->gp_sculpt.paintcursor = NULL;
@@ -6223,6 +6243,40 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->preview = direct_link_preview_image(fd, sce->preview);
direct_link_curvemapping(fd, &sce->r.mblur_shutter_curve);
+
+ /* this runs before the very first doversion */
+ if (sce->collection) {
+ sce->collection = newdataadr(fd, sce->collection);
+ direct_link_scene_collection(fd, sce->collection);
+ }
+
+ link_list(fd, &sce->render_layers);
+ for (sl = sce->render_layers.first; sl; sl = sl->next) {
+ sl->stats = NULL;
+ link_list(fd, &sl->object_bases);
+ sl->basact = newdataadr(fd, sl->basact);
+ direct_link_layer_collections(fd, &sl->layer_collections);
+
+ if (sl->properties != NULL) {
+ sl->properties = newdataadr(fd, sl->properties);
+ BLI_assert(sl->properties != NULL);
+ IDP_DirectLinkGroup_OrFree(&sl->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ BKE_scene_layer_engine_settings_validate_layer(sl);
+ }
+
+ sl->properties_evaluated = NULL;
+
+ BLI_listbase_clear(&sl->drawdata);
+ }
+
+ sce->collection_properties = newdataadr(fd, sce->collection_properties);
+ IDP_DirectLinkGroup_OrFree(&sce->collection_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+
+ sce->layer_properties = newdataadr(fd, sce->layer_properties);
+ IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+
+ BKE_layer_collection_engine_settings_validate_scene(sce);
+ BKE_scene_layer_engine_settings_validate_scene(sce);
}
/* ************ READ WM ***************** */
@@ -7034,6 +7088,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->sms = NULL;
rv3d->smooth_timer = NULL;
rv3d->compositor = NULL;
+ rv3d->viewport = NULL;
}
}
}
@@ -7050,6 +7105,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ar->type = NULL;
ar->swap = 0;
ar->do_draw = 0;
+ ar->manipulator_map = NULL;
ar->regiontimer = NULL;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
@@ -7096,6 +7152,8 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
sc->mainwin = sc->subwinactive= 0; /* indices */
sc->swap = 0;
+ sc->preview = direct_link_preview_image(fd, sc->preview);
+
/* edges */
for (se = sc->edgebase.first; se; se = se->next) {
se->v1 = newdataadr(fd, se->v1);
@@ -7561,7 +7619,7 @@ static void lib_link_group(FileData *fd, Main *main)
if (add_us) {
id_us_ensure_real(&group->id);
}
- BKE_group_object_unlink(group, NULL, NULL, NULL); /* removes NULL entries */
+ BKE_group_object_unlink(group, NULL); /* removes NULL entries */
group->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -8411,26 +8469,6 @@ static void link_global(FileData *fd, BlendFileData *bfd)
}
}
-static void convert_tface_mt(FileData *fd, Main *main)
-{
- Main *gmain;
-
- /* this is a delayed do_version (so it can create new materials) */
- if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 3)) {
- //XXX hack, material.c uses G.main all over the place, instead of main
- // temporarily set G.main to the current main
- gmain = G.main;
- G.main = main;
-
- if (!(do_version_tface(main))) {
- BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)");
- }
-
- //XXX hack, material.c uses G.main allover the place, instead of main
- G.main = gmain;
- }
-}
-
/* initialize userdef with non-UI dependency stuff */
/* other initializers (such as theme color defaults) go to resources.c */
static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
@@ -8484,6 +8522,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
blo_do_versions_250(fd, lib, main);
blo_do_versions_260(fd, lib, main);
blo_do_versions_270(fd, lib, main);
+ blo_do_versions_280(fd, lib, main);
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
@@ -8497,6 +8536,7 @@ static void do_versions_after_linking(Main *main)
// main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile);
do_versions_after_linking_270(main);
+ do_versions_after_linking_280(main);
}
static void lib_link_all(FileData *fd, Main *main)
@@ -9240,6 +9280,10 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
if (ma->group)
expand_doit(fd, mainvar, ma->group);
+
+ if (ma->edit_image) {
+ expand_doit(fd, mainvar, ma->edit_image);
+ }
}
static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
@@ -9329,9 +9373,7 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
{
- CustomDataLayer *layer;
- TFace *tf;
- int a, i;
+ int a;
if (me->adt)
expand_animdata(fd, mainvar, me->adt);
@@ -9342,46 +9384,6 @@ static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
expand_doit(fd, mainvar, me->key);
expand_doit(fd, mainvar, me->texcomesh);
-
- if (me->tface) {
- tf = me->tface;
- for (i=0; i<me->totface; i++, tf++) {
- if (tf->tpage)
- expand_doit(fd, mainvar, tf->tpage);
- }
- }
-
- if (me->mface && !me->mpoly) {
- MTFace *mtf;
-
- for (a = 0; a < me->fdata.totlayer; a++) {
- layer = &me->fdata.layers[a];
-
- if (layer->type == CD_MTFACE) {
- mtf = (MTFace *) layer->data;
- for (i = 0; i < me->totface; i++, mtf++) {
- if (mtf->tpage)
- expand_doit(fd, mainvar, mtf->tpage);
- }
- }
- }
- }
- else {
- MTexPoly *mtp;
-
- for (a = 0; a < me->pdata.totlayer; a++) {
- layer = &me->pdata.layers[a];
-
- if (layer->type == CD_MTEXPOLY) {
- mtp = (MTexPoly *) layer->data;
-
- for (i = 0; i < me->totpoly; i++, mtp++) {
- if (mtp->tpage)
- expand_doit(fd, mainvar, mtp->tpage);
- }
- }
- }
- }
}
/* temp struct used to transport needed info to expand_constraint_cb() */
@@ -9624,9 +9626,24 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
}
}
+static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ expand_doit(fd, mainvar, link->data);
+ }
+
+ for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
+ expand_doit(fd, mainvar, link->data);
+ }
+
+ for (SceneCollection *nsc= sc->scene_collections.first; nsc; nsc = nsc->next) {
+ expand_scene_collection(fd, mainvar, nsc);
+ }
+}
+
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
{
- Base *base;
+ BaseLegacy *base;
SceneRenderLayer *srl;
FreestyleModuleConfig *module;
FreestyleLineSet *lineset;
@@ -9695,6 +9712,8 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
}
expand_doit(fd, mainvar, sce->clip);
+
+ expand_scene_collection(fd, mainvar, sce->collection);
}
static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -9940,11 +9959,11 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
return false;
}
-static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Library *lib, const short flag)
+static void give_base_to_objects(
+ Main *mainvar, Scene *scene, SceneLayer *sl, SceneCollection *sc, Library *lib, const short flag)
{
Object *ob;
Base *base;
- const unsigned int active_lay = (flag & FILE_ACTIVELAY) ? BKE_screen_view3d_layer_active(v3d, scene) : 0;
const bool is_link = (flag & FILE_LINK) != 0;
BLI_assert(scene);
@@ -9964,25 +9983,22 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra
}
if (do_it) {
- base = MEM_callocN(sizeof(Base), __func__);
- BLI_addtail(&scene->base, base);
+ CLAMP_MIN(ob->id.us, 0);
+
+ BKE_collection_object_add(scene, sc, ob);
+ base = BKE_scene_layer_base_find(sl, ob);
+ BKE_scene_object_base_flag_sync_from_base(base);
- if (active_lay) {
- ob->lay = active_lay;
- }
if (flag & FILE_AUTOSELECT) {
/* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag,
* but it will miss objects from non-instanciated groups... */
- ob->flag |= SELECT;
+ if (base->flag & BASE_SELECTABLED) {
+ base->flag |= BASE_SELECTED;
+ BKE_scene_base_flag_sync_from_base(base);
+ }
/* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
}
- base->object = ob;
- base->lay = ob->lay;
- base->flag = ob->flag;
-
- CLAMP_MIN(ob->id.us, 0);
- id_us_plus_no_lib((ID *)ob);
ob->id.tag &= ~LIB_TAG_INDIRECT;
ob->id.tag |= LIB_TAG_EXTERN;
@@ -9992,12 +10008,12 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra
}
static void give_base_to_groups(
- Main *mainvar, Scene *scene, View3D *v3d, Library *UNUSED(lib), const short UNUSED(flag))
+ Main *mainvar, Scene *scene, SceneLayer *sl, SceneCollection *sc,
+ Library *UNUSED(lib), const short UNUSED(flag))
{
Group *group;
Base *base;
Object *ob;
- const unsigned int active_lay = BKE_screen_view3d_layer_active(v3d, scene);
/* give all objects which are tagged a base */
for (group = mainvar->group.first; group; group = group->id.next) {
@@ -10008,14 +10024,17 @@ static void give_base_to_groups(
/* BKE_object_add(...) messes with the selection */
ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2);
ob->type = OB_EMPTY;
- ob->lay = active_lay;
- /* assign the base */
- base = BKE_scene_base_add(scene, ob);
- base->flag |= SELECT;
- base->object->flag = base->flag;
- DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
- scene->basact = base;
+ BKE_collection_object_add(scene, sc, ob);
+ base = BKE_scene_layer_base_find(sl, ob);
+
+ if (base->flag & BASE_SELECTABLED) {
+ base->flag |= BASE_SELECTED;
+ }
+
+ BKE_scene_object_base_flag_sync_from_base(base);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ sl->basact = base;
/* assign the group */
ob->dup_group = group;
@@ -10092,31 +10111,42 @@ static ID *link_named_part(
return id;
}
-static void link_object_postprocess(ID *id, Scene *scene, View3D *v3d, const short flag)
+static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *sl, const short flag)
+{
+ LayerCollection *lc = NULL;
+
+ if (flag & FILE_ACTIVE_COLLECTION) {
+ lc = BKE_layer_collection_get_active_ensure(scene, sl);
+ }
+ else {
+ SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
+ lc = BKE_collection_link(sl, sc);
+ }
+
+ return lc->scene_collection;
+}
+
+static void link_object_postprocess(ID *id, Scene *scene, SceneLayer *sl, const short flag)
{
if (scene) {
+ /* link to scene */
Base *base;
Object *ob;
-
- base = MEM_callocN(sizeof(Base), "app_nam_part");
- BLI_addtail(&scene->base, base);
+ SceneCollection *sc;
ob = (Object *)id;
-
- /* link at active layer (view3d if available in context, else scene one */
- if (flag & FILE_ACTIVELAY) {
- ob->lay = BKE_screen_view3d_layer_active(v3d, scene);
- }
-
ob->mode = OB_MODE_OBJECT;
- base->lay = ob->lay;
- base->object = ob;
- base->flag = ob->flag;
- id_us_plus_no_lib((ID *)ob);
+
+ sc = get_scene_collection_active_or_create(scene, sl, flag);
+ BKE_collection_object_add(scene, sc, ob);
+ base = BKE_scene_layer_base_find(sl, ob);
+ BKE_scene_object_base_flag_sync_from_base(base);
if (flag & FILE_AUTOSELECT) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
+ if (base->flag & BASE_SELECTABLED) {
+ base->flag |= BASE_SELECTED;
+ BKE_scene_base_flag_sync_from_base(base);
+ }
/* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
}
}
@@ -10159,12 +10189,12 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
static ID *link_named_part_ex(
Main *mainl, FileData *fd, const short idcode, const char *name, const short flag,
- Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
+ Scene *scene, SceneLayer *sl, const bool use_placeholders, const bool force_indirect)
{
ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect);
if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */
- link_object_postprocess(id, scene, v3d, flag);
+ link_object_postprocess(id, scene, sl, flag);
}
else if (id && (GS(id->name) == ID_GR)) {
/* tag as needing to be instantiated */
@@ -10208,11 +10238,11 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcod
ID *BLO_library_link_named_part_ex(
Main *mainl, BlendHandle **bh,
const short idcode, const char *name, const short flag,
- Scene *scene, View3D *v3d,
+ Scene *scene, SceneLayer *sl,
const bool use_placeholders, const bool force_indirect)
{
FileData *fd = (FileData*)(*bh);
- return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d, use_placeholders, force_indirect);
+ return link_named_part_ex(mainl, fd, idcode, name, flag, scene, sl, use_placeholders, force_indirect);
}
static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
@@ -10325,7 +10355,7 @@ static void split_main_newid(Main *mainptr, Main *main_newid)
}
/* scene and v3d may be NULL. */
-static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, View3D *v3d)
+static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, SceneLayer *sl)
{
Main *mainvar;
Library *curlib;
@@ -10381,10 +10411,11 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
* Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co,
* here we handle indirect ones and other possible edge-cases. */
if (scene) {
- give_base_to_objects(mainvar, scene, v3d, curlib, flag);
+ SceneCollection *sc = get_scene_collection_active_or_create(scene, sl, FILE_ACTIVE_COLLECTION);
+ give_base_to_objects(mainvar, scene, sl, sc, curlib, flag);
if (flag & FILE_GROUP_INSTANCE) {
- give_base_to_groups(mainvar, scene, v3d, curlib, flag);
+ give_base_to_groups(mainvar, scene, sl, sc, curlib, flag);
}
}
else {
@@ -10410,12 +10441,12 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
* \param bh The blender file handle (WARNING! may be freed by this function!).
* \param flag Options for linking, used for instantiating.
* \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done).
- * \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL).
+ * \param sl The scene layer in which to instantiate objects/groups (if NULL, no instantiation is done).
*/
-void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, View3D *v3d)
+void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, SceneLayer *sl)
{
FileData *fd = (FileData*)(*bh);
- library_link_end(mainl, &fd, flag, scene, v3d);
+ library_link_end(mainl, &fd, flag, scene, sl);
*bh = (BlendHandle*)fd;
}
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 62ce15a640e..299c66f2bbb 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -34,6 +34,8 @@
#define __READFILE_H__
#include "zlib.h"
+#include "DNA_sdna_types.h"
+#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h" /* for ReportType */
struct OldNewMap;
@@ -171,8 +173,10 @@ void blo_do_versions_pre250(struct FileData *fd, struct Library *lib, struct Mai
void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *main);
+void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *main);
void do_versions_after_linking_270(struct Main *main);
+void do_versions_after_linking_280(struct Main *main);
#endif
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 1956a17d57b..0895b956563 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -736,7 +736,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 250) {
bScreen *screen;
Scene *scene;
- Base *base;
+ BaseLegacy *base;
Material *ma;
Camera *cam;
Mesh *me;
@@ -1119,8 +1119,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
sce->gm.matmode = GAME_MAT_MULTITEX;
else
sce->gm.matmode = GAME_MAT_TEXFACE;
-
- sce->gm.flag |= GAME_DISPLAY_LISTS;
}
for (ob = main->object.first; ob; ob = ob->id.next) {
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index d2f43a2d79e..db32b48c717 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1663,6 +1663,27 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
for (Mesh *me = main->mesh.first; me; me = me->id.next) {
CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, "");
}
+
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DDebug", "char", "background")) {
+ bScreen *screen;
+
+ for (screen = main->screen.first; screen; screen = screen->id.next) {
+ ScrArea *sa;
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D:
+ {
+ View3D *v3d = (View3D *)sl;
+ v3d->debug.background = V3D_DEBUG_BACKGROUND_NONE;
+ }
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
new file mode 100644
index 00000000000..3eeb0fc78e4
--- /dev/null
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -0,0 +1,288 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/blenloader/intern/versioning_280.c
+ * \ingroup blenloader
+ */
+
+/* allow readfile to use deprecated functionality */
+#define DNA_DEPRECATED_ALLOW
+
+#include "DNA_object_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_gpu_types.h"
+#include "DNA_layer_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_genfile.h"
+
+#include "BKE_collection.h"
+#include "BKE_customdata.h"
+#include "BKE_idprop.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_scene.h"
+
+#include "BLI_listbase.h"
+#include "BLI_mempool.h"
+#include "BLI_string.h"
+
+#include "BLO_readfile.h"
+#include "readfile.h"
+
+#include "MEM_guardedalloc.h"
+
+void do_versions_after_linking_280(Main *main)
+{
+ if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ /* since we don't have access to FileData we check the (always valid) first render layer instead */
+ if (scene->render_layers.first == NULL) {
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ BLI_strncpy(sc_master->name, "Master Collection", sizeof(sc_master->name));
+
+ SceneCollection *collections[20] = {NULL};
+ bool is_visible[20];
+
+ int lay_used = 0;
+ for (int i = 0; i < 20; i++) {
+ char name[MAX_NAME];
+
+ BLI_snprintf(name, sizeof(collections[i]->name), "Collection %d", i + 1);
+ collections[i] = BKE_collection_add(scene, sc_master, name);
+
+ is_visible[i] = (scene->lay & (1 << i));
+ }
+
+ for (Base *base = scene->base.first; base; base = base->next) {
+ lay_used |= base->lay & ((1 << 20) - 1); /* ignore localview */
+
+ for (int i = 0; i < 20; i++) {
+ if ((base->lay & (1 << i)) != 0) {
+ BKE_collection_object_add(scene, collections[i], base->object);
+ }
+ }
+ }
+
+ scene->active_layer = 0;
+
+ if (!BKE_scene_uses_blender_game(scene)) {
+ for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
+
+ SceneLayer *sl = BKE_scene_layer_add(scene, srl->name);
+ BKE_scene_layer_engine_set(sl, scene->r.engine);
+
+ if (srl->mat_override) {
+ BKE_collection_override_datablock_add((LayerCollection *)sl->layer_collections.first, "material", (ID *)srl->mat_override);
+ }
+
+ if (srl->light_override && BKE_scene_uses_blender_internal(scene)) {
+ /* not sure how we handle this, pending until we design the override system */
+ TODO_LAYER_OVERRIDE;
+ }
+
+ if (srl->lay != scene->lay) {
+ /* unlink master collection */
+ BKE_collection_unlink(sl, sl->layer_collections.first);
+
+ /* add new collection bases */
+ for (int i = 0; i < 20; i++) {
+ if ((srl->lay & (1 << i)) != 0) {
+ BKE_collection_link(sl, collections[i]);
+ }
+ }
+ }
+
+ /* for convenience set the same active object in all the layers */
+ if (scene->basact) {
+ sl->basact = BKE_scene_layer_base_find(sl, scene->basact->object);
+ }
+
+ /* TODO: passes, samples, mask_layesr, exclude, ... */
+ }
+
+ if (BLI_findlink(&scene->render_layers, scene->r.actlay)) {
+ scene->active_layer = scene->r.actlay;
+ }
+ }
+
+ SceneLayer *sl = BKE_scene_layer_add(scene, "Viewport");
+
+ /* In this particular case we can safely assume the data struct */
+ LayerCollection *lc = ((LayerCollection *)sl->layer_collections.first)->layer_collections.first;
+ for (int i = 0; i < 20; i++) {
+ if (!is_visible[i]) {
+ lc->flag &= ~COLLECTION_VISIBLE;
+ }
+ lc = lc->next;
+ }
+
+ /* convert active base */
+ if (scene->basact) {
+ sl->basact = BKE_scene_layer_base_find(sl, scene->basact->object);
+ }
+
+ /* convert selected bases */
+ for (Base *base = scene->base.first; base; base = base->next) {
+ Base *ob_base = BKE_scene_layer_base_find(sl, base->object);
+ if ((base->flag & SELECT) != 0) {
+ if ((ob_base->flag & BASE_SELECTABLED) != 0) {
+ ob_base->flag |= BASE_SELECTED;
+ }
+ }
+ else {
+ ob_base->flag &= ~BASE_SELECTED;
+ }
+
+ /* keep lay around for forward compatibility (open those files in 2.79) */
+ ob_base->lay = base->lay;
+ }
+
+ /* TODO: copy scene render data to layer */
+
+ /* Cleanup */
+ for (int i = 0; i < 20; i++) {
+ if ((lay_used & (1 << i)) == 0) {
+ BKE_collection_remove(scene, collections[i]);
+ }
+ }
+
+ /* Fallback name if only one layer was found in the original file */
+ if (BLI_listbase_count_ex(&sc_master->scene_collections, 2) == 1) {
+ BKE_collection_rename(scene, sc_master->scene_collections.first, "Default Collection");
+ }
+
+ /* remove bases once and for all */
+ for (Base *base = scene->base.first; base; base = base->next) {
+ id_us_min(&base->object->id);
+ }
+ BLI_freelistN(&scene->base);
+ scene->basact = NULL;
+ }
+ }
+
+ for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_OUTLINER) {
+ SpaceOops *soutliner = (SpaceOops *)sl;
+ SceneLayer *layer = BKE_scene_layer_context_active(screen->scene);
+
+ soutliner->outlinevis = SO_ACT_LAYER;
+
+ if (BLI_listbase_count_ex(&layer->layer_collections, 2) == 1) {
+ if (soutliner->treestore == NULL) {
+ soutliner->treestore = BLI_mempool_create(
+ sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
+ }
+
+ /* Create a tree store element for the collection. This is normally
+ * done in check_persistent (outliner_tree.c), but we need to access
+ * it here :/ (expand element if it's the only one) */
+ TreeStoreElem *tselem = BLI_mempool_calloc(soutliner->treestore);
+ tselem->type = TSE_LAYER_COLLECTION;
+ tselem->id = layer->layer_collections.first;
+ tselem->nr = tselem->used = 0;
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void do_version_layer_collections_idproperties(ListBase *lb)
+{
+ IDPropertyTemplate val = {0};
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ lc->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_layer_collection_engine_settings_create(lc->properties);
+
+ /* No overrides at first */
+ for (IDProperty *prop = lc->properties->data.group.first; prop; prop = prop->next) {
+ while (prop->data.group.first) {
+ IDP_FreeFromGroup(prop, prop->data.group.first);
+ }
+ }
+
+ /* Do it recursively */
+ do_version_layer_collections_idproperties(&lc->layer_collections);
+ }
+}
+
+void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
+{
+ if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "render_layers")) {
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ /* Master Collection */
+ scene->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
+ BLI_strncpy(scene->collection->name, "Master Collection", sizeof(scene->collection->name));
+ }
+ }
+
+ if (DNA_struct_elem_find(fd->filesdna, "LayerCollection", "ListBase", "engine_settings") &&
+ !DNA_struct_elem_find(fd->filesdna, "LayerCollection", "IDProperty", "properties"))
+ {
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ do_version_layer_collections_idproperties(&sl->layer_collections);
+ }
+ }
+ }
+
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "GPUDOFSettings", "float", "ratio")) {
+ for (Camera *ca = main->camera.first; ca; ca = ca->id.next) {
+ ca->gpu_dof.ratio = 1.0f;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "SceneLayer", "IDProperty", "*properties")) {
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ IDPropertyTemplate val = {0};
+ sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_scene_layer_engine_settings_create(sl->properties);
+ }
+ }
+ }
+
+ /* MTexPoly now removed. */
+ if (DNA_struct_find(fd->filesdna, "MTexPoly")) {
+ const int cd_mtexpoly = 15; /* CD_MTEXPOLY, deprecated */
+ for (Mesh *me = main->mesh.first; me; me = me->id.next) {
+ /* If we have UV's, so this file will have MTexPoly layers too! */
+ if (me->mloopuv != NULL) {
+ CustomData_update_typemap(&me->pdata);
+ CustomData_free_layers(&me->pdata, cd_mtexpoly, me->totpoly);
+ BKE_mesh_update_customdata_pointers(me, false);
+ }
+ }
+ }
+}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index e34f12b1cf9..a38f122ec56 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -28,6 +28,7 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "DNA_brush_types.h"
#include "DNA_freestyle_types.h"
@@ -88,6 +89,8 @@ void BLO_update_defaults_userpref_blend(void)
void BLO_update_defaults_startup_blend(Main *bmain)
{
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+ BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine));
+
scene->r.im_format.planes = R_IMF_PLANES_RGBA;
scene->r.im_format.compress = 15;
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index c29ffbb76f2..67b629222a2 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -319,55 +319,6 @@ static void idproperties_fix_group_lengths(ListBase idlist)
}
}
-static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
-{
- Material *ma;
- MFace *mf;
- MTFace *tf;
- int a, b, texalpha;
-
- /* verify we have a tface layer */
- for (b = 0; b < me->fdata.totlayer; b++)
- if (me->fdata.layers[b].type == CD_MTFACE)
- break;
-
- if (b == me->fdata.totlayer)
- return;
-
- /* if we do, set alpha sort if the game engine did it before */
- for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
- if (mf->mat_nr < me->totcol) {
- ma = blo_do_versions_newlibadr(fd, lib, me->mat[mf->mat_nr]);
- texalpha = 0;
-
- /* we can't read from this if it comes from a library,
- * because direct_link might not have happened on it,
- * so ma->mtex is not pointing to valid memory yet */
- if (ma && ma->id.lib)
- ma = NULL;
-
- for (b = 0; ma && b < MAX_MTEX; b++)
- if (ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
- texalpha = 1;
- }
- else {
- ma = NULL;
- texalpha = 0;
- }
-
- for (b = 0; b < me->fdata.totlayer; b++) {
- if (me->fdata.layers[b].type == CD_MTFACE) {
- tf = ((MTFace*)me->fdata.layers[b].data) + a;
-
- tf->mode &= ~TF_ALPHASORT;
- if (ma && (ma->mode & MA_ZTRANSP))
- if (ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP)))
- tf->mode |= TF_ALPHASORT;
- }
- }
- }
-}
-
static void customdata_version_242(Mesh *me)
{
CustomDataLayer *layer;
@@ -403,13 +354,6 @@ static void customdata_version_242(Mesh *me)
for (a = 0; a < me->totface; a++, mtf++, tf++, mcol += 4) {
memcpy(mcol, tf->col, sizeof(tf->col));
memcpy(mtf->uv, tf->uv, sizeof(tf->uv));
-
- mtf->flag = tf->flag;
- mtf->unwrap = tf->unwrap;
- mtf->mode = tf->mode;
- mtf->tile = tf->tile;
- mtf->tpage = tf->tpage;
- mtf->transp = tf->transp;
}
MEM_freeN(me->tface);
@@ -916,23 +860,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 196) {
- Mesh *me = main->mesh.first;
- int a, b;
- while (me) {
- if (me->tface) {
- TFace *tface = me->tface;
- for (a = 0; a < me->totface; a++, tface++) {
- for (b = 0; b < 4; b++) {
- tface->mode |= TF_DYNAMIC;
- tface->mode &= ~TF_INVISIBLE;
- }
- }
- }
- me = me->id.next;
- }
- }
-
if (main->versionfile <= 200) {
Object *ob = main->object.first;
while (ob) {
@@ -3290,14 +3217,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
-
- if (main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
- Mesh *me;
-
- for (me = main->mesh.first; me; me = me->id.next)
- alphasort_version_246(fd, lib, me);
- }
-
if (main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
Object *ob;
for (ob = main->object.first; ob; ob = ob->id.next) {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index ee9665dc834..19f6b9f370d 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -120,6 +120,7 @@
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_lamp_types.h"
+#include "DNA_layer_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
@@ -1687,6 +1688,13 @@ static void write_defgroups(WriteData *wd, ListBase *defbase)
}
}
+static void write_fmaps(WriteData *wd, ListBase *fbase)
+{
+ for (bFaceMap *fmap = fbase->first; fmap; fmap = fmap->next) {
+ writestruct(wd, DATA, bFaceMap, 1, fmap);
+ }
+}
+
static void write_modifiers(WriteData *wd, ListBase *modbase)
{
ModifierData *md;
@@ -1724,6 +1732,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
SmokeModifierData *smd = (SmokeModifierData *)md;
if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
+ writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain);
+
if (smd->domain) {
write_pointcaches(wd, &(smd->domain->ptcaches[0]));
@@ -1737,11 +1747,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
if (smd->domain->coba) {
writestruct(wd, DATA, ColorBand, 1, smd->domain->coba);
}
- }
- writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain);
- if (smd->domain) {
/* cleanup the fake pointcache */
BKE_ptcache_free_list(&smd->domain->ptcaches[1]);
smd->domain->point_cache[1] = NULL;
@@ -1891,6 +1898,7 @@ static void write_object(WriteData *wd, Object *ob)
write_pose(wd, ob->pose);
write_defgroups(wd, &ob->defbase);
+ write_fmaps(wd, &ob->fmaps);
write_constraints(wd, &ob->constraints);
write_motionpath(wd, ob->mpath);
@@ -2123,6 +2131,10 @@ static void write_customdata(
else if (layer->type == CD_GRID_PAINT_MASK) {
write_grid_paint_mask(wd, count, layer->data);
}
+ else if (layer->type == CD_FACEMAP) {
+ const int *layer_data = layer->data;
+ writedata(wd, DATA, sizeof(*layer_data) * count, layer_data);
+ }
else {
CustomData_file_write_info(layer->type, &structname, &structnum);
if (structnum) {
@@ -2537,6 +2549,34 @@ static void write_paint(WriteData *wd, Paint *p)
}
}
+static void write_scene_collection(WriteData *wd, SceneCollection *sc)
+{
+ writestruct(wd, DATA, SceneCollection, 1, sc);
+
+ writelist(wd, DATA, LinkData, &sc->objects);
+ writelist(wd, DATA, LinkData, &sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ write_scene_collection(wd, nsc);
+ }
+}
+
+static void write_layer_collections(WriteData *wd, ListBase *lb)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ writestruct(wd, DATA, LayerCollection, 1, lc);
+
+ writelist(wd, DATA, LinkData, &lc->object_bases);
+ writelist(wd, DATA, CollectionOverride, &lc->overrides);
+
+ if (lc->properties) {
+ IDP_WriteProperty(lc->properties, wd);
+ }
+
+ write_layer_collections(wd, &lc->layer_collections);
+ }
+}
+
static void write_scene(WriteData *wd, Scene *sce)
{
/* write LibData */
@@ -2549,8 +2589,8 @@ static void write_scene(WriteData *wd, Scene *sce)
write_keyingsets(wd, &sce->keyingsets);
/* direct data */
- for (Base *base = sce->base.first; base; base = base->next) {
- writestruct(wd, DATA, Base, 1, base);
+ for (BaseLegacy *base = sce->base.first; base; base = base->next) {
+ writestruct(wd, DATA, BaseLegacy, 1, base);
}
ToolSettings *tos = sce->toolsettings;
@@ -2743,6 +2783,24 @@ static void write_scene(WriteData *wd, Scene *sce)
write_previews(wd, sce->preview);
write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve);
+ write_scene_collection(wd, sce->collection);
+
+ for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+ writestruct(wd, DATA, SceneLayer, 1, sl);
+ writelist(wd, DATA, Base, &sl->object_bases);
+ if (sl->properties) {
+ IDP_WriteProperty(sl->properties, wd);
+ }
+ write_layer_collections(wd, &sl->layer_collections);
+ }
+
+ if (sce->layer_properties) {
+ IDP_WriteProperty(sce->layer_properties, wd);
+ }
+
+ if (sce->collection_properties) {
+ IDP_WriteProperty(sce->collection_properties, wd);
+ }
}
static void write_gpencil(WriteData *wd, bGPdata *gpd)
@@ -2876,6 +2934,8 @@ static void write_screen(WriteData *wd, bScreen *sc)
writestruct(wd, ID_SCRN, bScreen, 1, sc);
write_iddata(wd, &sc->id);
+ write_previews(wd, sc->preview);
+
/* direct data */
for (ScrVert *sv = sc->vertbase.first; sv; sv = sv->next) {
writestruct(wd, DATA, ScrVert, 1, sv);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 59ce91a3e70..49f055e1827 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -98,42 +98,6 @@
#include "bmesh.h"
#include "intern/bmesh_private.h" /* for element checking */
-/**
- * Currently this is only used for Python scripts
- * which may fail to keep matching UV/TexFace layers.
- *
- * \note This should only perform any changes in exceptional cases,
- * if we need this to be faster we could inline #BM_data_layer_add and only
- * call #update_data_blocks once at the end.
- */
-void BM_mesh_cd_validate(BMesh *bm)
-{
- int totlayer_mtex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
- int totlayer_uv = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
-
- if (LIKELY(totlayer_mtex == totlayer_uv)) {
- /* pass */
- }
- else if (totlayer_mtex < totlayer_uv) {
- const int uv_index_first = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
- do {
- const char *from_name = bm->ldata.layers[uv_index_first + totlayer_mtex].name;
- BM_data_layer_add_named(bm, &bm->pdata, CD_MTEXPOLY, from_name);
- CustomData_set_layer_unique_name(&bm->pdata, totlayer_mtex);
- } while (totlayer_uv != ++totlayer_mtex);
- }
- else if (totlayer_uv < totlayer_mtex) {
- const int mtex_index_first = CustomData_get_layer_index(&bm->pdata, CD_MTEXPOLY);
- do {
- const char *from_name = bm->pdata.layers[mtex_index_first + totlayer_uv].name;
- BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, from_name);
- CustomData_set_layer_unique_name(&bm->ldata, totlayer_uv);
- } while (totlayer_mtex != ++totlayer_uv);
- }
-
- BLI_assert(totlayer_mtex == totlayer_uv);
-}
-
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
{
const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
@@ -235,7 +199,7 @@ void BM_mesh_bm_from_me(
BMEdge *e, **etable = NULL;
BMFace *f;
float (*keyco)[3] = NULL;
- int totuv, totloops, i, j;
+ int totloops, i, j;
/* free custom data */
/* this isnt needed in most cases but do just incase */
@@ -266,13 +230,6 @@ void BM_mesh_bm_from_me(
CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
- /* make sure uv layer names are consisten */
- totuv = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
- for (i = 0; i < totuv; i++) {
- int li = CustomData_get_layer_index_n(&bm->pdata, CD_MTEXPOLY, i);
- CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
- }
-
if ((params->active_shapekey != 0) && (me->key != NULL)) {
actkey = BLI_findlink(&me->key->block, params->active_shapekey - 1);
}
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index b670f31ad9f..80b57eb3565 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -77,13 +77,13 @@ enum {
/* similar face selection slot values */
enum {
SIMFACE_MATERIAL = 201,
- SIMFACE_IMAGE,
SIMFACE_AREA,
SIMFACE_SIDES,
SIMFACE_PERIMETER,
SIMFACE_NORMAL,
SIMFACE_COPLANAR,
SIMFACE_SMOOTH,
+ SIMFACE_FACEMAP,
#ifdef WITH_FREESTYLE
SIMFACE_FREESTYLE
#endif
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
index 454d6d8c6c8..0cd17258834 100644
--- a/source/blender/bmesh/operators/bmo_similar.c
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -106,11 +106,28 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
const float thresh = BMO_slot_float_get(op->slots_in, "thresh");
const float thresh_radians = thresh * (float)M_PI;
const int compare = BMO_slot_int_get(op->slots_in, "compare");
+ /* for comparison types that use custom-data */
+ int cd_offset = -1;
/* initial_elem - other_elem */
float delta_fl;
int delta_i;
+ if (type == SIMFACE_FACEMAP) {
+ cd_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
+ if (cd_offset == -1) {
+ return;
+ }
+ }
+#ifdef WITH_FREESTYLE
+ else if (type == SIMFACE_FREESTYLE) {
+ cd_offset = CustomData_get_offset(&bm->pdata, CD_FREESTYLE_FACE);
+ if (cd_offset == -1) {
+ return;
+ }
+ }
+#endif
+
num_total = BM_mesh_elem_count(bm, BM_FACE);
/*
@@ -145,7 +162,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
* Save us some computation burden: In case of perimeter/area/coplanar selection we compute
* only once.
*/
- if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) {
+ if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR) {
for (i = 0; i < num_total; i++) {
switch (type) {
case SIMFACE_PERIMETER:
@@ -164,14 +181,6 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
case SIMFACE_AREA:
f_ext[i].area = BM_face_calc_area(f_ext[i].f);
break;
-
- case SIMFACE_IMAGE:
- f_ext[i].t = NULL;
- if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) {
- MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY);
- f_ext[i].t = mtpoly->tpage;
- }
- break;
}
}
}
@@ -190,14 +199,6 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
cont = false;
}
break;
-
- case SIMFACE_IMAGE:
- if (f_ext[i].t == f_ext[indices[idx]].t) {
- BMO_face_flag_enable(bm, fm, FACE_MARK);
- cont = false;
- }
- break;
-
case SIMFACE_NORMAL:
angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */
if (angle <= thresh_radians) {
@@ -254,20 +255,29 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
cont = false;
}
break;
+ case SIMFACE_FACEMAP:
+ {
+ BLI_assert(cd_offset != -1);
+ const int *fmap1 = BM_ELEM_CD_GET_VOID_P(fs, cd_offset);
+ const int *fmap2 = BM_ELEM_CD_GET_VOID_P(fm, cd_offset);
+ if (*fmap1 == *fmap2) {
+ BMO_face_flag_enable(bm, fm, FACE_MARK);
+ cont = false;
+ }
+ break;
+ }
#ifdef WITH_FREESTYLE
case SIMFACE_FREESTYLE:
- if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) {
- FreestyleEdge *ffa1, *ffa2;
-
- ffa1 = CustomData_bmesh_get(&bm->pdata, fs->head.data, CD_FREESTYLE_FACE);
- ffa2 = CustomData_bmesh_get(&bm->pdata, fm->head.data, CD_FREESTYLE_FACE);
-
- if (ffa1 && ffa2 && (ffa1->flag & FREESTYLE_FACE_MARK) == (ffa2->flag & FREESTYLE_FACE_MARK)) {
- BMO_face_flag_enable(bm, fm, FACE_MARK);
- cont = false;
- }
+ {
+ BLI_assert(cd_offset != -1);
+ const FreestyleEdge *ffa1 = BM_ELEM_CD_GET_VOID_P(fs, cd_offset);
+ const FreestyleEdge *ffa2 = BM_ELEM_CD_GET_VOID_P(fm, cd_offset);
+ if ((ffa1->flag & FREESTYLE_FACE_MARK) == (ffa2->flag & FREESTYLE_FACE_MARK)) {
+ BMO_face_flag_enable(bm, fm, FACE_MARK);
+ cont = false;
}
break;
+ }
#endif
default:
BLI_assert(0);
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index b9408492cc1..cfb43181703 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -81,12 +81,6 @@
/* use accelerated overlap check */
#define USE_BVH
-// #define USE_BOOLEAN_RAYCAST_DRAW
-
-#ifdef USE_BOOLEAN_RAYCAST_DRAW
-/* insert bl_debug_draw_quad_clear... here */
-#endif
-
// #define USE_DUMP
static void tri_v3_scale(
@@ -1006,10 +1000,6 @@ bool BM_mesh_intersect(
int i_a, i_b;
#endif
-#ifdef USE_BOOLEAN_RAYCAST_DRAW
- bl_debug_draw_quad_clear();
-#endif
-
s.bm = bm;
s.edgetri_cache = BLI_ghash_new(BLI_ghashutil_inthash_v4_p, BLI_ghashutil_inthash_v4_cmp, __func__);
@@ -1607,17 +1597,6 @@ bool BM_mesh_intersect(
do_flip = (side == 0);
break;
}
-
-#ifdef USE_BOOLEAN_RAYCAST_DRAW
- {
- uint colors[4] = {0x00000000, 0xffffffff, 0xff000000, 0x0000ff};
- float co_other[3] = {UNPACK3(co)};
- co_other[0] += 1000.0f;
- bl_debug_color_set(colors[(hits & 1) == 1]);
- bl_debug_draw_edge_add(co, co_other);
- }
-#endif
-
}
if (do_remove) {
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 3bff20e846b..707aaea0b65 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -938,7 +938,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
float ctime = BKE_scene_frame_get_from_ctime(scene, *it);
CFRA = BKE_scene_frame_get_from_ctime(scene, *it);
- //BKE_scene_update_for_newframe(G.main->eval_ctx, G.main,scene,scene->lay);
+ //BKE_scene_update_for_newframe(G.main->eval_ctx, G.main,scene);
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
if (bone) {
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 0ea8324ed7c..9c8b8fc25d6 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -34,7 +34,6 @@
extern "C" {
#include "BKE_action.h"
-#include "BKE_depsgraph.h"
#include "BKE_object.h"
#include "BKE_armature.h"
#include "BLI_string.h"
@@ -42,6 +41,8 @@ extern "C" {
#include "ED_armature.h"
}
+#include "DEG_depsgraph.h"
+
#include "collada_utils.h"
#include "ArmatureImporter.h"
@@ -496,7 +497,7 @@ void ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
ob_arms.push_back(ob_arm);
}
- DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
}
@@ -629,7 +630,7 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
ED_armature_from_edit(armature);
ED_armature_edit_free(armature);
- DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
return ob_arm;
}
diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt
index 293049a1a05..8642bbee698 100644
--- a/source/blender/collada/CMakeLists.txt
+++ b/source/blender/collada/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../blenkernel
../blenlib
../blentranslation
+ ../depsgraph
../editors/include
../makesdna
../makesrna
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 226f319cefd..7cb6045b73e 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -57,12 +57,12 @@ extern "C" {
#include "BLI_fileops.h"
#include "BKE_camera.h"
+#include "BKE_collection.h"
#include "BKE_main.h"
#include "BKE_lamp.h"
#include "BKE_library.h"
#include "BKE_texture.h"
#include "BKE_fcurve.h"
-#include "BKE_depsgraph.h"
#include "BKE_scene.h"
#include "BKE_global.h"
#include "BKE_material.h"
@@ -82,6 +82,9 @@ extern "C" {
}
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#include "ExtraHandler.h"
#include "ErrorHandler.h"
#include "DocumentImporter.h"
@@ -230,7 +233,7 @@ void DocumentImporter::finish()
}
// update scene
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL);
}
@@ -241,7 +244,7 @@ void DocumentImporter::finish()
armature_importer.set_tags_map(this->uid_tags_map);
armature_importer.make_armatures(mContext, *objects_to_scale);
armature_importer.make_shape_keys();
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
#if 0
armature_importer.fix_animation();
@@ -264,7 +267,7 @@ void DocumentImporter::finish()
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
Object *ob = *it;
- Base *base = BKE_scene_base_find(sce, ob);
+ BaseLegacy *base = (BaseLegacy *)BKE_scene_base_find(sce, ob);
if (base) {
BLI_remlink(&sce->base, base);
BKE_libblock_free_us(G.main, base->object);
@@ -275,7 +278,7 @@ void DocumentImporter::finish()
}
libnode_ob.clear();
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
}
bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
@@ -417,8 +420,8 @@ Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod
fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL);
Object *obn = BKE_object_copy(G.main, source_ob);
- DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
- BKE_scene_base_add(sce, obn);
+ DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ BKE_collection_object_add_from(sce, source_ob, obn);
if (instance_node) {
anim_importer.read_node_transform(instance_node, obn);
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index 76b51148509..978d79077fe 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -66,7 +66,7 @@ EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettin
bool EffectsExporter::hasEffects(Scene *sce)
{
- Base *base = (Base *)sce->base.first;
+ BaseLegacy *base = (BaseLegacy *)sce->base.first;
while (base) {
Object *ob = base->object;
@@ -311,58 +311,6 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
}
}
- int active_uv_layer = -1;
- std::set<Image *> uv_textures;
- if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) {
- bool active_uv_only = this->export_settings->active_uv_only;
- Mesh *me = (Mesh *) ob->data;
- active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
-
- BKE_mesh_tessface_ensure(me);
- for (int i = 0; i < me->pdata.totlayer; i++) {
- if (!active_uv_only || active_uv_layer == i)
- {
- if (me->pdata.layers[i].type == CD_MTEXPOLY) {
- MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
- MPoly *mpoly = me->mpoly;
- for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
-
- Material *mat = give_current_material(ob, mpoly->mat_nr + 1);
- if (mat != ma)
- continue;
-
- Image *ima = txface->tpage;
- if (ima == NULL)
- continue;
-
-
- bool not_in_list = uv_textures.find(ima)==uv_textures.end();
- if (not_in_list) {
- std::string name = id_name(ima);
- std::string key(name);
- key = translate_id(key);
-
- // create only one <sampler>/<surface> pair for each unique image
- if (im_samp_map.find(key) == im_samp_map.end()) {
- //<newparam> <sampler> <source>
- COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
- key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
- key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
- sampler.setImageId(key);
- samplers[a] = sampler;
- samp_surf[b] = &samplers[a];
- im_samp_map[key] = b;
- b++;
- a++;
- uv_textures.insert(ima);
- }
- }
- }
- }
- }
- }
- }
-
// used as fallback when MTex->uvname is "" (this is pretty common)
// it is indeed the correct value to use in that case
std::string active_uv(getActiveUVLayerName(ob));
@@ -385,19 +333,6 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
writeTextures(ep, key, sampler, t, ima, uvname);
}
- std::set<Image *>::iterator uv_t_iter;
- int idx;
- for (idx = 0, uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++, idx++ ) {
- if (active_uv_layer>-1 && idx==active_uv_layer) {
- Image *ima = *uv_t_iter;
- std::string key(id_name(ima));
- key = translate_id(key);
- int i = im_samp_map[key];
- COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i];
- ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse");
- }
- }
-
// performs the actual writing
ep.addProfileElements();
bool twoSided = false;
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index de91f68a492..33a7527f383 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -42,7 +42,6 @@ public:
bool deform_bones_only;
bool active_uv_only;
- bool include_uv_textures;
bool include_material_textures;
bool use_texture_copies;
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index aac41e2e93c..a2ab3ce520b 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -152,44 +152,6 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
}
}
-void ImagesExporter::export_UV_Images()
-{
- std::set<Image *> uv_textures;
- LinkNode *node;
- bool use_texture_copies = this->export_settings->use_texture_copies;
- bool active_uv_only = this->export_settings->active_uv_only;
-
- for (node = this->export_settings->export_set; node; node = node->next) {
- Object *ob = (Object *)node->link;
- if (ob->type == OB_MESH && ob->totcol) {
- Mesh *me = (Mesh *) ob->data;
- BKE_mesh_tessface_ensure(me);
- int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
- for (int i = 0; i < me->pdata.totlayer; i++) {
- if (me->pdata.layers[i].type == CD_MTEXPOLY) {
- if (!active_uv_only || active_uv_layer == i)
- {
- MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
- for (int j = 0; j < me->totpoly; j++, txface++) {
-
- Image *ima = txface->tpage;
- if (ima == NULL)
- continue;
-
- bool not_in_list = uv_textures.find(ima) == uv_textures.end();
- if (not_in_list) {
- uv_textures.insert(ima);
- export_UV_Image(ima, use_texture_copies);
- }
- }
- }
- }
- }
- }
- }
-}
-
-
bool ImagesExporter::hasImages(Scene *sce)
{
LinkNode *node;
@@ -209,20 +171,6 @@ bool ImagesExporter::hasImages(Scene *sce)
}
}
- if (ob->type == OB_MESH) {
- Mesh *me = (Mesh *) ob->data;
- BKE_mesh_tessface_ensure(me);
- bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
- if (has_uvs) {
- int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
- for (int a = 0; a < num_layers; a++) {
- MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a);
- Image *img = tface->tpage;
- if (img) return true;
- }
- }
- }
-
}
return false;
}
@@ -236,10 +184,6 @@ void ImagesExporter::exportImages(Scene *sce)
mf.forEachMaterialInExportSet<ImagesExporter>(sce, *this, this->export_settings->export_set);
}
- if (this->export_settings->include_uv_textures) {
- export_UV_Images();
- }
-
closeLibrary();
}
diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h
index 0eaebdd5cdd..f3dd2b336e4 100644
--- a/source/blender/collada/ImageExporter.h
+++ b/source/blender/collada/ImageExporter.h
@@ -51,7 +51,6 @@ public:
private:
std::vector<std::string> mImages; // contains list of written images, to avoid duplicates
- void export_UV_Images();
void export_UV_Image(Image *image, bool use_texture_copies);
bool hasImages(Scene *sce);
const ExportSettings *export_settings;
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index a1bfce88131..616c254a6ea 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -472,11 +472,9 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i];
COLLADAFW::String &uvname = info->mName;
// Allocate space for UV_data
- CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str());
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str());
}
// activate the first uv map
- me->mtpoly = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0);
me->mloopuv = (MLoopUV *) CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0);
}
@@ -1051,11 +1049,11 @@ void MeshImporter::optimize_material_assignements()
* which materials shall be moved to the created geometries. Also see
* optimize_material_assignements() above.
*/
-MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
- std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
- Object *ob, const COLLADAFW::UniqueId *geom_uid,
- char *layername, MTFace *texture_face,
- std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
+void MeshImporter::assign_material_to_geom(
+ COLLADAFW::MaterialBinding cmaterial,
+ std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
+ Object *ob, const COLLADAFW::UniqueId *geom_uid,
+ std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
{
MTex *color_texture = NULL;
Mesh *me = (Mesh *)ob->data;
@@ -1065,7 +1063,7 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
fprintf(stderr, "Cannot find material by UID.\n");
- return NULL;
+ return;
}
// first time we get geom_uid, ma_uid pair. Save for later check.
@@ -1089,15 +1087,6 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
color_texture);
}
- // set texture face
- if (color_texture &&
- strlen((color_texture)->uvname) &&
- !STREQ(layername, color_texture->uvname)) {
- texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
- color_texture->uvname);
- strcpy(layername, color_texture->uvname);
- }
-
MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
@@ -1114,15 +1103,9 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
for (i = 0; i < prim.totpoly; i++, mpoly++) {
mpoly->mat_nr = mat_index;
- // bind texture images to faces
- if (texture_face && color_texture) {
- texture_face->tpage = (Image *)color_texture->tex->ima;
- texture_face++;
- }
}
}
}
- return texture_face;
}
Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
@@ -1175,10 +1158,6 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh);
- char layername[100];
- layername[0] = '\0';
- MTFace *texture_face = NULL;
-
COLLADAFW::MaterialBindingArray& mat_array =
geom->getMaterialBindings();
@@ -1186,9 +1165,9 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
for (unsigned int i = 0; i < mat_array.getCount(); i++) {
if (mat_array[i].getReferencedMaterial().isValid()) {
- texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
- layername, texture_face,
- material_texture_mapping_map, i);
+ assign_material_to_geom(
+ mat_array[i], uid_material_map, ob, geom_uid,
+ material_texture_mapping_map, i);
}
else {
fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index d6426fbaf56..e8ae934a393 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -171,11 +171,11 @@ public:
void optimize_material_assignements();
- MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- Object *ob, const COLLADAFW::UniqueId *geom_uid,
- char *layername, MTFace *texture_face,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
+ void assign_material_to_geom(
+ COLLADAFW::MaterialBinding cmaterial,
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ Object *ob, const COLLADAFW::UniqueId *geom_uid,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index bfe3180909b..9cb0b414721 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -68,6 +68,7 @@ int collada_import(bContext *C,
}
int collada_export(Scene *sce,
+ SceneLayer *scene_layer,
const char *filepath,
int apply_modifiers,
@@ -80,7 +81,6 @@ int collada_export(Scene *sce,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
int include_material_textures,
int use_texture_copies,
@@ -106,7 +106,6 @@ int collada_export(Scene *sce,
export_settings.deform_bones_only = deform_bones_only != 0;
export_settings.active_uv_only = active_uv_only != 0;
- export_settings.include_uv_textures = include_uv_textures != 0;
export_settings.include_material_textures= include_material_textures != 0;
export_settings.use_texture_copies = use_texture_copies != 0;
@@ -124,7 +123,7 @@ int collada_export(Scene *sce,
if (export_settings.include_children) includeFilter |= OB_REL_CHILDREN_RECURSIVE;
eObjectSet objectSet = (export_settings.selected) ? OB_SET_SELECTED : OB_SET_ALL;
- export_settings.export_set = BKE_object_relational_superset(sce, objectSet, (eObRelationTypes)includeFilter);
+ export_settings.export_set = BKE_object_relational_superset(scene_layer, objectSet, (eObRelationTypes)includeFilter);
int export_count = BLI_linklist_count(export_settings.export_set);
if (export_count == 0) {
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 8035af59c8b..9aba51ef18a 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -48,6 +48,7 @@ typedef enum BC_export_transformation_type {
struct bContext;
struct Scene;
+struct SceneLayer;
/*
* both return 1 on success, 0 on error
@@ -63,6 +64,7 @@ int collada_import(struct bContext *C,
int keep_bind_info);
int collada_export(struct Scene *sce,
+ struct SceneLayer *scene_layer,
const char *filepath,
int apply_modifiers,
BC_export_mesh_type export_mesh_type,
@@ -74,7 +76,6 @@ int collada_export(struct Scene *sce,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
int include_material_textures,
int use_texture_copies,
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index ac4395e1430..1ba8658f245 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -45,7 +45,6 @@ extern "C" {
#include "BKE_context.h"
#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
@@ -61,6 +60,8 @@ extern "C" {
#include "bmesh_tools.h"
}
+#include "DEG_depsgraph.h"
+
#include "collada_utils.h"
#include "ExportSettings.h"
@@ -118,8 +119,8 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
BKE_object_workob_calc_parent(sce, ob, &workob);
invert_m4_m4(ob->parentinv, workob.obmat);
- DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
- DAG_id_tag_update(&par->id, OB_RECALC_OB);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(&par->id, OB_RECALC_OB);
/** done once after import */
#if 0
@@ -136,7 +137,7 @@ Object *bc_add_object(Scene *scene, int type, const char *name)
ob->data = BKE_object_obdata_add_from_type(G.main, type, name);
ob->lay = scene->lay;
- DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_scene_base_select(scene, BKE_scene_base_add(scene, ob));
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index b664af570b1..d5dcb84aaf5 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -43,11 +43,13 @@ set(SRC
intern/builder/deg_builder.cc
intern/builder/deg_builder_cycle.cc
intern/builder/deg_builder_nodes.cc
+ intern/builder/deg_builder_nodes_layer.cc
intern/builder/deg_builder_nodes_rig.cc
intern/builder/deg_builder_nodes_scene.cc
intern/builder/deg_builder_pchanmap.cc
intern/builder/deg_builder_relations.cc
intern/builder/deg_builder_relations_keys.cc
+ intern/builder/deg_builder_relations_layer.cc
intern/builder/deg_builder_relations_rig.cc
intern/builder/deg_builder_relations_scene.cc
intern/builder/deg_builder_transitive.cc
@@ -112,10 +114,6 @@ else()
endif()
endif()
-if(WITH_LEGACY_DEPSGRAPH)
- add_definitions(-DWITH_LEGACY_DEPSGRAPH)
-endif()
-
if(WITH_BOOST)
list(APPEND INC_SYS
${BOOST_INCLUDE_DIR}
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index 945a4785b9c..cda8664bc5a 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -66,6 +66,35 @@ struct Main;
struct PointerRNA;
struct PropertyRNA;
+/* Dependency graph evaluation context
+ *
+ * This structure stores all the local dependency graph data,
+ * which is needed for it's evaluation,
+ */
+typedef struct EvaluationContext {
+ int mode; /* evaluation mode */
+ float ctime; /* evaluation time */
+} EvaluationContext;
+
+typedef enum eEvaluationMode {
+ DAG_EVAL_VIEWPORT = 0, /* evaluate for OpenGL viewport */
+ DAG_EVAL_PREVIEW = 1, /* evaluate for render with preview settings */
+ DAG_EVAL_RENDER = 2, /* evaluate for render purposes */
+} eEvaluationMode;
+
+/* DagNode->eval_flags */
+enum {
+ /* Regardless to curve->path animation flag path is to be evaluated anyway,
+ * to meet dependencies with such a things as curve modifier and other guys
+ * who're using curve deform, where_on_path and so.
+ */
+ DAG_EVAL_NEED_CURVE_PATH = 1,
+ /* Scene evaluation would need to have object's data on CPU,
+ * meaning no GPU shortcuts is allowed.
+ */
+ DAG_EVAL_NEED_CPU = 2,
+};
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -167,16 +196,13 @@ void DEG_evaluation_context_free(struct EvaluationContext *eval_ctx);
void DEG_evaluate_on_framechange(struct EvaluationContext *eval_ctx,
struct Main *bmain,
Depsgraph *graph,
- float ctime,
- const unsigned int layer);
+ float ctime);
/* Data changed recalculation entry point.
* < context_type: context to perform evaluation for
- * < layers: visible layers bitmask to update the graph for
*/
void DEG_evaluate_on_refresh_ex(struct EvaluationContext *eval_ctx,
- Depsgraph *graph,
- const unsigned int layers);
+ Depsgraph *graph);
/* Data changed recalculation entry point.
* < context_type: context to perform evaluation for
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index fdc86540171..d861afd1fa7 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -40,10 +40,13 @@ struct Depsgraph;
/* ------------------------------------------------ */
+struct CacheFile;
+struct EffectorWeights;
+struct Group;
struct Main;
+struct ModifierData;
+struct Object;
struct Scene;
-struct Group;
-struct EffectorWeights;
#ifdef __cplusplus
extern "C" {
@@ -85,9 +88,6 @@ void DEG_scene_graph_free(struct Scene *scene);
*/
struct DepsNodeHandle;
-struct CacheFile;
-struct Object;
-
typedef enum eDepsSceneComponentType {
/* Parameters Component - Default when nothing else fits
* (i.e. just SDNA property setting).
@@ -161,16 +161,15 @@ typedef bool (*DEG_CollobjFilterFunction)(struct Object *obj, struct ModifierDat
void DEG_add_collision_relations(struct DepsNodeHandle *handle,
struct Scene *scene,
- Object *ob,
+ struct Object *ob,
struct Group *group,
- int layer,
unsigned int modifier_type,
DEG_CollobjFilterFunction fn,
bool dupli,
const char *name);
void DEG_add_forcefield_relations(struct DepsNodeHandle *handle,
struct Scene *scene,
- Object *ob,
+ struct Object *ob,
struct EffectorWeights *eff,
bool add_absorption,
int skip_forcefield,
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index ccd204a2083..6f7f98861dd 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -36,6 +36,8 @@
struct ID;
struct Depsgraph;
+struct BLI_Iterator;
+struct SceneLayer;
#ifdef __cplusplus
extern "C" {
@@ -47,6 +49,31 @@ bool DEG_id_type_tagged(struct Main *bmain, short idtype);
/* Get additional evaluation flags for the given ID. */
short DEG_get_eval_flags_for_id(struct Depsgraph *graph, struct ID *id);
+/* Get scene the despgraph is created for. */
+struct Scene *DEG_get_scene(struct Depsgraph *graph);
+
+/* Get scene layer the despgraph is created for. */
+struct SceneLayer *DEG_get_scene_layer(struct Depsgraph *graph);
+
+/* Get the object as properly evaluated by depsgraph. */
+struct Object *DEG_get_object(struct Depsgraph *depsgraph, struct Object *ob);
+
+/* ************************ DAG iterators ********************* */
+
+void DEG_objects_iterator_begin(struct BLI_Iterator *iter, void *data_in);
+void DEG_objects_iterator_next(struct BLI_Iterator *iter);
+void DEG_objects_iterator_end(struct BLI_Iterator *iter);
+
+/* Temporary hacky solution waiting for cow depsgraph implementation. */
+#define DEG_OBJECT_ITER(graph_, instance_) \
+ ITER_BEGIN(DEG_objects_iterator_begin, \
+ DEG_objects_iterator_next, \
+ DEG_objects_iterator_end, \
+ graph_, Object *, instance_)
+
+#define DEG_OBJECT_ITER_END \
+ ITER_END
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 55caad91b4e..dba589ed24f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -53,121 +53,21 @@ extern "C" {
namespace DEG {
-static bool check_object_needs_evaluation(Object *object)
-{
- if (object->recalc & OB_RECALC_ALL) {
- /* Object is tagged for update anyway, no need to re-tag it. */
- return false;
- }
- if (object->type == OB_MESH) {
- return object->derivedFinal == NULL;
- }
- else if (ELEM(object->type,
- OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
- {
- return object->curve_cache == NULL;
- }
- return false;
-}
-
-void deg_graph_build_flush_layers(Depsgraph *graph)
-{
- BLI_Stack *stack = BLI_stack_new(sizeof(OperationDepsNode*),
- "DEG flush layers stack");
- foreach (OperationDepsNode *node, graph->operations) {
- IDDepsNode *id_node = node->owner->owner;
- node->done = 0;
- node->num_links_pending = 0;
- foreach (DepsRelation *rel, node->outlinks) {
- if ((rel->from->type == DEG_NODE_TYPE_OPERATION) &&
- (rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
- {
- ++node->num_links_pending;
- }
- }
- if (node->num_links_pending == 0) {
- BLI_stack_push(stack, &node);
- node->done = 1;
- }
- node->owner->layers = id_node->layers;
- id_node->id->tag |= LIB_TAG_DOIT;
- }
- while (!BLI_stack_is_empty(stack)) {
- OperationDepsNode *node;
- BLI_stack_pop(stack, &node);
- /* Flush layers to parents. */
- foreach (DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
- OperationDepsNode *from = (OperationDepsNode *)rel->from;
- from->owner->layers |= node->owner->layers;
- }
- }
- /* Schedule parent nodes. */
- foreach (DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
- OperationDepsNode *from = (OperationDepsNode *)rel->from;
- if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) {
- BLI_assert(from->num_links_pending > 0);
- --from->num_links_pending;
- }
- if (from->num_links_pending == 0 && from->done == 0) {
- BLI_stack_push(stack, &from);
- from->done = 1;
- }
- }
- }
- }
- BLI_stack_free(stack);
-}
-
void deg_graph_build_finalize(Depsgraph *graph)
{
- /* STEP 1: Make sure new invisible dependencies are ready for use.
- *
- * TODO(sergey): This might do a bit of extra tagging, but it's kinda nice
- * to do it ahead of a time and don't spend time on flushing updates on
- * every frame change.
- */
- GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash)
- {
- if (id_node->layers == 0) {
- ID *id = id_node->id;
- if (GS(id->name) == ID_OB) {
- Object *object = (Object *)id;
- if (check_object_needs_evaluation(object)) {
- id_node->tag_update(graph);
- }
- }
- }
- }
- GHASH_FOREACH_END();
- /* STEP 2: Flush visibility layers from children to parent. */
- deg_graph_build_flush_layers(graph);
- /* STEP 3: Re-tag IDs for update if it was tagged before the relations
+ /* Re-tag IDs for update if it was tagged before the relations
* update tag.
*/
GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash)
{
- GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp, id_node->components)
- {
- id_node->layers |= comp->layers;
+ ID *id = id_node->id;
+ if ((id->tag & LIB_TAG_ID_RECALC_ALL)) {
+ id_node->tag_update(graph);
}
- GHASH_FOREACH_END();
-
- if ((id_node->layers & graph->layers) != 0 || graph->layers == 0) {
- ID *id = id_node->id;
- if ((id->tag & LIB_TAG_ID_RECALC_ALL) &&
- (id->tag & LIB_TAG_DOIT))
- {
+ else if (GS(id->name) == ID_OB) {
+ Object *object = (Object *)id;
+ if (object->recalc & OB_RECALC_ALL) {
id_node->tag_update(graph);
- id->tag &= ~LIB_TAG_DOIT;
- }
- else if (GS(id->name) == ID_OB) {
- Object *object = (Object *)id;
- if (object->recalc & OB_RECALC_ALL) {
- id_node->tag_update(graph);
- id->tag &= ~LIB_TAG_DOIT;
- }
}
}
id_node->finalize_build();
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index b8ea8c8e599..31426819fb9 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -39,6 +39,5 @@ namespace DEG {
struct Depsgraph;
void deg_graph_build_finalize(struct Depsgraph *graph);
-void deg_graph_build_flush_layers(struct Depsgraph *graph);
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 1e51b8131e4..eb8b175a423 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -72,7 +72,6 @@ extern "C" {
#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_idcode.h"
@@ -125,7 +124,7 @@ static void modifier_walk(void *user_data,
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
if (*obpoin) {
- data->builder->build_object(data->scene, NULL, *obpoin);
+ data->builder->build_object(data->scene, *obpoin);
}
}
@@ -138,7 +137,7 @@ void constraint_walk(bConstraint * /*con*/,
if (*idpoin) {
ID *id = *idpoin;
if (GS(id->name) == ID_OB) {
- data->builder->build_object(data->scene, NULL, (Object *)id);
+ data->builder->build_object(data->scene, (Object *)id);
}
}
}
@@ -302,9 +301,7 @@ void DepsgraphNodeBuilder::begin_build(Main *bmain) {
} FOREACH_NODETREE_END
}
-void DepsgraphNodeBuilder::build_group(Scene *scene,
- Base *base,
- Group *group)
+void DepsgraphNodeBuilder::build_group(Scene *scene, Group *group)
{
ID *group_id = &group->id;
if (group_id->tag & LIB_TAG_DOIT) {
@@ -313,39 +310,27 @@ void DepsgraphNodeBuilder::build_group(Scene *scene,
group_id->tag |= LIB_TAG_DOIT;
LINKLIST_FOREACH (GroupObject *, go, &group->gobject) {
- build_object(scene, base, go->ob);
+ build_object(scene, go->ob);
}
}
-void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
+void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob)
{
- const bool has_object = (ob->id.tag & LIB_TAG_DOIT);
- IDDepsNode *id_node = (has_object)
- ? m_graph->find_id_node(&ob->id)
- : add_id_node(&ob->id);
- /* Update node layers.
- * Do it for both new and existing ID nodes. This is so because several
- * bases might be sharing same object.
- */
- if (base != NULL) {
- id_node->layers |= base->lay;
- }
- if (ob == scene->camera) {
- /* Camera should always be updated, it used directly by viewport. */
- id_node->layers |= (unsigned int)(-1);
- }
/* Skip rest of components if the ID node was already there. */
- if (has_object) {
+ if (ob->id.tag & LIB_TAG_DOIT) {
return;
}
ob->id.tag |= LIB_TAG_DOIT;
+
+ /* Create ID node for obejct and begin init. */
+ IDDepsNode *id_node = add_id_node(&ob->id);
ob->customdata_mask = 0;
/* Standard components. */
build_object_transform(scene, ob);
if (ob->parent != NULL) {
- build_object(scene, NULL, ob->parent);
+ build_object(scene, ob->parent);
}
if (ob->modifiers.first != NULL) {
BuilderWalkUserData data;
@@ -431,12 +416,12 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
/* Object that this is a proxy for. */
if (ob->proxy) {
ob->proxy->proxy_from = ob;
- build_object(scene, base, ob->proxy);
+ build_object(scene, ob->proxy);
}
/* Object dupligroup. */
if (ob->dup_group != NULL) {
- build_group(scene, base, ob->dup_group);
+ build_group(scene, ob->dup_group);
}
}
@@ -880,13 +865,13 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
*/
Curve *cu = (Curve *)obdata;
if (cu->bevobj != NULL) {
- build_object(scene, NULL, cu->bevobj);
+ build_object(scene, cu->bevobj);
}
if (cu->taperobj != NULL) {
- build_object(scene, NULL, cu->taperobj);
+ build_object(scene, cu->taperobj);
}
if (ob->type == OB_FONT && cu->textoncurve != NULL) {
- build_object(scene, NULL, cu->textoncurve);
+ build_object(scene, cu->textoncurve);
}
break;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index ba8a5d01cb0..83a4dfda8a5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -32,7 +32,6 @@
#include "intern/depsgraph_types.h"
-struct Base;
struct CacheFile;
struct bGPdata;
struct ListBase;
@@ -42,6 +41,7 @@ struct Image;
struct FCurve;
struct Group;
struct Key;
+struct LayerCollection;
struct Main;
struct Material;
struct Mask;
@@ -121,8 +121,8 @@ struct DepsgraphNodeBuilder {
int name_tag = -1);
void build_scene(Main *bmain, Scene *scene);
- void build_group(Scene *scene, Base *base, Group *group);
- void build_object(Scene *scene, Base *base, Object *ob);
+ void build_group(Scene *scene, Group *group);
+ void build_object(Scene *scene, Object *ob);
void build_object_transform(Scene *scene, Object *ob);
void build_object_constraints(Scene *scene, Object *ob);
void build_pose_constraints(Scene *scene, Object *ob, bPoseChannel *pchan);
@@ -157,6 +157,17 @@ struct DepsgraphNodeBuilder {
void build_mask(Mask *mask);
void build_movieclip(MovieClip *clip);
+ struct LayerCollectionState {
+ int index;
+ LayerCollection *parent;
+ };
+ void build_layer_collection(Scene *scene,
+ LayerCollection *layer_collection,
+ LayerCollectionState *state);
+ void build_layer_collections(Scene *scene,
+ ListBase *layer_collections,
+ LayerCollectionState *state);
+ void build_scene_layer_collections(Scene *scene);
protected:
Main *m_bmain;
Depsgraph *m_graph;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc
new file mode 100644
index 00000000000..e419b72fee8
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc
@@ -0,0 +1,117 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Original Author: Joshua Leung
+ * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
+ * \ingroup depsgraph
+ *
+ * Methods for constructing depsgraph's nodes
+ */
+
+#include "intern/builder/deg_builder_nodes.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "BLI_utildefines.h"
+
+#include "BKE_layer.h"
+
+#include "DNA_scene_types.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+} /* extern "C" */
+
+#include "intern/builder/deg_builder.h"
+#include "intern/nodes/deg_node.h"
+#include "intern/nodes/deg_node_component.h"
+#include "intern/nodes/deg_node_operation.h"
+#include "intern/depsgraph_types.h"
+#include "intern/depsgraph_intern.h"
+#include "util/deg_util_foreach.h"
+
+namespace DEG {
+
+void DepsgraphNodeBuilder::build_layer_collection(Scene *scene,
+ LayerCollection *layer_collection,
+ LayerCollectionState *state)
+{
+ /* TODO(sergey): This will attempt to create component for each collection.
+ * Harmless but could be optimized.
+ */
+ ComponentDepsNode *comp = add_component_node(&scene->id, DEG_NODE_TYPE_LAYER_COLLECTIONS);
+
+ add_operation_node(comp,
+ function_bind(BKE_layer_eval_layer_collection,
+ _1,
+ layer_collection,
+ state->parent),
+ DEG_OPCODE_SCENE_LAYER_EVAL,
+ layer_collection->scene_collection->name,
+ state->index);
+ ++state->index;
+
+ /* Recurs into nested layer collections. */
+ LayerCollection *parent = state->parent;
+ state->parent = layer_collection;
+ build_layer_collections(scene, &layer_collection->layer_collections, state);
+ state->parent = parent;
+}
+
+void DepsgraphNodeBuilder::build_layer_collections(Scene *scene,
+ ListBase *layer_collections,
+ LayerCollectionState *state)
+{
+ LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) {
+ build_layer_collection(scene, layer_collection, state);
+ }
+}
+
+void DepsgraphNodeBuilder::build_scene_layer_collections(Scene *scene)
+{
+ LayerCollectionState state;
+ state.index = 0;
+ LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) {
+ ComponentDepsNode *comp = add_component_node(&scene->id, DEG_NODE_TYPE_LAYER_COLLECTIONS);
+
+ add_operation_node(comp,
+ function_bind(BKE_layer_eval_layer_collection_pre, _1, scene, scene_layer),
+ DEG_OPCODE_SCENE_LAYER_INIT,
+ scene_layer->name);
+ add_operation_node(comp,
+ function_bind(BKE_layer_eval_layer_collection_post, _1, scene_layer),
+ DEG_OPCODE_SCENE_LAYER_DONE,
+ scene_layer->name);
+
+ state.parent = NULL;
+ build_layer_collections(scene, &scene_layer->layer_collections, &state);
+ }
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 7ab52c1fd07..79ee7b6f4de 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -133,7 +133,7 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob)
/* Rebuild pose if not up to date. */
if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
- BKE_pose_rebuild_ex(ob, arm, false);
+ BKE_pose_rebuild(ob, arm);
/* XXX: Without this animation gets lost in certain circumstances
* after loading file. Need to investigate further since it does
* not happen with simple scenes..
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
index d7ae10421df..2041235ade1 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
@@ -43,9 +43,11 @@ extern "C" {
#include "BLI_utildefines.h"
#include "DNA_node_types.h"
+#include "DNA_layer_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -79,9 +81,13 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene)
}
/* scene objects */
- LINKLIST_FOREACH (Base *, base, &scene->base) {
- Object *ob = base->object;
- build_object(scene, base, ob);
+ int selection_color = 1;
+ for (SceneLayer *sl = (SceneLayer *)scene->render_layers.first; sl; sl = sl->next) {
+ for (Base *base = (Base *)sl->object_bases.first; base; base = base->next) {
+ /* object itself */
+ build_object(scene, base->object);
+ base->selcol = selection_color++;
+ }
}
/* rigidbody */
@@ -126,6 +132,9 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene)
LINKLIST_FOREACH (MovieClip *, clip, &bmain->movieclip) {
build_movieclip(clip);
}
+
+ /* Collections. */
+ build_scene_layer_collections(scene);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 736766b5491..292777ed55b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -308,10 +308,10 @@ void DepsgraphRelationBuilder::add_operation_relation(
}
}
-void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name)
+void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name)
{
unsigned int numcollobj;
- Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, eModifierType_Collision, dupli);
+ Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, eModifierType_Collision, dupli);
for (unsigned int i = 0; i < numcollobj; i++)
{
@@ -363,7 +363,7 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key,
}
if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
- add_collision_relations(key, scene, ob, NULL, eff->ob->lay, true, "Force Absorption");
+ add_collision_relations(key, scene, ob, NULL, true, "Force Absorption");
}
}
}
@@ -1278,10 +1278,10 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
/* collisions */
if (part->type != PART_HAIR) {
- add_collision_relations(psys_key, scene, ob, part->collision_group, ob->lay, true, "Particle Collision");
+ add_collision_relations(psys_key, scene, ob, part->collision_group, true, "Particle Collision");
}
else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) {
- add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, ob->lay | scene->lay, true, "Hair Collision");
+ add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, true, "Hair Collision");
}
/* effectors */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 411f3be4036..edca1905873 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -45,7 +45,7 @@
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_operation.h"
-struct Base;
+struct BaseLegacy;
struct bGPdata;
struct CacheFile;
struct ListBase;
@@ -54,6 +54,7 @@ struct ID;
struct FCurve;
struct Group;
struct Key;
+struct LayerCollection;
struct Main;
struct Mask;
struct Material;
@@ -227,9 +228,23 @@ struct DepsgraphRelationBuilder
void build_mask(Mask *mask);
void build_movieclip(MovieClip *clip);
- void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name);
+ void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name);
void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name);
+ struct LayerCollectionState {
+ int index;
+ OperationKey init_key;
+ OperationKey done_key;
+ OperationKey prev_key;
+ };
+ void build_layer_collection(Scene *scene,
+ LayerCollection *layer_collection,
+ LayerCollectionState *state);
+ void build_layer_collections(Scene *scene,
+ ListBase *layer_collections,
+ LayerCollectionState *state);
+ void build_scene_layer_collections(Scene *scene);
+
template <typename KeyType>
OperationDepsNode *find_operation_node(const KeyType &key);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc
new file mode 100644
index 00000000000..a6c9fdfc6bc
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc
@@ -0,0 +1,127 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Original Author: Joshua Leung
+ * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+ * \ingroup depsgraph
+ *
+ * Methods for constructing depsgraph
+ */
+
+#include "intern/builder/deg_builder_relations.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring> /* required for STREQ later on. */
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+} /* extern "C" */
+
+#include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_pchanmap.h"
+
+#include "intern/nodes/deg_node.h"
+#include "intern/nodes/deg_node_component.h"
+#include "intern/nodes/deg_node_operation.h"
+
+#include "intern/depsgraph_intern.h"
+#include "intern/depsgraph_types.h"
+
+#include "util/deg_util_foreach.h"
+
+namespace DEG {
+
+void DepsgraphRelationBuilder::build_layer_collection(Scene *scene,
+ LayerCollection *layer_collection,
+ LayerCollectionState *state)
+{
+ OperationKey layer_key(&scene->id,
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ DEG_OPCODE_SCENE_LAYER_EVAL,
+ layer_collection->scene_collection->name,
+ state->index);
+ add_relation(state->prev_key, layer_key, "Layer collection order");
+
+ ++state->index;
+ state->prev_key = layer_key;
+
+ /* Recurs into nested layer collections. */
+ build_layer_collections(scene,
+ &layer_collection->layer_collections,
+ state);
+}
+
+void DepsgraphRelationBuilder::build_layer_collections(Scene *scene,
+ ListBase *layer_collections,
+ LayerCollectionState *state)
+{
+ LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) {
+ /* Recurs into the layer. */
+ build_layer_collection(scene, layer_collection, state);
+ }
+}
+
+void DepsgraphRelationBuilder::build_scene_layer_collections(Scene *scene)
+{
+ LayerCollectionState state;
+ state.index = 0;
+ LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) {
+ OperationKey init_key(&scene->id,
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ DEG_OPCODE_SCENE_LAYER_INIT,
+ scene_layer->name);
+ OperationKey done_key(&scene->id,
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ DEG_OPCODE_SCENE_LAYER_DONE,
+ scene_layer->name);
+
+ state.init_key = init_key;
+ state.done_key = done_key;
+ state.prev_key = init_key;
+
+ build_layer_collections(scene,
+ &scene_layer->layer_collections,
+ &state);
+
+ add_relation(state.prev_key, done_key, "Layer collection order");
+ }
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
index 3bf435c37e0..aa04e0e888c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
@@ -46,6 +46,7 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -73,11 +74,15 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene)
build_scene(bmain, scene->set);
}
+ /* XXX store scene to access from DAG_get_scene */
+ m_graph->scene = scene;
+
/* scene objects */
- LINKLIST_FOREACH (Base *, base, &scene->base) {
- Object *ob = base->object;
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
build_object(bmain, scene, ob);
}
+ FOREACH_SCENE_OBJECT_END
/* rigidbody */
if (scene->rigidbody_world) {
@@ -114,6 +119,9 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene)
build_movieclip(clip);
}
+ /* Collections. */
+ build_scene_layer_collections(scene);
+
for (Depsgraph::OperationNodes::const_iterator it_op = m_graph->operations.begin();
it_op != m_graph->operations.end();
++it_op)
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
index 8da3e097d07..a38419e7eff 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
@@ -82,15 +82,16 @@ static const int deg_debug_node_type_color_map[][2] = {
{DEG_NODE_TYPE_ID_REF, 2},
/* Outer Types */
- {DEG_NODE_TYPE_PARAMETERS, 3},
- {DEG_NODE_TYPE_PROXY, 4},
- {DEG_NODE_TYPE_ANIMATION, 5},
- {DEG_NODE_TYPE_TRANSFORM, 6},
- {DEG_NODE_TYPE_GEOMETRY, 7},
- {DEG_NODE_TYPE_SEQUENCER, 8},
- {DEG_NODE_TYPE_SHADING, 9},
- {DEG_NODE_TYPE_CACHE, 10},
- {-1, 0}
+ {DEG_NODE_TYPE_PARAMETERS, 3},
+ {DEG_NODE_TYPE_PROXY, 4},
+ {DEG_NODE_TYPE_ANIMATION, 5},
+ {DEG_NODE_TYPE_TRANSFORM, 6},
+ {DEG_NODE_TYPE_GEOMETRY, 7},
+ {DEG_NODE_TYPE_SEQUENCER, 8},
+ {DEG_NODE_TYPE_SHADING, 9},
+ {DEG_NODE_TYPE_CACHE, 10},
+ {DEG_NODE_TYPE_LAYER_COLLECTIONS, 11},
+ {-1, 0}
};
#endif
@@ -178,7 +179,7 @@ static void deg_debug_graphviz_legend(const DebugContext &ctx)
#ifdef COLOR_SCHEME_NODE_TYPE
const int (*pair)[2];
for (pair = deg_debug_node_type_color_map; (*pair)[0] >= 0; ++pair) {
- DepsNodeFactory *nti = DEG_get_node_factory((eDepsNode_Type)(*pair)[0]);
+ DepsNodeFactory *nti = DEG_get_node_factory((eDEG_NODE_TYPE)(*pair)[0]);
deg_debug_graphviz_legend_color(ctx,
nti->tname().c_str(),
deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors]);
@@ -285,12 +286,6 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx,
const char *shape = "box";
string name = node->identifier();
float priority = -1.0f;
- if (node->type == DEG_NODE_TYPE_ID_REF) {
- IDDepsNode *id_node = (IDDepsNode *)node;
- char buf[256];
- BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
- name += buf;
- }
if (ctx.show_eval_priority && node->tclass == DEG_NODE_CLASS_OPERATION) {
priority = ((OperationDepsNode *)node)->eval_priority;
}
@@ -321,12 +316,6 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx,
const DepsNode *node)
{
string name = node->identifier();
- if (node->type == DEG_NODE_TYPE_ID_REF) {
- IDDepsNode *id_node = (IDDepsNode *)node;
- char buf[256];
- BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
- name += buf;
- }
deg_debug_fprintf(ctx, "// %s\n", name.c_str());
deg_debug_fprintf(ctx, "subgraph \"cluster_%p\" {" NL, node);
// deg_debug_fprintf(ctx, "label=<<B>%s</B>>;" NL, name);
@@ -389,6 +378,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
case DEG_NODE_TYPE_BONE:
case DEG_NODE_TYPE_SHADING:
case DEG_NODE_TYPE_CACHE:
+ case DEG_NODE_TYPE_LAYER_COLLECTIONS:
case DEG_NODE_TYPE_EVAL_PARTICLES:
{
ComponentDepsNode *comp_node = (ComponentDepsNode *)node;
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 330f8a0dcb6..8c9de1faeb2 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -46,8 +46,6 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_sequence_types.h"
-#include "BKE_depsgraph.h"
-
#include "RNA_access.h"
}
@@ -70,8 +68,7 @@ static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
Depsgraph::Depsgraph()
: root_node(NULL),
- need_update(false),
- layers(0)
+ need_update(false)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index 1c9ba8c4cb1..bc017e0c72a 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -45,6 +45,7 @@ struct GHash;
struct GSet;
struct PointerRNA;
struct PropertyRNA;
+struct Scene;
namespace DEG {
@@ -160,12 +161,9 @@ struct Depsgraph {
*/
SpinLock lock;
- /* Layers Visibility .................. */
-
- /* Visible layers bitfield, used for skipping invisible objects updates. */
- unsigned int layers;
-
// XXX: additional stuff like eval contexts, mempools for allocating nodes from, etc.
+
+ Scene *scene; /* XXX: We really shouldn't do that, but it's required for shader preview */
};
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index 9434387ecb8..ac773ab523c 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -320,14 +320,13 @@ void DEG_add_collision_relations(DepsNodeHandle *handle,
Scene *scene,
Object *ob,
Group *group,
- int layer,
unsigned int modifier_type,
DEG_CollobjFilterFunction fn,
bool dupli,
const char *name)
{
unsigned int numcollobj;
- Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, modifier_type, dupli);
+ Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, modifier_type, dupli);
for (unsigned int i = 0; i < numcollobj; i++) {
Object *ob1 = collobjs[i];
@@ -382,7 +381,6 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
scene,
ob,
NULL,
- eff->ob->lay,
eModifierType_Collision,
NULL,
true,
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index c41f28b07e8..64e130ba3b9 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -38,7 +38,6 @@ extern "C" {
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BKE_depsgraph.h"
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
@@ -52,43 +51,9 @@ extern "C" {
#include "intern/depsgraph.h"
-#ifdef WITH_LEGACY_DEPSGRAPH
-static bool use_legacy_depsgraph = true;
-#endif
-
/* Unfinished and unused, and takes quite some pre-processing time. */
#undef USE_EVAL_PRIORITY
-bool DEG_depsgraph_use_legacy(void)
-{
-#ifdef DISABLE_NEW_DEPSGRAPH
- return true;
-#elif defined(WITH_LEGACY_DEPSGRAPH)
- return use_legacy_depsgraph;
-#else
- BLI_assert(!"Should not be used with new depsgraph");
- return false;
-#endif
-}
-
-void DEG_depsgraph_switch_to_legacy(void)
-{
-#ifdef WITH_LEGACY_DEPSGRAPH
- use_legacy_depsgraph = true;
-#else
- BLI_assert(!"Should not be used with new depsgraph");
-#endif
-}
-
-void DEG_depsgraph_switch_to_new(void)
-{
-#ifdef WITH_LEGACY_DEPSGRAPH
- use_legacy_depsgraph = false;
-#else
- BLI_assert(!"Should not be used with new depsgraph");
-#endif
-}
-
/* ****************** */
/* Evaluation Context */
@@ -127,22 +92,14 @@ void DEG_evaluate_on_refresh(EvaluationContext *eval_ctx,
/* Update time on primary timesource. */
DEG::TimeSourceDepsNode *tsrc = deg_graph->find_time_source();
tsrc->cfra = BKE_scene_frame_get(scene);
- unsigned int layers = deg_graph->layers;
- /* XXX(sergey): This works around missing updates in temp scenes used
- * by various scripts, but is weak and needs closer investigation.
- */
- if (layers == 0) {
- layers = scene->lay;
- }
- DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers);
+ DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph);
}
/* Frame-change happened for root scene that graph belongs to. */
void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx,
Main *bmain,
Depsgraph *graph,
- float ctime,
- const unsigned int layers)
+ float ctime)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
/* Update time on primary timesource. */
@@ -151,7 +108,7 @@ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx,
tsrc->tag_update(deg_graph);
DEG::deg_graph_flush_updates(bmain, deg_graph);
/* Perform recalculation updates. */
- DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers);
+ DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph);
}
bool DEG_needs_eval(Depsgraph *graph)
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 7f2f6a65f5e..b6c71524eca 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -34,12 +34,17 @@
extern "C" {
#include "BKE_idcode.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
#include "DEG_depsgraph_query.h"
} /* extern "C" */
#include "intern/depsgraph_intern.h"
+#include "util/deg_util_foreach.h"
bool DEG_id_type_tagged(Main *bmain, short idtype)
{
@@ -68,3 +73,105 @@ short DEG_get_eval_flags_for_id(Depsgraph *graph, ID *id)
return id_node->eval_flags;
}
+
+Scene *DEG_get_scene(Depsgraph *graph)
+{
+ DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
+ return deg_graph->scene;
+}
+
+SceneLayer *DEG_get_scene_layer(Depsgraph *graph)
+{
+ Scene *scene = DEG_get_scene(graph);
+ if (scene) {
+ return BKE_scene_layer_context_active(scene);
+ }
+ return NULL;
+}
+
+Object *DEG_get_object(Depsgraph * /*depsgraph*/, Object *ob)
+{
+ /* XXX TODO */
+ return ob;
+}
+
+/* ************************ DAG ITERATORS ********************* */
+
+typedef struct DEGObjectsIteratorData {
+ Depsgraph *graph;
+ Scene *scene;
+ SceneLayer *scene_layer;
+ Base *base;
+ int flag;
+} DEGObjectsIteratorData;
+
+void DEG_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
+{
+ SceneLayer *scene_layer;
+ Depsgraph *graph = (Depsgraph *) data_in;
+ DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)
+ MEM_callocN(sizeof(DEGObjectsIteratorData), __func__);
+ iter->data = data;
+ iter->valid = true;
+
+ data->graph = graph;
+ data->scene = DEG_get_scene(graph);
+ scene_layer = DEG_get_scene_layer(graph);
+ data->flag = ~(BASE_FROM_SET);
+
+ Base base = {(Base *)scene_layer->object_bases.first, NULL};
+ data->base = &base;
+ DEG_objects_iterator_next(iter);
+}
+
+void DEG_objects_iterator_next(BLI_Iterator *iter)
+{
+ DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
+ Base *base = data->base->next;
+
+ while (base) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ Object *ob = DEG_get_object(data->graph, base->object);
+ iter->current = ob;
+
+ /* Make sure we have the base collection settings is already populated.
+ * This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet
+ * Which usually means a missing call to DAG_id_tag_update(). */
+ BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group));
+
+ /* Flushing depsgraph data. */
+ ob->base_flag = (base->flag | BASE_FROM_SET) & data->flag;
+ ob->base_collection_properties = base->collection_properties;
+ ob->base_selection_color = base->selcol;
+ data->base = base;
+ return;
+ }
+ base = base->next;
+ }
+
+ /* Look for an object in the next set. */
+ if (data->scene->set) {
+ SceneLayer *scene_layer;
+ data->scene = data->scene->set;
+ data->flag = ~(BASE_SELECTED | BASE_SELECTABLED);
+
+ /* For the sets we use the layer used for rendering. */
+ scene_layer = BKE_scene_layer_render_active(data->scene);
+
+ Base base = {(Base *)scene_layer->object_bases.first, NULL};
+ data->base = &base;
+ DEG_objects_iterator_next(iter);
+ return;
+ }
+
+ iter->current = NULL;
+ iter->valid = false;
+}
+
+void DEG_objects_iterator_end(BLI_Iterator *iter)
+{
+ DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
+ if (data) {
+ MEM_freeN(data);
+ }
+}
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index ee45ce536c6..c3d64dc05bd 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -289,89 +289,13 @@ void DEG_ids_flush_tagged(Main *bmain)
/* Update dependency graph when visible scenes/layers changes. */
void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
{
+ (void) bmain;
DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph);
- wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
- int old_layers = graph->layers;
- if (wm != NULL) {
- BKE_main_id_tag_listbase(&bmain->scene, LIB_TAG_DOIT, true);
- graph->layers = 0;
- for (wmWindow *win = (wmWindow *)wm->windows.first;
- win != NULL;
- win = (wmWindow *)win->next)
- {
- Scene *scene = win->screen->scene;
- if (scene->id.tag & LIB_TAG_DOIT) {
- graph->layers |= BKE_screen_visible_layers(win->screen, scene);
- scene->id.tag &= ~LIB_TAG_DOIT;
- }
- }
- }
- else {
- /* All the layers for background render for now. */
- graph->layers = (1 << 20) - 1;
- }
- if (old_layers != graph->layers) {
- /* Tag all objects which becomes visible (or which becomes needed for dependencies)
- * for recalc.
- *
- * This is mainly needed on file load only, after that updates of invisible objects
- * will be stored in the pending list.
- */
- GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash)
- {
- ID *id = id_node->id;
- if ((id->tag & LIB_TAG_ID_RECALC_ALL) != 0 ||
- (id_node->layers & scene->lay_updated) == 0)
- {
- id_node->tag_update(graph);
- }
- /* A bit of magic: if object->recalc is set it means somebody tagged
- * it for update. If corresponding ID recalc flags are zero it means
- * graph has been evaluated after that and the recalc was skipped
- * because of visibility check.
- */
- if (GS(id->name) == ID_OB) {
- Object *object = (Object *)id;
- if ((id->tag & LIB_TAG_ID_RECALC_ALL) == 0 &&
- (object->recalc & OB_RECALC_ALL) != 0)
- {
- id_node->tag_update(graph);
- DEG::ComponentDepsNode *anim_comp =
- id_node->find_component(DEG::DEG_NODE_TYPE_ANIMATION);
- if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) {
- anim_comp->tag_update(graph);
- }
- }
- }
- }
- GHASH_FOREACH_END();
- }
- scene->lay_updated |= graph->layers;
- /* Special trick to get local view to work. */
- LINKLIST_FOREACH (Base *, base, &scene->base) {
- Object *object = base->object;
- DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
- id_node->layers = 0;
- }
- LINKLIST_FOREACH (Base *, base, &scene->base) {
- Object *object = base->object;
- DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
- id_node->layers |= base->lay;
- if (object == scene->camera) {
- /* Camera should always be updated, it used directly by viewport. */
- id_node->layers |= (unsigned int)(-1);
- }
- }
- DEG::deg_graph_build_flush_layers(graph);
- LINKLIST_FOREACH (Base *, base, &scene->base) {
- Object *object = base->object;
- DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
- GHASH_FOREACH_BEGIN(DEG::ComponentDepsNode *, comp, id_node->components)
- {
- id_node->layers |= comp->layers;
- }
- GHASH_FOREACH_END();
+ GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash)
+ {
+ id_node->tag_update(graph);
}
+ GHASH_FOREACH_END();
}
void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
index 39c189629f2..6c3e3805169 100644
--- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc
+++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
@@ -130,6 +130,10 @@ static const char *stringify_opcode(eDepsOperation_Code opcode)
STRINGIFY_OPCODE(BONE_DONE);
STRINGIFY_OPCODE(PSYS_EVAL);
+ STRINGIFY_OPCODE(SCENE_LAYER_INIT);
+ STRINGIFY_OPCODE(SCENE_LAYER_EVAL);
+ STRINGIFY_OPCODE(SCENE_LAYER_DONE);
+
case DEG_NUM_OPCODES: return "SpecialCase";
#undef STRINGIFY_OPCODE
}
diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h
index c6960bf1351..2668ff70d7f 100644
--- a/source/blender/depsgraph/intern/depsgraph_types.h
+++ b/source/blender/depsgraph/intern/depsgraph_types.h
@@ -129,6 +129,8 @@ typedef enum eDepsNode_Type {
DEG_NODE_TYPE_SHADING,
/* Cache Component */
DEG_NODE_TYPE_CACHE,
+ /* Component which contains all operations needed for layer collections evaluation. */
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
} eDepsNode_Type;
/* Identifiers for common operations (as an enum). */
@@ -237,6 +239,11 @@ typedef enum eDepsOperation_Code {
/* XXX: placeholder - Particle System eval */
DEG_OPCODE_PSYS_EVAL,
+ /* Collections ------------------------------------- */
+ DEG_OPCODE_SCENE_LAYER_INIT,
+ DEG_OPCODE_SCENE_LAYER_EVAL,
+ DEG_OPCODE_SCENE_LAYER_DONE,
+
DEG_NUM_OPCODES,
} eDepsOperation_Code;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index e8dbe8e84eb..046037d8b1d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -39,7 +39,6 @@ extern "C" {
#include "BLI_task.h"
#include "BLI_ghash.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "DEG_depsgraph.h"
@@ -73,13 +72,11 @@ namespace DEG {
static void schedule_children(TaskPool *pool,
Depsgraph *graph,
OperationDepsNode *node,
- const unsigned int layers,
const int thread_id);
struct DepsgraphEvalState {
EvaluationContext *eval_ctx;
Depsgraph *graph;
- unsigned int layers;
};
static void deg_task_run_func(TaskPool *pool,
@@ -127,39 +124,31 @@ static void deg_task_run_func(TaskPool *pool,
}
BLI_task_pool_delayed_push_begin(pool, thread_id);
- schedule_children(pool, state->graph, node, state->layers, thread_id);
+ schedule_children(pool, state->graph, node, thread_id);
BLI_task_pool_delayed_push_end(pool, thread_id);
}
typedef struct CalculatePengindData {
Depsgraph *graph;
- unsigned int layers;
} CalculatePengindData;
static void calculate_pending_func(void *data_v, int i)
{
CalculatePengindData *data = (CalculatePengindData *)data_v;
Depsgraph *graph = data->graph;
- unsigned int layers = data->layers;
OperationDepsNode *node = graph->operations[i];
- IDDepsNode *id_node = node->owner->owner;
node->num_links_pending = 0;
node->scheduled = false;
/* count number of inputs that need updates */
- if ((id_node->layers & layers) != 0 &&
- (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
- {
+ if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
foreach (DepsRelation *rel, node->inlinks) {
if (rel->from->type == DEG_NODE_TYPE_OPERATION &&
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
{
OperationDepsNode *from = (OperationDepsNode *)rel->from;
- IDDepsNode *id_from_node = from->owner->owner;
- if ((id_from_node->layers & layers) != 0 &&
- (from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
- {
+ if ((from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
++node->num_links_pending;
}
}
@@ -167,13 +156,12 @@ static void calculate_pending_func(void *data_v, int i)
}
}
-static void calculate_pending_parents(Depsgraph *graph, unsigned int layers)
+static void calculate_pending_parents(Depsgraph *graph)
{
const int num_operations = graph->operations.size();
const bool do_threads = num_operations > 256;
CalculatePengindData data;
data.graph = graph;
- data.layers = layers;
BLI_task_parallel_range(0,
num_operations,
&data,
@@ -212,15 +200,11 @@ static void calculate_eval_priority(OperationDepsNode *node)
* dec_parents: Decrement pending parents count, true when child nodes are
* scheduled after a task has been completed.
*/
-static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
+static void schedule_node(TaskPool *pool, Depsgraph *graph,
OperationDepsNode *node, bool dec_parents,
const int thread_id)
{
- unsigned int id_layers = node->owner->owner->layers;
-
- if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 &&
- (id_layers & layers) != 0)
- {
+ if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
if (dec_parents) {
BLI_assert(node->num_links_pending > 0);
atomic_sub_and_fetch_uint32(&node->num_links_pending, 1);
@@ -232,7 +216,7 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
if (!is_scheduled) {
if (node->is_noop()) {
/* skip NOOP node, schedule children right away */
- schedule_children(pool, graph, node, layers, thread_id);
+ schedule_children(pool, graph, node, thread_id);
}
else {
/* children are scheduled once this task is completed */
@@ -248,19 +232,16 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
}
}
-static void schedule_graph(TaskPool *pool,
- Depsgraph *graph,
- const unsigned int layers)
+static void schedule_graph(TaskPool *pool, Depsgraph *graph)
{
foreach (OperationDepsNode *node, graph->operations) {
- schedule_node(pool, graph, layers, node, false, 0);
+ schedule_node(pool, graph, node, false, 0);
}
}
static void schedule_children(TaskPool *pool,
Depsgraph *graph,
OperationDepsNode *node,
- const unsigned int layers,
const int thread_id)
{
foreach (DepsRelation *rel, node->outlinks) {
@@ -272,7 +253,6 @@ static void schedule_children(TaskPool *pool,
}
schedule_node(pool,
graph,
- layers,
child,
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0,
thread_id);
@@ -287,8 +267,7 @@ static void schedule_children(TaskPool *pool,
* \note Time sources should be all valid!
*/
void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
- Depsgraph *graph,
- const unsigned int layers)
+ Depsgraph *graph)
{
/* Generate base evaluation context, upon which all the others are derived. */
// TODO: this needs both main and scene access...
@@ -298,11 +277,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
return;
}
- DEG_DEBUG_PRINTF("%s: layers:%u, graph->layers:%u\n",
- __func__,
- layers,
- graph->layers);
-
/* Set time for the current graph evaluation context. */
TimeSourceDepsNode *time_src = graph->find_time_source();
eval_ctx->ctime = time_src->cfra;
@@ -311,7 +285,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
DepsgraphEvalState state;
state.eval_ctx = eval_ctx;
state.graph = graph;
- state.layers = layers;
TaskScheduler *task_scheduler;
bool need_free_scheduler;
@@ -327,7 +300,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
- calculate_pending_parents(graph, layers);
+ calculate_pending_parents(graph);
/* Clear tags. */
foreach (OperationDepsNode *node, graph->operations) {
@@ -343,7 +316,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
DepsgraphDebug::eval_begin(eval_ctx);
- schedule_graph(task_pool, graph, layers);
+ schedule_graph(task_pool, graph);
BLI_task_pool_work_and_wait(task_pool);
BLI_task_pool_free(task_pool);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.h b/source/blender/depsgraph/intern/eval/deg_eval.h
index 49c0379939e..576ab89dec1 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval.h
@@ -46,7 +46,6 @@ struct Depsgraph;
* \note Time sources should be all valid!
*/
void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
- Depsgraph *graph,
- const unsigned int layers);
+ Depsgraph *graph);
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 963c16c3a13..34abbf46ed7 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -172,6 +172,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
case DEG_NODE_TYPE_ID_REF:
case DEG_NODE_TYPE_PARAMETERS:
case DEG_NODE_TYPE_SEQUENCER:
+ case DEG_NODE_TYPE_LAYER_COLLECTIONS:
/* Ignore, does not translate to object component. */
break;
case DEG_NODE_TYPE_ANIMATION:
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index be4783e616f..218b32e92c8 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -189,14 +189,8 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
/* Store ID-pointer. */
BLI_assert(id != NULL);
this->id = (ID *)id;
- this->layers = (1 << 20) - 1;
this->eval_flags = 0;
- /* For object we initialize layers to layer from base. */
- if (GS(id->name) == ID_OB) {
- this->layers = 0;
- }
-
components = BLI_ghash_new(id_deps_node_hash_key,
id_deps_node_hash_key_cmp,
"Depsgraph id components hash");
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h
index 354f0fd6857..d0687dbb5eb 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node.h
@@ -173,9 +173,6 @@ struct IDDepsNode : public DepsNode {
/* Hash to make it faster to look up components. */
GHash *components;
- /* Layers of this node with accumulated layers of it's output relations. */
- unsigned int layers;
-
/* Additional flags needed for scene evaluation.
* TODO(sergey): Only needed for until really granular updates
* of all the entities.
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
index 0171fd9ac25..7a8c4494230 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
@@ -123,8 +123,7 @@ static void comp_node_hash_value_free(void *value_v)
ComponentDepsNode::ComponentDepsNode() :
entry_operation(NULL),
- exit_operation(NULL),
- layers(0)
+ exit_operation(NULL)
{
operations_map = BLI_ghash_new(comp_node_hash_key,
comp_node_hash_key_cmp,
@@ -157,10 +156,7 @@ string ComponentDepsNode::identifier() const
char typebuf[16];
sprintf(typebuf, "(%d)", type);
- char layers[16];
- sprintf(layers, "%u", this->layers);
-
- return string(typebuf) + name + " : " + idname + " (Layers: " + layers + ")";
+ return string(typebuf) + name + " : " + idname;
}
OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const
@@ -405,6 +401,10 @@ static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING;
DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEG_NODE_TYPE_CACHE, "Cache Component");
static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE;
+/* Layer Collections Defines ============================ */
+
+DEG_DEPSNODE_DEFINE(LayerCollectionsDepsNode, DEG_NODE_TYPE_LAYER_COLLECTIONS, "Layer Collections Component");
+static DepsNodeFactoryImpl<LayerCollectionsDepsNode> DNTI_LAYER_COLLECTIONS;
/* Node Types Register =================================== */
@@ -424,6 +424,8 @@ void deg_register_component_depsnodes()
deg_register_node_typeinfo(&DNTI_SHADING);
deg_register_node_typeinfo(&DNTI_CACHE);
+
+ deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h
index f476d8ff202..c358c510ae3 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h
@@ -151,9 +151,6 @@ struct ComponentDepsNode : public DepsNode {
OperationDepsNode *exit_operation;
// XXX: a poll() callback to check if component's first node can be started?
-
- /* Temporary bitmask, used during graph construction. */
- unsigned int layers;
};
/* ---------------------------------------- */
@@ -207,6 +204,10 @@ struct CacheComponentDepsNode : public ComponentDepsNode {
DEG_DEPSNODE_DECLARE;
};
+struct LayerCollectionsDepsNode : public ComponentDepsNode {
+ DEG_DEPSNODE_DECLARE;
+};
+
void deg_register_component_depsnodes();
diff --git a/source/blender/depsgraph/util/deg_util_foreach.h b/source/blender/depsgraph/util/deg_util_foreach.h
index cb7361fc708..e00aa5dbb5e 100644
--- a/source/blender/depsgraph/util/deg_util_foreach.h
+++ b/source/blender/depsgraph/util/deg_util_foreach.h
@@ -36,13 +36,5 @@
# include <boost/foreach.hpp>
# define foreach BOOST_FOREACH
#else
-#pragma message("No available foreach() implementation. Using stub instead, disabling new depsgraph")
-
-#ifndef WITH_LEGACY_DEPSGRAPH
-# error "Unable to build new depsgraph and legacy one is disabled."
-#endif
-
-#define DISABLE_NEW_DEPSGRAPH
-
-# define foreach(x, y) for (x; false; (void)y)
+# error "Depsgraph requires either Boost or C++11 for range-based loops."
#endif
diff --git a/source/blender/depsgraph/util/deg_util_function.h b/source/blender/depsgraph/util/deg_util_function.h
index 1e34ae04d9a..da31bb037f9 100644
--- a/source/blender/depsgraph/util/deg_util_function.h
+++ b/source/blender/depsgraph/util/deg_util_function.h
@@ -47,64 +47,5 @@ using boost::function;
#define function_bind boost::bind
#else
-
-#pragma message("No available function binding implementation. Using stub instead, disabling new depsgraph")
-
-#ifndef WITH_LEGACY_DEPSGRAPH
-# error "Unable to build new depsgraph and legacy one is disabled."
-#endif
-
-#define DISABLE_NEW_DEPSGRAPH
-
-#include "BLI_utildefines.h"
-#include <cstdlib>
-
-template<typename T>
-class function {
-public:
- function() {};
- function(void *) {}
- operator bool() const { return false; }
- bool operator== (void *) { return false; }
-
- template<typename T1>
- void operator() (T1) {
- BLI_assert(!"Should not be used");
- }
-};
-
-class Wrap {
-public:
- Wrap() {}
- template <typename T>
- Wrap(T /*arg*/) {}
-};
-
-template <typename T>
-void *function_bind(T func,
- Wrap arg1 = Wrap(),
- Wrap arg2 = Wrap(),
- Wrap arg3 = Wrap(),
- Wrap arg4 = Wrap(),
- Wrap arg5 = Wrap(),
- Wrap arg6 = Wrap(),
- Wrap arg7 = Wrap())
-{
- BLI_assert(!"Should not be used");
- (void)func;
- (void)arg1;
- (void)arg2;
- (void)arg3;
- (void)arg4;
- (void)arg5;
- (void)arg6;
- (void)arg7;
- return NULL;
-}
-
-#define _1 Wrap()
-#define _2 Wrap()
-#define _3 Wrap()
-#define _4 Wrap()
-
+# error "Depsgraph requires either Boost or C++11 for function bindings."
#endif
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
new file mode 100644
index 00000000000..a8a6d3144ca
--- /dev/null
+++ b/source/blender/draw/CMakeLists.txt
@@ -0,0 +1,178 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# 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) 2016, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Blender Institute
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ intern
+ modes
+
+ ../blenfont
+ ../blenkernel
+ ../blenlib
+ ../blentranslation
+ ../bmesh
+ ../depsgraph
+ ../editors/include
+ ../editors/space_view3d
+ ../gpu
+ ../imbuf
+ ../makesdna
+ ../makesrna
+ ../render/extern/include
+ ../render/intern/include
+ ../windowmanager
+
+ ../../../intern/glew-mx
+ ../../../intern/guardedalloc
+)
+
+set(INC_SYS
+ ${GLEW_INCLUDE_PATH}
+)
+
+set(SRC
+ intern/draw_armature.c
+ intern/draw_cache.c
+ intern/draw_cache_impl_curve.c
+ intern/draw_cache_impl_displist.c
+ intern/draw_cache_impl_lattice.c
+ intern/draw_cache_impl_mesh.c
+ intern/draw_cache_impl_particles.c
+ intern/draw_common.c
+ intern/draw_manager.c
+ intern/draw_manager_text.c
+ intern/draw_view.c
+ modes/edit_armature_mode.c
+ modes/edit_curve_mode.c
+ modes/edit_lattice_mode.c
+ modes/edit_mesh_mode.c
+ modes/edit_metaball_mode.c
+ modes/edit_surface_mode.c
+ modes/edit_text_mode.c
+ modes/object_mode.c
+ modes/paint_texture_mode.c
+ modes/paint_vertex_mode.c
+ modes/paint_weight_mode.c
+ modes/particle_mode.c
+ modes/pose_mode.c
+ modes/sculpt_mode.c
+ engines/basic/basic_engine.c
+ engines/clay/clay_engine.c
+ engines/eevee/eevee_engine.c
+ engines/eevee/eevee_lights.c
+ engines/eevee/eevee_probes.c
+ engines/eevee/eevee_effects.c
+ engines/external/external_engine.c
+
+ DRW_engine.h
+ intern/DRW_render.h
+ intern/draw_cache.h
+ intern/draw_cache_impl.h
+ intern/draw_common.h
+ intern/draw_manager_text.h
+ intern/draw_view.h
+ modes/draw_mode_engines.h
+ engines/basic/basic_engine.h
+ engines/clay/clay_engine.h
+ engines/eevee/eevee_engine.h
+ engines/eevee/eevee_private.h
+ engines/external/external_engine.h
+)
+
+if(WITH_CLAY_ENGINE)
+ add_definitions(-DWITH_CLAY_ENGINE)
+endif()
+
+data_to_c_simple(engines/clay/shaders/clay_frag.glsl SRC)
+data_to_c_simple(engines/clay/shaders/clay_vert.glsl SRC)
+data_to_c_simple(engines/clay/shaders/clay_particle_vert.glsl SRC)
+data_to_c_simple(engines/clay/shaders/clay_particle_strand_frag.glsl SRC)
+data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
+data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
+
+data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/probe_filter_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/probe_sh_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/probe_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/probe_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_store_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_store_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_store_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
+
+data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_geom_tri.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_geom_edge.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_loosevert_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_facedot_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_facedot_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_curve_overlay_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
+data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
+data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_outline_expand_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_outline_detect_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
+data_to_c_simple(modes/shaders/object_particle_prim_vert.glsl SRC)
+data_to_c_simple(modes/shaders/object_particle_prim_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_particle_dot_vert.glsl SRC)
+data_to_c_simple(modes/shaders/object_particle_dot_frag.glsl SRC)
+data_to_c_simple(modes/shaders/paint_texture_frag.glsl SRC)
+data_to_c_simple(modes/shaders/paint_texture_vert.glsl SRC)
+data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC)
+data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
+data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC)
+
+list(APPEND INC
+)
+
+blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
new file mode 100644
index 00000000000..0aca41a970d
--- /dev/null
+++ b/source/blender/draw/DRW_engine.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file DRW_engine.h
+ * \ingroup draw
+ */
+
+#ifndef __DRW_ENGINE_H__
+#define __DRW_ENGINE_H__
+
+struct ARegion;
+struct CollectionEngineSettings;
+struct Depsgraph;
+struct DRWPass;
+struct Material;
+struct Scene;
+struct DrawEngineType;
+struct IDProperty;
+struct bContext;
+struct Object;
+struct SceneLayer;
+struct ViewContext;
+struct ViewportEngineData;
+struct View3D;
+struct rcti;
+struct GPUOffScreen;
+
+#include "BLI_sys_types.h" /* for bool */
+
+/* Buffer and textures used by the viewport by default */
+typedef struct DefaultFramebufferList {
+ struct GPUFrameBuffer *default_fb;
+} DefaultFramebufferList;
+
+typedef struct DefaultTextureList {
+ struct GPUTexture *color;
+ struct GPUTexture *depth;
+} DefaultTextureList;
+
+void DRW_engines_register(void);
+void DRW_engines_free(void);
+
+void DRW_engine_register(struct DrawEngineType *draw_engine_type);
+void DRW_engine_viewport_data_size_get(
+ const void *engine_type,
+ int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len);
+
+void DRW_draw_view(const struct bContext *C);
+
+void DRW_draw_render_loop(
+ struct Depsgraph *graph,
+ struct ARegion *ar, struct View3D *v3d);
+void DRW_draw_render_loop_offscreen(
+ struct Depsgraph *graph,
+ struct ARegion *ar, struct View3D *v3d,
+ struct GPUOffScreen *ofs);
+void DRW_draw_select_loop(
+ struct Depsgraph *graph,
+ struct ARegion *ar, struct View3D *v3d,
+ bool use_obedit_skip, bool use_nearest, const struct rcti *rect);
+void DRW_draw_depth_loop(
+ struct Depsgraph *graph,
+ struct ARegion *ar, struct View3D *v3d);
+
+/* This is here because GPUViewport needs it */
+void DRW_pass_free(struct DRWPass *pass);
+
+/* Mode engines initialization */
+void OBJECT_collection_settings_create(struct IDProperty *properties);
+void EDIT_MESH_collection_settings_create(struct IDProperty *properties);
+void EDIT_ARMATURE_collection_settings_create(struct IDProperty *properties);
+void PAINT_WEIGHT_collection_settings_create(struct IDProperty *properties);
+void PAINT_VERTEX_collection_settings_create(struct IDProperty *properties);
+
+#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
new file mode 100644
index 00000000000..96eaf541cae
--- /dev/null
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file basic_engine.h
+ * \ingroup draw_engine
+ *
+ * Simple engine for drawing color and/or depth.
+ * When we only need simple flat shaders.
+ */
+
+#include "DRW_render.h"
+
+#include "BKE_icons.h"
+#include "BKE_idprop.h"
+#include "BKE_main.h"
+
+#include "GPU_shader.h"
+
+#include "basic_engine.h"
+/* Shaders */
+
+#define BASIC_ENGINE "BLENDER_BASIC"
+
+/* we may want this later? */
+#define USE_DEPTH
+
+/* *********** LISTS *********** */
+
+/* GPUViewport.storage
+ * Is freed everytime the viewport engine changes */
+typedef struct BASIC_Storage {
+ int dummy;
+} BASIC_Storage;
+
+typedef struct BASIC_StorageList {
+ struct BASIC_Storage *storage;
+ struct BASIC_PrivateData *g_data;
+} BASIC_StorageList;
+
+typedef struct BASIC_FramebufferList {
+ /* default */
+ struct GPUFrameBuffer *default_fb;
+ /* engine specific */
+#ifdef USE_DEPTH
+ struct GPUFrameBuffer *dupli_depth;
+#endif
+} BASIC_FramebufferList;
+
+typedef struct BASIC_TextureList {
+ /* default */
+ struct GPUTexture *color;
+#ifdef USE_DEPTH
+ struct GPUTexture *depth;
+ /* engine specific */
+ struct GPUTexture *depth_dup;
+#endif
+} BASIC_TextureList;
+
+typedef struct BASIC_PassList {
+#ifdef USE_DEPTH
+ struct DRWPass *depth_pass;
+ struct DRWPass *depth_pass_cull;
+#endif
+ struct DRWPass *color_pass;
+} BASIC_PassList;
+
+typedef struct BASIC_Data {
+ void *engine_type;
+ BASIC_FramebufferList *fbl;
+ BASIC_TextureList *txl;
+ BASIC_PassList *psl;
+ BASIC_StorageList *stl;
+} BASIC_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+#ifdef USE_DEPTH
+ /* Depth Pre Pass */
+ struct GPUShader *depth_sh;
+#endif
+ /* Shading Pass */
+ struct GPUShader *color_sh;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct BASIC_PrivateData {
+#ifdef USE_DEPTH
+ DRWShadingGroup *depth_shgrp;
+ DRWShadingGroup *depth_shgrp_cull;
+#endif
+ DRWShadingGroup *color_shgrp;
+} BASIC_PrivateData; /* Transient data */
+
+/* Functions */
+
+static void BASIC_engine_init(void *vedata)
+{
+ BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+ BASIC_TextureList *txl = ((BASIC_Data *)vedata)->txl;
+ BASIC_FramebufferList *fbl = ((BASIC_Data *)vedata)->fbl;
+
+#ifdef USE_DEPTH
+ /* Depth prepass */
+ if (!e_data.depth_sh) {
+ e_data.depth_sh = DRW_shader_create_3D_depth_only();
+ }
+#endif
+
+ /* Shading pass */
+ if (!e_data.color_sh) {
+ e_data.color_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!stl->storage) {
+ stl->storage = MEM_callocN(sizeof(BASIC_Storage), "BASIC_Storage");
+ }
+
+#ifdef USE_DEPTH
+ if (DRW_state_is_fbo()) {
+ const float *viewport_size = DRW_viewport_size_get();
+ DRWFboTexture tex = {&txl->depth_dup, DRW_TEX_DEPTH_24, 0};
+ DRW_framebuffer_init(&fbl->dupli_depth, &draw_engine_basic_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &tex, 1);
+ }
+#endif
+}
+
+static void BASIC_cache_init(void *vedata)
+{
+ BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
+ BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+#ifdef USE_DEPTH
+ /* Depth Pass */
+ {
+ psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+
+ psl->depth_pass_cull = DRW_pass_create(
+ "Depth Pass Cull",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
+ }
+#endif
+
+ /* Color Pass */
+ {
+ psl->color_pass = DRW_pass_create("Color Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ stl->g_data->color_shgrp = DRW_shgroup_create(e_data.color_sh, psl->color_pass);
+ }
+}
+
+static void BASIC_cache_populate(void *vedata, Object *ob)
+{
+ BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+
+ if (!DRW_object_is_renderable(ob))
+ return;
+
+ struct Batch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ bool do_cull = false; /* TODO (we probably wan't to take this from the viewport?) */
+#ifdef USE_DEPTH
+ /* Depth Prepass */
+ DRW_shgroup_call_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat);
+#endif
+ /* Shading */
+ DRW_shgroup_call_add(stl->g_data->color_shgrp, geom, ob->obmat);
+ }
+}
+
+static void BASIC_cache_finish(void *vedata)
+{
+ BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+
+ UNUSED_VARS(stl);
+}
+
+static void BASIC_draw_scene(void *vedata)
+{
+
+ BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
+ BASIC_FramebufferList *fbl = ((BASIC_Data *)vedata)->fbl;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+#ifdef USE_DEPTH
+ /* Pass 1 : Depth pre-pass */
+ DRW_draw_pass(psl->depth_pass);
+ DRW_draw_pass(psl->depth_pass_cull);
+
+ /* Pass 2 : Duplicate depth */
+ /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
+ if (DRW_state_is_fbo()) {
+ DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true);
+ }
+#endif
+
+ /* Pass 3 : Shading */
+ DRW_draw_pass(psl->color_pass);
+}
+
+static void BASIC_engine_free(void)
+{
+ /* all shaders are builtin */
+}
+
+static const DrawEngineDataSize BASIC_data_size = DRW_VIEWPORT_DATA_SIZE(BASIC_Data);
+
+DrawEngineType draw_engine_basic_type = {
+ NULL, NULL,
+ N_("Basic"),
+ &BASIC_data_size,
+ &BASIC_engine_init,
+ &BASIC_engine_free,
+ &BASIC_cache_init,
+ &BASIC_cache_populate,
+ &BASIC_cache_finish,
+ NULL,
+ &BASIC_draw_scene
+};
+
+/* Note: currently unused, we may want to register so we can see this when debugging the view. */
+
+RenderEngineType DRW_engine_viewport_basic_type = {
+ NULL, NULL,
+ BASIC_ENGINE, N_("Basic"), RE_INTERNAL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &draw_engine_basic_type,
+ {NULL, NULL, NULL}
+};
+
+
+#undef BASIC_ENGINE
diff --git a/source/blender/draw/engines/basic/basic_engine.h b/source/blender/draw/engines/basic/basic_engine.h
new file mode 100644
index 00000000000..0adf99835a2
--- /dev/null
+++ b/source/blender/draw/engines/basic/basic_engine.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file basic_engine.h
+ * \ingroup draw_engine
+ */
+
+#ifndef __BASIC_ENGINE_H__
+#define __BASIC_ENGINE_H__
+
+extern DrawEngineType draw_engine_basic_type;
+extern RenderEngineType DRW_engine_viewport_basic_type;
+
+#endif /* __BASIC_ENGINE_H__ */
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
new file mode 100644
index 00000000000..be43542a5ff
--- /dev/null
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -0,0 +1,907 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+#include "DRW_render.h"
+
+#include "DNA_particle_types.h"
+
+#include "BKE_icons.h"
+#include "BKE_idprop.h"
+#include "BKE_main.h"
+#include "BKE_particle.h"
+
+#include "BLI_dynstr.h"
+#include "BLI_rand.h"
+
+#include "GPU_shader.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "UI_resources.h"
+#include "UI_interface_icons.h"
+
+#include "clay_engine.h"
+#ifdef WITH_CLAY_ENGINE
+/* Shaders */
+
+#define CLAY_ENGINE "BLENDER_CLAY"
+
+#define MAX_CLAY_MAT 512 /* 512 = 9 bit material id */
+
+#define SHADER_DEFINES \
+ "#define MAX_MATERIAL " STRINGIFY(MAX_CLAY_MAT) "\n" \
+ "#define USE_ROTATION\n" \
+ "#define USE_AO\n" \
+ "#define USE_HSV\n"
+
+extern char datatoc_clay_frag_glsl[];
+extern char datatoc_clay_vert_glsl[];
+extern char datatoc_clay_particle_vert_glsl[];
+extern char datatoc_clay_particle_strand_frag_glsl[];
+extern char datatoc_ssao_alchemy_glsl[];
+
+/* *********** LISTS *********** */
+
+/**
+ * UBOs data needs to be 16 byte aligned (size of vec4)
+ *
+ * Reminder: float, int, bool are 4 bytes
+ *
+ * \note struct is expected to be initialized with all pad-bits zero'd
+ * so we can use 'memcmp' to check for duplicates. Possibly hash data later.
+ */
+typedef struct CLAY_UBO_Material {
+ float ssao_params_var[4];
+ /* - 16 -*/
+ float matcap_hsv[3];
+ float matcap_id; /* even float encoding have enough precision */
+ /* - 16 -*/
+ float matcap_rot[2];
+ float pad[2]; /* ensure 16 bytes alignement */
+} CLAY_UBO_Material; /* 48 bytes */
+BLI_STATIC_ASSERT_ALIGN(CLAY_UBO_Material, 16)
+
+typedef struct CLAY_HAIR_UBO_Material {
+ float hair_randomness;
+ float matcap_id;
+ float matcap_rot[2];
+ float matcap_hsv[3];
+ float pad;
+} CLAY_HAIR_UBO_Material; /* 32 bytes */
+BLI_STATIC_ASSERT_ALIGN(CLAY_HAIR_UBO_Material, 16)
+
+typedef struct CLAY_UBO_Storage {
+ CLAY_UBO_Material materials[MAX_CLAY_MAT];
+} CLAY_UBO_Storage;
+
+typedef struct CLAY_HAIR_UBO_Storage {
+ CLAY_HAIR_UBO_Material materials[MAX_CLAY_MAT];
+} CLAY_HAIR_UBO_Storage;
+
+/* GPUViewport.storage
+ * Is freed everytime the viewport engine changes */
+typedef struct CLAY_Storage {
+ /* Materials Parameter UBO */
+ CLAY_UBO_Storage mat_storage;
+ CLAY_HAIR_UBO_Storage hair_mat_storage;
+ int ubo_current_id;
+ int hair_ubo_current_id;
+ DRWShadingGroup *shgrps[MAX_CLAY_MAT];
+ DRWShadingGroup *shgrps_flat[MAX_CLAY_MAT];
+ DRWShadingGroup *hair_shgrps[MAX_CLAY_MAT];
+} CLAY_Storage;
+
+typedef struct CLAY_StorageList {
+ struct CLAY_Storage *storage;
+ struct GPUUniformBuffer *mat_ubo;
+ struct GPUUniformBuffer *hair_mat_ubo;
+ struct CLAY_PrivateData *g_data;
+} CLAY_StorageList;
+
+typedef struct CLAY_FramebufferList {
+ /* default */
+ struct GPUFrameBuffer *default_fb;
+ /* engine specific */
+ struct GPUFrameBuffer *dupli_depth;
+} CLAY_FramebufferList;
+
+typedef struct CLAY_PassList {
+ struct DRWPass *depth_pass;
+ struct DRWPass *depth_pass_cull;
+ struct DRWPass *clay_pass;
+ struct DRWPass *clay_pass_flat;
+ struct DRWPass *hair_pass;
+} CLAY_PassList;
+
+typedef struct CLAY_Data {
+ void *engine_type;
+ CLAY_FramebufferList *fbl;
+ DRWViewportEmptyList *txl;
+ CLAY_PassList *psl;
+ CLAY_StorageList *stl;
+} CLAY_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Depth Pre Pass */
+ struct GPUShader *depth_sh;
+ /* Shading Pass */
+ struct GPUShader *clay_sh;
+ struct GPUShader *clay_flat_sh;
+ struct GPUShader *hair_sh;
+
+ /* Matcap textures */
+ struct GPUTexture *matcap_array;
+ float matcap_colors[24][3];
+
+ /* Ssao */
+ float winmat[4][4];
+ float viewvecs[3][4];
+ float ssao_params[4];
+ int cached_sample_num;
+ struct GPUTexture *jitter_tx;
+ struct GPUTexture *sampling_tx;
+
+ /* Just a serie of int from 0 to MAX_CLAY_MAT-1 */
+ int ubo_mat_idxs[MAX_CLAY_MAT];
+
+ /* engine specific */
+ struct GPUTexture *depth_dup;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct CLAY_PrivateData {
+ DRWShadingGroup *depth_shgrp;
+ DRWShadingGroup *depth_shgrp_select;
+ DRWShadingGroup *depth_shgrp_active;
+ DRWShadingGroup *depth_shgrp_cull;
+ DRWShadingGroup *depth_shgrp_cull_select;
+ DRWShadingGroup *depth_shgrp_cull_active;
+} CLAY_PrivateData; /* Transient data */
+
+/* Functions */
+
+static void add_icon_to_rect(PreviewImage *prv, float *final_rect, int layer)
+{
+ int image_size = prv->w[0] * prv->h[0];
+ float *new_rect = &final_rect[image_size * 4 * layer];
+
+ IMB_buffer_float_from_byte(new_rect, (unsigned char *)prv->rect[0], IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ false, prv->w[0], prv->h[0], prv->w[0], prv->w[0]);
+
+ /* Find overall color */
+ for (int y = 0; y < 4; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ e_data.matcap_colors[layer][0] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 0];
+ e_data.matcap_colors[layer][1] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 1];
+ e_data.matcap_colors[layer][2] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 2];
+ }
+ }
+
+ e_data.matcap_colors[layer][0] /= 16.0f * 2.0f; /* the * 2 is to darken for shadows */
+ e_data.matcap_colors[layer][1] /= 16.0f * 2.0f;
+ e_data.matcap_colors[layer][2] /= 16.0f * 2.0f;
+}
+
+static struct GPUTexture *load_matcaps(PreviewImage *prv[24], int nbr)
+{
+ struct GPUTexture *tex;
+ int w = prv[0]->w[0];
+ int h = prv[0]->h[0];
+ float *final_rect = MEM_callocN(sizeof(float) * 4 * w * h * nbr, "Clay Matcap array rect");
+
+ for (int i = 0; i < nbr; ++i) {
+ add_icon_to_rect(prv[i], final_rect, i);
+ BKE_previewimg_free(&prv[i]);
+ }
+
+ tex = DRW_texture_create_2D_array(w, h, nbr, DRW_TEX_RGBA_8, DRW_TEX_FILTER, final_rect);
+ MEM_freeN(final_rect);
+
+ return tex;
+}
+
+static int matcap_to_index(int matcap)
+{
+ switch (matcap) {
+ case ICON_MATCAP_01: return 0;
+ case ICON_MATCAP_02: return 1;
+ case ICON_MATCAP_03: return 2;
+ case ICON_MATCAP_04: return 3;
+ case ICON_MATCAP_05: return 4;
+ case ICON_MATCAP_06: return 5;
+ case ICON_MATCAP_07: return 6;
+ case ICON_MATCAP_08: return 7;
+ case ICON_MATCAP_09: return 8;
+ case ICON_MATCAP_10: return 9;
+ case ICON_MATCAP_11: return 10;
+ case ICON_MATCAP_12: return 11;
+ case ICON_MATCAP_13: return 12;
+ case ICON_MATCAP_14: return 13;
+ case ICON_MATCAP_15: return 14;
+ case ICON_MATCAP_16: return 15;
+ case ICON_MATCAP_17: return 16;
+ case ICON_MATCAP_18: return 17;
+ case ICON_MATCAP_19: return 18;
+ case ICON_MATCAP_20: return 19;
+ case ICON_MATCAP_21: return 20;
+ case ICON_MATCAP_22: return 21;
+ case ICON_MATCAP_23: return 22;
+ case ICON_MATCAP_24: return 23;
+ }
+ BLI_assert(!"Should not happen");
+ return 0;
+}
+
+static struct GPUTexture *create_spiral_sample_texture(int numsaples)
+{
+ struct GPUTexture *tex;
+ float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * numsaples, "concentric_tex");
+ const float numsaples_inv = 1.0f / numsaples;
+ int i;
+ /* arbitrary number to ensure we don't get conciding samples every circle */
+ const float spirals = 7.357;
+
+ for (i = 0; i < numsaples; i++) {
+ float r = (i + 0.5f) * numsaples_inv;
+ float phi = r * spirals * (float)(2.0 * M_PI);
+ texels[i][0] = r * cosf(phi);
+ texels[i][1] = r * sinf(phi);
+ }
+
+ tex = DRW_texture_create_1D(numsaples, DRW_TEX_RG_16, 0, (float *)texels);
+
+ MEM_freeN(texels);
+ return tex;
+}
+
+static struct GPUTexture *create_jitter_texture(void)
+{
+ float jitter[64 * 64][2];
+ int i;
+
+ /* TODO replace by something more evenly distributed like blue noise */
+ for (i = 0; i < 64 * 64; i++) {
+ jitter[i][0] = 2.0f * BLI_frand() - 1.0f;
+ jitter[i][1] = 2.0f * BLI_frand() - 1.0f;
+ normalize_v2(jitter[i]);
+ }
+
+ return DRW_texture_create_2D(64, 64, DRW_TEX_RG_16, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
+}
+
+static void CLAY_engine_init(void *vedata)
+{
+ CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
+ CLAY_FramebufferList *fbl = ((CLAY_Data *)vedata)->fbl;
+
+ /* Create Texture Array */
+ if (!e_data.matcap_array) {
+ PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */
+
+ /* TODO only load used matcaps */
+ prv[0] = UI_icon_to_preview(ICON_MATCAP_01);
+ prv[1] = UI_icon_to_preview(ICON_MATCAP_02);
+ prv[2] = UI_icon_to_preview(ICON_MATCAP_03);
+ prv[3] = UI_icon_to_preview(ICON_MATCAP_04);
+ prv[4] = UI_icon_to_preview(ICON_MATCAP_05);
+ prv[5] = UI_icon_to_preview(ICON_MATCAP_06);
+ prv[6] = UI_icon_to_preview(ICON_MATCAP_07);
+ prv[7] = UI_icon_to_preview(ICON_MATCAP_08);
+ prv[8] = UI_icon_to_preview(ICON_MATCAP_09);
+ prv[9] = UI_icon_to_preview(ICON_MATCAP_10);
+ prv[10] = UI_icon_to_preview(ICON_MATCAP_11);
+ prv[11] = UI_icon_to_preview(ICON_MATCAP_12);
+ prv[12] = UI_icon_to_preview(ICON_MATCAP_13);
+ prv[13] = UI_icon_to_preview(ICON_MATCAP_14);
+ prv[14] = UI_icon_to_preview(ICON_MATCAP_15);
+ prv[15] = UI_icon_to_preview(ICON_MATCAP_16);
+ prv[16] = UI_icon_to_preview(ICON_MATCAP_17);
+ prv[17] = UI_icon_to_preview(ICON_MATCAP_18);
+ prv[18] = UI_icon_to_preview(ICON_MATCAP_19);
+ prv[19] = UI_icon_to_preview(ICON_MATCAP_20);
+ prv[20] = UI_icon_to_preview(ICON_MATCAP_21);
+ prv[21] = UI_icon_to_preview(ICON_MATCAP_22);
+ prv[22] = UI_icon_to_preview(ICON_MATCAP_23);
+ prv[23] = UI_icon_to_preview(ICON_MATCAP_24);
+
+ e_data.matcap_array = load_matcaps(prv, 24);
+ }
+
+ /* AO Jitter */
+ if (!e_data.jitter_tx) {
+ e_data.jitter_tx = create_jitter_texture();
+ }
+
+
+ /* Depth prepass */
+ if (!e_data.depth_sh) {
+ e_data.depth_sh = DRW_shader_create_3D_depth_only();
+ }
+
+ /* Shading pass */
+ if (!e_data.clay_sh) {
+ DynStr *ds = BLI_dynstr_new();
+ char *matcap_with_ao;
+
+ BLI_dynstr_append(ds, datatoc_clay_frag_glsl);
+ BLI_dynstr_append(ds, datatoc_ssao_alchemy_glsl);
+
+ matcap_with_ao = BLI_dynstr_get_cstring(ds);
+
+ e_data.clay_sh = DRW_shader_create(
+ datatoc_clay_vert_glsl, NULL, matcap_with_ao,
+ SHADER_DEFINES);
+ e_data.clay_flat_sh = DRW_shader_create(
+ datatoc_clay_vert_glsl, NULL, matcap_with_ao,
+ SHADER_DEFINES
+ "#define USE_FLAT_NORMAL\n");
+
+ BLI_dynstr_free(ds);
+ MEM_freeN(matcap_with_ao);
+ }
+
+ if (!e_data.hair_sh) {
+ e_data.hair_sh = DRW_shader_create(
+ datatoc_clay_particle_vert_glsl, NULL, datatoc_clay_particle_strand_frag_glsl,
+ "#define MAX_MATERIAL 512\n");
+ }
+
+ if (!stl->storage) {
+ stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage");
+ }
+
+ if (!stl->mat_ubo) {
+ stl->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
+ }
+
+ if (!stl->hair_mat_ubo) {
+ stl->hair_mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_HAIR_UBO_Storage), NULL);
+ }
+
+ if (e_data.ubo_mat_idxs[1] == 0) {
+ /* Just int to have pointers to them */
+ for (int i = 0; i < MAX_CLAY_MAT; ++i) {
+ e_data.ubo_mat_idxs[i] = i;
+ }
+ }
+
+ if (DRW_state_is_fbo()) {
+ const float *viewport_size = DRW_viewport_size_get();
+ DRWFboTexture tex = {&e_data.depth_dup, DRW_TEX_DEPTH_24, DRW_TEX_TEMP};
+ DRW_framebuffer_init(&fbl->dupli_depth, &draw_engine_clay_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &tex, 1);
+ }
+
+ /* SSAO setup */
+ {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SceneLayer *scene_layer = draw_ctx->sl;
+ IDProperty *props = BKE_scene_layer_engine_evaluated_get(
+ scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
+ int ssao_samples = BKE_collection_engine_property_value_get_int(props, "ssao_samples");
+
+ float invproj[4][4];
+ float dfdyfacs[2];
+ const bool is_persp = DRW_viewport_is_persp_get();
+ /* view vectors for the corners of the view frustum.
+ * Can be used to recreate the world space position easily */
+ float viewvecs[3][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f}
+ };
+ int i;
+ const float *size = DRW_viewport_size_get();
+
+ DRW_state_dfdy_factors_get(dfdyfacs);
+
+ e_data.ssao_params[0] = ssao_samples;
+ e_data.ssao_params[1] = size[0] / 64.0;
+ e_data.ssao_params[2] = size[1] / 64.0;
+ e_data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
+
+ /* invert the view matrix */
+ DRW_viewport_matrix_get(e_data.winmat, DRW_MAT_WIN);
+ invert_m4_m4(invproj, e_data.winmat);
+
+ /* convert the view vectors to view space */
+ for (i = 0; i < 3; i++) {
+ mul_m4_v4(invproj, viewvecs[i]);
+ /* normalized trick see:
+ * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
+ if (is_persp)
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
+ viewvecs[i][3] = 1.0;
+
+ copy_v4_v4(e_data.viewvecs[i], viewvecs[i]);
+ }
+
+ /* we need to store the differences */
+ e_data.viewvecs[1][0] -= e_data.viewvecs[0][0];
+ e_data.viewvecs[1][1] = e_data.viewvecs[2][1] - e_data.viewvecs[0][1];
+
+ /* calculate a depth offset as well */
+ if (!is_persp) {
+ float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
+ mul_m4_v4(invproj, vec_far);
+ mul_v3_fl(vec_far, 1.0f / vec_far[3]);
+ e_data.viewvecs[1][2] = vec_far[2] - e_data.viewvecs[0][2];
+ }
+
+ /* AO Samples Tex */
+ if (e_data.sampling_tx && (e_data.cached_sample_num != ssao_samples)) {
+ DRW_texture_free(e_data.sampling_tx);
+ e_data.sampling_tx = NULL;
+ }
+
+ if (!e_data.sampling_tx) {
+ e_data.sampling_tx = create_spiral_sample_texture(ssao_samples);
+ e_data.cached_sample_num = ssao_samples;
+ }
+ }
+}
+
+static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *UNUSED(vedata), DRWPass *pass, int *material_id, bool use_flat)
+{
+ DRWShadingGroup *grp = DRW_shgroup_create(use_flat ? e_data.clay_flat_sh : e_data.clay_sh, pass);
+
+ DRW_shgroup_uniform_vec2(grp, "screenres", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_buffer(grp, "depthtex", &e_data.depth_dup);
+ DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array);
+ DRW_shgroup_uniform_mat4(grp, "WinMatrix", (float *)e_data.winmat);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)e_data.viewvecs, 3);
+ DRW_shgroup_uniform_vec4(grp, "ssao_params", e_data.ssao_params, 1);
+ DRW_shgroup_uniform_vec3(grp, "matcaps_color[0]", (float *)e_data.matcap_colors, 24);
+
+ DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
+
+ DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
+ DRW_shgroup_uniform_texture(grp, "ssao_samples", e_data.sampling_tx);
+
+ return grp;
+}
+
+static DRWShadingGroup *CLAY_hair_shgroup_create(DRWPass *pass, int *material_id)
+{
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.hair_sh, pass);
+
+ DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array);
+ DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
+
+ return grp;
+}
+
+static int search_mat_to_ubo(CLAY_Storage *storage, const CLAY_UBO_Material *mat_ubo_test)
+{
+ /* For now just use a linear search and test all parameters */
+ /* TODO make a hash table */
+ for (int i = 0; i < storage->ubo_current_id; ++i) {
+ CLAY_UBO_Material *ubo = &storage->mat_storage.materials[i];
+ if (memcmp(ubo, mat_ubo_test, sizeof(*mat_ubo_test)) == 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int search_hair_mat_to_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material *hair_mat_ubo_test)
+{
+ /* For now just use a linear search and test all parameters */
+ /* TODO make a hash table */
+ for (int i = 0; i < storage->hair_ubo_current_id; ++i) {
+ CLAY_HAIR_UBO_Material *ubo = &storage->hair_mat_storage.materials[i];
+ if (memcmp(ubo, hair_mat_ubo_test, sizeof(*hair_mat_ubo_test)) == 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int push_mat_to_ubo(CLAY_Storage *storage, const CLAY_UBO_Material *mat_ubo_test)
+{
+ int id = storage->ubo_current_id;
+ CLAY_UBO_Material *ubo = &storage->mat_storage.materials[id];
+
+ *ubo = *mat_ubo_test;
+
+ storage->ubo_current_id++;
+
+ return id;
+}
+
+static int push_hair_mat_to_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material *hair_mat_ubo_test)
+{
+ int id = storage->hair_ubo_current_id;
+ CLAY_HAIR_UBO_Material *ubo = &storage->hair_mat_storage.materials[id];
+
+ *ubo = *hair_mat_ubo_test;
+
+ storage->hair_ubo_current_id++;
+
+ return id;
+}
+
+static int mat_in_ubo(CLAY_Storage *storage, const CLAY_UBO_Material *mat_ubo_test)
+{
+ /* Search material in UBO */
+ int id = search_mat_to_ubo(storage, mat_ubo_test);
+
+ /* if not found create it */
+ if (id == -1) {
+ id = push_mat_to_ubo(storage, mat_ubo_test);
+ }
+
+ return id;
+}
+
+static int hair_mat_in_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material *hair_mat_ubo_test)
+{
+ /* Search material in UBO */
+ int id = search_hair_mat_to_ubo(storage, hair_mat_ubo_test);
+
+ /* if not found create it */
+ if (id == -1) {
+ id = push_hair_mat_to_ubo(storage, hair_mat_ubo_test);
+ }
+
+ return id;
+}
+
+static void ubo_mat_from_object(Object *ob, CLAY_UBO_Material *r_ubo)
+{
+ IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
+
+ /* Default Settings */
+ float matcap_rot = BKE_collection_engine_property_value_get_float(props, "matcap_rotation");
+ float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue");
+ float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation");
+ float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value");
+ float ssao_distance = BKE_collection_engine_property_value_get_float(props, "ssao_distance");
+ float ssao_factor_cavity = BKE_collection_engine_property_value_get_float(props, "ssao_factor_cavity");
+ float ssao_factor_edge = BKE_collection_engine_property_value_get_float(props, "ssao_factor_edge");
+ float ssao_attenuation = BKE_collection_engine_property_value_get_float(props, "ssao_attenuation");
+ int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon");
+
+ memset(r_ubo, 0x0, sizeof(*r_ubo));
+
+ r_ubo->matcap_rot[0] = cosf(matcap_rot * 3.14159f * 2.0f);
+ r_ubo->matcap_rot[1] = sinf(matcap_rot * 3.14159f * 2.0f);
+
+ r_ubo->matcap_hsv[0] = matcap_hue + 0.5f;
+ r_ubo->matcap_hsv[1] = matcap_sat * 2.0f;
+ r_ubo->matcap_hsv[2] = matcap_val * 2.0f;
+
+ r_ubo->ssao_params_var[0] = ssao_distance;
+ r_ubo->ssao_params_var[1] = ssao_factor_cavity;
+ r_ubo->ssao_params_var[2] = ssao_factor_edge;
+ r_ubo->ssao_params_var[3] = ssao_attenuation;
+ r_ubo->matcap_id = matcap_to_index(matcap_icon);
+}
+
+static void hair_ubo_mat_from_object(Object *ob, CLAY_HAIR_UBO_Material *r_ubo)
+{
+ IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
+
+ /* Default Settings */
+ float matcap_rot = BKE_collection_engine_property_value_get_float(props, "matcap_rotation");
+ float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue");
+ float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation");
+ float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value");
+ float hair_randomness = BKE_collection_engine_property_value_get_float(props, "hair_brightness_randomness");
+ int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon");
+
+ memset(r_ubo, 0x0, sizeof(*r_ubo));
+
+ r_ubo->matcap_rot[0] = cosf(matcap_rot * 3.14159f * 2.0f);
+ r_ubo->matcap_rot[1] = sinf(matcap_rot * 3.14159f * 2.0f);
+ r_ubo->matcap_hsv[0] = matcap_hue + 0.5f;
+ r_ubo->matcap_hsv[1] = matcap_sat * 2.0f;
+ r_ubo->matcap_hsv[2] = matcap_val * 2.0f;
+ r_ubo->hair_randomness = hair_randomness;
+ r_ubo->matcap_id = matcap_to_index(matcap_icon);
+}
+
+static DRWShadingGroup *CLAY_object_shgrp_get(
+ CLAY_Data *vedata, Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl, bool use_flat)
+{
+ DRWShadingGroup **shgrps = use_flat ? stl->storage->shgrps_flat : stl->storage->shgrps;
+ CLAY_UBO_Material mat_ubo_test;
+
+ ubo_mat_from_object(ob, &mat_ubo_test);
+
+ int id = mat_in_ubo(stl->storage, &mat_ubo_test);
+
+ if (shgrps[id] == NULL) {
+ shgrps[id] = CLAY_shgroup_create(
+ vedata, use_flat ? psl->clay_pass_flat : psl->clay_pass, &e_data.ubo_mat_idxs[id], use_flat);
+ /* if it's the first shgrp, pass bind the material UBO */
+ if (stl->storage->ubo_current_id == 1) {
+ DRW_shgroup_uniform_block(shgrps[0], "material_block", stl->mat_ubo);
+ }
+ }
+
+ return shgrps[id];
+}
+
+static DRWShadingGroup *CLAY_hair_shgrp_get(Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl)
+{
+ DRWShadingGroup **hair_shgrps = stl->storage->hair_shgrps;
+
+ CLAY_HAIR_UBO_Material hair_mat_ubo_test;
+ hair_ubo_mat_from_object(ob, &hair_mat_ubo_test);
+
+ int hair_id = hair_mat_in_ubo(stl->storage, &hair_mat_ubo_test);
+
+ if (hair_shgrps[hair_id] == NULL) {
+ hair_shgrps[hair_id] = CLAY_hair_shgroup_create(psl->hair_pass, &e_data.ubo_mat_idxs[hair_id]);
+ /* if it's the first shgrp, pass bind the material UBO */
+ if (stl->storage->hair_ubo_current_id == 1) {
+ DRW_shgroup_uniform_block(hair_shgrps[0], "material_block", stl->hair_mat_ubo);
+ }
+ }
+
+ return hair_shgrps[hair_id];
+}
+
+static DRWShadingGroup *CLAY_object_shgrp_default_mode_get(
+ CLAY_Data *vedata, Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl)
+{
+ bool use_flat = DRW_object_is_flat_normal(ob);
+ return CLAY_object_shgrp_get(vedata, ob, stl, psl, use_flat);
+}
+
+static void CLAY_cache_init(void *vedata)
+{
+ CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
+ CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ /* Depth Pass */
+ {
+ psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+
+ psl->depth_pass_cull = DRW_pass_create(
+ "Depth Pass Cull",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
+ }
+
+ /* Clay Pass */
+ {
+ psl->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ stl->storage->ubo_current_id = 0;
+ memset(stl->storage->shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
+ }
+
+ /* Clay Pass (Flat) */
+ {
+ psl->clay_pass_flat = DRW_pass_create("Clay Pass Flat", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ memset(stl->storage->shgrps_flat, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
+ }
+
+ /* Hair Pass */
+ {
+ psl->hair_pass = DRW_pass_create(
+ "Hair Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE);
+ stl->storage->hair_ubo_current_id = 0;
+ memset(stl->storage->hair_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
+ }
+}
+
+static void CLAY_cache_populate(void *vedata, Object *ob)
+{
+ CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
+ CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
+
+ DRWShadingGroup *clay_shgrp, *hair_shgrp;
+
+ if (!DRW_object_is_renderable(ob))
+ return;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const bool is_active = (ob == draw_ctx->obact);
+ if (is_active) {
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+ return;
+ }
+ }
+
+ struct Batch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
+ const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
+ const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
+ const bool is_default_mode_shader = is_sculpt_mode;
+
+ /* Depth Prepass */
+ {
+ DRWShadingGroup *depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(depth_shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_add(depth_shgrp, geom, ob->obmat);
+ }
+ }
+
+ /* Shading */
+ if (is_default_mode_shader) {
+ clay_shgrp = CLAY_object_shgrp_default_mode_get(vedata, ob, stl, psl);
+ }
+ else {
+ clay_shgrp = CLAY_object_shgrp_get(vedata, ob, stl, psl, false);
+ }
+
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(clay_shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
+ }
+ }
+
+ if (ob->type == OB_MESH) {
+ Scene *scene = draw_ctx->scene;
+ Object *obedit = scene->obedit;
+
+ if (ob != obedit) {
+ for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
+ if (psys_check_enabled(ob, psys, false)) {
+ ParticleSettings *part = psys->part;
+ int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+
+ if (draw_as == PART_DRAW_PATH && !psys->pathcache && !psys->childcache) {
+ draw_as = PART_DRAW_DOT;
+ }
+
+ static float mat[4][4];
+ unit_m4(mat);
+
+ if (draw_as == PART_DRAW_PATH) {
+ geom = DRW_cache_particles_get_hair(psys);
+ hair_shgrp = CLAY_hair_shgrp_get(ob, stl, psl);
+ DRW_shgroup_call_add(hair_shgrp, geom, mat);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void CLAY_cache_finish(void *vedata)
+{
+ CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
+
+ DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
+ DRW_uniformbuffer_update(stl->hair_mat_ubo, &stl->storage->hair_mat_storage);
+}
+
+static void CLAY_draw_scene(void *vedata)
+{
+
+ CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
+ CLAY_FramebufferList *fbl = ((CLAY_Data *)vedata)->fbl;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ /* Pass 1 : Depth pre-pass */
+ DRW_draw_pass(psl->depth_pass);
+ DRW_draw_pass(psl->depth_pass_cull);
+
+ /* Pass 2 : Duplicate depth */
+ /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
+ if (DRW_state_is_fbo()) {
+ /* attach temp textures */
+ DRW_framebuffer_texture_attach(fbl->dupli_depth, e_data.depth_dup, 0, 0);
+
+ DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true);
+
+ /* detach temp textures */
+ DRW_framebuffer_texture_detach(e_data.depth_dup);
+
+ /* restore default fb */
+ DRW_framebuffer_bind(dfbl->default_fb);
+ }
+
+ /* Pass 3 : Shading */
+ DRW_draw_pass(psl->clay_pass);
+ DRW_draw_pass(psl->clay_pass_flat);
+ DRW_draw_pass(psl->hair_pass);
+}
+
+static void CLAY_layer_collection_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
+{
+ BLI_assert(props &&
+ props->type == IDP_GROUP &&
+ props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
+
+ BKE_collection_engine_property_add_int(props, "matcap_icon", ICON_MATCAP_01);
+ BKE_collection_engine_property_add_int(props, "type", CLAY_MATCAP_NONE);
+ BKE_collection_engine_property_add_float(props, "matcap_rotation", 0.0f);
+ BKE_collection_engine_property_add_float(props, "matcap_hue", 0.5f);
+ BKE_collection_engine_property_add_float(props, "matcap_saturation", 0.5f);
+ BKE_collection_engine_property_add_float(props, "matcap_value", 0.5f);
+ BKE_collection_engine_property_add_float(props, "ssao_distance", 0.2f);
+ BKE_collection_engine_property_add_float(props, "ssao_attenuation", 1.0f);
+ BKE_collection_engine_property_add_float(props, "ssao_factor_cavity", 1.0f);
+ BKE_collection_engine_property_add_float(props, "ssao_factor_edge", 1.0f);
+ BKE_collection_engine_property_add_float(props, "hair_brightness_randomness", 0.0f);
+}
+
+static void CLAY_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
+{
+ BLI_assert(props &&
+ props->type == IDP_GROUP &&
+ props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
+
+ BKE_collection_engine_property_add_int(props, "ssao_samples", 32);
+}
+
+static void CLAY_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.clay_sh);
+ DRW_SHADER_FREE_SAFE(e_data.clay_flat_sh);
+ DRW_SHADER_FREE_SAFE(e_data.hair_sh);
+ DRW_TEXTURE_FREE_SAFE(e_data.matcap_array);
+ DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
+ DRW_TEXTURE_FREE_SAFE(e_data.sampling_tx);
+}
+
+static const DrawEngineDataSize CLAY_data_size = DRW_VIEWPORT_DATA_SIZE(CLAY_Data);
+
+DrawEngineType draw_engine_clay_type = {
+ NULL, NULL,
+ N_("Clay"),
+ &CLAY_data_size,
+ &CLAY_engine_init,
+ &CLAY_engine_free,
+ &CLAY_cache_init,
+ &CLAY_cache_populate,
+ &CLAY_cache_finish,
+ NULL,
+ &CLAY_draw_scene
+};
+
+RenderEngineType DRW_engine_viewport_clay_type = {
+ NULL, NULL,
+ CLAY_ENGINE, N_("Clay"), RE_INTERNAL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &CLAY_layer_collection_settings_create,
+ &CLAY_scene_layer_settings_create,
+ &draw_engine_clay_type,
+ {NULL, NULL, NULL}
+};
+
+
+#undef CLAY_ENGINE
+
+#endif
diff --git a/source/blender/draw/engines/clay/clay_engine.h b/source/blender/draw/engines/clay/clay_engine.h
new file mode 100644
index 00000000000..b7c9d00c9ae
--- /dev/null
+++ b/source/blender/draw/engines/clay/clay_engine.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file clay_engine.h
+ * \ingroup draw_engine
+ */
+
+#ifndef __CLAY_ENGINE_H__
+#define __CLAY_ENGINE_H__
+
+extern DrawEngineType draw_engine_clay_type;
+extern RenderEngineType DRW_engine_viewport_clay_type;
+
+struct IDProperty;
+
+struct IDProperty *CLAY_render_settings_create(void);
+
+#endif /* __CLAY_ENGINE_H__ */
diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
new file mode 100644
index 00000000000..033db365337
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
@@ -0,0 +1,198 @@
+uniform vec2 screenres;
+uniform sampler2D depthtex;
+uniform mat4 WinMatrix;
+
+/* Matcap */
+uniform sampler2DArray matcaps;
+uniform vec3 matcaps_color[24];
+
+/* Screen Space Occlusion */
+/* store the view space vectors for the corners of the view frustum here.
+ * It helps to quickly reconstruct view space vectors by using uv coordinates,
+ * see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+uniform vec4 viewvecs[3];
+uniform vec4 ssao_params;
+
+uniform sampler2D ssao_jitter;
+uniform sampler1D ssao_samples;
+
+/* Material Parameters packed in an UBO */
+struct Material {
+ vec4 ssao_params_var;
+ vec4 matcap_hsv_id;
+ vec4 matcap_rot; /* vec4 to ensure 16 bytes alignement (don't trust compiler) */
+};
+
+layout(std140) uniform material_block {
+ Material matcaps_param[MAX_MATERIAL];
+};
+
+uniform int mat_id;
+
+/* Aliases */
+#define ssao_samples_num ssao_params.x
+#define jitter_tilling ssao_params.yz
+#define dfdy_sign ssao_params.w
+
+#define matcap_hsv matcaps_param[mat_id].matcap_hsv_id.xyz
+#define matcap_index matcaps_param[mat_id].matcap_hsv_id.w
+#define matcap_rotation matcaps_param[mat_id].matcap_rot.xy
+
+#ifdef USE_FLAT_NORMAL
+flat in vec3 normal;
+#else
+in vec3 normal;
+#endif
+
+out vec4 fragColor;
+
+/* TODO Move this to SSAO modules */
+/* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
+ * we change the factors from the article to fit the OpennGL model. */
+vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
+{
+ if (WinMatrix[3][3] == 0.0) {
+ /* Perspective */
+ float d = 2.0 * depth - 1.0;
+
+ float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]);
+
+ return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz);
+ }
+ else {
+ /* Orthographic */
+ vec3 offset = vec3(uvcoords, depth);
+
+ return viewvecs[0].xyz + offset * viewvecs[1].xyz;
+ }
+}
+
+#ifdef USE_HSV
+void rgb_to_hsv(vec3 rgb, out vec3 outcol)
+{
+ float cmax, cmin, h, s, v, cdelta;
+ vec3 c;
+
+ cmax = max(rgb[0], max(rgb[1], rgb[2]));
+ cmin = min(rgb[0], min(rgb[1], rgb[2]));
+ cdelta = cmax - cmin;
+
+ v = cmax;
+ if (cmax != 0.0)
+ s = cdelta / cmax;
+ else {
+ s = 0.0;
+ h = 0.0;
+ }
+
+ if (s == 0.0) {
+ h = 0.0;
+ }
+ else {
+ c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta;
+
+ if (rgb.x == cmax) h = c[2] - c[1];
+ else if (rgb.y == cmax) h = 2.0 + c[0] - c[2];
+ else h = 4.0 + c[1] - c[0];
+
+ h /= 6.0;
+
+ if (h < 0.0)
+ h += 1.0;
+ }
+
+ outcol = vec3(h, s, v);
+}
+
+void hsv_to_rgb(vec3 hsv, out vec3 outcol)
+{
+ float i, f, p, q, t, h, s, v;
+ vec3 rgb;
+
+ h = hsv[0];
+ s = hsv[1];
+ v = hsv[2];
+
+ if (s == 0.0) {
+ rgb = vec3(v, v, v);
+ }
+ else {
+ if (h == 1.0)
+ h = 0.0;
+
+ h *= 6.0;
+ i = floor(h);
+ f = h - i;
+ rgb = vec3(f, f, f);
+ p = v * (1.0 - s);
+ q = v * (1.0 - (s * f));
+ t = v * (1.0 - (s * (1.0 - f)));
+
+ if (i == 0.0) rgb = vec3(v, t, p);
+ else if (i == 1.0) rgb = vec3(q, v, p);
+ else if (i == 2.0) rgb = vec3(p, v, t);
+ else if (i == 3.0) rgb = vec3(p, q, v);
+ else if (i == 4.0) rgb = vec3(t, p, v);
+ else rgb = vec3(v, p, q);
+ }
+
+ outcol = rgb;
+}
+
+void hue_sat(float hue, float sat, float value, inout vec3 col)
+{
+ vec3 hsv;
+
+ rgb_to_hsv(col, hsv);
+
+ hsv.x += hue;
+ hsv.x -= floor(hsv.x);
+ hsv.y *= sat;
+ hsv.y = clamp(hsv.y, 0.0, 1.0);
+ hsv.z *= value;
+ hsv.z = clamp(hsv.z, 0.0, 1.0);
+
+ hsv_to_rgb(hsv, col);
+}
+#endif
+
+#ifdef USE_AO
+/* Prototype */
+void ssao_factors(
+ in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+ out float cavities, out float edges);
+#endif
+
+void main() {
+ vec2 screenco = vec2(gl_FragCoord.xy) / screenres;
+ float depth = texture(depthtex, screenco).r;
+
+ vec3 position = get_view_space_from_depth(screenco, depth);
+
+#ifdef USE_ROTATION
+ /* Rotate texture coordinates */
+ vec2 rotY = vec2(-matcap_rotation.y, matcap_rotation.x);
+ vec2 texco = abs(vec2(dot(normal.xy, matcap_rotation), dot(normal.xy, rotY)) * .49 + 0.5);
+#else
+ vec2 texco = abs(normal.xy * .49 + 0.5);
+#endif
+ vec3 col = texture(matcaps, vec3(texco, matcap_index)).rgb;
+
+#ifdef USE_AO
+ float cavity, edges;
+ ssao_factors(depth, normal, position, screenco, cavity, edges);
+
+ col *= mix(vec3(1.0), matcaps_color[int(matcap_index)], cavity);
+#endif
+
+#ifdef USE_HSV
+ hue_sat(matcap_hsv.x, matcap_hsv.y, matcap_hsv.z, col);
+#endif
+
+#ifdef USE_AO
+ /* Apply highlights after hue shift */
+ col *= edges + 1.0;
+#endif
+
+ fragColor = vec4(col, 1.0);
+}
diff --git a/source/blender/draw/engines/clay/shaders/clay_particle_strand_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_particle_strand_frag.glsl
new file mode 100644
index 00000000000..980a1e4690d
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/clay_particle_strand_frag.glsl
@@ -0,0 +1,144 @@
+
+/* Material Parameters packed in an UBO */
+struct Material {
+ vec4 one;
+ vec4 two;
+};
+
+layout(std140) uniform material_block {
+ Material shader_param[MAX_MATERIAL];
+};
+
+uniform mat4 ProjectionMatrix;
+uniform sampler2DArray matcaps;
+uniform int mat_id;
+
+#define randomness shader_param[mat_id].one.x
+#define matcap_index shader_param[mat_id].one.y
+#define matcap_rotation shader_param[mat_id].one.zw
+#define matcap_hsv shader_param[mat_id].two.xyz
+
+in vec3 tangent;
+in vec3 viewPosition;
+flat in float colRand;
+out vec4 fragColor;
+
+vec3 rotate(vec3 norm, vec3 ortho, float ang)
+{
+ return norm * cos(ang) + ortho * sin(ang);
+}
+
+void rgb_to_hsv(vec3 rgb, out vec3 outcol)
+{
+ float cmax, cmin, h, s, v, cdelta;
+ vec3 c;
+
+ cmax = max(rgb[0], max(rgb[1], rgb[2]));
+ cmin = min(rgb[0], min(rgb[1], rgb[2]));
+ cdelta = cmax - cmin;
+
+ v = cmax;
+ if (cmax != 0.0)
+ s = cdelta / cmax;
+ else {
+ s = 0.0;
+ h = 0.0;
+ }
+
+ if (s == 0.0) {
+ h = 0.0;
+ }
+ else {
+ c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta;
+
+ if (rgb.x == cmax) h = c[2] - c[1];
+ else if (rgb.y == cmax) h = 2.0 + c[0] - c[2];
+ else h = 4.0 + c[1] - c[0];
+
+ h /= 6.0;
+
+ if (h < 0.0)
+ h += 1.0;
+ }
+
+ outcol = vec3(h, s, v);
+}
+
+void hsv_to_rgb(vec3 hsv, out vec3 outcol)
+{
+ float i, f, p, q, t, h, s, v;
+ vec3 rgb;
+
+ h = hsv[0];
+ s = hsv[1];
+ v = hsv[2];
+
+ if (s == 0.0) {
+ rgb = vec3(v, v, v);
+ }
+ else {
+ if (h == 1.0)
+ h = 0.0;
+
+ h *= 6.0;
+ i = floor(h);
+ f = h - i;
+ rgb = vec3(f, f, f);
+ p = v * (1.0 - s);
+ q = v * (1.0 - (s * f));
+ t = v * (1.0 - (s * (1.0 - f)));
+
+ if (i == 0.0) rgb = vec3(v, t, p);
+ else if (i == 1.0) rgb = vec3(q, v, p);
+ else if (i == 2.0) rgb = vec3(p, v, t);
+ else if (i == 3.0) rgb = vec3(p, q, v);
+ else if (i == 4.0) rgb = vec3(t, p, v);
+ else rgb = vec3(v, p, q);
+ }
+
+ outcol = rgb;
+}
+
+void hue_sat(float hue, float sat, float value, inout vec3 col)
+{
+ vec3 hsv;
+
+ rgb_to_hsv(col, hsv);
+
+ hsv.x += hue;
+ hsv.x -= floor(hsv.x);
+ hsv.y *= sat;
+ hsv.y = clamp(hsv.y, 0.0, 1.0);
+ hsv.z *= value;
+ hsv.z = clamp(hsv.z, 0.0, 1.0);
+
+ hsv_to_rgb(hsv, col);
+}
+
+void main()
+{
+ vec3 viewvec = (ProjectionMatrix[3][3] == 0.0) ? normalize(viewPosition) : vec3(0.0, 0.0, -1.0);
+ vec3 ortho = normalize(cross(viewvec, tangent));
+ vec3 norm = normalize(cross(ortho, tangent));
+
+ vec3 col = vec3(0);
+
+ vec2 rotY = vec2(-matcap_rotation.y, matcap_rotation.x);
+
+ for (int i = 0; i < 9; i++) {
+ vec3 rotNorm = rotate(norm, ortho, -0.5 + (i * 0.125));
+ vec3 ray = reflect(viewvec, rotNorm);
+ vec2 texco = abs(vec2(dot(ray.xy, matcap_rotation), dot(ray.xy, rotY)) * .49 + 0.5);
+
+ col += texture(matcaps, vec3(texco, matcap_index)).rgb / 9.0;
+ }
+
+ hue_sat(matcap_hsv.x, matcap_hsv.y, matcap_hsv.z, col);
+
+ float maxChan = max(max(col.r, col.g), col.b);
+
+ col += (colRand * maxChan * randomness * 1.5) - (maxChan * randomness * 0.75);
+
+ fragColor.rgb = col;
+ fragColor.a = 1.0;
+}
diff --git a/source/blender/draw/engines/clay/shaders/clay_particle_vert.glsl b/source/blender/draw/engines/clay/shaders/clay_particle_vert.glsl
new file mode 100644
index 00000000000..b28b3cadd6f
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/clay_particle_vert.glsl
@@ -0,0 +1,34 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+uniform mat4 ModelViewMatrix;
+
+in vec3 pos;
+in vec3 tang;
+in int ind;
+out vec3 tangent;
+out vec3 viewPosition;
+flat out float colRand;
+
+float rand(int s)
+{
+ int seed = s * 1023423;
+
+ seed = (seed ^ 61) ^ (seed >> 16);
+ seed *= 9;
+ seed = seed ^ (seed >> 4);
+ seed *= 0x27d4eb2d;
+ seed = seed ^ (seed >> 15);
+
+ float value = float(seed);
+ value *= 1.0 / 42596.0;
+ return fract(value);
+}
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ tangent = normalize(NormalMatrix * tang);
+ viewPosition = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
+ colRand = rand(ind);
+}
diff --git a/source/blender/draw/engines/clay/shaders/clay_vert.glsl b/source/blender/draw/engines/clay/shaders/clay_vert.glsl
new file mode 100644
index 00000000000..8f8866b3839
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/clay_vert.glsl
@@ -0,0 +1,17 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+
+in vec3 pos;
+in vec3 nor;
+
+#ifdef USE_FLAT_NORMAL
+flat out vec3 normal;
+#else
+out vec3 normal;
+#endif
+
+void main()
+{
+ normal = normalize(NormalMatrix * nor);
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+}
diff --git a/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl b/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl
new file mode 100644
index 00000000000..447d1ece8f8
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl
@@ -0,0 +1,75 @@
+#define ssao_distance matcaps_param[mat_id].ssao_params_var.x
+#define ssao_factor_cavity matcaps_param[mat_id].ssao_params_var.y
+#define ssao_factor_edge matcaps_param[mat_id].ssao_params_var.z
+#define ssao_attenuation matcaps_param[mat_id].ssao_params_var.w
+
+/* from The Alchemy screen-space ambient obscurance algorithm
+ * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
+
+void ssao_factors(
+ in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+ out float cavities, out float edges)
+{
+ /* take the normalized ray direction here */
+ vec2 rotX = texture(ssao_jitter, screenco.xy * jitter_tilling).rg;
+ vec2 rotY = vec2(-rotX.y, rotX.x);
+
+ /* find the offset in screen space by multiplying a point
+ * in camera space at the depth of the point by the projection matrix. */
+ vec2 offset;
+ float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
+ offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
+ offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
+ /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+ offset *= 0.5;
+
+ cavities = edges = 0.0;
+ int x;
+ int num_samples = int(ssao_samples_num);
+
+ for (x = 0; x < num_samples; x++) {
+ /* TODO : optimisation replace by constant */
+ vec2 dir_sample = texture(ssao_samples, (float(x) + 0.5) / ssao_samples_num).rg;
+
+ /* rotate with random direction to get jittered result */
+ vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY));
+
+ vec2 uvcoords = screenco.xy + dir_jittered * offset;
+
+ if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
+ continue;
+
+ float depth_new = texture(depthtex, uvcoords).r;
+
+ /* Handle Background case */
+ bool is_background = (depth_new == 1.0);
+
+ /* This trick provide good edge effect even if no neighboor is found. */
+ vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new);
+
+ if (is_background)
+ pos_new.z -= ssao_distance;
+
+ vec3 dir = pos_new - position;
+ float len = length(dir);
+ float f_cavities = dot(dir, normal);
+ float f_edge = -f_cavities;
+ float f_bias = 0.05 * len + 0.0001;
+
+ float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation));
+
+ /* use minor bias here to avoid self shadowing */
+ if (f_cavities > -f_bias)
+ cavities += f_cavities * attenuation;
+
+ if (f_edge > f_bias)
+ edges += f_edge * attenuation;
+ }
+
+ cavities /= ssao_samples_num;
+ edges /= ssao_samples_num;
+
+ /* don't let cavity wash out the surface appearance */
+ cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0);
+ edges = edges * ssao_factor_edge;
+}
diff --git a/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl b/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl
new file mode 100644
index 00000000000..9c203a4246c
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl
@@ -0,0 +1,122 @@
+#define ssao_distance matcaps_param[mat_id].ssao_params_var.x
+#define ssao_factor_cavity matcaps_param[mat_id].ssao_params_var.y
+#define ssao_factor_edge matcaps_param[mat_id].ssao_params_var.z
+#define ssao_attenuation matcaps_param[mat_id].ssao_params_var.w
+
+/* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
+ * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
+ * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx */
+
+#define COSINE_WEIGHTING
+
+float integrate_arc(in float h1, in float h2, in float gamma, in float n_proj_len)
+{
+ float a = 0.0;
+#ifdef COSINE_WEIGHTING
+ float cos_gamma = cos(gamma);
+ float sin_gamma_2 = 2.0 * sin(gamma);
+ a += -cos(2.0 * h1 - gamma) + cos_gamma + h1 * sin_gamma_2;
+ a += -cos(2.0 * h2 - gamma) + cos_gamma + h2 * sin_gamma_2;
+ a *= 0.25; /* 1/4 */
+ a *= n_proj_len;
+#else
+ /* Uniform weighting (slide 59) */
+ a += 1 - cos(h1);
+ a += 1 - cos(h2);
+#endif
+ return a;
+}
+
+float get_max_horizon(in vec2 co, in vec3 x, in vec3 omega_o, in float h)
+{
+ if (co.x > 1.0 || co.x < 0.0 || co.y > 1.0 || co.y < 0.0)
+ return h;
+
+ float depth = texture(depthtex, co).r;
+
+ /* Background case */
+ if (depth == 1.0)
+ return h;
+
+ vec3 s = get_view_space_from_depth(co, depth); /* s View coordinate */
+ vec3 omega_s = s - x;
+ float len = length(omega_s);
+
+ if (len < ssao_distance) {
+ omega_s /= len;
+ h = max(h, dot(omega_s, omega_o));
+ }
+ return h;
+}
+
+void ssao_factors(
+ in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+ out float cavities, out float edges)
+{
+ /* Renaming */
+ vec3 omega_o = -normalize(position); /* viewvec */
+ vec2 x_ = screenco; /* x^ Screen coordinate */
+ vec3 x = position; /* x view space coordinate */
+
+#ifdef SPATIAL_DENOISE
+ float noise_dir = (1.0 / 16.0) * float(((int(gl_FragCoord.x + gl_FragCoord.y) & 0x3) << 2) + (int(gl_FragCoord.x) & 0x3));
+ float noise_offset = (1.0 / 4.0) * float(int(gl_FragCoord.y - gl_FragCoord.x) & 0x3);
+#else
+ float noise_dir = (1.0 / 16.0) * float(((int(gl_FragCoord.x + gl_FragCoord.y) & 0x3) << 2) + (int(gl_FragCoord.x) & 0x3));
+ float noise_offset = (0.5 / 16.0) + (1.0 / 16.0) * float(((int(gl_FragCoord.x - gl_FragCoord.y) & 0x3) << 2) + (int(gl_FragCoord.x) & 0x3));
+#endif
+
+ const float phi_step = 16.0;
+ const float theta_step = 16.0;
+ const float m_pi = 3.14159265358979323846;
+ vec2 pixel_ratio = vec2(screenres.y / screenres.x, 1.0);
+ vec2 pixel_size = vec2(1.0) / screenres.xy;
+ float min_stride = length(pixel_size);
+ float homcco = WinMatrix[2][3] * position.z + WinMatrix[3][3];
+ float n = max(min_stride * theta_step, ssao_distance / homcco); /* Search distance */
+
+ /* Integral over PI */
+ float A = 0.0;
+ for (float i = 0.0; i < phi_step; i++) {
+ float phi = m_pi * ((noise_dir + i) / phi_step);
+
+ vec2 t_phi = vec2(cos(phi), sin(phi)); /* Screen space direction */
+
+ /* Search maximum horizon angles Theta1 and Theta2 */
+ float theta1 = -1.0, theta2 = -1.0; /* init at cos(pi) */
+ for (float j = 0.0; j < theta_step; j++) {
+ vec2 s_ = t_phi * pixel_ratio * n * ((j + noise_offset)/ theta_step); /* s^ Screen coordinate */
+ vec2 co;
+
+ co = x_ + s_;
+ theta1 = get_max_horizon(co, x, omega_o, theta1);
+
+ co = x_ - s_;
+ theta2 = get_max_horizon(co, x, omega_o, theta2);
+ }
+
+ /* (Slide 54) */
+ theta1 = -acos(theta1);
+ theta2 = acos(theta2);
+
+ /* Projecting Normal to Plane P defined by t_phi and omega_o */
+ vec3 h = normalize(cross(vec3(t_phi, 0.0), omega_o)); /* Normal vector to Integration plane */
+ vec3 t = cross(h, omega_o); /* Normal vector to plane */
+ vec3 n_proj = normal - h * dot(normal, h);
+ float n_proj_len = length(n_proj);
+ vec3 n_proj_norm = normalize(n_proj);
+
+ /* Clamping thetas (slide 58) */
+ float gamma = sign(dot(n_proj_norm, t)) * acos(dot(normal, omega_o)); /* Angle between view vec and normal */
+ theta1 = gamma + max(theta1 - gamma, -m_pi * 0.5);
+ theta2 = gamma + min(theta2 - gamma, m_pi * 0.5);
+
+ /* Solving inner integral */
+ A += integrate_arc(theta1, theta2, gamma, n_proj_len);
+ }
+
+ A /= phi_step;
+
+ cavities = 1.0 - A;
+ edges = 0.0;
+}
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
new file mode 100644
index 00000000000..205e1588b43
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/* Gather all screen space effects technique such as Bloom, Motion Blur, DoF, SSAO, SSR, ...
+ */
+
+/** \file eevee_effects.c
+ * \ingroup draw_engine
+ */
+
+#include "DRW_render.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_camera.h"
+#include "BKE_object.h"
+#include "BKE_animsys.h"
+#include "BKE_screen.h"
+
+#include "eevee_private.h"
+#include "GPU_texture.h"
+
+typedef struct EEVEE_ProbeData {
+ short probe_id, shadow_id;
+} EEVEE_ProbeData;
+
+/* TODO Option */
+#define ENABLE_EFFECT_MOTION_BLUR 1
+#define ENABLE_EFFECT_BLOOM 1
+#define ENABLE_EFFECT_DOF 1
+
+static struct {
+ /* Motion Blur */
+ struct GPUShader *motion_blur_sh;
+
+ /* Bloom */
+ struct GPUShader *bloom_blit_sh[2];
+ struct GPUShader *bloom_downsample_sh[2];
+ struct GPUShader *bloom_upsample_sh[2];
+ struct GPUShader *bloom_resolve_sh[2];
+
+ /* Depth Of Field */
+ struct GPUShader *dof_downsample_sh;
+ struct GPUShader *dof_scatter_sh;
+ struct GPUShader *dof_resolve_sh;
+} e_data = {NULL}; /* Engine data */
+
+extern char datatoc_effect_motion_blur_frag_glsl[];
+extern char datatoc_effect_bloom_frag_glsl[];
+extern char datatoc_effect_dof_vert_glsl[];
+extern char datatoc_effect_dof_geom_glsl[];
+extern char datatoc_effect_dof_frag_glsl[];
+extern char datatoc_tonemap_frag_glsl[];
+
+static void eevee_motion_blur_camera_get_matrix_at_time(
+ Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, Object *camera, float time, float r_mat[4][4])
+{
+ float obmat[4][4];
+
+ /* HACK */
+ Object cam_cpy; Camera camdata_cpy;
+ memcpy(&cam_cpy, camera, sizeof(cam_cpy));
+ memcpy(&camdata_cpy, camera->data, sizeof(camdata_cpy));
+ cam_cpy.data = &camdata_cpy;
+
+ /* Past matrix */
+ /* FIXME : This is a temporal solution that does not take care of parent animations */
+ /* Recalc Anim manualy */
+ BKE_animsys_evaluate_animdata(scene, &cam_cpy.id, cam_cpy.adt, time, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &camdata_cpy.id, camdata_cpy.adt, time, ADT_RECALC_ALL);
+ BKE_object_where_is_calc_time(scene, &cam_cpy, time);
+
+ /* Compute winmat */
+ CameraParams params;
+ BKE_camera_params_init(&params);
+
+ /* copy of BKE_camera_params_from_view3d */
+ {
+ params.lens = v3d->lens;
+ params.clipsta = v3d->near;
+ params.clipend = v3d->far;
+
+ /* camera view */
+ BKE_camera_params_from_object(&params, &cam_cpy);
+
+ params.zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
+
+ params.offsetx = 2.0f * rv3d->camdx * params.zoom;
+ params.offsety = 2.0f * rv3d->camdy * params.zoom;
+
+ params.shiftx *= params.zoom;
+ params.shifty *= params.zoom;
+
+ params.zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB / params.zoom;
+ }
+
+ BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
+ BKE_camera_params_compute_matrix(&params);
+
+ /* FIXME Should be done per view (MULTIVIEW) */
+ normalize_m4_m4(obmat, cam_cpy.obmat);
+ invert_m4(obmat);
+ mul_m4_m4m4(r_mat, params.winmat, obmat);
+}
+
+void EEVEE_effects_init(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_EffectsInfo *effects;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SceneLayer *scene_layer = draw_ctx->sl;
+ Scene *scene = draw_ctx->scene;
+ View3D *v3d = draw_ctx->v3d;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ ARegion *ar = draw_ctx->ar;
+ IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+
+ const float *viewport_size = DRW_viewport_size_get();
+
+ if (!e_data.motion_blur_sh) {
+ e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL);
+ }
+
+ if (!e_data.dof_downsample_sh) {
+ e_data.dof_downsample_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
+ datatoc_effect_dof_frag_glsl, "#define STEP_DOWNSAMPLE\n");
+ e_data.dof_scatter_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
+ datatoc_effect_dof_frag_glsl, "#define STEP_SCATTER\n");
+ e_data.dof_resolve_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
+ datatoc_effect_dof_frag_glsl, "#define STEP_RESOLVE\n");
+ }
+
+ if (!e_data.bloom_blit_sh[0]) {
+ e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n");
+ e_data.bloom_blit_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n"
+ "#define HIGH_QUALITY\n");
+
+ e_data.bloom_downsample_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_DOWNSAMPLE\n");
+ e_data.bloom_downsample_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_DOWNSAMPLE\n"
+ "#define HIGH_QUALITY\n");
+
+ e_data.bloom_upsample_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_UPSAMPLE\n");
+ e_data.bloom_upsample_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_UPSAMPLE\n"
+ "#define HIGH_QUALITY\n");
+
+ e_data.bloom_resolve_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_RESOLVE\n");
+ e_data.bloom_resolve_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_RESOLVE\n"
+ "#define HIGH_QUALITY\n");
+ }
+
+ if (!stl->effects) {
+ stl->effects = MEM_callocN(sizeof(EEVEE_EffectsInfo), "EEVEE_EffectsInfo");
+ }
+
+ effects = stl->effects;
+
+ int enabled_effects = 0;
+
+#if ENABLE_EFFECT_MOTION_BLUR
+ if (BKE_collection_engine_property_value_get_bool(props, "motion_blur_enable")) {
+ /* Update Motion Blur Matrices */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ float persmat[4][4];
+ float ctime = BKE_scene_frame_get(scene);
+ float delta = BKE_collection_engine_property_value_get_float(props, "motion_blur_shutter");
+
+ /* Current matrix */
+ eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime, effects->current_ndc_to_world);
+
+ /* Viewport Matrix */
+ DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
+
+ /* Only continue if camera is not being keyed */
+ if (compare_m4m4(persmat, effects->current_ndc_to_world, 0.0001f)) {
+
+ /* Past matrix */
+ eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime - delta, effects->past_world_to_ndc);
+
+#if 0 /* for future high quality blur */
+ /* Future matrix */
+ eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime + delta, effects->future_world_to_ndc);
+#endif
+ invert_m4(effects->current_ndc_to_world);
+
+ effects->motion_blur_samples = BKE_collection_engine_property_value_get_int(props, "motion_blur_samples");
+ enabled_effects |= EFFECT_MOTION_BLUR;
+ }
+ }
+ }
+#endif /* ENABLE_EFFECT_MOTION_BLUR */
+
+#if ENABLE_EFFECT_BLOOM
+ if (BKE_collection_engine_property_value_get_bool(props, "bloom_enable")) {
+ /* Bloom */
+ int blitsize[2], texsize[2];
+
+ /* Blit Buffer */
+ effects->source_texel_size[0] = 1.0f / viewport_size[0];
+ effects->source_texel_size[1] = 1.0f / viewport_size[1];
+
+ blitsize[0] = (int)viewport_size[0];
+ blitsize[1] = (int)viewport_size[1];
+
+ effects->blit_texel_size[0] = 1.0f / (float)blitsize[0];
+ effects->blit_texel_size[1] = 1.0f / (float)blitsize[1];
+
+ DRWFboTexture tex_blit = {&txl->bloom_blit, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fbl->bloom_blit_fb, &draw_engine_eevee_type,
+ (int)blitsize[0], (int)blitsize[1],
+ &tex_blit, 1);
+
+ /* Parameters */
+ float threshold = BKE_collection_engine_property_value_get_float(props, "bloom_threshold");
+ float knee = BKE_collection_engine_property_value_get_float(props, "bloom_knee");
+ float intensity = BKE_collection_engine_property_value_get_float(props, "bloom_intensity");
+ float radius = BKE_collection_engine_property_value_get_float(props, "bloom_radius");
+
+ /* determine the iteration count */
+ const float minDim = (float)MIN2(blitsize[0], blitsize[1]);
+ const float maxIter = (radius - 8.0f) + log(minDim) / log(2);
+ const int maxIterInt = effects->bloom_iteration_ct = (int)maxIter;
+
+ CLAMP(effects->bloom_iteration_ct, 1, MAX_BLOOM_STEP);
+
+ effects->bloom_sample_scale = 0.5f + maxIter - (float)maxIterInt;
+ effects->bloom_curve_threshold[0] = threshold - knee;
+ effects->bloom_curve_threshold[1] = knee * 2.0f;
+ effects->bloom_curve_threshold[2] = 0.25f / max_ff(1e-5f, knee);
+ effects->bloom_curve_threshold[3] = threshold;
+ effects->bloom_intensity = intensity;
+
+ /* Downsample buffers */
+ copy_v2_v2_int(texsize, blitsize);
+ for (int i = 0; i < effects->bloom_iteration_ct; ++i) {
+ texsize[0] /= 2; texsize[1] /= 2;
+ texsize[0] = MAX2(texsize[0], 2);
+ texsize[1] = MAX2(texsize[1], 2);
+
+ effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0];
+ effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1];
+
+ DRWFboTexture tex_bloom = {&txl->bloom_downsample[i], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fbl->bloom_down_fb[i], &draw_engine_eevee_type,
+ (int)texsize[0], (int)texsize[1],
+ &tex_bloom, 1);
+ }
+
+ /* Upsample buffers */
+ copy_v2_v2_int(texsize, blitsize);
+ for (int i = 0; i < effects->bloom_iteration_ct - 1; ++i) {
+ texsize[0] /= 2; texsize[1] /= 2;
+ texsize[0] = MAX2(texsize[0], 2);
+ texsize[1] = MAX2(texsize[1], 2);
+
+ DRWFboTexture tex_bloom = {&txl->bloom_upsample[i], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fbl->bloom_accum_fb[i], &draw_engine_eevee_type,
+ (int)texsize[0], (int)texsize[1],
+ &tex_bloom, 1);
+ }
+
+ enabled_effects |= EFFECT_BLOOM;
+ }
+#endif /* ENABLE_EFFECT_BLOOM */
+
+#if ENABLE_EFFECT_DOF
+ if (BKE_collection_engine_property_value_get_bool(props, "dof_enable")) {
+ /* Depth Of Field */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ Camera *cam = (Camera *)v3d->camera->data;
+
+ /* Retreive Near and Far distance */
+ effects->dof_near_far[0] = -cam->clipsta;
+ effects->dof_near_far[1] = -cam->clipend;
+
+ int buffer_size[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2};
+
+ struct GPUTexture **dof_down_near = &txl->dof_down_near;
+ bool fb_reset = false;
+
+ /* Reuse buffer from Bloom if available */
+ /* WATCH IT : must have the same size */
+ if ((enabled_effects & EFFECT_BLOOM) != 0) {
+ dof_down_near = &txl->bloom_downsample[0]; /* should always exists */
+ if ((effects->enabled_effects & EFFECT_BLOOM) == 0) {
+ fb_reset = true;
+ }
+ }
+ else if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ fb_reset = true;
+ }
+
+ /* if framebuffer config must be changed */
+ if (fb_reset && (fbl->dof_down_fb != NULL)) {
+ DRW_framebuffer_free(fbl->dof_down_fb);
+ fbl->dof_down_fb = NULL;
+ }
+
+ /* Setup buffers */
+ DRWFboTexture tex_down[3] = {{dof_down_near, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}, /* filter to not interfeer with bloom */
+ {&txl->dof_down_far, DRW_TEX_RGB_11_11_10, 0},
+ {&txl->dof_coc, DRW_TEX_RG_16, 0}};
+ DRW_framebuffer_init(&fbl->dof_down_fb, &draw_engine_eevee_type, buffer_size[0], buffer_size[1], tex_down, 3);
+
+ DRWFboTexture tex_scatter_far = {&txl->dof_far_blur, DRW_TEX_RGBA_16, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fbl->dof_scatter_far_fb, &draw_engine_eevee_type, buffer_size[0], buffer_size[1], &tex_scatter_far, 1);
+
+ DRWFboTexture tex_scatter_near = {&txl->dof_near_blur, DRW_TEX_RGBA_16, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fbl->dof_scatter_near_fb, &draw_engine_eevee_type, buffer_size[0], buffer_size[1], &tex_scatter_near, 1);
+
+ /* Parameters */
+ /* TODO UI Options */
+ float fstop = cam->gpu_dof.fstop;
+ float blades = cam->gpu_dof.num_blades;
+ float rotation = cam->gpu_dof.rotation;
+ float ratio = 1.0f / cam->gpu_dof.ratio;
+ float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
+ float focus_dist = BKE_camera_object_dof_distance(v3d->camera);
+ float focal_len = cam->lens;
+
+ UNUSED_VARS(rotation, ratio);
+
+ /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
+ * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
+ * because the shader reads coordinates in world space, which is in blender units.
+ * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
+ float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f;
+ float scale_camera = 0.001f / scale;
+ /* we want radius here for the aperture number */
+ float aperture = 0.5f * scale_camera * focal_len / fstop;
+ float focal_len_scaled = scale_camera * focal_len;
+ float sensor_scaled = scale_camera * sensor;
+
+ effects->dof_params[0] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
+ effects->dof_params[1] = -focus_dist;
+ effects->dof_params[2] = viewport_size[0] / (rv3d->viewcamtexcofac[0] * sensor_scaled);
+ effects->dof_bokeh[0] = blades;
+ effects->dof_bokeh[1] = rotation;
+ effects->dof_bokeh[2] = ratio;
+ effects->dof_bokeh[3] = BKE_collection_engine_property_value_get_float(props, "bokeh_max_size");
+
+ enabled_effects |= EFFECT_DOF;
+ }
+ }
+#endif /* ENABLE_EFFECT_DOF */
+
+ effects->enabled_effects = enabled_effects;
+
+ /* Only allocate if at least one effect is activated */
+ if (effects->enabled_effects != 0) {
+ /* Ping Pong buffer */
+ DRWFboTexture tex = {&txl->color_post, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
+
+ DRW_framebuffer_init(&fbl->effect_fb, &draw_engine_eevee_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &tex, 1);
+ }
+}
+
+static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample)
+{
+ struct Batch *quad = DRW_cache_fullscreen_quad_get();
+
+ *pass = DRW_pass_create(name, DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, *pass);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_uniform_buffer(grp, "sourceBuffer", &effects->unf_source_buffer);
+ DRW_shgroup_uniform_vec2(grp, "sourceBufferTexelSize", effects->unf_source_texel_size, 1);
+ if (upsample) {
+ DRW_shgroup_uniform_buffer(grp, "baseBuffer", &effects->unf_base_buffer);
+ DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
+ }
+
+ return grp;
+}
+
+void EEVEE_effects_cache_init(EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ struct Batch *quad = DRW_cache_fullscreen_quad_get();
+
+ {
+ psl->motion_blur = DRW_pass_create("Motion Blur", DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.motion_blur_sh, psl->motion_blur);
+ DRW_shgroup_uniform_int(grp, "samples", &effects->motion_blur_samples, 1);
+ DRW_shgroup_uniform_mat4(grp, "currInvViewProjMatrix", (float *)effects->current_ndc_to_world);
+ DRW_shgroup_uniform_mat4(grp, "pastViewProjMatrix", (float *)effects->past_world_to_ndc);
+ DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->source_buffer);
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+
+ {
+ /** Bloom algorithm
+ *
+ * Overview :
+ * - Downsample the color buffer doing a small blur during each step.
+ * - Accumulate bloom color using previously downsampled color buffers
+ * and do an upsample blur for each new accumulated layer.
+ * - Finally add accumulation buffer onto the source color buffer.
+ *
+ * [1/1] is original copy resolution (can be half or quater res for performance)
+ *
+ * [DOWNSAMPLE CHAIN] [UPSAMPLE CHAIN]
+ *
+ * Source Color ── [Blit] ──> Bright Color Extract [1/1] Final Color
+ * | Λ
+ * [Downsample First] Source Color ─> + [Resolve]
+ * v |
+ * Color Downsampled [1/2] ────────────> + Accumulation Buffer [1/2]
+ * | Λ
+ * ─── ───
+ * Repeat Repeat
+ * ─── ───
+ * v |
+ * Color Downsampled [1/N-1] ──────────> + Accumulation Buffer [1/N-1]
+ * | Λ
+ * [Downsample] [Upsample]
+ * v |
+ * Color Downsampled [1/N] ─────────────────────────┘
+ **/
+ DRWShadingGroup *grp;
+ const bool use_highres = true;
+ const bool use_antiflicker = true;
+ eevee_create_bloom_pass("Bloom Downsample First", effects, e_data.bloom_downsample_sh[use_antiflicker], &psl->bloom_downsample_first, false);
+ eevee_create_bloom_pass("Bloom Downsample", effects, e_data.bloom_downsample_sh[0], &psl->bloom_downsample, false);
+ eevee_create_bloom_pass("Bloom Upsample", effects, e_data.bloom_upsample_sh[use_highres], &psl->bloom_upsample, true);
+ grp = eevee_create_bloom_pass("Bloom Blit", effects, e_data.bloom_blit_sh[use_antiflicker], &psl->bloom_blit, false);
+ DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
+ grp = eevee_create_bloom_pass("Bloom Resolve", effects, e_data.bloom_resolve_sh[use_highres], &psl->bloom_resolve, true);
+ DRW_shgroup_uniform_float(grp, "bloomIntensity", &effects->bloom_intensity, 1);
+ }
+
+ {
+ /** Depth of Field algorithm
+ *
+ * Overview :
+ * - Downsample the color buffer into 2 buffers weighted with
+ * CoC values. Also output CoC into a texture.
+ * - Shoot quads for every pixel and expand it depending on the CoC.
+ * Do one pass for near Dof and one pass for far Dof.
+ * - Finally composite the 2 blurred buffers with the original render.
+ **/
+ DRWShadingGroup *grp;
+
+ psl->dof_down = DRW_pass_create("DoF Downsample", DRW_STATE_WRITE_COLOR);
+
+ grp = DRW_shgroup_create(e_data.dof_downsample_sh, psl->dof_down);
+ DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->source_buffer);
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
+ DRW_shgroup_uniform_vec3(grp, "dofParams", effects->dof_params, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->dof_scatter = DRW_pass_create("DoF Scatter", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
+
+ /* This create an empty batch of N triangles to be positioned
+ * by the vertex shader 0.4ms against 6ms with instancing */
+ const float *viewport_size = DRW_viewport_size_get();
+ const int sprite_ct = ((int)viewport_size[0]/2) * ((int)viewport_size[1]/2); /* brackets matters */
+ grp = DRW_shgroup_empty_tri_batch_create(e_data.dof_scatter_sh, psl->dof_scatter, sprite_ct);
+
+ DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->unf_source_buffer);
+ DRW_shgroup_uniform_buffer(grp, "cocBuffer", &txl->dof_coc);
+ DRW_shgroup_uniform_vec2(grp, "layerSelection", effects->dof_layer_select, 1);
+ DRW_shgroup_uniform_vec4(grp, "bokehParams", effects->dof_bokeh, 1);
+
+ psl->dof_resolve = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR);
+
+ grp = DRW_shgroup_create(e_data.dof_resolve_sh, psl->dof_resolve);
+ DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->source_buffer);
+ DRW_shgroup_uniform_buffer(grp, "nearBuffer", &txl->dof_near_blur);
+ DRW_shgroup_uniform_buffer(grp, "farBuffer", &txl->dof_far_blur);
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
+ DRW_shgroup_uniform_vec3(grp, "dofParams", effects->dof_params, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+}
+
+#define SWAP_BUFFERS() { \
+ if (effects->source_buffer == txl->color) { \
+ effects->source_buffer = txl->color_post; \
+ effects->target_buffer = fbl->main; \
+ } \
+ else { \
+ effects->source_buffer = txl->color; \
+ effects->target_buffer = fbl->effect_fb; \
+ } \
+} ((void)0)
+
+void EEVEE_draw_effects(EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ /* Init pointers */
+ effects->source_buffer = txl->color; /* latest updated texture */
+ effects->target_buffer = fbl->effect_fb; /* next target to render to */
+
+ /* Detach depth for effects to use it */
+ DRW_framebuffer_texture_detach(dtxl->depth);
+
+ /* Motion Blur */
+ if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
+ DRW_framebuffer_bind(effects->target_buffer);
+ DRW_draw_pass(psl->motion_blur);
+ SWAP_BUFFERS();
+ }
+
+ /* Depth Of Field */
+ if ((effects->enabled_effects & EFFECT_DOF) != 0) {
+ float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Downsample */
+ DRW_framebuffer_bind(fbl->dof_down_fb);
+ DRW_draw_pass(psl->dof_down);
+
+ /* Scatter Far */
+ effects->unf_source_buffer = txl->dof_down_far;
+ copy_v2_fl2(effects->dof_layer_select, 0.0f, 1.0f);
+ DRW_framebuffer_bind(fbl->dof_scatter_far_fb);
+ DRW_framebuffer_clear(true, false, false, clear_col, 0.0f);
+ DRW_draw_pass(psl->dof_scatter);
+
+ /* Scatter Near */
+ if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ /* Reuse bloom half res buffer */
+ effects->unf_source_buffer = txl->bloom_downsample[0];
+ }
+ else {
+ effects->unf_source_buffer = txl->dof_down_near;
+ }
+ copy_v2_fl2(effects->dof_layer_select, 1.0f, 0.0f);
+ DRW_framebuffer_bind(fbl->dof_scatter_near_fb);
+ DRW_framebuffer_clear(true, false, false, clear_col, 0.0f);
+ DRW_draw_pass(psl->dof_scatter);
+
+ /* Resolve */
+ DRW_framebuffer_bind(effects->target_buffer);
+ DRW_draw_pass(psl->dof_resolve);
+ SWAP_BUFFERS();
+ }
+
+ /* Bloom */
+ if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ struct GPUTexture *last;
+
+ /* Extract bright pixels */
+ copy_v2_v2(effects->unf_source_texel_size, effects->source_texel_size);
+ effects->unf_source_buffer = effects->source_buffer;
+
+ DRW_framebuffer_bind(fbl->bloom_blit_fb);
+ DRW_draw_pass(psl->bloom_blit);
+
+ /* Downsample */
+ copy_v2_v2(effects->unf_source_texel_size, effects->blit_texel_size);
+ effects->unf_source_buffer = txl->bloom_blit;
+
+ DRW_framebuffer_bind(fbl->bloom_down_fb[0]);
+ DRW_draw_pass(psl->bloom_downsample_first);
+
+ last = txl->bloom_downsample[0];
+
+ for (int i = 1; i < effects->bloom_iteration_ct; ++i) {
+ copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[i-1]);
+ effects->unf_source_buffer = last;
+
+ DRW_framebuffer_bind(fbl->bloom_down_fb[i]);
+ DRW_draw_pass(psl->bloom_downsample);
+
+ /* Used in next loop */
+ last = txl->bloom_downsample[i];
+ }
+
+ /* Upsample and accumulate */
+ for (int i = effects->bloom_iteration_ct - 2; i >= 0; --i) {
+ copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[i]);
+ effects->unf_source_buffer = txl->bloom_downsample[i];
+ effects->unf_base_buffer = last;
+
+ DRW_framebuffer_bind(fbl->bloom_accum_fb[i]);
+ DRW_draw_pass(psl->bloom_upsample);
+
+ last = txl->bloom_upsample[i];
+ }
+
+ /* Resolve */
+ copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[0]);
+ effects->unf_source_buffer = last;
+ effects->unf_base_buffer = effects->source_buffer;
+
+ DRW_framebuffer_bind(effects->target_buffer);
+ DRW_draw_pass(psl->bloom_resolve);
+ SWAP_BUFFERS();
+ }
+
+ /* Restore default framebuffer */
+ DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ DRW_framebuffer_bind(dfbl->default_fb);
+
+ /* Tonemapping */
+ DRW_transform_to_display(effects->source_buffer);
+}
+
+void EEVEE_effects_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.motion_blur_sh);
+ DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh);
+ DRW_SHADER_FREE_SAFE(e_data.dof_scatter_sh);
+ DRW_SHADER_FREE_SAFE(e_data.dof_resolve_sh);
+
+ DRW_SHADER_FREE_SAFE(e_data.bloom_blit_sh[0]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_downsample_sh[0]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_upsample_sh[0]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[0]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_blit_sh[1]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_downsample_sh[1]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_upsample_sh[1]);
+ DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[1]);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
new file mode 100644
index 00000000000..cd3819b88e1
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -0,0 +1,715 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_engine.c
+ * \ingroup draw_engine
+ */
+
+#include "DRW_render.h"
+
+#include "DNA_world_types.h"
+
+#include "BLI_dynstr.h"
+#include "BLI_rand.h"
+
+#include "GPU_material.h"
+#include "GPU_glew.h"
+
+#include "eevee_engine.h"
+#include "eevee_private.h"
+#include "eevee_lut.h"
+
+#define EEVEE_ENGINE "BLENDER_EEVEE"
+
+#define SHADER_DEFINES \
+ "#define EEVEE_ENGINE\n" \
+ "#define MAX_LIGHT " STRINGIFY(MAX_LIGHT) "\n" \
+ "#define MAX_SHADOW_CUBE " STRINGIFY(MAX_SHADOW_CUBE) "\n" \
+ "#define MAX_SHADOW_MAP " STRINGIFY(MAX_SHADOW_MAP) "\n" \
+ "#define MAX_SHADOW_CASCADE " STRINGIFY(MAX_SHADOW_CASCADE) "\n" \
+ "#define MAX_CASCADE_NUM " STRINGIFY(MAX_CASCADE_NUM) "\n"
+
+/* *********** STATIC *********** */
+static struct {
+ char *frag_shader_lib;
+
+ struct GPUShader *default_lit;
+ struct GPUShader *default_lit_flat;
+ struct GPUShader *default_world;
+ struct GPUShader *default_background;
+ struct GPUShader *depth_sh;
+
+ struct GPUShader *probe_filter_sh;
+ struct GPUShader *probe_spherical_harmonic_sh;
+
+ struct GPUTexture *ltc_mat;
+ struct GPUTexture *brdf_lut;
+ struct GPUTexture *jitter;
+
+ float camera_pos[3];
+} e_data = {NULL}; /* Engine data */
+
+extern char datatoc_default_frag_glsl[];
+extern char datatoc_default_world_frag_glsl[];
+extern char datatoc_ltc_lib_glsl[];
+extern char datatoc_bsdf_lut_frag_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_bsdf_direct_lib_glsl[];
+extern char datatoc_bsdf_sampling_lib_glsl[];
+extern char datatoc_lit_surface_frag_glsl[];
+extern char datatoc_lit_surface_vert_glsl[];
+extern char datatoc_shadow_frag_glsl[];
+extern char datatoc_shadow_geom_glsl[];
+extern char datatoc_shadow_vert_glsl[];
+extern char datatoc_probe_filter_frag_glsl[];
+extern char datatoc_probe_sh_frag_glsl[];
+extern char datatoc_probe_geom_glsl[];
+extern char datatoc_probe_vert_glsl[];
+extern char datatoc_background_vert_glsl[];
+
+extern Material defmaterial;
+extern GlobalsUboStorage ts;
+
+/* Prototypes */
+static void EEVEE_scene_layer_data_free(void *storage);
+
+static struct GPUTexture *create_jitter_texture(int w, int h)
+{
+ struct GPUTexture *tex;
+ float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * w * h, "jitter_tex");
+ int i;
+
+ /* TODO replace by something more evenly distributed like blue noise */
+ for (i = 0; i < w * h; i++) {
+ texels[i][0] = 2.0f * BLI_frand() - 1.0f;
+ texels[i][1] = 2.0f * BLI_frand() - 1.0f;
+ normalize_v2(texels[i]);
+ }
+
+ tex = DRW_texture_create_2D(w, h, DRW_TEX_RG_16, DRW_TEX_WRAP, (float *)texels);
+ MEM_freeN(texels);
+ return tex;
+}
+
+static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
+{
+ struct GPUTexture *tex;
+#if 0 /* Used only to generate the LUT values */
+ struct GPUFrameBuffer *fb = NULL;
+ static float samples_ct = 8192.0f;
+ static float inv_samples_ct = 1.0f / 8192.0f;
+
+ char *lib_str = NULL;
+
+ DynStr *ds_vert = BLI_dynstr_new();
+ BLI_dynstr_append(ds_vert, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_vert, datatoc_bsdf_sampling_lib_glsl);
+ lib_str = BLI_dynstr_get_cstring(ds_vert);
+ BLI_dynstr_free(ds_vert);
+
+ struct GPUShader *sh = DRW_shader_create_with_lib(
+ datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_bsdf_lut_frag_glsl, lib_str,
+ "#define HAMMERSLEY_SIZE 8192\n"
+ "#define BRDF_LUT_SIZE 64\n"
+ "#define NOISE_SIZE 64\n");
+
+ DRWPass *pass = DRW_pass_create("Probe Filtering", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
+ DRW_shgroup_uniform_float(grp, "sampleCount", &samples_ct, 1);
+ DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_ct, 1);
+ DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
+ DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
+
+ struct Batch *geom = DRW_cache_fullscreen_quad_get();
+ DRW_shgroup_call_add(grp, geom, NULL);
+
+ float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
+
+ tex = DRW_texture_create_2D(w, h, DRW_TEX_RG_16, DRW_TEX_FILTER, (float *)texels);
+
+ DRWFboTexture tex_filter = {&tex, DRW_TEX_RG_16, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
+
+ DRW_framebuffer_bind(fb);
+ DRW_draw_pass(pass);
+
+ float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glReadPixels(0, 0, w, h, GL_RGB, GL_FLOAT, data);
+
+ printf("{");
+ for (int i = 0; i < w*h * 3; i+=3) {
+ printf("%ff, %ff, ", data[i], data[i+1]); i+=3;
+ printf("%ff, %ff, ", data[i], data[i+1]); i+=3;
+ printf("%ff, %ff, ", data[i], data[i+1]); i+=3;
+ printf("%ff, %ff, \n", data[i], data[i+1]);
+ }
+ printf("}");
+
+ MEM_freeN(texels);
+ MEM_freeN(data);
+#else
+ float (*texels)[3] = MEM_mallocN(sizeof(float[3]) * 64 * 64, "bsdf lut texels");
+
+ for (int i = 0; i < 64 * 64; i++) {
+ texels[i][0] = bsdf_split_sum_ggx[i*2 + 0];
+ texels[i][1] = bsdf_split_sum_ggx[i*2 + 1];
+ texels[i][2] = ltc_mag_ggx[i];
+ }
+
+ tex = DRW_texture_create_2D(64, 64, DRW_TEX_RGB_16, DRW_TEX_FILTER, (float *)texels);
+ MEM_freeN(texels);
+#endif
+
+ return tex;
+}
+
+
+/* *********** FUNCTIONS *********** */
+
+static void EEVEE_engine_init(void *ved)
+{
+ EEVEE_Data *vedata = (EEVEE_Data *)ved;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_SceneLayerData **sldata = (EEVEE_SceneLayerData **)DRW_scene_layer_engine_data_get(&draw_engine_eevee_type, &EEVEE_scene_layer_data_free);
+
+ if (*sldata == NULL) {
+ *sldata = MEM_callocN(sizeof(EEVEE_SceneLayerData), "EEVEE_SceneLayerData");
+ }
+
+ DRWFboTexture tex = {&txl->color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
+
+ const float *viewport_size = DRW_viewport_size_get();
+ DRW_framebuffer_init(&fbl->main, &draw_engine_eevee_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &tex, 1);
+
+ if (!e_data.frag_shader_lib) {
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_ltc_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_direct_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_lit_surface_frag_glsl);
+ e_data.frag_shader_lib = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+ }
+
+ if (!e_data.depth_sh) {
+ e_data.depth_sh = DRW_shader_create_3D_depth_only();
+ }
+
+ if (!e_data.default_lit) {
+ char *frag_str = NULL;
+
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, e_data.frag_shader_lib);
+ BLI_dynstr_append(ds_frag, datatoc_default_frag_glsl);
+ frag_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.default_lit = DRW_shader_create(
+ datatoc_lit_surface_vert_glsl, NULL, frag_str, SHADER_DEFINES "#define MESH_SHADER\n");
+
+ e_data.default_lit_flat = DRW_shader_create(
+ datatoc_lit_surface_vert_glsl, NULL, frag_str,
+ SHADER_DEFINES
+ "#define MESH_SHADER\n"
+ "#define USE_FLAT_NORMAL\n");
+
+ MEM_freeN(frag_str);
+ }
+
+ if (!e_data.default_world) {
+ e_data.default_world = DRW_shader_create(
+ datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_default_world_frag_glsl, NULL);
+ }
+
+ if (!e_data.default_background) {
+ e_data.default_background = DRW_shader_create_fullscreen(datatoc_default_world_frag_glsl, NULL);
+ }
+
+ if (!e_data.ltc_mat) {
+ e_data.ltc_mat = DRW_texture_create_2D(64, 64, DRW_TEX_RGBA_16, DRW_TEX_FILTER, ltc_mat_ggx);
+ }
+
+ if (!e_data.jitter) {
+ e_data.jitter = create_jitter_texture(64, 64);
+ }
+
+ if (!e_data.brdf_lut) {
+ e_data.brdf_lut = create_ggx_lut_texture(64, 64);
+ }
+
+ {
+ float viewinvmat[4][4];
+ DRW_viewport_matrix_get(viewinvmat, DRW_MAT_VIEWINV);
+
+ copy_v3_v3(e_data.camera_pos, viewinvmat[3]);
+ }
+
+ EEVEE_lights_init(*sldata);
+
+ EEVEE_probes_init(*sldata);
+
+ EEVEE_effects_init(vedata);
+
+ // EEVEE_lights_update(stl);
+}
+
+static DRWShadingGroup *eevee_cube_shgroup(struct GPUShader *sh, DRWPass *pass, struct Batch *geom)
+{
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+
+ for (int i = 0; i < 6; ++i)
+ DRW_shgroup_call_dynamic_add_empty(grp);
+
+ return grp;
+}
+
+static void EEVEE_cache_init(void *vedata)
+{
+ static int zero = 0;
+
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_SceneLayerData *sldata = *(EEVEE_SceneLayerData **)DRW_scene_layer_engine_data_get(&draw_engine_eevee_type, &EEVEE_scene_layer_data_free);
+
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ // psl->shadow_pass = DRW_pass_create("Shadow Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ // stl->g_data->shadow_shgrp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
+ // DRW_shgroup_uniform_mat4(stl->g_data->shadow_shgrp, "ShadowMatrix", (float *)stl->lamps->shadowmat);
+ // DRW_shgroup_uniform_int(stl->g_data->shadow_shgrp, "Layer", &stl->lamps->layer, 1);
+ }
+
+ {
+ psl->probe_background = DRW_pass_create("Probe Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR);
+
+ struct Batch *geom = DRW_cache_fullscreen_quad_get();
+ DRWShadingGroup *grp = NULL;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ World *wo = scene->world;
+
+ float *col = ts.colorBackground;
+ if (wo) {
+ col = &wo->horr;
+ }
+
+ if (wo && wo->use_nodes && wo->nodetree) {
+ struct GPUMaterial *gpumat = GPU_material_from_nodetree(
+ scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type, 0,
+ datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, e_data.frag_shader_lib,
+ SHADER_DEFINES "#define PROBE_CAPTURE\n");
+
+ grp = DRW_shgroup_material_instance_create(gpumat, psl->probe_background, geom);
+
+ if (grp) {
+ DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
+
+ for (int i = 0; i < 6; ++i)
+ DRW_shgroup_call_dynamic_add_empty(grp);
+ }
+ else {
+ /* Shader failed : pink background */
+ static float pink[3] = {1.0f, 0.0f, 1.0f};
+ col = pink;
+ }
+ }
+
+ /* Fallback if shader fails or if not using nodetree. */
+ if (grp == NULL) {
+ grp = eevee_cube_shgroup(e_data.default_world, psl->probe_background, geom);
+ DRW_shgroup_uniform_vec3(grp, "color", col, 1);
+ DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
+ }
+ }
+
+ {
+ psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR);
+
+ struct Batch *geom = DRW_cache_fullscreen_quad_get();
+ DRWShadingGroup *grp = NULL;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ World *wo = scene->world;
+
+ float *col = ts.colorBackground;
+ if (wo) {
+ col = &wo->horr;
+ }
+
+ if (wo && wo->use_nodes && wo->nodetree) {
+ struct GPUMaterial *gpumat = GPU_material_from_nodetree(
+ scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type, 1,
+ datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
+ SHADER_DEFINES "#define WORLD_BACKGROUND\n");
+
+ grp = DRW_shgroup_material_create(gpumat, psl->background_pass);
+
+ if (grp) {
+ DRW_shgroup_call_add(grp, geom, NULL);
+ }
+ else {
+ /* Shader failed : pink background */
+ static float pink[3] = {1.0f, 0.0f, 1.0f};
+ col = pink;
+ }
+ }
+
+ /* Fallback if shader fails or if not using nodetree. */
+ if (grp == NULL) {
+ grp = DRW_shgroup_create(e_data.default_background, psl->background_pass);
+ DRW_shgroup_uniform_vec3(grp, "color", col, 1);
+ DRW_shgroup_call_add(grp, geom, NULL);
+ }
+ }
+
+ {
+ psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+
+ psl->depth_pass_cull = DRW_pass_create(
+ "Depth Pass Cull",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
+ }
+
+ {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
+ psl->default_pass = DRW_pass_create("Default Shader Pass", state);
+
+ for (uint j = 0; j < 2; j++) {
+ struct GPUShader *shader;
+ struct DRWShadingGroup *shgrp;
+
+ if (j == 0) {
+ shader = e_data.default_lit;
+ shgrp = DRW_shgroup_create(shader, psl->default_pass);
+ }
+ else {
+ shader = e_data.default_lit_flat;
+ shgrp = DRW_shgroup_create(shader, psl->default_pass);
+ }
+
+ DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_int(shgrp, "light_count", &sldata->lamps->num_light, 1);
+ DRW_shgroup_uniform_float(shgrp, "lodMax", &sldata->probes->lodmax, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "shCoefs[0]", (float *)sldata->probes->shcoefs, 9);
+ DRW_shgroup_uniform_vec3(shgrp, "cameraPos", e_data.camera_pos, 1);
+ DRW_shgroup_uniform_texture(shgrp, "ltcMat", e_data.ltc_mat);
+ DRW_shgroup_uniform_texture(shgrp, "brdfLut", e_data.brdf_lut);
+ DRW_shgroup_uniform_texture(shgrp, "probeFiltered", sldata->probe_pool);
+ /* NOTE : Adding Shadow Map textures uniform in EEVEE_cache_finish */
+ }
+ }
+
+ {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
+ psl->material_pass = DRW_pass_create("Material Shader Pass", state);
+ }
+
+ EEVEE_probes_cache_init(sldata, psl);
+ EEVEE_lights_cache_init(sldata, psl);
+ EEVEE_effects_cache_init(vedata);
+}
+
+static void EEVEE_cache_populate(void *vedata, Object *ob)
+{
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ EEVEE_SceneLayerData *sldata = *(EEVEE_SceneLayerData **)DRW_scene_layer_engine_data_get(&draw_engine_eevee_type, &EEVEE_scene_layer_data_free);
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const bool is_active = (ob == draw_ctx->obact);
+ if (is_active) {
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+ return;
+ }
+ }
+
+ struct Batch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
+ const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
+ const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
+ const bool is_default_mode_shader = is_sculpt_mode;
+
+ /* Depth Prepass */
+ {
+ DRWShadingGroup *depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(depth_shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_object_add(depth_shgrp, geom, ob);
+ }
+ }
+
+ /* Get per-material split surface */
+ struct Batch **mat_geom = DRW_cache_object_surface_material_get(ob);
+ if (mat_geom) {
+ struct GPUShader *default_shader = e_data.default_lit;
+
+ if (is_default_mode_shader) {
+ if (is_sculpt_mode) {
+ bool use_flat = DRW_object_is_flat_normal(ob);
+ default_shader = use_flat ? e_data.default_lit_flat : e_data.default_lit;
+ }
+ }
+
+ for (int i = 0; i < MAX2(1, (is_sculpt_mode ? 1 : ob->totcol)); ++i) {
+ Material *ma = give_current_material(ob, i + 1);
+
+ if (ma == NULL)
+ ma = &defmaterial;
+
+ if (ma->use_nodes && ma->nodetree) {
+ Scene *scene = draw_ctx->scene;
+ struct GPUMaterial *gpumat = GPU_material_from_nodetree(
+ scene, ma->nodetree, &ma->gpumaterial, &DRW_engine_viewport_eevee_type, 0,
+ datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib,
+ SHADER_DEFINES "#define MESH_SHADER\n");
+
+ DRWShadingGroup *shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
+ if (shgrp) {
+ DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_int(shgrp, "light_count", &sldata->lamps->num_light, 1);
+ DRW_shgroup_uniform_float(shgrp, "lodMax", &sldata->probes->lodmax, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "shCoefs[0]", (float *)sldata->probes->shcoefs, 9);
+ DRW_shgroup_uniform_vec3(shgrp, "cameraPos", e_data.camera_pos, 1);
+ DRW_shgroup_uniform_texture(shgrp, "ltcMat", e_data.ltc_mat);
+ DRW_shgroup_uniform_texture(shgrp, "brdfLut", e_data.brdf_lut);
+ DRW_shgroup_uniform_texture(shgrp, "probeFiltered", sldata->probe_pool);
+
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_object_add(shgrp, mat_geom[i], ob);
+ }
+ }
+ else {
+ /* Shader failed : pink color */
+ static float col[3] = {1.0f, 0.0f, 1.0f};
+ static float half = 0.5f;
+
+ shgrp = DRW_shgroup_create(default_shader, psl->default_pass);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", col, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", &half, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", &half, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", &half, 1);
+ DRW_shgroup_uniform_texture(shgrp, "ltcMat", e_data.ltc_mat);
+ DRW_shgroup_uniform_texture(shgrp, "brdfLut", e_data.brdf_lut);
+ DRW_shgroup_uniform_texture(shgrp, "probeFiltered", sldata->probe_pool);
+
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_object_add(shgrp, mat_geom[i], ob);
+ }
+ }
+ }
+ else {
+ DRWShadingGroup *shgrp = DRW_shgroup_create(default_shader, psl->default_pass);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", &ma->r, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", &ma->ray_mirror, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", &ma->spec, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", &ma->gloss_mir, 1);
+ DRW_shgroup_uniform_texture(shgrp, "ltcMat", e_data.ltc_mat);
+ DRW_shgroup_uniform_texture(shgrp, "brdfLut", e_data.brdf_lut);
+ DRW_shgroup_uniform_texture(shgrp, "probeFiltered", sldata->probe_pool);
+
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_object_add(shgrp, mat_geom[i], ob);
+ }
+ }
+ }
+ }
+ // GPUMaterial *gpumat = GPU_material_from_nodetree(struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options)
+
+ // DRW_shgroup_call_add(stl->g_data->shadow_shgrp, geom, ob->obmat);
+ const bool cast_shadow = true;
+
+ if (cast_shadow) {
+ EEVEE_lights_cache_shcaster_add(sldata, psl, geom, ob->obmat);
+ }
+ }
+ else if (ob->type == OB_LAMP) {
+ EEVEE_lights_cache_add(sldata, ob);
+ }
+}
+
+typedef struct eevee_bind_shadow_data {
+ struct GPUTexture *shadow_depth_cube_pool;
+ struct GPUTexture *shadow_depth_cascade_pool;
+} eevee_bind_shadow_data;
+
+static void eevee_bind_shadow(void *data, DRWShadingGroup *shgrp)
+{
+ eevee_bind_shadow_data *shdw_data = data;
+ DRW_shgroup_uniform_texture(shgrp, "shadowCubes", shdw_data->shadow_depth_cube_pool);
+ DRW_shgroup_uniform_texture(shgrp, "shadowCascades", shdw_data->shadow_depth_cascade_pool);
+}
+
+static void EEVEE_cache_finish(void *vedata)
+{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ EEVEE_SceneLayerData *sldata = *(EEVEE_SceneLayerData **)DRW_scene_layer_engine_data_get(&draw_engine_eevee_type, &EEVEE_scene_layer_data_free);
+
+ EEVEE_lights_cache_finish(sldata);
+ EEVEE_probes_cache_finish(sldata);
+
+ /* Shadows binding */
+ eevee_bind_shadow_data data;
+
+ data.shadow_depth_cube_pool = sldata->shadow_depth_cube_pool;
+ data.shadow_depth_cascade_pool = sldata->shadow_depth_cascade_pool;
+
+ DRW_pass_foreach_shgroup(psl->default_pass, eevee_bind_shadow, &data);
+ DRW_pass_foreach_shgroup(psl->material_pass, eevee_bind_shadow, &data);
+}
+
+static void EEVEE_draw_scene(void *vedata)
+{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl;
+ EEVEE_SceneLayerData *sldata = *(EEVEE_SceneLayerData **)DRW_scene_layer_engine_data_get(&draw_engine_eevee_type, &EEVEE_scene_layer_data_free);
+
+ /* Default framebuffer and texture */
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ /* Refresh Probes */
+ EEVEE_refresh_probe(sldata, psl);
+
+ /* Refresh shadows */
+ EEVEE_draw_shadows(sldata, psl);
+
+ /* Attach depth to the hdr buffer and bind it */
+ DRW_framebuffer_texture_detach(dtxl->depth);
+ DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
+ DRW_framebuffer_bind(fbl->main);
+ DRW_framebuffer_clear(false, true, false, NULL, 1.0f);
+
+ DRW_draw_pass(psl->background_pass);
+ DRW_draw_pass(psl->depth_pass);
+ DRW_draw_pass(psl->depth_pass_cull);
+ DRW_draw_pass(psl->default_pass);
+ DRW_draw_pass(psl->material_pass);
+
+ EEVEE_draw_effects(vedata);
+}
+
+static void EEVEE_engine_free(void)
+{
+ EEVEE_effects_free();
+ EEVEE_lights_free();
+ EEVEE_probes_free();
+
+ MEM_SAFE_FREE(e_data.frag_shader_lib);
+ DRW_SHADER_FREE_SAFE(e_data.default_lit);
+ DRW_SHADER_FREE_SAFE(e_data.default_lit_flat);
+ DRW_SHADER_FREE_SAFE(e_data.default_world);
+ DRW_SHADER_FREE_SAFE(e_data.default_background);
+ DRW_SHADER_FREE_SAFE(e_data.probe_filter_sh);
+ DRW_SHADER_FREE_SAFE(e_data.probe_spherical_harmonic_sh);
+ DRW_TEXTURE_FREE_SAFE(e_data.ltc_mat);
+ DRW_TEXTURE_FREE_SAFE(e_data.brdf_lut);
+ DRW_TEXTURE_FREE_SAFE(e_data.jitter);
+}
+
+static void EEVEE_scene_layer_data_free(void *storage)
+{
+ EEVEE_SceneLayerData *sldata = (EEVEE_SceneLayerData *)storage;
+ EEVEE_scene_layer_lights_free(sldata);
+ EEVEE_scene_layer_probes_free(sldata);
+}
+
+static void EEVEE_layer_collection_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
+{
+ BLI_assert(props &&
+ props->type == IDP_GROUP &&
+ props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
+ // BKE_collection_engine_property_add_int(props, "high_quality_sphere_lamps", false);
+ UNUSED_VARS_NDEBUG(props);
+}
+
+static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
+{
+ BLI_assert(props &&
+ props->type == IDP_GROUP &&
+ props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
+
+ BKE_collection_engine_property_add_bool(props, "dof_enable", false);
+ BKE_collection_engine_property_add_float(props, "bokeh_max_size", 100.0f);
+ BKE_collection_engine_property_add_float(props, "bokeh_threshold", 1.0f);
+
+ BKE_collection_engine_property_add_bool(props, "bloom_enable", false);
+ BKE_collection_engine_property_add_float(props, "bloom_threshold", 0.8f);
+ BKE_collection_engine_property_add_float(props, "bloom_knee", 0.5f);
+ BKE_collection_engine_property_add_float(props, "bloom_intensity", 0.8f);
+ BKE_collection_engine_property_add_float(props, "bloom_radius", 6.5f);
+
+ BKE_collection_engine_property_add_bool(props, "motion_blur_enable", false);
+ BKE_collection_engine_property_add_int(props, "motion_blur_samples", 8);
+ BKE_collection_engine_property_add_float(props, "motion_blur_shutter", 1.0f);
+}
+
+static const DrawEngineDataSize EEVEE_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data);
+
+DrawEngineType draw_engine_eevee_type = {
+ NULL, NULL,
+ N_("Eevee"),
+ &EEVEE_data_size,
+ &EEVEE_engine_init,
+ &EEVEE_engine_free,
+ &EEVEE_cache_init,
+ &EEVEE_cache_populate,
+ &EEVEE_cache_finish,
+ &EEVEE_draw_scene,
+ NULL//&EEVEE_draw_scene
+};
+
+RenderEngineType DRW_engine_viewport_eevee_type = {
+ NULL, NULL,
+ EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_SHADING_NODES,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &EEVEE_layer_collection_settings_create, &EEVEE_scene_layer_settings_create,
+ &draw_engine_eevee_type,
+ {NULL, NULL, NULL}
+};
+
+
+#undef EEVEE_ENGINE
diff --git a/source/blender/draw/engines/eevee/eevee_engine.h b/source/blender/draw/engines/eevee/eevee_engine.h
new file mode 100644
index 00000000000..0cbd89a79fa
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_engine.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_engine.h
+ * \ingroup DNA
+ */
+
+#ifndef __EEVEE_ENGINE_H__
+#define __EEVEE_ENGINE_H__
+
+extern RenderEngineType DRW_engine_viewport_eevee_type;
+
+#endif /* __EEVEE_ENGINE_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
new file mode 100644
index 00000000000..4c992fca8e0
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -0,0 +1,668 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_lights.c
+ * \ingroup DNA
+ */
+
+#include "DRW_render.h"
+
+#include "eevee_engine.h"
+#include "eevee_private.h"
+
+typedef struct EEVEE_LightData {
+ short light_id, shadow_id;
+} EEVEE_LightData;
+
+typedef struct EEVEE_ShadowCubeData {
+ short light_id, shadow_id;
+ float viewprojmat[6][4][4];
+} EEVEE_ShadowCubeData;
+
+typedef struct EEVEE_ShadowMapData {
+ short light_id, shadow_id;
+ float viewprojmat[4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
+} EEVEE_ShadowMapData;
+
+typedef struct EEVEE_ShadowCascadeData {
+ short light_id, shadow_id;
+ float viewprojmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
+} EEVEE_ShadowCascadeData;
+
+static struct {
+ struct GPUShader *shadow_sh;
+ struct GPUShader *shadow_store_sh;
+} e_data = {NULL}; /* Engine data */
+
+extern char datatoc_shadow_vert_glsl[];
+extern char datatoc_shadow_geom_glsl[];
+extern char datatoc_shadow_frag_glsl[];
+extern char datatoc_shadow_store_vert_glsl[];
+extern char datatoc_shadow_store_geom_glsl[];
+extern char datatoc_shadow_store_frag_glsl[];
+
+/* *********** FUNCTIONS *********** */
+
+void EEVEE_lights_init(EEVEE_SceneLayerData *sldata)
+{
+ const unsigned int shadow_ubo_size = sizeof(EEVEE_ShadowCube) * MAX_SHADOW_CUBE +
+ sizeof(EEVEE_ShadowMap) * MAX_SHADOW_MAP +
+ sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE;
+
+ if (!e_data.shadow_sh) {
+ e_data.shadow_sh = DRW_shader_create(
+ datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_frag_glsl, NULL);
+
+ e_data.shadow_store_sh = DRW_shader_create(
+ datatoc_shadow_store_vert_glsl, datatoc_shadow_store_geom_glsl, datatoc_shadow_store_frag_glsl, NULL);
+ }
+
+ if (!sldata->lamps) {
+ sldata->lamps = MEM_callocN(sizeof(EEVEE_LampsInfo), "EEVEE_LampsInfo");
+ sldata->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
+ sldata->shadow_ubo = DRW_uniformbuffer_create(shadow_ubo_size, NULL);
+ sldata->shadow_render_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_ShadowRender), NULL);
+ }
+}
+
+void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
+{
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+
+ linfo->num_light = linfo->num_cube = linfo->num_map = linfo->num_cascade = 0;
+ memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
+ memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
+ memset(linfo->shadow_map_ref, 0, sizeof(linfo->shadow_map_ref));
+ memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
+
+ {
+ psl->shadow_cube_store_pass = DRW_pass_create("Shadow Storage Pass", DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_sh, psl->shadow_cube_store_pass);
+ DRW_shgroup_uniform_buffer(grp, "shadowCube", &sldata->shadow_color_cube_target);
+ DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+
+ {
+ psl->shadow_cube_pass = DRW_pass_create("Shadow Cube Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ }
+
+ {
+ psl->shadow_cascade_pass = DRW_pass_create("Shadow Cascade Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ }
+}
+
+void EEVEE_lights_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
+{
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+
+ /* Step 1 find all lamps in the scene and setup them */
+ if (linfo->num_light > MAX_LIGHT) {
+ printf("Too much lamps in the scene !!!\n");
+ linfo->num_light = MAX_LIGHT;
+ }
+ else {
+ Lamp *la = (Lamp *)ob->data;
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+
+ DRW_lamp_engine_data_free((void *)led);
+
+#if 1 /* TODO Waiting for notified refresh. only on scene change. Else too much perf cost. */
+ if (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) {
+ if (la->type == LA_SUN && linfo->num_cascade < MAX_SHADOW_CASCADE) {
+#if 0 /* TODO filter cascaded shadow map */
+ led->sto = MEM_mallocN(sizeof(EEVEE_ShadowCascadeData), "EEVEE_ShadowCascadeData");
+ ((EEVEE_ShadowCascadeData *)led->sto)->shadow_id = linfo->num_cascade;
+ linfo->shadow_cascade_ref[linfo->num_cascade] = ob;
+ linfo->num_cascade++;
+#endif
+ }
+ else if ((la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA)
+ && linfo->num_cube < MAX_SHADOW_CUBE) {
+ led->sto = MEM_mallocN(sizeof(EEVEE_ShadowCubeData), "EEVEE_ShadowCubeData");
+ ((EEVEE_ShadowCubeData *)led->sto)->shadow_id = linfo->num_cube;
+ linfo->shadow_cube_ref[linfo->num_cube] = ob;
+ linfo->num_cube++;
+ }
+ }
+#else
+ UNUSED_VARS(la);
+#endif
+ if (!led->sto) {
+ led->sto = MEM_mallocN(sizeof(EEVEE_LightData), "EEVEE_LightData");
+ ((EEVEE_LightData *)led->sto)->shadow_id = -1;
+ }
+
+ ((EEVEE_LightData *)led->sto)->light_id = linfo->num_light;
+ linfo->light_ref[linfo->num_light] = ob;
+ linfo->num_light++;
+ }
+}
+
+/* Add a shadow caster to the shadowpasses */
+void EEVEE_lights_cache_shcaster_add(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, struct Batch *geom, float (*obmat)[4])
+{
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom);
+ DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+ DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
+
+ for (int i = 0; i < 6; ++i)
+ DRW_shgroup_call_dynamic_add_empty(grp);
+
+ grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom);
+ DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+ DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
+
+ for (int i = 0; i < MAX_CASCADE_NUM; ++i)
+ DRW_shgroup_call_dynamic_add_empty(grp);
+}
+
+void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
+{
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+
+ /* Step 4 Update Lamp UBOs */
+ EEVEE_lights_update(sldata);
+
+ /* Step 5 Setup enough layers */
+ /* Free textures if number mismatch */
+ if (linfo->num_cube != linfo->cache_num_cube) {
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cube_pool);
+ linfo->cache_num_cube = linfo->num_cube;
+ }
+ if (linfo->num_map != linfo->cache_num_map) {
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_map_pool);
+ linfo->cache_num_map = linfo->num_map;
+ }
+ if (linfo->num_cascade != linfo->cache_num_cascade) {
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cascade_pool);
+ linfo->cache_num_cascade = linfo->num_cascade;
+ }
+
+ /* Initialize Textures Arrays first so DRW_framebuffer_init just bind them. */
+ if (!sldata->shadow_depth_cube_target) {
+ /* Render Cubemap */
+ sldata->shadow_depth_cube_target = DRW_texture_create_cube(512, DRW_TEX_DEPTH_24, 0, NULL);
+ sldata->shadow_color_cube_target = DRW_texture_create_cube(512, DRW_TEX_R_32, DRW_TEX_FILTER, NULL);
+ if (sldata->shadow_cube_fb) {
+ DRW_framebuffer_texture_attach(sldata->shadow_cube_fb, sldata->shadow_depth_cube_target, 0, 0);
+ DRW_framebuffer_texture_attach(sldata->shadow_cube_fb, sldata->shadow_color_cube_target, 0, 0);
+ }
+ }
+ if (!sldata->shadow_depth_cube_pool) {
+ /* Cubemap / octahedral map pool */
+ /* TODO Cubemap array */
+ sldata->shadow_depth_cube_pool = DRW_texture_create_2D_array(
+ 512, 512, max_ff(1, linfo->num_cube), DRW_TEX_R_32,
+ DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
+ if (sldata->shadow_cube_fb) {
+ DRW_framebuffer_texture_attach(sldata->shadow_cube_fb, sldata->shadow_depth_cube_pool, 0, 0);
+ }
+ }
+ if (!sldata->shadow_depth_map_pool) {
+ sldata->shadow_depth_map_pool = DRW_texture_create_2D_array(
+ 512, 512, max_ff(1, linfo->num_map), DRW_TEX_DEPTH_24,
+ DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
+ if (sldata->shadow_map_fb) {
+ DRW_framebuffer_texture_attach(sldata->shadow_map_fb, sldata->shadow_depth_map_pool, 0, 0);
+ }
+ }
+ if (!sldata->shadow_depth_cascade_pool) {
+ sldata->shadow_depth_cascade_pool = DRW_texture_create_2D_array(
+ 512, 512, max_ff(1, linfo->num_cascade * MAX_CASCADE_NUM), DRW_TEX_DEPTH_24,
+ DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
+ if (sldata->shadow_cascade_fb) {
+ DRW_framebuffer_texture_attach(sldata->shadow_cascade_fb, sldata->shadow_depth_map_pool, 0, 0);
+ }
+ }
+
+ DRWFboTexture tex_cube_target[2] = {
+ {&sldata->shadow_depth_cube_target, DRW_TEX_DEPTH_24, 0},
+ {&sldata->shadow_color_cube_target, DRW_TEX_R_32, DRW_TEX_FILTER}};
+ DRW_framebuffer_init(&sldata->shadow_cube_target_fb, &draw_engine_eevee_type, 512, 512, tex_cube_target, 2);
+
+ DRWFboTexture tex_cube = {&sldata->shadow_depth_cube_pool, DRW_TEX_R_32, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&sldata->shadow_cube_fb, &draw_engine_eevee_type, 512, 512, &tex_cube, 1);
+
+ DRWFboTexture tex_cascade = {&sldata->shadow_depth_cascade_pool, DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE};
+ DRW_framebuffer_init(&sldata->shadow_cascade_fb, &draw_engine_eevee_type, 512, 512, &tex_cascade, 1);
+}
+
+/* Update buffer with lamp data */
+static void eevee_light_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
+{
+ /* TODO only update if data changes */
+ EEVEE_LightData *evld = led->sto;
+ EEVEE_Light *evli = linfo->light_data + evld->light_id;
+ Lamp *la = (Lamp *)ob->data;
+ float mat[4][4], scale[3], power;
+
+ /* Position */
+ copy_v3_v3(evli->position, ob->obmat[3]);
+
+ /* Color */
+ copy_v3_v3(evli->color, &la->r);
+
+ /* Influence Radius */
+ evli->dist = la->dist;
+
+ /* Vectors */
+ normalize_m4_m4_ex(mat, ob->obmat, scale);
+ copy_v3_v3(evli->forwardvec, mat[2]);
+ normalize_v3(evli->forwardvec);
+ negate_v3(evli->forwardvec);
+
+ copy_v3_v3(evli->rightvec, mat[0]);
+ normalize_v3(evli->rightvec);
+
+ copy_v3_v3(evli->upvec, mat[1]);
+ normalize_v3(evli->upvec);
+
+ /* Spot size & blend */
+ if (la->type == LA_SPOT) {
+ evli->sizex = scale[0] / scale[2];
+ evli->sizey = scale[1] / scale[2];
+ evli->spotsize = cosf(la->spotsize * 0.5f);
+ evli->spotblend = (1.0f - evli->spotsize) * la->spotblend;
+ evli->radius = max_ff(0.001f, la->area_size);
+ }
+ else if (la->type == LA_AREA) {
+ evli->sizex = max_ff(0.0001f, la->area_size * scale[0] * 0.5f);
+ if (la->area_shape == LA_AREA_RECT) {
+ evli->sizey = max_ff(0.0001f, la->area_sizey * scale[1] * 0.5f);
+ }
+ else {
+ evli->sizey = max_ff(0.0001f, la->area_size * scale[1] * 0.5f);
+ }
+ }
+ else {
+ evli->radius = max_ff(0.001f, la->area_size);
+ }
+
+ /* Make illumination power constant */
+ if (la->type == LA_AREA) {
+ power = 1.0f / (evli->sizex * evli->sizey * 4.0f * M_PI) /* 1/(w*h*Pi) */
+ * 80.0f; /* XXX : Empirical, Fit cycles power */
+ }
+ else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
+ power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI) /* 1/(4*r²*Pi²) */
+ * M_PI * M_PI * M_PI * 10.0; /* XXX : Empirical, Fit cycles power */
+
+ /* for point lights (a.k.a radius == 0.0) */
+ // power = M_PI * M_PI * 0.78; /* XXX : Empirical, Fit cycles power */
+ }
+ else {
+ power = 1.0f;
+ }
+ mul_v3_fl(evli->color, power * la->energy);
+
+ /* Lamp Type */
+ evli->lamptype = (float)la->type;
+
+ /* No shadow by default */
+ evli->shadowid = -1.0f;
+}
+
+static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
+{
+ float projmat[4][4];
+
+ EEVEE_ShadowCubeData *evsmp = (EEVEE_ShadowCubeData *)led->sto;
+ EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
+ EEVEE_ShadowCube *evsh = linfo->shadow_cube_data + evsmp->shadow_id;
+ Lamp *la = (Lamp *)ob->data;
+
+ perspective_m4(projmat, -la->clipsta, la->clipsta, -la->clipsta, la->clipsta, la->clipsta, la->clipend);
+
+ for (int i = 0; i < 6; ++i) {
+ float tmp[4][4];
+ unit_m4(tmp);
+ negate_v3_v3(tmp[3], ob->obmat[3]);
+ mul_m4_m4m4(tmp, cubefacemat[i], tmp);
+ mul_m4_m4m4(evsmp->viewprojmat[i], projmat, tmp);
+ }
+
+ evsh->bias = 0.05f * la->bias;
+ evsh->near = la->clipsta;
+ evsh->far = la->clipend;
+
+ evli->shadowid = (float)(evsmp->shadow_id);
+}
+
+static void eevee_shadow_map_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
+{
+ float viewmat[4][4], projmat[4][4];
+
+ EEVEE_ShadowMapData *evsmp = (EEVEE_ShadowMapData *)led->sto;
+ EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
+ EEVEE_ShadowMap *evsh = linfo->shadow_map_data + evsmp->shadow_id;
+ Lamp *la = (Lamp *)ob->data;
+
+ invert_m4_m4(viewmat, ob->obmat);
+ normalize_v3(viewmat[0]);
+ normalize_v3(viewmat[1]);
+ normalize_v3(viewmat[2]);
+
+ float wsize = la->shadow_frustum_size;
+ orthographic_m4(projmat, -wsize, wsize, -wsize, wsize, la->clipsta, la->clipend);
+
+ mul_m4_m4m4(evsmp->viewprojmat, projmat, viewmat);
+ mul_m4_m4m4(evsh->shadowmat, texcomat, evsmp->viewprojmat);
+
+ evsh->bias = 0.005f * la->bias;
+
+ evli->shadowid = (float)(MAX_SHADOW_CUBE + evsmp->shadow_id);
+}
+
+#define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
+
+static void frustum_min_bounding_sphere(const float corners[8][4], float r_center[3], float *r_radius)
+{
+#if 0 /* Simple solution but waist too much space. */
+ float minvec[3], maxvec[3];
+
+ /* compute the bounding box */
+ INIT_MINMAX(minvec, maxvec);
+ for (int i = 0; i < 8; ++i) {
+ minmax_v3v3_v3(minvec, maxvec, corners[i]);
+ }
+
+ /* compute the bounding sphere of this box */
+ r_radius = len_v3v3(minvec, maxvec) * 0.5f;
+ add_v3_v3v3(r_center, minvec, maxvec);
+ mul_v3_fl(r_center, 0.5f);
+#else
+ /* Make the bouding sphere always centered on the front diagonal */
+ add_v3_v3v3(r_center, corners[4], corners[7]);
+ mul_v3_fl(r_center, 0.5f);
+ *r_radius = len_v3v3(corners[0], r_center);
+
+ /* Search the largest distance between the sphere center
+ * and the front plane corners. */
+ for (int i = 0; i < 4; ++i) {
+ float rad = len_v3v3(corners[4+i], r_center);
+ if (rad > *r_radius) {
+ *r_radius = rad;
+ }
+ }
+#endif
+}
+
+static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
+{
+ /* Camera Matrices */
+ float persmat[4][4], persinv[4][4];
+ float viewprojmat[4][4], projinv[4][4];
+ float near, far;
+ float near_v[4] = {0.0f, 0.0f, -1.0f, 1.0f};
+ float far_v[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+ bool is_persp = DRW_viewport_is_persp_get();
+ DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
+ invert_m4_m4(persinv, persmat);
+ /* FIXME : Get near / far from Draw manager? */
+ DRW_viewport_matrix_get(viewprojmat, DRW_MAT_WIN);
+ invert_m4_m4(projinv, viewprojmat);
+ mul_m4_v4(projinv, near_v);
+ mul_m4_v4(projinv, far_v);
+ near = near_v[2];
+ far = far_v[2]; /* TODO: Should be a shadow parameter */
+ if (is_persp) {
+ near /= near_v[3];
+ far /= far_v[3];
+ }
+
+ /* Lamps Matrices */
+ float viewmat[4][4], projmat[4][4];
+ int cascade_ct = MAX_CASCADE_NUM;
+ float shadow_res = 512.0f; /* TODO parameter */
+
+ EEVEE_ShadowCascadeData *evscp = (EEVEE_ShadowCascadeData *)led->sto;
+ EEVEE_Light *evli = linfo->light_data + evscp->light_id;
+ EEVEE_ShadowCascade *evsh = linfo->shadow_cascade_data + evscp->shadow_id;
+ Lamp *la = (Lamp *)ob->data;
+
+ /* The technique consists into splitting
+ * the view frustum into several sub-frustum
+ * that are individually receiving one shadow map */
+
+ /* init near/far */
+ for (int c = 0; c < MAX_CASCADE_NUM; ++c) {
+ evsh->split[c] = far;
+ }
+
+ /* Compute split planes */
+ float splits_ndc[MAX_CASCADE_NUM + 1];
+ splits_ndc[0] = -1.0f;
+ splits_ndc[cascade_ct] = 1.0f;
+ for (int c = 1; c < cascade_ct; ++c) {
+ const float lambda = 0.8f; /* TODO : Parameter */
+
+ /* View Space */
+ float linear_split = LERP(((float)(c) / (float)cascade_ct), near, far);
+ float exp_split = near * powf(far / near, (float)(c) / (float)cascade_ct);
+
+ if (is_persp) {
+ evsh->split[c-1] = LERP(lambda, linear_split, exp_split);
+ }
+ else {
+ evsh->split[c-1] = linear_split;
+ }
+
+ /* NDC Space */
+ float p[4] = {1.0f, 1.0f, evsh->split[c-1], 1.0f};
+ mul_m4_v4(viewprojmat, p);
+ splits_ndc[c] = p[2];
+
+ if (is_persp) {
+ splits_ndc[c] /= p[3];
+ }
+ }
+
+ /* For each cascade */
+ for (int c = 0; c < cascade_ct; ++c) {
+ /* Given 8 frustrum corners */
+ float corners[8][4] = {
+ /* Near Cap */
+ {-1.0f, -1.0f, splits_ndc[c], 1.0f},
+ { 1.0f, -1.0f, splits_ndc[c], 1.0f},
+ {-1.0f, 1.0f, splits_ndc[c], 1.0f},
+ { 1.0f, 1.0f, splits_ndc[c], 1.0f},
+ /* Far Cap */
+ {-1.0f, -1.0f, splits_ndc[c+1], 1.0f},
+ { 1.0f, -1.0f, splits_ndc[c+1], 1.0f},
+ {-1.0f, 1.0f, splits_ndc[c+1], 1.0f},
+ { 1.0f, 1.0f, splits_ndc[c+1], 1.0f}
+ };
+
+ /* Transform them into world space */
+ for (int i = 0; i < 8; ++i) {
+ mul_m4_v4(persinv, corners[i]);
+ mul_v3_fl(corners[i], 1.0f / corners[i][3]);
+ corners[i][3] = 1.0f;
+ }
+
+ /* Project them into light space */
+ invert_m4_m4(viewmat, ob->obmat);
+ normalize_v3(viewmat[0]);
+ normalize_v3(viewmat[1]);
+ normalize_v3(viewmat[2]);
+
+ for (int i = 0; i < 8; ++i) {
+ mul_m4_v4(viewmat, corners[i]);
+ }
+
+ float center[3], radius;
+ frustum_min_bounding_sphere(corners, center, &radius);
+
+ /* Snap projection center to nearest texel to cancel shimering. */
+ float shadow_origin[2], shadow_texco[2];
+ mul_v2_v2fl(shadow_origin, center, shadow_res / (2.0f * radius)); /* Light to texture space. */
+
+ /* Find the nearest texel. */
+ shadow_texco[0] = round(shadow_origin[0]);
+ shadow_texco[1] = round(shadow_origin[1]);
+
+ /* Compute offset. */
+ sub_v2_v2(shadow_texco, shadow_origin);
+ mul_v2_fl(shadow_texco, (2.0f * radius) / shadow_res); /* Texture to light space. */
+
+ /* Apply offset. */
+ add_v2_v2(center, shadow_texco);
+
+ /* Expand the projection to cover frustum range */
+ orthographic_m4(projmat,
+ center[0] - radius,
+ center[0] + radius,
+ center[1] - radius,
+ center[1] + radius,
+ la->clipsta, la->clipend);
+
+ mul_m4_m4m4(evscp->viewprojmat[c], projmat, viewmat);
+ mul_m4_m4m4(evsh->shadowmat[c], texcomat, evscp->viewprojmat[c]);
+
+ /* TODO modify bias depending on the cascade radius */
+ evsh->bias[c] = 0.005f * la->bias;
+ }
+
+ evli->shadowid = (float)(MAX_SHADOW_CUBE + MAX_SHADOW_MAP + evscp->shadow_id);
+}
+
+void EEVEE_lights_update(EEVEE_SceneLayerData *sldata)
+{
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+ Object *ob;
+ int i;
+
+ for (i = 0; (ob = linfo->light_ref[i]) && (i < MAX_LIGHT); i++) {
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+ eevee_light_setup(ob, linfo, led);
+ }
+
+ for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+ eevee_shadow_cube_setup(ob, linfo, led);
+ }
+
+ for (i = 0; (ob = linfo->shadow_map_ref[i]) && (i < MAX_SHADOW_MAP); i++) {
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+ eevee_shadow_map_setup(ob, linfo, led);
+ }
+
+ for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) {
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+ eevee_shadow_cascade_setup(ob, linfo, led);
+ }
+
+ DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data);
+ DRW_uniformbuffer_update(sldata->shadow_ubo, &linfo->shadow_cube_data); /* Update all data at once */
+}
+
+/* this refresh lamps shadow buffers */
+void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
+{
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+ Object *ob;
+ int i;
+ float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Cube Shadow Maps */
+ /* Render each shadow to one layer of the array */
+ for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+ EEVEE_ShadowCubeData *evscd = (EEVEE_ShadowCubeData *)led->sto;
+ EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
+
+ srd->layer = i;
+ copy_v3_v3(srd->position, ob->obmat[3]);
+ for (int j = 0; j < 6; ++j) {
+ copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
+ }
+ DRW_uniformbuffer_update(sldata->shadow_render_ubo, &linfo->shadow_render_data);
+
+ DRW_framebuffer_bind(sldata->shadow_cube_target_fb);
+ DRW_framebuffer_clear(true, true, false, clear_color, 1.0);
+ /* Render shadow cube */
+ DRW_draw_pass(psl->shadow_cube_pass);
+
+ /* Push it to shadowmap array */
+ DRW_framebuffer_bind(sldata->shadow_cube_fb);
+ DRW_draw_pass(psl->shadow_cube_store_pass);
+ }
+
+#if 0
+ /* Standard Shadow Maps */
+ DRW_framebuffer_bind(fbl->shadow_map_fb);
+ DRW_framebuffer_clear(false, true, false, NULL, 1.0);
+
+ /* Render each shadow to one layer of the array */
+ for (i = 0; (ob = linfo->shadow_map_ref[i]) && (i < MAX_SHADOW_MAP); i++) {
+ EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+ EEVEE_ShadowMapData *evsmd = (EEVEE_ShadowMapData *)led->sto;
+
+ linfo->layer = i;
+ copy_m4_m4(linfo->shadowmat, evsmd->viewprojmat);
+ DRW_draw_pass(vedata->psl->shadow_pass);
+ }
+#endif
+
+ /* Cascaded Shadow Maps */
+// DRW_framebuffer_bind(fbl->shadow_cascade_fb);
+// DRW_framebuffer_clear(false, true, false, NULL, 1.0);
+
+// /* Render each shadow to one layer of the array */
+// for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) {
+// EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type);
+// EEVEE_ShadowCascadeData *evscd = (EEVEE_ShadowCascadeData *)led->sto;
+// EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
+
+// srd->layer = i;
+// for (int j = 0; j < MAX_CASCADE_NUM; ++j) {
+// copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
+// }
+// DRW_uniformbuffer_update(sldata->shadow_render_ubo, &linfo->shadow_render_data);
+
+// DRW_draw_pass(psl->shadow_cascade_pass);
+// }
+}
+
+void EEVEE_lights_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_store_sh);
+}
+
+void EEVEE_scene_layer_lights_free(EEVEE_SceneLayerData *sldata)
+{
+ MEM_SAFE_FREE(sldata->lamps);
+ DRW_UBO_FREE_SAFE(sldata->light_ubo);
+ DRW_UBO_FREE_SAFE(sldata->shadow_ubo);
+ DRW_UBO_FREE_SAFE(sldata->shadow_render_ubo);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_cube_target_fb);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_cube_fb);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_map_fb);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_cascade_fb);
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cube_target);
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_color_cube_target);
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cube_pool);
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_map_pool);
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cascade_pool);
+}
diff --git a/source/blender/draw/engines/eevee/eevee_lut.h b/source/blender/draw/engines/eevee/eevee_lut.h
new file mode 100644
index 00000000000..f2b53467708
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_lut.h
@@ -0,0 +1,3347 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file eeveee_lut.h
+ * \ingroup gpu
+ */
+
+#ifndef __EEVEE_LUT_H__
+#define __EEVEE_LUT_H__
+
+static float ltc_mat_ggx[64 * 64 * 4] = {
+ 0.000200, -0.000000, 1.000000, -0.000000, 0.000504, -0.000000, 1.000000, -0.000000, 0.002016,
+ -0.000000, 1.000000, -0.000000, 0.004535, -0.000000, 1.000000, -0.000000, 0.008063, -0.000000,
+ 1.000000, -0.000000, 0.012598, -0.000000, 1.000000, -0.000000, 0.018141, -0.000000, 1.000000,
+ -0.000000, 0.024692, -0.000000, 1.000000, -0.000000, 0.032252, -0.000000, 1.000000, -0.000000,
+ 0.040821, -0.000000, 1.000000, -0.000000, 0.050400, -0.000000, 1.000000, -0.000000, 0.060989,
+ -0.000000, 1.000000, -0.000000, 0.072591, -0.000000, 1.000000, -0.000000, 0.085206, -0.000000,
+ 1.000000, -0.000000, 0.098836, -0.000000, 1.000000, -0.000000, 0.113483, -0.000000, 1.000000,
+ -0.000000, 0.129147, -0.000000, 1.000000, -0.000000, 0.145828, -0.000000, 1.000000, -0.000000,
+ 0.163499, -0.000000, 1.000000, -0.000000, 0.181972, -0.000000, 1.000000, -0.000000, 0.199498,
+ -0.000000, 1.000000, -0.000000, 0.220031, -0.000000, 1.000000, -0.000000, 0.241588, -0.000000,
+ 1.000000, -0.000000, 0.264120, -0.000000, 1.000000, -0.000000, 0.287521, -0.000000, 1.000000,
+ -0.000000, 0.311478, -0.000000, 1.000000, -0.000000, 0.335127, -0.000000, 1.000000, -0.000000,
+ 0.359811, -0.000000, 1.000000, -0.000000, 0.386446, -0.000000, 1.000000, -0.000000, 0.413161,
+ -0.000000, 1.000000, -0.000000, 0.439142, -0.000000, 1.000000, -0.000000, 0.467039, -0.000000,
+ 1.000000, -0.000000, 0.495170, -0.000000, 1.000000, -0.000000, 0.522324, -0.000000, 1.000000,
+ -0.000000, 0.551482, -0.000000, 1.000000, -0.000000, 0.579621, -0.000000, 1.000000, -0.000000,
+ 0.608255, -0.000000, 1.000000, -0.000000, 0.636515, -0.000000, 1.000000, -0.000000, 0.664835,
+ -0.000000, 1.000000, -0.000000, 0.692549, -0.000000, 1.000000, -0.000000, 0.720375, -0.000000,
+ 1.000000, -0.000000, 0.747238, -0.000000, 1.000000, -0.000000, 0.773956, -0.000000, 1.000000,
+ -0.000000, 0.799879, -0.000000, 1.000000, -0.000000, 0.824889, -0.000000, 1.000000, -0.000000,
+ 0.849357, -0.000000, 1.000000, -0.000000, 0.873016, -0.000000, 1.000000, -0.000000, 0.895670,
+ -0.000000, 1.000000, -0.000000, 0.917194, -0.000000, 1.000000, -0.000000, 0.937978, -0.000000,
+ 1.000000, -0.000000, 0.957872, -0.000000, 1.000000, -0.000000, 0.976736, -0.000000, 1.000000,
+ -0.000000, 0.994433, -0.000000, 1.000000, -0.000000, 1.011206, -0.000000, 1.000000, -0.000000,
+ 1.026820, -0.000000, 1.000000, -0.000000, 1.041720, -0.000000, 1.000000, -0.000000, 1.055657,
+ -0.000000, 1.000000, -0.000000, 1.068642, -0.000000, 1.000000, -0.000000, 1.080646, -0.000000,
+ 1.000000, -0.000000, 1.091637, -0.000000, 1.000000, -0.000000, 1.101837, -0.000000, 1.000000,
+ -0.000000, 1.111292, -0.000000, 1.000000, -0.000000, 1.120025, -0.000000, 1.000000, -0.000000,
+ 1.127918, -0.000000, 1.000000, -0.000000, 0.000200, -0.000005, 1.000623, 0.024938, 0.000504,
+ -0.000013, 1.000643, 0.024938, 0.002016, -0.000050, 1.000618, 0.024938, 0.004535, -0.000113,
+ 1.000621, 0.024938, 0.008063, -0.000201, 1.000746, 0.024938, 0.012596, -0.000314, 1.000463,
+ 0.024937, 0.018140, -0.000452, 1.000511, 0.024939, 0.024693, -0.000616, 1.000541, 0.024938,
+ 0.032253, -0.000804, 1.000684, 0.024938, 0.040815, -0.001018, 1.000524, 0.024940, 0.050399,
+ -0.001257, 1.000582, 0.024937, 0.060989, -0.001521, 1.000655, 0.024937, 0.072591, -0.001810,
+ 1.000608, 0.024938, 0.085204, -0.002125, 1.000622, 0.024939, 0.098835, -0.002465, 1.000632,
+ 0.024937, 0.113483, -0.002830, 1.000640, 0.024939, 0.129143, -0.003220, 1.000568, 0.024938,
+ 0.145830, -0.003633, 1.000635, 0.024938, 0.163497, -0.004062, 1.000626, 0.024938, 0.181956,
+ -0.004424, 1.000612, 0.024924, 0.199791, -0.004593, 1.000627, 0.024890, 0.220029, -0.005480,
+ 1.000594, 0.024935, 0.241586, -0.006010, 1.000616, 0.024933, 0.264115, -0.006550, 1.000607,
+ 0.024927, 0.287514, -0.007072, 1.000595, 0.024909, 0.311455, -0.007472, 1.000616, 0.024872,
+ 0.335083, -0.007491, 1.000589, 0.024755, 0.359805, -0.008810, 1.000601, 0.024877, 0.386438,
+ -0.009282, 1.000640, 0.024824, 0.413131, -0.009534, 1.000599, 0.024708, 0.439249, -0.009701,
+ 1.000497, 0.024573, 0.466997, -0.010878, 1.000467, 0.024652, 0.495138, -0.010959, 1.000539,
+ 0.024455, 0.522654, -0.011386, 1.000518, 0.024318, 0.551415, -0.012022, 1.000533, 0.024216,
+ 0.579610, -0.011805, 1.000495, 0.023867, 0.608185, -0.012773, 1.000474, 0.023834, 0.636492,
+ -0.012377, 1.000488, 0.023327, 0.664826, -0.013172, 1.000576, 0.023205, 0.692674, -0.012847,
+ 1.000505, 0.022708, 0.720341, -0.013141, 1.000424, 0.022349, 0.747373, -0.013227, 1.000449,
+ 0.021871, 0.773980, -0.012739, 1.000478, 0.021171, 0.799839, -0.012999, 1.000396, 0.020606,
+ 0.825113, -0.012727, 1.000425, 0.020006, 0.849579, -0.012170, 1.000469, 0.019089, 0.873046,
+ -0.011855, 1.000411, 0.018291, 0.895777, -0.011711, 1.000426, 0.017534, 0.917518, -0.011107,
+ 1.000373, 0.016542, 0.938264, -0.010439, 1.000322, 0.015512, 0.958032, -0.009807, 1.000324,
+ 0.014491, 0.976838, -0.009268, 1.000341, 0.013468, 0.994631, -0.008662, 1.000318, 0.012376,
+ 1.011434, -0.007923, 1.000289, 0.011187, 1.027169, -0.007132, 1.000216, 0.010078, 1.041929,
+ -0.006332, 1.000096, 0.008924, 1.055767, -0.005554, 1.000156, 0.007770, 1.068595, -0.004811,
+ 1.000084, 0.006611, 1.080612, -0.003950, 1.000047, 0.005485, 1.091785, -0.003174, 1.000109,
+ 0.004352, 1.101998, -0.002363, 1.000029, 0.003180, 1.111423, -0.001552, 0.999985, 0.002091,
+ 1.120007, -0.000786, 0.999947, 0.000991, 1.127918, 0.000004, 1.000000, -0.000004, 0.000200,
+ -0.000010, 1.002495, 0.049907, 0.000504, -0.000025, 1.002476, 0.049908, 0.002016, -0.000101,
+ 1.002500, 0.049908, 0.004535, -0.000226, 1.002487, 0.049908, 0.008062, -0.000402, 1.002364,
+ 0.049908, 0.012598, -0.000629, 1.002412, 0.049908, 0.018140, -0.000905, 1.002379, 0.049908,
+ 0.024691, -0.001232, 1.002490, 0.049907, 0.032251, -0.001610, 1.002398, 0.049908, 0.040821,
+ -0.002037, 1.002392, 0.049908, 0.050398, -0.002515, 1.002431, 0.049907, 0.060989, -0.003044,
+ 1.002475, 0.049908, 0.072592, -0.003623, 1.002546, 0.049907, 0.085204, -0.004252, 1.002467,
+ 0.049907, 0.098832, -0.004932, 1.002450, 0.049908, 0.113481, -0.005663, 1.002482, 0.049907,
+ 0.129145, -0.006443, 1.002443, 0.049907, 0.145825, -0.007271, 1.002495, 0.049906, 0.163491,
+ -0.008128, 1.002475, 0.049903, 0.181911, -0.008826, 1.002459, 0.049879, 0.200065, -0.009285,
+ 1.002443, 0.049824, 0.220025, -0.010966, 1.002450, 0.049897, 0.241581, -0.012025, 1.002463,
+ 0.049893, 0.264099, -0.013105, 1.002395, 0.049881, 0.287493, -0.014145, 1.002390, 0.049855,
+ 0.311399, -0.014925, 1.002414, 0.049769, 0.335096, -0.015239, 1.002363, 0.049591, 0.359815,
+ -0.017559, 1.002415, 0.049777, 0.386365, -0.018554, 1.002354, 0.049675, 0.413017, -0.019043,
+ 1.002297, 0.049444, 0.439519, -0.019815, 1.002284, 0.049253, 0.466938, -0.021741, 1.002307,
+ 0.049327, 0.494999, -0.021887, 1.002181, 0.048922, 0.522922, -0.022844, 1.002107, 0.048677,
+ 0.551270, -0.024014, 1.002101, 0.048478, 0.579771, -0.024156, 1.002060, 0.047904, 0.608156,
+ -0.025317, 1.002077, 0.047594, 0.636662, -0.025321, 1.001975, 0.046876, 0.664846, -0.026018,
+ 1.001992, 0.046354, 0.692877, -0.026041, 1.001846, 0.045504, 0.720316, -0.026252, 1.001846,
+ 0.044655, 0.747658, -0.026159, 1.001931, 0.043670, 0.774252, -0.026086, 1.001845, 0.042515,
+ 0.800179, -0.025653, 1.001794, 0.041211, 0.825525, -0.025170, 1.001787, 0.039823, 0.850013,
+ -0.024788, 1.001806, 0.038409, 0.873593, -0.023992, 1.001688, 0.036767, 0.896343, -0.022985,
+ 1.001666, 0.034900, 0.918062, -0.022005, 1.001548, 0.033010, 0.938928, -0.021110, 1.001503,
+ 0.031143, 0.958667, -0.019893, 1.001341, 0.029059, 0.977457, -0.018546, 1.001194, 0.026888,
+ 0.995243, -0.017152, 1.001095, 0.024713, 1.012023, -0.015750, 1.001100, 0.022496, 1.027614,
+ -0.014289, 1.000851, 0.020153, 1.042389, -0.012688, 1.000724, 0.017839, 1.056161, -0.011118,
+ 1.000572, 0.015529, 1.068968, -0.009540, 1.000407, 0.013240, 1.080866, -0.007963, 1.000258,
+ 0.010940, 1.091944, -0.006416, 1.000254, 0.008716, 1.102104, -0.004771, 1.000175, 0.006434,
+ 1.111571, -0.003056, 1.000148, 0.004169, 1.120084, -0.001458, 1.000050, 0.002033, 1.127981,
+ 0.000021, 0.999987, -0.000027, 0.000200, -0.000015, 1.005620, 0.074940, 0.000504, -0.000038,
+ 1.005650, 0.074939, 0.002016, -0.000151, 1.005613, 0.074939, 0.004535, -0.000340, 1.005618,
+ 0.074939, 0.008062, -0.000604, 1.005614, 0.074939, 0.012597, -0.000944, 1.005616, 0.074940,
+ 0.018141, -0.001359, 1.005558, 0.074939, 0.024695, -0.001851, 1.005495, 0.074940, 0.032253,
+ -0.002417, 1.005616, 0.074939, 0.040822, -0.003059, 1.005591, 0.074940, 0.050399, -0.003777,
+ 1.005596, 0.074940, 0.060989, -0.004570, 1.005599, 0.074939, 0.072591, -0.005440, 1.005616,
+ 0.074940, 0.085203, -0.006385, 1.005616, 0.074939, 0.098833, -0.007406, 1.005595, 0.074938,
+ 0.113481, -0.008502, 1.005605, 0.074938, 0.129147, -0.009674, 1.005605, 0.074937, 0.145817,
+ -0.010916, 1.005513, 0.074937, 0.163485, -0.012199, 1.005579, 0.074928, 0.181824, -0.013172,
+ 1.005552, 0.074885, 0.200274, -0.014100, 1.005524, 0.074825, 0.220017, -0.016464, 1.005529,
+ 0.074928, 0.241568, -0.018052, 1.005490, 0.074914, 0.264084, -0.019671, 1.005457, 0.074898,
+ 0.287450, -0.021217, 1.005431, 0.074860, 0.311281, -0.022341, 1.005395, 0.074717, 0.335228,
+ -0.023296, 1.005320, 0.074526, 0.360047, -0.025965, 1.005302, 0.074649, 0.386273, -0.027808,
+ 1.005285, 0.074575, 0.412855, -0.028504, 1.005167, 0.074237, 0.439705, -0.030007, 1.005129,
+ 0.074013, 0.466975, -0.032263, 1.005082, 0.073967, 0.494874, -0.032931, 1.004960, 0.073475,
+ 0.523066, -0.034348, 1.004834, 0.073084, 0.551198, -0.035739, 1.004806, 0.072657, 0.579889,
+ -0.036575, 1.004687, 0.072029, 0.608282, -0.037434, 1.004605, 0.071309, 0.636812, -0.038323,
+ 1.004589, 0.070507, 0.665010, -0.038676, 1.004403, 0.069424, 0.693063, -0.039237, 1.004340,
+ 0.068370, 0.720750, -0.039332, 1.004224, 0.066988, 0.747911, -0.039179, 1.004117, 0.065447,
+ 0.774576, -0.039110, 1.004035, 0.063838, 0.800737, -0.038542, 1.004027, 0.061923, 0.825966,
+ -0.037966, 1.003825, 0.059859, 0.850534, -0.036943, 1.003786, 0.057529, 0.874289, -0.035853,
+ 1.003560, 0.055081, 0.897152, -0.034730, 1.003549, 0.052476, 0.919029, -0.033242, 1.003454,
+ 0.049647, 0.939851, -0.031508, 1.003215, 0.046670, 0.959599, -0.029695, 1.002916, 0.043588,
+ 0.978293, -0.027845, 1.002720, 0.040401, 0.996085, -0.025775, 1.002445, 0.037060, 1.012768,
+ -0.023607, 1.002133, 0.033726, 1.028404, -0.021374, 1.001822, 0.030217, 1.043150, -0.019108,
+ 1.001602, 0.026820, 1.056760, -0.016823, 1.001274, 0.023372, 1.069471, -0.014378, 1.000964,
+ 0.019891, 1.081283, -0.011884, 1.000684, 0.016405, 1.092238, -0.009398, 1.000514, 0.012950,
+ 1.102384, -0.007030, 1.000319, 0.009579, 1.111737, -0.004751, 1.000225, 0.006384, 1.120274,
+ -0.002404, 1.000046, 0.003192, 1.128182, 0.000031, 1.000020, 0.000033, 0.000200, -0.000020,
+ 1.010006, 0.100065, 0.000504, -0.000050, 1.009927, 0.100065, 0.002016, -0.000202, 1.010026,
+ 0.100064, 0.004535, -0.000454, 1.010018, 0.100065, 0.008062, -0.000807, 1.009891, 0.100064,
+ 0.012599, -0.001261, 1.010175, 0.100064, 0.018141, -0.001815, 1.010067, 0.100065, 0.024692,
+ -0.002471, 1.010014, 0.100066, 0.032251, -0.003227, 1.009950, 0.100065, 0.040818, -0.004084,
+ 1.009963, 0.100067, 0.050401, -0.005043, 1.010032, 0.100064, 0.060988, -0.006102, 1.009979,
+ 0.100064, 0.072588, -0.007263, 1.009984, 0.100063, 0.085205, -0.008525, 1.010023, 0.100063,
+ 0.098832, -0.009888, 1.009960, 0.100062, 0.113479, -0.011352, 1.009974, 0.100063, 0.129142,
+ -0.012916, 1.009945, 0.100062, 0.145817, -0.014573, 1.009924, 0.100058, 0.163468, -0.016276,
+ 1.009912, 0.100050, 0.181674, -0.017411, 1.009859, 0.099975, 0.200435, -0.019002, 1.009842,
+ 0.099932, 0.220005, -0.021978, 1.009820, 0.100043, 0.241550, -0.024096, 1.009778, 0.100031,
+ 0.264058, -0.026250, 1.009765, 0.100002, 0.287399, -0.028286, 1.009724, 0.099939, 0.311134,
+ -0.029698, 1.009596, 0.099748, 0.335350, -0.031442, 1.009508, 0.099582, 0.360295, -0.034401,
+ 1.009475, 0.099613, 0.386112, -0.037030, 1.009329, 0.099558, 0.412733, -0.038163, 1.009250,
+ 0.099137, 0.439833, -0.040250, 1.009125, 0.098866, 0.467099, -0.042583, 1.009011, 0.098626,
+ 0.494828, -0.044299, 1.008803, 0.098149, 0.523217, -0.045876, 1.008712, 0.097600, 0.551338,
+ -0.047440, 1.008509, 0.096929, 0.579917, -0.048995, 1.008371, 0.096178, 0.608454, -0.049901,
+ 1.008212, 0.095145, 0.636785, -0.051224, 1.007963, 0.094151, 0.665220, -0.051675, 1.007741,
+ 0.092728, 0.693194, -0.052278, 1.007616, 0.091195, 0.721008, -0.052406, 1.007327, 0.089384,
+ 0.748196, -0.052529, 1.007219, 0.087461, 0.774975, -0.051950, 1.006851, 0.085133, 0.801129,
+ -0.051456, 1.006732, 0.082628, 0.826668, -0.050569, 1.006612, 0.079817, 0.851291, -0.049328,
+ 1.006374, 0.076710, 0.875056, -0.047988, 1.006183, 0.073481, 0.897872, -0.046149, 1.005742,
+ 0.069943, 0.919803, -0.044144, 1.005514, 0.066151, 0.940701, -0.042095, 1.005153, 0.062247,
+ 0.960580, -0.039730, 1.004843, 0.058158, 0.979427, -0.037104, 1.004535, 0.053850, 0.997157,
+ -0.034369, 1.004023, 0.049403, 1.013777, -0.031555, 1.003622, 0.044944, 1.029452, -0.028571,
+ 1.003212, 0.040414, 1.044029, -0.025416, 1.002698, 0.035723, 1.057586, -0.022217, 1.002202,
+ 0.031072, 1.070148, -0.019037, 1.001703, 0.026429, 1.081875, -0.015936, 1.001322, 0.021896,
+ 1.092789, -0.012734, 1.001053, 0.017288, 1.102704, -0.009454, 1.000604, 0.012841, 1.112011,
+ -0.006199, 1.000387, 0.008446, 1.120590, -0.003010, 1.000166, 0.004122, 1.128283, 0.000027,
+ 0.999956, -0.000038, 0.000200, -0.000025, 1.015664, 0.125315, 0.000504, -0.000063, 1.015664,
+ 0.125316, 0.002016, -0.000253, 1.015727, 0.125315, 0.004535, -0.000568, 1.015695, 0.125314,
+ 0.008063, -0.001010, 1.015823, 0.125316, 0.012599, -0.001579, 1.015867, 0.125315, 0.018141,
+ -0.002273, 1.015758, 0.125316, 0.024691, -0.003094, 1.015662, 0.125316, 0.032252, -0.004042,
+ 1.015674, 0.125316, 0.040820, -0.005115, 1.015678, 0.125316, 0.050400, -0.006316, 1.015684,
+ 0.125315, 0.060989, -0.007642, 1.015685, 0.125315, 0.072590, -0.009096, 1.015703, 0.125314,
+ 0.085203, -0.010676, 1.015654, 0.125314, 0.098833, -0.012383, 1.015670, 0.125315, 0.113477,
+ -0.014215, 1.015635, 0.125312, 0.129138, -0.016173, 1.015599, 0.125311, 0.145815, -0.018246,
+ 1.015610, 0.125306, 0.163450, -0.020360, 1.015564, 0.125294, 0.181595, -0.021807, 1.015460,
+ 0.125204, 0.200563, -0.023971, 1.015440, 0.125165, 0.220186, -0.027280, 1.015412, 0.125250,
+ 0.241528, -0.030164, 1.015342, 0.125267, 0.264020, -0.032847, 1.015269, 0.125233, 0.287311,
+ -0.035345, 1.015232, 0.125138, 0.310993, -0.037108, 1.015063, 0.124903, 0.335467, -0.039653,
+ 1.014970, 0.124749, 0.360497, -0.042914, 1.014819, 0.124702, 0.385986, -0.046142, 1.014685,
+ 0.124623, 0.412703, -0.048050, 1.014543, 0.124193, 0.439929, -0.050527, 1.014315, 0.123833,
+ 0.467163, -0.052880, 1.014087, 0.123375, 0.494824, -0.055672, 1.013898, 0.122982, 0.523222,
+ -0.057388, 1.013647, 0.122166, 0.551557, -0.059328, 1.013403, 0.121343, 0.579884, -0.061315,
+ 1.013059, 0.120430, 0.608619, -0.062531, 1.012745, 0.119140, 0.637014, -0.063778, 1.012425,
+ 0.117721, 0.665425, -0.064734, 1.012067, 0.116069, 0.693580, -0.065315, 1.011712, 0.114146,
+ 0.721194, -0.065535, 1.011200, 0.111846, 0.748586, -0.065501, 1.010896, 0.109309, 0.775437,
+ -0.065091, 1.010576, 0.106504, 0.801554, -0.064332, 1.010136, 0.103308, 0.827079, -0.063078,
+ 1.009629, 0.099695, 0.851693, -0.061728, 1.009233, 0.095946, 0.875586, -0.059853, 1.008726,
+ 0.091802, 0.898589, -0.057727, 1.008412, 0.087339, 0.920421, -0.055377, 1.007767, 0.082687,
+ 0.941533, -0.052571, 1.007529, 0.077716, 0.961426, -0.049544, 1.006929, 0.072574, 0.980287,
+ -0.046400, 1.006393, 0.067217, 0.998080, -0.042966, 1.005872, 0.061757, 1.014940, -0.039321,
+ 1.005346, 0.056072, 1.030455, -0.035585, 1.004609, 0.050410, 1.045078, -0.031823, 1.004151,
+ 0.044622, 1.058555, -0.027947, 1.003421, 0.038893, 1.071009, -0.023891, 1.002704, 0.032977,
+ 1.082594, -0.019822, 1.002023, 0.027290, 1.093265, -0.015765, 1.001403, 0.021543, 1.103132,
+ -0.011790, 1.000944, 0.016072, 1.112348, -0.007784, 1.000550, 0.010511, 1.120845, -0.003849,
+ 1.000224, 0.005174, 1.128573, 0.000057, 0.999975, -0.000039, 0.000200, -0.000030, 1.022609,
+ 0.150725, 0.000504, -0.000076, 1.022728, 0.150725, 0.002016, -0.000304, 1.022728, 0.150725,
+ 0.004535, -0.000684, 1.022733, 0.150725, 0.008062, -0.001215, 1.022715, 0.150725, 0.012598,
+ -0.001899, 1.022720, 0.150725, 0.018141, -0.002734, 1.022659, 0.150725, 0.024694, -0.003722,
+ 1.022801, 0.150724, 0.032254, -0.004861, 1.022779, 0.150726, 0.040815, -0.006152, 1.022693,
+ 0.150724, 0.050400, -0.007596, 1.022716, 0.150725, 0.060990, -0.009192, 1.022733, 0.150725,
+ 0.072587, -0.010939, 1.022630, 0.150723, 0.085203, -0.012839, 1.022676, 0.150725, 0.098828,
+ -0.014891, 1.022659, 0.150725, 0.113473, -0.017095, 1.022589, 0.150720, 0.129137, -0.019449,
+ 1.022572, 0.150716, 0.145803, -0.021938, 1.022508, 0.150712, 0.163417, -0.024443, 1.022471,
+ 0.150691, 0.181580, -0.026329, 1.022406, 0.150600, 0.200667, -0.028997, 1.022336, 0.150553,
+ 0.220429, -0.032584, 1.022296, 0.150610, 0.241497, -0.036260, 1.022202, 0.150658, 0.263975,
+ -0.039465, 1.022119, 0.150619, 0.287210, -0.042385, 1.021988, 0.150490, 0.310935, -0.044758,
+ 1.021771, 0.150241, 0.335556, -0.047922, 1.021658, 0.150076, 0.360667, -0.051493, 1.021437,
+ 0.149931, 0.386028, -0.054931, 1.021228, 0.149754, 0.412665, -0.058007, 1.021023, 0.149400,
+ 0.439951, -0.060813, 1.020723, 0.148913, 0.467262, -0.063461, 1.020332, 0.148319, 0.494972,
+ -0.066738, 1.020097, 0.147798, 0.523153, -0.068976, 1.019630, 0.146903, 0.551700, -0.071268,
+ 1.019245, 0.145863, 0.580046, -0.073439, 1.018797, 0.144695, 0.608649, -0.075193, 1.018201,
+ 0.143237, 0.637239, -0.076536, 1.017746, 0.141463, 0.665388, -0.077771, 1.017111, 0.139462,
+ 0.693755, -0.078344, 1.016609, 0.137082, 0.721345, -0.078817, 1.015863, 0.134403, 0.748879,
+ -0.078512, 1.015390, 0.131252, 0.775560, -0.078128, 1.014652, 0.127866, 0.801897, -0.077094,
+ 1.013877, 0.123928, 0.827193, -0.075863, 1.013021, 0.119733, 0.851990, -0.073973, 1.012395,
+ 0.115055, 0.875823, -0.071765, 1.011595, 0.110098, 0.898655, -0.069241, 1.010862, 0.104722,
+ 0.920915, -0.066232, 1.010185, 0.098991, 0.941969, -0.062980, 1.009588, 0.093044, 0.961882,
+ -0.059507, 1.008777, 0.086925, 0.980952, -0.055606, 1.008252, 0.080520, 0.998955, -0.051503,
+ 1.007633, 0.073890, 1.015756, -0.047292, 1.006908, 0.067302, 1.031571, -0.042804, 1.006338,
+ 0.060412, 1.046095, -0.038132, 1.005512, 0.053497, 1.059542, -0.033380, 1.004592, 0.046569,
+ 1.072006, -0.028613, 1.003731, 0.039679, 1.083348, -0.023811, 1.002871, 0.032772, 1.093969,
+ -0.018930, 1.002068, 0.025894, 1.103697, -0.014098, 1.001284, 0.019178, 1.112813, -0.009339,
+ 1.000820, 0.012652, 1.121193, -0.004661, 1.000324, 0.006226, 1.128930, 0.000052, 0.999988,
+ -0.000008, 0.000200, -0.000035, 1.030857, 0.176327, 0.000504, -0.000089, 1.031137, 0.176326,
+ 0.002016, -0.000355, 1.031049, 0.176325, 0.004535, -0.000800, 1.031105, 0.176326, 0.008062,
+ -0.001422, 1.030973, 0.176326, 0.012598, -0.002221, 1.031168, 0.176326, 0.018141, -0.003199,
+ 1.031093, 0.176326, 0.024695, -0.004354, 1.031297, 0.176326, 0.032253, -0.005687, 1.031091,
+ 0.176327, 0.040821, -0.007197, 1.031012, 0.176326, 0.050399, -0.008886, 1.031068, 0.176325,
+ 0.060987, -0.010752, 1.030967, 0.176323, 0.072588, -0.012797, 1.031028, 0.176324, 0.085200,
+ -0.015019, 1.030985, 0.176322, 0.098829, -0.017419, 1.030983, 0.176320, 0.113474, -0.019997,
+ 1.030953, 0.176317, 0.129133, -0.022748, 1.030891, 0.176312, 0.145800, -0.025655, 1.030825,
+ 0.176306, 0.163372, -0.028510, 1.030781, 0.176279, 0.181578, -0.030914, 1.030683, 0.176187,
+ 0.200761, -0.034076, 1.030574, 0.176139, 0.220645, -0.037985, 1.030476, 0.176160, 0.241473,
+ -0.042391, 1.030384, 0.176238, 0.263922, -0.046105, 1.030241, 0.176175, 0.287074, -0.049390,
+ 1.030049, 0.176013, 0.310915, -0.052511, 1.029839, 0.175776, 0.335604, -0.056236, 1.029608,
+ 0.175578, 0.360775, -0.060118, 1.029355, 0.175359, 0.386196, -0.063907, 1.029052, 0.175083,
+ 0.412599, -0.067997, 1.028766, 0.174791, 0.439916, -0.071088, 1.028326, 0.174174, 0.467444,
+ -0.074247, 1.027890, 0.173487, 0.495132, -0.077728, 1.027374, 0.172774, 0.523117, -0.080822,
+ 1.026763, 0.171824, 0.551783, -0.083228, 1.026205, 0.170554, 0.580234, -0.085682, 1.025614,
+ 0.169090, 0.608568, -0.087860, 1.024668, 0.167468, 0.637357, -0.089346, 1.023939, 0.165283,
+ 0.665507, -0.090704, 1.022946, 0.162966, 0.693704, -0.091388, 1.022010, 0.160131, 0.721396,
+ -0.091783, 1.021085, 0.156957, 0.748676, -0.091688, 1.019894, 0.153292, 0.775370, -0.090992,
+ 1.018608, 0.149158, 0.801547, -0.089881, 1.017646, 0.144551, 0.827013, -0.088267, 1.016355,
+ 0.139614, 0.851708, -0.086132, 1.015446, 0.134026, 0.875652, -0.083707, 1.014321, 0.128101,
+ 0.898703, -0.080619, 1.013454, 0.121841, 0.920904, -0.077280, 1.012634, 0.115379, 0.942077,
+ -0.073484, 1.011770, 0.108355, 0.962245, -0.069252, 1.010894, 0.101153, 0.981385, -0.064807,
+ 1.010114, 0.093666, 0.999379, -0.060080, 1.009294, 0.086007, 1.016494, -0.055007, 1.008591,
+ 0.078194, 1.032357, -0.049760, 1.007821, 0.070328, 1.047061, -0.044468, 1.006871, 0.062358,
+ 1.060675, -0.038960, 1.006062, 0.054279, 1.073032, -0.033343, 1.004911, 0.046158, 1.084293,
+ -0.027699, 1.003791, 0.038111, 1.094724, -0.022130, 1.002744, 0.030239, 1.104302, -0.016508,
+ 1.001815, 0.022397, 1.113290, -0.010846, 1.001083, 0.014747, 1.121649, -0.005294, 1.000490,
+ 0.007234, 1.129230, 0.000071, 0.999975, -0.000053, 0.000200, -0.000040, 1.040431, 0.202155,
+ 0.000504, -0.000102, 1.040912, 0.202154, 0.002016, -0.000407, 1.041328, 0.202152, 0.004535,
+ -0.000917, 1.040877, 0.202154, 0.008063, -0.001630, 1.040867, 0.202153, 0.012598, -0.002547,
+ 1.040870, 0.202153, 0.018140, -0.003667, 1.040808, 0.202153, 0.024692, -0.004991, 1.040861,
+ 0.202153, 0.032252, -0.006519, 1.040861, 0.202153, 0.040822, -0.008252, 1.040864, 0.202153,
+ 0.050397, -0.010187, 1.040717, 0.202151, 0.060988, -0.012327, 1.040791, 0.202152, 0.072582,
+ -0.014669, 1.040640, 0.202149, 0.085198, -0.017217, 1.040716, 0.202147, 0.098827, -0.019968,
+ 1.040748, 0.202141, 0.113467, -0.022921, 1.040632, 0.202142, 0.129129, -0.026074, 1.040606,
+ 0.202137, 0.145793, -0.029399, 1.040566, 0.202127, 0.163294, -0.032524, 1.040459, 0.202078,
+ 0.181589, -0.035552, 1.040315, 0.201996, 0.200844, -0.039208, 1.040221, 0.201948, 0.220835,
+ -0.043489, 1.040047, 0.201945, 0.241471, -0.048523, 1.039921, 0.202031, 0.263854, -0.052764,
+ 1.039756, 0.201957, 0.286935, -0.056387, 1.039497, 0.201743, 0.310902, -0.060338, 1.039252,
+ 0.201531, 0.335642, -0.064594, 1.038954, 0.201286, 0.360859, -0.068772, 1.038582, 0.200983,
+ 0.386419, -0.073086, 1.038160, 0.200651, 0.412588, -0.077887, 1.037724, 0.200343, 0.439836,
+ -0.081391, 1.037182, 0.199618, 0.467538, -0.085121, 1.036602, 0.198839, 0.495286, -0.088718,
+ 1.035893, 0.197895, 0.523231, -0.092514, 1.035121, 0.196887, 0.551730, -0.095238, 1.034127,
+ 0.195390, 0.580302, -0.097949, 1.033131, 0.193668, 0.608559, -0.100418, 1.031962, 0.191773,
+ 0.637224, -0.102129, 1.030838, 0.189319, 0.665597, -0.103578, 1.029511, 0.186529, 0.693535,
+ -0.104652, 1.028263, 0.183303, 0.721325, -0.104766, 1.026611, 0.179497, 0.748384, -0.104717,
+ 1.025128, 0.175283, 0.775058, -0.103846, 1.023385, 0.170493, 0.801387, -0.102728, 1.022236,
+ 0.165187, 0.826412, -0.100679, 1.019908, 0.159362, 0.851314, -0.098451, 1.018839, 0.153059,
+ 0.875100, -0.095363, 1.017306, 0.146284, 0.898280, -0.092008, 1.016151, 0.138975, 0.920450,
+ -0.088095, 1.014880, 0.131361, 0.941727, -0.083690, 1.013556, 0.123417, 0.962308, -0.079077,
+ 1.012998, 0.115201, 0.981364, -0.073894, 1.011841, 0.106711, 0.999798, -0.068435, 1.011021,
+ 0.098063, 1.016983, -0.062830, 1.010194, 0.089183, 1.033039, -0.056914, 1.009292, 0.080190,
+ 1.047994, -0.050721, 1.008474, 0.071010, 1.061580, -0.044454, 1.007386, 0.061867, 1.074023,
+ -0.038145, 1.006135, 0.052711, 1.085470, -0.031679, 1.004890, 0.043595, 1.095673, -0.025157,
+ 1.003627, 0.034506, 1.105000, -0.018702, 1.002331, 0.025468, 1.113795, -0.012458, 1.001278,
+ 0.016834, 1.122012, -0.006169, 1.000548, 0.008265, 1.129683, 0.000078, 0.999988, -0.000072,
+ 0.000200, -0.000046, 1.052496, 0.228243, 0.000504, -0.000115, 1.052079, 0.228243, 0.002016,
+ -0.000460, 1.052079, 0.228241, 0.004535, -0.001035, 1.052091, 0.228242, 0.008062, -0.001840,
+ 1.051962, 0.228242, 0.012598, -0.002875, 1.052087, 0.228242, 0.018141, -0.004140, 1.052088,
+ 0.228242, 0.024692, -0.005636, 1.052096, 0.228239, 0.032251, -0.007361, 1.052029, 0.228243,
+ 0.040820, -0.009316, 1.052038, 0.228241, 0.050399, -0.011501, 1.052042, 0.228239, 0.060990,
+ -0.013917, 1.052046, 0.228238, 0.072586, -0.016562, 1.051990, 0.228236, 0.085198, -0.019437,
+ 1.051946, 0.228234, 0.098824, -0.022542, 1.051879, 0.228229, 0.113467, -0.025875, 1.051841,
+ 0.228227, 0.129121, -0.029430, 1.051724, 0.228219, 0.145780, -0.033170, 1.051672, 0.228205,
+ 0.163222, -0.036567, 1.051556, 0.228143, 0.181604, -0.040245, 1.051382, 0.228069, 0.200913,
+ -0.044395, 1.051230, 0.228010, 0.221005, -0.049088, 1.051062, 0.227988, 0.241667, -0.054506,
+ 1.050881, 0.228044, 0.263777, -0.059437, 1.050643, 0.227986, 0.286841, -0.063590, 1.050312,
+ 0.227755, 0.310879, -0.068224, 1.050009, 0.227525, 0.335650, -0.072986, 1.049597, 0.227253,
+ 0.360869, -0.077435, 1.049121, 0.226845, 0.386609, -0.082385, 1.048587, 0.226466, 0.412742,
+ -0.087570, 1.047987, 0.226059, 0.439789, -0.091929, 1.047308, 0.225331, 0.467558, -0.096038,
+ 1.046423, 0.224409, 0.495406, -0.099938, 1.045481, 0.223288, 0.523417, -0.104050, 1.044512,
+ 0.222066, 0.551755, -0.107503, 1.043408, 0.220487, 0.580468, -0.110234, 1.042016, 0.218451,
+ 0.608904, -0.112993, 1.040535, 0.216200, 0.637230, -0.115173, 1.038934, 0.213458, 0.665566,
+ -0.116433, 1.036961, 0.210158, 0.693413, -0.117589, 1.035130, 0.206457, 0.721025, -0.117885,
+ 1.033080, 0.202197, 0.748054, -0.117606, 1.030752, 0.197296, 0.774631, -0.116771, 1.028608,
+ 0.191813, 0.800677, -0.115194, 1.026350, 0.185691, 0.826062, -0.113138, 1.024472, 0.179053,
+ 0.850590, -0.110359, 1.022174, 0.171839, 0.874550, -0.107072, 1.020381, 0.164067, 0.897567,
+ -0.103268, 1.018777, 0.155959, 0.919609, -0.098794, 1.016886, 0.147320, 0.941177, -0.094067,
+ 1.015880, 0.138365, 0.961752, -0.088670, 1.014616, 0.129051, 0.981518, -0.082965, 1.013807,
+ 0.119515, 0.999880, -0.076971, 1.012793, 0.109897, 1.017370, -0.070518, 1.011894, 0.099872,
+ 1.033661, -0.063830, 1.010943, 0.089883, 1.048672, -0.057040, 1.009802, 0.079691, 1.062479,
+ -0.049917, 1.008670, 0.069458, 1.075052, -0.042735, 1.007429, 0.059191, 1.086371, -0.035513,
+ 1.005991, 0.048894, 1.096623, -0.028359, 1.004468, 0.038770, 1.105871, -0.021111, 1.002927,
+ 0.028745, 1.114481, -0.013908, 1.001728, 0.018884, 1.122610, -0.006843, 1.000740, 0.009264,
+ 1.130165, 0.000062, 0.999983, -0.000006, 0.000200, -0.000051, 1.064931, 0.254630, 0.000504,
+ -0.000128, 1.064668, 0.254630, 0.002016, -0.000513, 1.064794, 0.254630, 0.004535, -0.001155,
+ 1.064851, 0.254630, 0.008063, -0.002053, 1.064966, 0.254630, 0.012598, -0.003208, 1.064840,
+ 0.254630, 0.018140, -0.004619, 1.064602, 0.254631, 0.024695, -0.006288, 1.064965, 0.254632,
+ 0.032251, -0.008211, 1.064795, 0.254630, 0.040821, -0.010393, 1.064802, 0.254628, 0.050398,
+ -0.012830, 1.064758, 0.254627, 0.060987, -0.015525, 1.064731, 0.254625, 0.072584, -0.018474,
+ 1.064615, 0.254621, 0.085199, -0.021682, 1.064672, 0.254619, 0.098826, -0.025144, 1.064630,
+ 0.254613, 0.113465, -0.028860, 1.064515, 0.254606, 0.129119, -0.032823, 1.064416, 0.254598,
+ 0.145767, -0.036969, 1.064347, 0.254579, 0.163190, -0.040754, 1.064132, 0.254506, 0.181622,
+ -0.044989, 1.063951, 0.254437, 0.200981, -0.049642, 1.063745, 0.254370, 0.221145, -0.054776,
+ 1.063547, 0.254324, 0.241896, -0.060538, 1.063289, 0.254346, 0.263684, -0.066113, 1.063013,
+ 0.254296, 0.286796, -0.070925, 1.062625, 0.254059, 0.310867, -0.076187, 1.062216, 0.253817,
+ 0.335644, -0.081406, 1.061703, 0.253481, 0.360917, -0.086336, 1.061066, 0.253005, 0.386786,
+ -0.091790, 1.060454, 0.252558, 0.412921, -0.097230, 1.059568, 0.252008, 0.439722, -0.102574,
+ 1.058706, 0.251323, 0.467559, -0.106972, 1.057682, 0.250239, 0.495605, -0.111329, 1.056612,
+ 0.248944, 0.523589, -0.115561, 1.055101, 0.247471, 0.551787, -0.119732, 1.053745, 0.245777,
+ 0.580426, -0.122711, 1.051829, 0.243448, 0.608778, -0.125436, 1.049642, 0.240769, 0.637069,
+ -0.127993, 1.047749, 0.237739, 0.665251, -0.129448, 1.045244, 0.233928, 0.692977, -0.130408,
+ 1.042279, 0.229640, 0.720346, -0.130931, 1.039693, 0.224829, 0.747365, -0.130392, 1.036675,
+ 0.219144, 0.773734, -0.129540, 1.033719, 0.212965, 0.799578, -0.127689, 1.030774, 0.206047,
+ 0.825002, -0.125456, 1.028551, 0.198576, 0.849564, -0.122291, 1.025800, 0.190471, 0.873412,
+ -0.118720, 1.023657, 0.181739, 0.896628, -0.114323, 1.021381, 0.172586, 0.918952, -0.109587,
+ 1.019674, 0.162914, 0.940602, -0.104093, 1.018126, 0.153039, 0.960917, -0.098187, 1.016339,
+ 0.142774, 0.980911, -0.091963, 1.015440, 0.132316, 0.999686, -0.085159, 1.014377, 0.121453,
+ 1.017538, -0.078139, 1.013498, 0.110527, 1.033918, -0.070797, 1.012332, 0.099437, 1.049390,
+ -0.063129, 1.011368, 0.088157, 1.063402, -0.055354, 1.010111, 0.076951, 1.076096, -0.047522,
+ 1.008774, 0.065616, 1.087562, -0.039447, 1.007202, 0.054310, 1.097591, -0.031359, 1.005346,
+ 0.042948, 1.106782, -0.023393, 1.003710, 0.031799, 1.115234, -0.015461, 1.002116, 0.020943,
+ 1.123166, -0.007589, 1.000858, 0.010288, 1.130796, 0.000104, 1.000032, -0.000024, 0.000200,
+ -0.000056, 1.078780, 0.281356, 0.000504, -0.000142, 1.079271, 0.281355, 0.002015, -0.000567,
+ 1.078635, 0.281355, 0.004535, -0.001276, 1.079164, 0.281356, 0.008064, -0.002269, 1.079300,
+ 0.281355, 0.012598, -0.003544, 1.079149, 0.281355, 0.018143, -0.005104, 1.079329, 0.281355,
+ 0.024691, -0.006947, 1.079073, 0.281353, 0.032254, -0.009074, 1.079253, 0.281354, 0.040822,
+ -0.011484, 1.079176, 0.281353, 0.050399, -0.014177, 1.079057, 0.281349, 0.060987, -0.017153,
+ 1.079007, 0.281347, 0.072586, -0.020412, 1.078998, 0.281343, 0.085203, -0.023956, 1.078962,
+ 0.281336, 0.098823, -0.027778, 1.078839, 0.281332, 0.113464, -0.031882, 1.078783, 0.281325,
+ 0.129114, -0.036255, 1.078633, 0.281315, 0.145748, -0.040790, 1.078545, 0.281287, 0.163179,
+ -0.045024, 1.078311, 0.281208, 0.181649, -0.049791, 1.078135, 0.281137, 0.201042, -0.054953,
+ 1.077845, 0.281063, 0.221267, -0.060551, 1.077576, 0.281006, 0.242114, -0.066663, 1.077257,
+ 0.280978, 0.263568, -0.072771, 1.076897, 0.280925, 0.286744, -0.078349, 1.076405, 0.280689,
+ 0.310840, -0.084201, 1.075898, 0.280418, 0.335612, -0.089846, 1.075287, 0.280020, 0.360975,
+ -0.095394, 1.074482, 0.279513, 0.386932, -0.101290, 1.073617, 0.278961, 0.413171, -0.107042,
+ 1.072719, 0.278283, 0.439886, -0.113083, 1.071698, 0.277547, 0.467535, -0.118010, 1.070213,
+ 0.276311, 0.495701, -0.122793, 1.068857, 0.274867, 0.523772, -0.127278, 1.067037, 0.273153,
+ 0.551849, -0.131671, 1.064923, 0.271176, 0.580338, -0.135293, 1.062749, 0.268626, 0.608771,
+ -0.138065, 1.059944, 0.265569, 0.636756, -0.140565, 1.056851, 0.262054, 0.664574, -0.142434,
+ 1.053461, 0.257807, 0.692151, -0.143237, 1.049910, 0.252930, 0.719376, -0.143717, 1.046426,
+ 0.247414, 0.745852, -0.143117, 1.042377, 0.241001, 0.772300, -0.141975, 1.038789, 0.233797,
+ 0.798050, -0.140114, 1.035290, 0.226218, 0.823370, -0.137379, 1.032374, 0.217785, 0.847735,
+ -0.134119, 1.028853, 0.208748, 0.871897, -0.129985, 1.026395, 0.198877, 0.894950, -0.125324,
+ 1.023787, 0.188803, 0.917909, -0.120007, 1.022073, 0.178493, 0.939567, -0.114099, 1.020098,
+ 0.167466, 0.960534, -0.107748, 1.018851, 0.156223, 0.980423, -0.100748, 1.017362, 0.144716,
+ 0.999334, -0.093494, 1.015961, 0.133028, 1.017561, -0.085728, 1.015059, 0.120953, 1.034225,
+ -0.077627, 1.013888, 0.108943, 1.049937, -0.069375, 1.012898, 0.096678, 1.064265, -0.060807,
+ 1.011635, 0.084350, 1.077188, -0.052052, 1.010095, 0.071964, 1.088637, -0.043304, 1.008399,
+ 0.059531, 1.098766, -0.034458, 1.006397, 0.047134, 1.107697, -0.025637, 1.004354, 0.034887,
+ 1.116055, -0.016932, 1.002611, 0.022948, 1.123819, -0.008437, 1.001023, 0.011386, 1.131333,
+ 0.000087, 0.999952, -0.000097, 0.000200, -0.000062, 1.095622, 0.308458, 0.000504, -0.000155,
+ 1.094863, 0.308458, 0.002016, -0.000622, 1.095169, 0.308458, 0.004535, -0.001399, 1.095156,
+ 0.308458, 0.008063, -0.002487, 1.095413, 0.308455, 0.012598, -0.003886, 1.095147, 0.308458,
+ 0.018141, -0.005596, 1.095150, 0.308457, 0.024692, -0.007616, 1.095140, 0.308457, 0.032252,
+ -0.009947, 1.095098, 0.308456, 0.040822, -0.012589, 1.095096, 0.308453, 0.050399, -0.015541,
+ 1.095070, 0.308451, 0.060985, -0.018803, 1.094922, 0.308448, 0.072583, -0.022375, 1.094902,
+ 0.308444, 0.085197, -0.026258, 1.094882, 0.308438, 0.098822, -0.030448, 1.094775, 0.308429,
+ 0.113460, -0.034944, 1.094641, 0.308419, 0.129112, -0.039731, 1.094530, 0.308403, 0.145711,
+ -0.044610, 1.094332, 0.308365, 0.163178, -0.049362, 1.094149, 0.308285, 0.181679, -0.054666,
+ 1.093876, 0.308210, 0.201109, -0.060336, 1.093603, 0.308132, 0.221388, -0.066414, 1.093250,
+ 0.308047, 0.242315, -0.072881, 1.092835, 0.307985, 0.263651, -0.079453, 1.092391, 0.307902,
+ 0.286720, -0.085882, 1.091866, 0.307688, 0.310817, -0.092274, 1.091225, 0.307379, 0.335562,
+ -0.098306, 1.090346, 0.306906, 0.361043, -0.104572, 1.089423, 0.306374, 0.387051, -0.110843,
+ 1.088437, 0.305710, 0.413405, -0.117062, 1.087228, 0.304906, 0.440122, -0.123501, 1.085879,
+ 0.304017, 0.467522, -0.129245, 1.084197, 0.302783, 0.495721, -0.134285, 1.082284, 0.301104,
+ 0.523925, -0.139143, 1.080109, 0.299142, 0.551814, -0.143638, 1.077043, 0.296825, 0.579878,
+ -0.147774, 1.074071, 0.294071, 0.608316, -0.150724, 1.070621, 0.290519, 0.636059, -0.153168,
+ 1.066390, 0.286424, 0.663481, -0.155139, 1.062069, 0.281559, 0.690753, -0.155944, 1.057211,
+ 0.276024, 0.717767, -0.156176, 1.052682, 0.269622, 0.743937, -0.155783, 1.047747, 0.262532,
+ 0.770214, -0.154245, 1.043510, 0.254609, 0.795542, -0.152192, 1.039121, 0.246007, 0.821099,
+ -0.149256, 1.035962, 0.236663, 0.845452, -0.145605, 1.032320, 0.226751, 0.869780, -0.141186,
+ 1.029390, 0.216165, 0.893141, -0.136137, 1.026485, 0.204937, 0.916034, -0.130332, 1.024389,
+ 0.193624, 0.938089, -0.124040, 1.022270, 0.181756, 0.959488, -0.117011, 1.020457, 0.169339,
+ 0.979594, -0.109617, 1.018871, 0.156875, 0.998912, -0.101562, 1.017533, 0.144288, 1.017100,
+ -0.093164, 1.016445, 0.131370, 1.034413, -0.084488, 1.015453, 0.118322, 1.050347, -0.075377,
+ 1.014259, 0.104963, 1.064958, -0.066108, 1.013057, 0.091722, 1.078045, -0.056702, 1.011491,
+ 0.078231, 1.089749, -0.047106, 1.009662, 0.064797, 1.099831, -0.037467, 1.007417, 0.051315,
+ 1.108789, -0.027990, 1.005144, 0.038064, 1.116865, -0.018464, 1.002925, 0.025008, 1.124609,
+ -0.009068, 1.001221, 0.012250, 1.132040, 0.000093, 0.999984, -0.000071, 0.000200, -0.000067,
+ 1.112554, 0.335981, 0.000504, -0.000169, 1.112660, 0.335981, 0.002016, -0.000677, 1.112827,
+ 0.335981, 0.004533, -0.001523, 1.112147, 0.335982, 0.008063, -0.002709, 1.112882, 0.335979,
+ 0.012598, -0.004233, 1.112891, 0.335980, 0.018141, -0.006095, 1.112882, 0.335980, 0.024693,
+ -0.008296, 1.112877, 0.335978, 0.032252, -0.010834, 1.112860, 0.335976, 0.040824, -0.013713,
+ 1.112965, 0.335974, 0.050398, -0.016927, 1.112753, 0.335971, 0.060991, -0.020482, 1.112826,
+ 0.335970, 0.072587, -0.024371, 1.112676, 0.335962, 0.085199, -0.028597, 1.112593, 0.335955,
+ 0.098822, -0.033159, 1.112453, 0.335943, 0.113461, -0.038052, 1.112329, 0.335930, 0.129108,
+ -0.043255, 1.112144, 0.335910, 0.145665, -0.048412, 1.111905, 0.335857, 0.163185, -0.053786,
+ 1.111668, 0.335781, 0.181710, -0.059608, 1.111345, 0.335696, 0.201166, -0.065794, 1.110979,
+ 0.335606, 0.221489, -0.072361, 1.110553, 0.335505, 0.242471, -0.079184, 1.110112, 0.335396,
+ 0.263900, -0.086213, 1.109584, 0.335271, 0.286688, -0.093491, 1.108927, 0.335089, 0.310773,
+ -0.100406, 1.108091, 0.334737, 0.335573, -0.106987, 1.107169, 0.334208, 0.361117, -0.113844,
+ 1.106097, 0.333600, 0.387175, -0.120463, 1.104826, 0.332828, 0.413665, -0.127245, 1.103415,
+ 0.331929, 0.440386, -0.133927, 1.101632, 0.330851, 0.467527, -0.140496, 1.099563, 0.329538,
+ 0.495630, -0.145874, 1.096956, 0.327618, 0.523864, -0.150997, 1.094201, 0.325390, 0.551705,
+ -0.155713, 1.090342, 0.322688, 0.579383, -0.159993, 1.086010, 0.319483, 0.607301, -0.163238,
+ 1.081226, 0.315522, 0.634873, -0.165667, 1.076065, 0.310840, 0.662028, -0.167606, 1.070466,
+ 0.305377, 0.688755, -0.168626, 1.064601, 0.299056, 0.715612, -0.168578, 1.059269, 0.291963,
+ 0.741604, -0.167961, 1.053648, 0.284018, 0.767757, -0.166439, 1.048928, 0.275474, 0.793264,
+ -0.164023, 1.044343, 0.266056, 0.818165, -0.160965, 1.039909, 0.255750, 0.843255, -0.156896,
+ 1.036180, 0.244843, 0.867249, -0.152262, 1.032303, 0.233464, 0.890994, -0.146655, 1.029365,
+ 0.221128, 0.913829, -0.140574, 1.026607, 0.208554, 0.936508, -0.133640, 1.024512, 0.195772,
+ 0.957720, -0.126220, 1.022421, 0.182420, 0.978940, -0.118164, 1.021293, 0.168852, 0.998285,
+ -0.109558, 1.019444, 0.155261, 1.016764, -0.100562, 1.017825, 0.141395, 1.034387, -0.091064,
+ 1.016996, 0.127311, 1.050916, -0.081468, 1.015945, 0.113089, 1.065652, -0.071463, 1.014547,
+ 0.098879, 1.079155, -0.061240, 1.013066, 0.084468, 1.090822, -0.050980, 1.010788, 0.069940,
+ 1.101100, -0.040549, 1.008563, 0.055475, 1.109824, -0.030101, 1.005950, 0.041033, 1.117828,
+ -0.019884, 1.003453, 0.027022, 1.125443, -0.009900, 1.001484, 0.013306, 1.132869, 0.000094,
+ 1.000004, -0.000046, 0.000200, -0.000073, 1.132849, 0.363970, 0.000504, -0.000183, 1.132155,
+ 0.363969, 0.002016, -0.000734, 1.132516, 0.363969, 0.004535, -0.001651, 1.132256, 0.363969,
+ 0.008062, -0.002934, 1.132318, 0.363966, 0.012597, -0.004585, 1.132386, 0.363968, 0.018141,
+ -0.006602, 1.132457, 0.363967, 0.024693, -0.008987, 1.132511, 0.363967, 0.032252, -0.011737,
+ 1.132488, 0.363965, 0.040819, -0.014853, 1.132241, 0.363959, 0.050398, -0.018336, 1.132372,
+ 0.363958, 0.060988, -0.022185, 1.132373, 0.363954, 0.072582, -0.026396, 1.132137, 0.363943,
+ 0.085195, -0.030973, 1.132071, 0.363935, 0.098822, -0.035913, 1.131978, 0.363922, 0.113461,
+ -0.041209, 1.131801, 0.363905, 0.129116, -0.046833, 1.131535, 0.363867, 0.145640, -0.052346,
+ 1.131290, 0.363814, 0.163199, -0.058275, 1.131046, 0.363734, 0.181742, -0.064623, 1.130671,
+ 0.363642, 0.201227, -0.071336, 1.130224, 0.363539, 0.221587, -0.078396, 1.129758, 0.363419,
+ 0.242625, -0.085545, 1.129213, 0.363256, 0.264183, -0.093110, 1.128549, 0.363097, 0.286668,
+ -0.101206, 1.127767, 0.362939, 0.310745, -0.108586, 1.126796, 0.362516, 0.335602, -0.115827,
+ 1.125686, 0.361953, 0.361202, -0.123212, 1.124451, 0.361275, 0.387298, -0.130294, 1.122861,
+ 0.360376, 0.413918, -0.137553, 1.121154, 0.359362, 0.440680, -0.144577, 1.118825, 0.358069,
+ 0.467667, -0.151558, 1.116002, 0.356581, 0.495449, -0.157621, 1.112778, 0.354531, 0.523514,
+ -0.162844, 1.108842, 0.351915, 0.551250, -0.167744, 1.104075, 0.348797, 0.578629, -0.172132,
+ 1.098733, 0.345222, 0.605757, -0.175733, 1.092224, 0.340665, 0.633392, -0.178109, 1.086201,
+ 0.335286, 0.660783, -0.180009, 1.080110, 0.329286, 0.687219, -0.181105, 1.073419, 0.322319,
+ 0.713873, -0.181046, 1.067410, 0.314616, 0.740094, -0.180219, 1.061414, 0.306014, 0.765233,
+ -0.178559, 1.055287, 0.296704, 0.790885, -0.175806, 1.049727, 0.286394, 0.815464, -0.172354,
+ 1.044519, 0.275189, 0.840259, -0.168048, 1.040375, 0.263441, 0.864285, -0.162904, 1.036010,
+ 0.250918, 0.888806, -0.157194, 1.033525, 0.237611, 0.911682, -0.150486, 1.029490, 0.223809,
+ 0.934481, -0.143212, 1.026778, 0.209705, 0.956337, -0.135233, 1.024632, 0.195281, 0.977380,
+ -0.126650, 1.022737, 0.180878, 0.997427, -0.117552, 1.021110, 0.166112, 1.016666, -0.107814,
+ 1.019869, 0.151231, 1.034337, -0.097814, 1.018543, 0.136375, 1.051082, -0.087330, 1.017476,
+ 0.121187, 1.066326, -0.076614, 1.016083, 0.106043, 1.079897, -0.065793, 1.014227, 0.090566,
+ 1.092136, -0.054654, 1.012334, 0.074988, 1.102315, -0.043516, 1.009627, 0.059577, 1.111105,
+ -0.032509, 1.006808, 0.044202, 1.118861, -0.021381, 1.003917, 0.028995, 1.126363, -0.010489,
+ 1.001670, 0.014269, 1.133598, 0.000083, 0.999989, -0.000035, 0.000200, -0.000079, 1.155026,
+ 0.392470, 0.000504, -0.000198, 1.154184, 0.392469, 0.002016, -0.000791, 1.153990, 0.392469,
+ 0.004535, -0.001780, 1.154045, 0.392469, 0.008063, -0.003164, 1.154007, 0.392466, 0.012598,
+ -0.004944, 1.154022, 0.392469, 0.018141, -0.007119, 1.154015, 0.392468, 0.024692, -0.009690,
+ 1.154017, 0.392466, 0.032254, -0.012656, 1.154069, 0.392465, 0.040826, -0.016018, 1.153980,
+ 0.392459, 0.050399, -0.019771, 1.153911, 0.392456, 0.060987, -0.023919, 1.153860, 0.392447,
+ 0.072588, -0.028461, 1.153777, 0.392442, 0.085197, -0.033393, 1.153582, 0.392428, 0.098822,
+ -0.038716, 1.153434, 0.392412, 0.113462, -0.044422, 1.153271, 0.392390, 0.129101, -0.050455,
+ 1.153019, 0.392359, 0.145642, -0.056392, 1.152721, 0.392283, 0.163223, -0.062859, 1.152404,
+ 0.392201, 0.181779, -0.069721, 1.151941, 0.392099, 0.201289, -0.076968, 1.151422, 0.391978,
+ 0.221678, -0.084518, 1.150861, 0.391833, 0.242752, -0.092017, 1.150156, 0.391618, 0.264474,
+ -0.100184, 1.149402, 0.391421, 0.286768, -0.108921, 1.148545, 0.391249, 0.310719, -0.116815,
+ 1.147388, 0.390773, 0.335638, -0.124785, 1.146042, 0.390168, 0.361240, -0.132630, 1.144529,
+ 0.389394, 0.387443, -0.140298, 1.142602, 0.388391, 0.414067, -0.147913, 1.140361, 0.387199,
+ 0.440904, -0.155362, 1.137612, 0.385742, 0.467771, -0.162574, 1.133659, 0.383926, 0.494907,
+ -0.169312, 1.129246, 0.381715, 0.522801, -0.174778, 1.124228, 0.378678, 0.550751, -0.179824,
+ 1.118697, 0.375158, 0.578018, -0.184284, 1.112019, 0.370851, 0.605291, -0.188215, 1.105151,
+ 0.365928, 0.632269, -0.190760, 1.097677, 0.360114, 0.659432, -0.192457, 1.090816, 0.353498,
+ 0.685839, -0.193458, 1.083286, 0.346094, 0.711876, -0.193502, 1.076245, 0.337754, 0.738184,
+ -0.192371, 1.069684, 0.328412, 0.763723, -0.190531, 1.063249, 0.318164, 0.789192, -0.187726,
+ 1.057265, 0.306900, 0.813744, -0.183783, 1.051177, 0.295021, 0.838408, -0.179328, 1.045902,
+ 0.282144, 0.862116, -0.173573, 1.040853, 0.268438, 0.885636, -0.167350, 1.036515, 0.254108,
+ 0.909342, -0.160229, 1.033269, 0.239082, 0.931962, -0.152529, 1.029627, 0.224024, 0.954671,
+ -0.144080, 1.027507, 0.208393, 0.975707, -0.135023, 1.024657, 0.192630, 0.996644, -0.125258,
+ 1.022998, 0.176741, 1.015817, -0.115089, 1.021234, 0.160926, 1.034301, -0.104317, 1.020025,
+ 0.145042, 1.051131, -0.093218, 1.018739, 0.129052, 1.066836, -0.081828, 1.017419, 0.112905,
+ 1.081027, -0.070132, 1.015714, 0.096578, 1.093225, -0.058382, 1.013465, 0.080077, 1.103691,
+ -0.046527, 1.010853, 0.063580, 1.112431, -0.034624, 1.007702, 0.047118, 1.120035, -0.022913,
+ 1.004551, 0.031018, 1.127336, -0.011284, 1.001924, 0.015283, 1.134510, 0.000170, 0.999937,
+ -0.000058, 0.000200, -0.000084, 1.177044, 0.421534, 0.000504, -0.000212, 1.177312, 0.421533,
+ 0.002016, -0.000850, 1.177730, 0.421533, 0.004535, -0.001912, 1.177722, 0.421533, 0.008063,
+ -0.003399, 1.177844, 0.421529, 0.012598, -0.005310, 1.177768, 0.421533, 0.018141, -0.007646,
+ 1.177730, 0.421531, 0.024692, -0.010407, 1.177663, 0.421530, 0.032252, -0.013592, 1.177681,
+ 0.421527, 0.040821, -0.017201, 1.177562, 0.421524, 0.050401, -0.021234, 1.177445, 0.421516,
+ 0.060988, -0.025688, 1.177461, 0.421509, 0.072590, -0.030565, 1.177364, 0.421498, 0.085200,
+ -0.035860, 1.177205, 0.421482, 0.098823, -0.041572, 1.177011, 0.421462, 0.113465, -0.047694,
+ 1.176794, 0.421436, 0.129094, -0.054122, 1.176504, 0.421396, 0.145652, -0.060530, 1.176203,
+ 0.421311, 0.163245, -0.067517, 1.175805, 0.421218, 0.181825, -0.074919, 1.175271, 0.421108,
+ 0.201360, -0.082700, 1.174717, 0.420974, 0.221773, -0.090727, 1.174021, 0.420795, 0.242908,
+ -0.098719, 1.173173, 0.420536, 0.264742, -0.107417, 1.172285, 0.420296, 0.287091, -0.116601,
+ 1.171326, 0.420065, 0.310723, -0.125265, 1.169907, 0.419582, 0.335685, -0.133876, 1.168352,
+ 0.418912, 0.361285, -0.142140, 1.166322, 0.418006, 0.387562, -0.150436, 1.164136, 0.416899,
+ 0.414175, -0.158388, 1.161162, 0.415513, 0.441021, -0.166258, 1.157608, 0.413836, 0.467698,
+ -0.173720, 1.152519, 0.411702, 0.494730, -0.180843, 1.147020, 0.409102, 0.522524, -0.186906,
+ 1.141256, 0.405789, 0.550055, -0.192004, 1.134114, 0.401759, 0.577512, -0.196588, 1.127086,
+ 0.397153, 0.604348, -0.200420, 1.119029, 0.391767, 0.630970, -0.203320, 1.110308, 0.385573,
+ 0.658023, -0.204883, 1.102643, 0.378245, 0.684422, -0.205716, 1.094573, 0.370191, 0.710405,
+ -0.205767, 1.086405, 0.361231, 0.736417, -0.204513, 1.078712, 0.351106, 0.761836, -0.202281,
+ 1.071619, 0.340096, 0.787140, -0.199395, 1.064873, 0.328139, 0.812197, -0.195185, 1.058313,
+ 0.315044, 0.836342, -0.190191, 1.052085, 0.300933, 0.860311, -0.184343, 1.046705, 0.286411,
+ 0.883597, -0.177415, 1.041072, 0.270897, 0.906852, -0.170003, 1.036797, 0.254825, 0.929991,
+ -0.161592, 1.033264, 0.238176, 0.952478, -0.152792, 1.030250, 0.221581, 0.974216, -0.143032,
+ 1.027331, 0.204378, 0.995372, -0.132922, 1.025135, 0.187470, 1.015330, -0.122009, 1.023250,
+ 0.170538, 1.034070, -0.110740, 1.022021, 0.153777, 1.051295, -0.099016, 1.020271, 0.136916,
+ 1.067460, -0.086920, 1.018948, 0.119880, 1.082022, -0.074729, 1.017336, 0.102565, 1.094378,
+ -0.062036, 1.014820, 0.084994, 1.104998, -0.049413, 1.011999, 0.067650, 1.113773, -0.036812,
+ 1.008711, 0.050148, 1.121263, -0.024274, 1.005141, 0.032976, 1.128420, -0.012038, 1.002196,
+ 0.016239, 1.135496, 0.000106, 1.000042, -0.000062, 0.000200, -0.000090, 1.203048, 0.451217,
+ 0.000504, -0.000227, 1.203226, 0.451215, 0.002016, -0.000909, 1.203450, 0.451215, 0.004535,
+ -0.002046, 1.203569, 0.451215, 0.008062, -0.003638, 1.203609, 0.451209, 0.012598, -0.005684,
+ 1.203580, 0.451214, 0.018141, -0.008185, 1.203515, 0.451212, 0.024694, -0.011141, 1.203618,
+ 0.451211, 0.032253, -0.014549, 1.203609, 0.451207, 0.040815, -0.018409, 1.203302, 0.451203,
+ 0.050401, -0.022727, 1.203454, 0.451195, 0.060990, -0.027495, 1.203480, 0.451188, 0.072591,
+ -0.032713, 1.203220, 0.451172, 0.085203, -0.038378, 1.203058, 0.451154, 0.098829, -0.044489,
+ 1.202838, 0.451130, 0.113466, -0.051031, 1.202530, 0.451098, 0.129084, -0.057808, 1.202270,
+ 0.451041, 0.145669, -0.064769, 1.201904, 0.450956, 0.163278, -0.072278, 1.201411, 0.450853,
+ 0.181880, -0.080224, 1.200825, 0.450721, 0.201436, -0.088537, 1.200164, 0.450566, 0.221865,
+ -0.097009, 1.199335, 0.450351, 0.243083, -0.105591, 1.198383, 0.450062, 0.265033, -0.114818,
+ 1.197380, 0.449769, 0.287456, -0.124372, 1.196137, 0.449438, 0.310758, -0.133892, 1.194554,
+ 0.448974, 0.335721, -0.143052, 1.192649, 0.448216, 0.361348, -0.151868, 1.190233, 0.447202,
+ 0.387573, -0.160644, 1.187211, 0.445926, 0.414159, -0.169028, 1.183452, 0.444313, 0.440950,
+ -0.177169, 1.178562, 0.442315, 0.467998, -0.185090, 1.173540, 0.439960, 0.494566, -0.192396,
+ 1.166344, 0.436989, 0.521730, -0.198915, 1.159283, 0.433439, 0.549405, -0.204240, 1.151503,
+ 0.428984, 0.576755, -0.208861, 1.143004, 0.423839, 0.603635, -0.212734, 1.134099, 0.418012,
+ 0.629979, -0.215712, 1.124555, 0.411445, 0.656597, -0.217385, 1.115293, 0.403628, 0.683317,
+ -0.218093, 1.106460, 0.394639, 0.708990, -0.217835, 1.097389, 0.385012, 0.734898, -0.216774,
+ 1.088940, 0.373999, 0.760342, -0.214120, 1.080385, 0.362128, 0.785517, -0.210821, 1.072959,
+ 0.349184, 0.809933, -0.206443, 1.065450, 0.335080, 0.834339, -0.200942, 1.058701, 0.320257,
+ 0.858793, -0.194938, 1.052711, 0.304133, 0.882300, -0.187615, 1.047044, 0.287771, 0.905560,
+ -0.179626, 1.042083, 0.270571, 0.927916, -0.170753, 1.037077, 0.252741, 0.950415, -0.161270,
+ 1.033200, 0.234656, 0.972920, -0.151239, 1.030418, 0.216652, 0.993893, -0.140358, 1.027479,
+ 0.198252, 1.014204, -0.128963, 1.024897, 0.180113, 1.033878, -0.117128, 1.023648, 0.162282,
+ 1.051754, -0.104678, 1.022230, 0.144366, 1.067924, -0.092000, 1.020453, 0.126455, 1.082643,
+ -0.078837, 1.018518, 0.108194, 1.095503, -0.065669, 1.016199, 0.089966, 1.106290, -0.052345,
+ 1.013113, 0.071530, 1.115219, -0.039024, 1.009636, 0.053158, 1.122587, -0.025789, 1.005801,
+ 0.034959, 1.129461, -0.012622, 1.002442, 0.017222, 1.136468, 0.000152, 0.999964, -0.000065,
+ 0.000200, -0.000096, 1.231156, 0.481574, 0.000504, -0.000243, 1.232187, 0.481572, 0.002016,
+ -0.000971, 1.231948, 0.481572, 0.004535, -0.002184, 1.231919, 0.481572, 0.008061, -0.003882,
+ 1.231453, 0.481566, 0.012597, -0.006066, 1.231800, 0.481572, 0.018142, -0.008736, 1.231756,
+ 0.481569, 0.024693, -0.011889, 1.232062, 0.481570, 0.032254, -0.015528, 1.231915, 0.481563,
+ 0.040822, -0.019650, 1.231863, 0.481559, 0.050402, -0.024255, 1.231737, 0.481550, 0.060992,
+ -0.029342, 1.231678, 0.481537, 0.072592, -0.034908, 1.231537, 0.481521, 0.085207, -0.040953,
+ 1.231336, 0.481499, 0.098834, -0.047469, 1.231071, 0.481469, 0.113474, -0.054441, 1.230757,
+ 0.481431, 0.129077, -0.061556, 1.230424, 0.481359, 0.145691, -0.069091, 1.230022, 0.481269,
+ 0.163321, -0.077151, 1.229461, 0.481156, 0.181936, -0.085636, 1.228718, 0.481011, 0.201516,
+ -0.094484, 1.228023, 0.480830, 0.221963, -0.103362, 1.227057, 0.480562, 0.243264, -0.112628,
+ 1.225997, 0.480247, 0.265291, -0.122366, 1.224744, 0.479891, 0.287824, -0.132256, 1.223255,
+ 0.479461, 0.310927, -0.142614, 1.221348, 0.478978, 0.335749, -0.152326, 1.218953, 0.478132,
+ 0.361361, -0.161747, 1.215806, 0.476971, 0.387480, -0.170879, 1.211853, 0.475477, 0.414231,
+ -0.179865, 1.207783, 0.473686, 0.441065, -0.188331, 1.202051, 0.471415, 0.467923, -0.196454,
+ 1.195463, 0.468647, 0.494526, -0.204048, 1.187542, 0.465459, 0.521318, -0.211020, 1.179235,
+ 0.461650, 0.548654, -0.216520, 1.170110, 0.456868, 0.575778, -0.221098, 1.160163, 0.451227,
+ 0.602610, -0.224923, 1.149751, 0.444866, 0.628891, -0.227895, 1.139169, 0.437577, 0.655635,
+ -0.230020, 1.129736, 0.429369, 0.682115, -0.230419, 1.119516, 0.419673, 0.707514, -0.229789,
+ 1.108277, 0.409143, 0.733169, -0.228520, 1.099159, 0.397296, 0.758342, -0.225793, 1.089839,
+ 0.384578, 0.783477, -0.222049, 1.081428, 0.370323, 0.808497, -0.217562, 1.073742, 0.355253,
+ 0.832790, -0.211697, 1.065850, 0.339282, 0.856677, -0.204989, 1.058834, 0.322181, 0.880662,
+ -0.197653, 1.053291, 0.304610, 0.903474, -0.188858, 1.046822, 0.286042, 0.926313, -0.179746,
+ 1.041663, 0.267224, 0.948458, -0.169542, 1.036532, 0.247978, 0.970873, -0.159005, 1.033008,
+ 0.228535, 0.992958, -0.147658, 1.029844, 0.208819, 1.013413, -0.135771, 1.026930, 0.189486,
+ 1.033483, -0.123256, 1.025545, 0.170422, 1.051872, -0.110401, 1.023935, 0.152075, 1.068396,
+ -0.096860, 1.022092, 0.133169, 1.083731, -0.083259, 1.020221, 0.114022, 1.096849, -0.069266,
+ 1.017663, 0.094772, 1.107864, -0.055203, 1.014524, 0.075432, 1.116600, -0.041097, 1.010514,
+ 0.055980, 1.123871, -0.027083, 1.006313, 0.036839, 1.130718, -0.013510, 1.002778, 0.018156,
+ 1.137649, 0.000154, 1.000033, -0.000028, 0.000200, -0.000103, 1.264025, 0.512670, 0.000504,
+ -0.000258, 1.262437, 0.512667, 0.002016, -0.001033, 1.262691, 0.512668, 0.004535, -0.002325,
+ 1.262834, 0.512667, 0.008063, -0.004133, 1.262783, 0.512659, 0.012598, -0.006458, 1.262803,
+ 0.512666, 0.018141, -0.009299, 1.262720, 0.512665, 0.024683, -0.012652, 1.262061, 0.512655,
+ 0.032257, -0.016532, 1.262858, 0.512656, 0.040826, -0.020919, 1.262709, 0.512649, 0.050403,
+ -0.025820, 1.262685, 0.512639, 0.060993, -0.031233, 1.262544, 0.512625, 0.072597, -0.037157,
+ 1.262435, 0.512607, 0.085211, -0.043587, 1.262209, 0.512581, 0.098842, -0.050520, 1.261907,
+ 0.512544, 0.113484, -0.057926, 1.261575, 0.512500, 0.129097, -0.065460, 1.261293, 0.512420,
+ 0.145727, -0.073543, 1.260736, 0.512316, 0.163375, -0.082134, 1.260117, 0.512190, 0.182011,
+ -0.091173, 1.259299, 0.512024, 0.201598, -0.100540, 1.258381, 0.511810, 0.222084, -0.109931,
+ 1.257293, 0.511505, 0.243446, -0.119838, 1.256050, 0.511151, 0.265574, -0.130090, 1.254607,
+ 0.510724, 0.288230, -0.140421, 1.252808, 0.510191, 0.311336, -0.151343, 1.250489, 0.509627,
+ 0.335719, -0.161689, 1.247279, 0.508688, 0.361314, -0.171748, 1.243467, 0.507393, 0.387541,
+ -0.181399, 1.239145, 0.505758, 0.414204, -0.190768, 1.233760, 0.503676, 0.441092, -0.199659,
+ 1.227433, 0.501129, 0.467789, -0.207934, 1.219247, 0.498078, 0.494454, -0.215747, 1.210441,
+ 0.494630, 0.520950, -0.222869, 1.200559, 0.490467, 0.547802, -0.228881, 1.189872, 0.485444,
+ 0.575563, -0.233760, 1.180081, 0.479268, 0.602426, -0.237566, 1.168544, 0.472272, 0.628772,
+ -0.240447, 1.156546, 0.464390, 0.654963, -0.242427, 1.145123, 0.455345, 0.681384, -0.242980,
+ 1.134322, 0.444885, 0.707173, -0.242150, 1.122665, 0.433338, 0.732477, -0.240435, 1.111733,
+ 0.420647, 0.757567, -0.237806, 1.101271, 0.406799, 0.782341, -0.233503, 1.091341, 0.391761,
+ 0.806690, -0.228346, 1.082042, 0.375576, 0.830804, -0.222386, 1.073504, 0.358545, 0.854940,
+ -0.215141, 1.065880, 0.340431, 0.878709, -0.207207, 1.058850, 0.321690, 0.901928, -0.198273,
+ 1.052588, 0.301930, 0.924845, -0.188476, 1.046521, 0.281513, 0.946932, -0.177996, 1.040966,
+ 0.261234, 0.969256, -0.166644, 1.036670, 0.240356, 0.991323, -0.154968, 1.032694, 0.219748,
+ 1.013013, -0.142425, 1.030061, 0.199103, 1.032845, -0.129456, 1.027254, 0.178936, 1.051887,
+ -0.115763, 1.025497, 0.159243, 1.069179, -0.101851, 1.023807, 0.139560, 1.084499, -0.087357,
+ 1.021441, 0.119607, 1.097921, -0.072796, 1.018780, 0.099501, 1.109281, -0.058037, 1.015566,
+ 0.079211, 1.118194, -0.043226, 1.011494, 0.058873, 1.125351, -0.028633, 1.007089, 0.038736,
+ 1.132002, -0.013996, 1.003014, 0.019063, 1.138951, 0.000132, 1.000036, -0.000007, 0.000200,
+ -0.000109, 1.296791, 0.544571, 0.000504, -0.000274, 1.296055, 0.544568, 0.002016, -0.001098,
+ 1.297239, 0.544568, 0.004535, -0.002470, 1.296600, 0.544568, 0.008062, -0.004390, 1.296368,
+ 0.544559, 0.012597, -0.006860, 1.296454, 0.544566, 0.018141, -0.009878, 1.296522, 0.544565,
+ 0.024693, -0.013444, 1.296536, 0.544560, 0.032256, -0.017559, 1.296638, 0.544557, 0.040824,
+ -0.022218, 1.296491, 0.544547, 0.050408, -0.027426, 1.296552, 0.544532, 0.060997, -0.033173,
+ 1.296283, 0.544518, 0.072600, -0.039463, 1.296113, 0.544496, 0.085220, -0.046292, 1.295894,
+ 0.544466, 0.098851, -0.053648, 1.295545, 0.544422, 0.113496, -0.061487, 1.295201, 0.544371,
+ 0.129112, -0.069467, 1.294754, 0.544273, 0.145765, -0.078092, 1.294209, 0.544160, 0.163431,
+ -0.087231, 1.293534, 0.544017, 0.182088, -0.096837, 1.292580, 0.543828, 0.201698, -0.106713,
+ 1.291586, 0.543585, 0.222231, -0.116699, 1.290325, 0.543238, 0.243653, -0.127208, 1.288888,
+ 0.542836, 0.265855, -0.137949, 1.287131, 0.542329, 0.288623, -0.148847, 1.284936, 0.541700,
+ 0.311830, -0.160204, 1.282109, 0.540997, 0.335728, -0.171324, 1.278036, 0.540045, 0.361403,
+ -0.181915, 1.273912, 0.538603, 0.387647, -0.192124, 1.268881, 0.536741, 0.414217, -0.201807,
+ 1.262363, 0.534432, 0.441090, -0.211093, 1.254755, 0.531623, 0.467823, -0.219678, 1.245456,
+ 0.528314, 0.494361, -0.227581, 1.234953, 0.524391, 0.521264, -0.235087, 1.224839, 0.519902,
+ 0.547881, -0.241508, 1.213175, 0.514574, 0.574965, -0.246315, 1.200505, 0.507837, 0.601847,
+ -0.250061, 1.187901, 0.500286, 0.628207, -0.252822, 1.174601, 0.491502, 0.654445, -0.254691,
+ 1.161944, 0.481726, 0.680175, -0.255318, 1.149305, 0.470727, 0.706168, -0.254257, 1.136708,
+ 0.458045, 0.731458, -0.252100, 1.124047, 0.444438, 0.756378, -0.249115, 1.112942, 0.429611,
+ 0.781311, -0.244899, 1.101800, 0.413501, 0.805755, -0.239225, 1.091662, 0.395889, 0.829867,
+ -0.232830, 1.082291, 0.377860, 0.853067, -0.225193, 1.072820, 0.358704, 0.877084, -0.216648,
+ 1.065415, 0.338413, 0.900123, -0.207390, 1.058403, 0.317596, 0.923370, -0.197095, 1.051412,
+ 0.296301, 0.946021, -0.186084, 1.045877, 0.274498, 0.967669, -0.174262, 1.040316, 0.252565,
+ 0.989761, -0.161814, 1.035489, 0.230312, 1.012163, -0.149076, 1.032540, 0.208746, 1.032547,
+ -0.135299, 1.029598, 0.187180, 1.052032, -0.121277, 1.027355, 0.166482, 1.069907, -0.106582,
+ 1.025622, 0.145939, 1.085563, -0.091589, 1.023244, 0.125362, 1.099447, -0.076263, 1.020661,
+ 0.104087, 1.110848, -0.060825, 1.017035, 0.083036, 1.119923, -0.045319, 1.012675, 0.061719,
+ 1.126805, -0.029852, 1.007668, 0.040583, 1.133282, -0.014846, 1.003335, 0.019969, 1.140128,
+ 0.000149, 1.000024, -0.000037, 0.000200, -0.000116, 1.334863, 0.577350, 0.000504, -0.000291,
+ 1.333350, 0.577348, 0.002015, -0.001164, 1.332853, 0.577347, 0.004535, -0.002618, 1.333295,
+ 0.577347, 0.008062, -0.004655, 1.333189, 0.577336, 0.012598, -0.007273, 1.333309, 0.577345,
+ 0.018141, -0.010472, 1.333274, 0.577342, 0.024694, -0.014253, 1.333231, 0.577339, 0.032254,
+ -0.018614, 1.333265, 0.577332, 0.040827, -0.023556, 1.333261, 0.577321, 0.050400, -0.029069,
+ 1.332893, 0.577309, 0.061000, -0.035166, 1.332998, 0.577288, 0.072608, -0.041833, 1.332901,
+ 0.577263, 0.085227, -0.049067, 1.332603, 0.577226, 0.098864, -0.056860, 1.332264, 0.577177,
+ 0.113507, -0.065114, 1.331825, 0.577109, 0.129146, -0.073610, 1.331311, 0.577005, 0.145808,
+ -0.082766, 1.330639, 0.576872, 0.163494, -0.092458, 1.329878, 0.576709, 0.182176, -0.102639,
+ 1.328889, 0.576501, 0.201804, -0.112983, 1.327710, 0.576207, 0.222394, -0.123650, 1.326256,
+ 0.575823, 0.243881, -0.134780, 1.324593, 0.575363, 0.266122, -0.145931, 1.322426, 0.574751,
+ 0.289043, -0.157500, 1.319837, 0.574033, 0.312330, -0.169208, 1.316301, 0.573181, 0.336120,
+ -0.181125, 1.312251, 0.572188, 0.361506, -0.192232, 1.307003, 0.570631, 0.387757, -0.202981,
+ 1.301068, 0.568558, 0.414365, -0.213160, 1.293695, 0.566027, 0.440986, -0.222617, 1.283958,
+ 0.562942, 0.467943, -0.231583, 1.274057, 0.559219, 0.494821, -0.239881, 1.262864, 0.554913,
+ 0.521486, -0.247336, 1.250633, 0.549953, 0.547884, -0.253921, 1.237448, 0.544251, 0.574582,
+ -0.259099, 1.223164, 0.537120, 0.601342, -0.262695, 1.208784, 0.528650, 0.627861, -0.265337,
+ 1.194424, 0.518978, 0.653745, -0.266872, 1.179361, 0.508525, 0.679348, -0.267403, 1.165010,
+ 0.496705, 0.705068, -0.266429, 1.151693, 0.482926, 0.730312, -0.263829, 1.137584, 0.468519,
+ 0.755576, -0.260491, 1.125328, 0.452213, 0.780371, -0.256166, 1.113759, 0.435127, 0.804632,
+ -0.250079, 1.101656, 0.416833, 0.828983, -0.243181, 1.091235, 0.397009, 0.852585, -0.235383,
+ 1.081475, 0.376647, 0.875237, -0.226031, 1.071806, 0.355506, 0.899152, -0.216343, 1.064453,
+ 0.333133, 0.922121, -0.205772, 1.057161, 0.311073, 0.944523, -0.193980, 1.050447, 0.287781,
+ 0.967313, -0.181920, 1.044531, 0.264350, 0.989042, -0.168822, 1.039312, 0.241128, 1.010881,
+ -0.155350, 1.035298, 0.218138, 1.032368, -0.141231, 1.032073, 0.195579, 1.052254, -0.126521,
+ 1.029395, 0.173399, 1.070207, -0.111243, 1.026938, 0.151866, 1.086528, -0.095617, 1.024957,
+ 0.130711, 1.100670, -0.079687, 1.021924, 0.108865, 1.112461, -0.063593, 1.018281, 0.086760,
+ 1.121588, -0.047313, 1.013747, 0.064575, 1.128522, -0.031385, 1.008433, 0.042499, 1.134759,
+ -0.015356, 1.003569, 0.020840, 1.141448, 0.000114, 0.999978, -0.000056, 0.000200, -0.000122,
+ 1.372763, 0.611086, 0.000503, -0.000308, 1.371456, 0.611084, 0.002016, -0.001232, 1.373440,
+ 0.611084, 0.004535, -0.002771, 1.373387, 0.611083, 0.008061, -0.004926, 1.372916, 0.611083,
+ 0.012601, -0.007700, 1.373956, 0.611084, 0.018142, -0.011084, 1.373419, 0.611078, 0.024695,
+ -0.015087, 1.373492, 0.611074, 0.032255, -0.019701, 1.373360, 0.611066, 0.040827, -0.024930,
+ 1.373327, 0.611055, 0.050408, -0.030769, 1.373222, 0.611037, 0.061004, -0.037217, 1.373079,
+ 0.611014, 0.072613, -0.044270, 1.372895, 0.610982, 0.085238, -0.051923, 1.372624, 0.610941,
+ 0.098878, -0.060161, 1.372252, 0.610883, 0.113522, -0.068785, 1.371785, 0.610798, 0.129176,
+ -0.077863, 1.371103, 0.610683, 0.145876, -0.087593, 1.370541, 0.610537, 0.163570, -0.097847,
+ 1.369496, 0.610349, 0.182283, -0.108592, 1.368477, 0.610109, 0.201930, -0.119420, 1.366980,
+ 0.609763, 0.222570, -0.130789, 1.365375, 0.609343, 0.244123, -0.142514, 1.363456, 0.608815,
+ 0.266437, -0.154232, 1.360916, 0.608114, 0.289467, -0.166370, 1.357909, 0.607291, 0.312861,
+ -0.178505, 1.353588, 0.606272, 0.336736, -0.190980, 1.349211, 0.605153, 0.361740, -0.202859,
+ 1.343319, 0.603548, 0.387878, -0.213997, 1.335908, 0.601268, 0.414357, -0.224584, 1.326676,
+ 0.598499, 0.441442, -0.234664, 1.317331, 0.595066, 0.468409, -0.243875, 1.305818, 0.590996,
+ 0.494999, -0.252121, 1.291863, 0.586293, 0.521730, -0.259714, 1.278212, 0.580840, 0.547894,
+ -0.266242, 1.262656, 0.574494, 0.573865, -0.271578, 1.246364, 0.567007, 0.601124, -0.275503,
+ 1.231274, 0.557771, 0.627606, -0.277954, 1.215252, 0.547255, 0.654004, -0.279404, 1.199977,
+ 0.535766, 0.679554, -0.279632, 1.183995, 0.522792, 0.704280, -0.278457, 1.167428, 0.508488,
+ 0.729830, -0.275706, 1.152760, 0.492425, 0.754376, -0.271640, 1.137942, 0.475285, 0.779209,
+ -0.266911, 1.125222, 0.456679, 0.803562, -0.260838, 1.112179, 0.437267, 0.827985, -0.253353,
+ 1.101439, 0.416227, 0.851737, -0.245027, 1.089890, 0.394728, 0.874850, -0.235719, 1.080018,
+ 0.372244, 0.897680, -0.225051, 1.070807, 0.348846, 0.921351, -0.214051, 1.063180, 0.324961,
+ 0.943818, -0.202039, 1.056148, 0.300836, 0.966368, -0.189134, 1.049277, 0.276333, 0.987426,
+ -0.175613, 1.042176, 0.251862, 1.010162, -0.161473, 1.038567, 0.227217, 1.031224, -0.146866,
+ 1.034102, 0.203582, 1.052317, -0.131644, 1.031600, 0.180629, 1.070879, -0.115909, 1.028913,
+ 0.158165, 1.087407, -0.099638, 1.026193, 0.135905, 1.102159, -0.083091, 1.023567, 0.113394,
+ 1.114006, -0.066178, 1.019567, 0.090325, 1.123374, -0.049430, 1.014856, 0.067302, 1.130310,
+ -0.032557, 1.009141, 0.044264, 1.136334, -0.016157, 1.003984, 0.021807, 1.142961, 0.000172,
+ 0.999951, -0.000077, 0.000200, -0.000129, 1.416584, 0.645866, 0.000504, -0.000326, 1.417762,
+ 0.645865, 0.002016, -0.001302, 1.417825, 0.645866, 0.004535, -0.002929, 1.417142, 0.645865,
+ 0.008062, -0.005207, 1.416968, 0.645864, 0.012598, -0.008136, 1.417109, 0.645862, 0.018141,
+ -0.011715, 1.417001, 0.645859, 0.024690, -0.015941, 1.416878, 0.645853, 0.032257, -0.020823,
+ 1.417134, 0.645843, 0.040827, -0.026347, 1.416983, 0.645829, 0.050411, -0.032518, 1.416949,
+ 0.645808, 0.061007, -0.039330, 1.416694, 0.645781, 0.072621, -0.046783, 1.416599, 0.645746,
+ 0.085249, -0.054865, 1.416241, 0.645695, 0.098897, -0.063563, 1.415832, 0.645630, 0.113546,
+ -0.072607, 1.415264, 0.645529, 0.129220, -0.082257, 1.414482, 0.645396, 0.145888, -0.092515,
+ 1.413626, 0.645268, 0.163659, -0.103393, 1.412710, 0.645018, 0.182385, -0.114684, 1.411418,
+ 0.644739, 0.202078, -0.126098, 1.409822, 0.644348, 0.222772, -0.138145, 1.407948, 0.643872,
+ 0.244370, -0.150405, 1.405678, 0.643255, 0.266787, -0.162798, 1.402763, 0.642463, 0.289844,
+ -0.175434, 1.398863, 0.641504, 0.313540, -0.188158, 1.394695, 0.640346, 0.337489, -0.201014,
+ 1.389376, 0.639042, 0.362008, -0.213719, 1.382439, 0.637412, 0.387990, -0.225248, 1.373281,
+ 0.634930, 0.414728, -0.236348, 1.363729, 0.631861, 0.441635, -0.246701, 1.352304, 0.628155,
+ 0.468588, -0.256167, 1.339162, 0.623625, 0.495337, -0.264662, 1.323811, 0.618458, 0.521886,
+ -0.272207, 1.307630, 0.612373, 0.548355, -0.278890, 1.291265, 0.605263, 0.574535, -0.284442,
+ 1.273752, 0.597048, 0.600870, -0.288389, 1.256171, 0.587401, 0.627715, -0.290816, 1.238447,
+ 0.576001, 0.653830, -0.291886, 1.221036, 0.563198, 0.679175, -0.291629, 1.202283, 0.549249,
+ 0.704539, -0.290489, 1.185866, 0.533881, 0.729126, -0.287529, 1.168822, 0.516966, 0.754297,
+ -0.283184, 1.152934, 0.498501, 0.778678, -0.277732, 1.137821, 0.478728, 0.802473, -0.271203,
+ 1.123387, 0.457814, 0.826596, -0.263494, 1.110573, 0.435865, 0.850835, -0.254572, 1.099099,
+ 0.412597, 0.874203, -0.244815, 1.088403, 0.388995, 0.897271, -0.233993, 1.078085, 0.364487,
+ 0.919667, -0.221934, 1.068543, 0.339344, 0.943001, -0.209714, 1.061081, 0.313770, 0.965688,
+ -0.196367, 1.054023, 0.287928, 0.987598, -0.182263, 1.047247, 0.262157, 1.009280, -0.167775,
+ 1.041376, 0.236855, 1.031762, -0.152530, 1.037647, 0.211847, 1.051965, -0.136809, 1.033396,
+ 0.187546, 1.071699, -0.120418, 1.031021, 0.164186, 1.088881, -0.103618, 1.028403, 0.141184,
+ 1.103482, -0.086271, 1.024987, 0.117665, 1.115646, -0.068973, 1.020884, 0.093896, 1.125258,
+ -0.051285, 1.015966, 0.069978, 1.132045, -0.033998, 1.009990, 0.046126, 1.138004, -0.016696,
+ 1.004270, 0.022635, 1.144463, 0.000089, 0.999987, -0.000016, 0.000200, -0.000136, 1.463614,
+ 0.681786, 0.000504, -0.000344, 1.465345, 0.681785, 0.002015, -0.001374, 1.464172, 0.681783,
+ 0.004535, -0.003092, 1.464846, 0.681784, 0.008062, -0.005496, 1.464783, 0.681784, 0.012598,
+ -0.008588, 1.464883, 0.681781, 0.018141, -0.012366, 1.464740, 0.681777, 0.024692, -0.016829,
+ 1.464665, 0.681770, 0.032258, -0.021980, 1.464720, 0.681760, 0.040829, -0.027811, 1.464625,
+ 0.681742, 0.050415, -0.034324, 1.464571, 0.681720, 0.061013, -0.041513, 1.464346, 0.681688,
+ 0.072628, -0.049375, 1.464131, 0.681644, 0.085264, -0.057903, 1.463847, 0.681588, 0.098918,
+ -0.067067, 1.463369, 0.681509, 0.113568, -0.076570, 1.462549, 0.681389, 0.129265, -0.086782,
+ 1.461703, 0.681239, 0.145997, -0.097637, 1.460840, 0.681047, 0.163751, -0.109101, 1.459737,
+ 0.680806, 0.182505, -0.120922, 1.458231, 0.680480, 0.202241, -0.133007, 1.456393, 0.680042,
+ 0.222987, -0.145693, 1.454258, 0.679503, 0.244638, -0.158488, 1.451543, 0.678792, 0.267132,
+ -0.171585, 1.448115, 0.677907, 0.290365, -0.184746, 1.443992, 0.676796, 0.314178, -0.198101,
+ 1.439271, 0.675498, 0.338289, -0.211370, 1.432830, 0.673922, 0.362543, -0.224489, 1.424163,
+ 0.672151, 0.388470, -0.236914, 1.415160, 0.669601, 0.415105, -0.248342, 1.403811, 0.666255,
+ 0.441925, -0.258957, 1.390149, 0.662166, 0.468668, -0.268556, 1.374104, 0.657229, 0.495720,
+ -0.277359, 1.358102, 0.651347, 0.522574, -0.285078, 1.340754, 0.644598, 0.548981, -0.291718,
+ 1.322033, 0.636820, 0.574946, -0.297087, 1.302148, 0.627812, 0.600744, -0.301079, 1.282130,
+ 0.617485, 0.627565, -0.303566, 1.263339, 0.605047, 0.653598, -0.304330, 1.242712, 0.591167,
+ 0.679239, -0.303820, 1.223212, 0.576025, 0.704043, -0.302064, 1.203763, 0.559649, 0.728796,
+ -0.299095, 1.185434, 0.541271, 0.753581, -0.294392, 1.167630, 0.521800, 0.778577, -0.288603,
+ 1.151930, 0.500628, 0.802550, -0.281604, 1.136072, 0.478434, 0.825803, -0.273472, 1.121673,
+ 0.455384, 0.849768, -0.264011, 1.108491, 0.430811, 0.873250, -0.253653, 1.096550, 0.405524,
+ 0.896725, -0.242642, 1.085905, 0.380038, 0.919158, -0.230191, 1.075091, 0.353482, 0.942236,
+ -0.217145, 1.066848, 0.326605, 0.965031, -0.203555, 1.059310, 0.299842, 0.987048, -0.188777,
+ 1.051749, 0.272859, 1.008718, -0.173613, 1.044999, 0.246040, 1.031097, -0.157972, 1.040066,
+ 0.219826, 1.052493, -0.141589, 1.035951, 0.194278, 1.071773, -0.124814, 1.032520, 0.169830,
+ 1.089646, -0.107321, 1.029803, 0.146135, 1.104932, -0.089726, 1.026612, 0.122127, 1.117687,
+ -0.071433, 1.022391, 0.097461, 1.127188, -0.053395, 1.017113, 0.072556, 1.134010, -0.035151,
+ 1.010934, 0.047749, 1.139746, -0.017427, 1.004633, 0.023530, 1.146205, 0.000151, 1.000020,
+ -0.000106, 0.000200, -0.000144, 1.517643, 0.718949, 0.000504, -0.000362, 1.516387, 0.718947,
+ 0.002016, -0.001449, 1.516742, 0.718946, 0.004536, -0.003261, 1.517196, 0.718946, 0.008063,
+ -0.005796, 1.516806, 0.718945, 0.012598, -0.009057, 1.516986, 0.718943, 0.018140, -0.013039,
+ 1.516603, 0.718937, 0.024694, -0.017747, 1.516739, 0.718929, 0.032260, -0.023178, 1.516994,
+ 0.718917, 0.040831, -0.029325, 1.516649, 0.718896, 0.050419, -0.036192, 1.516594, 0.718870,
+ 0.061019, -0.043770, 1.516327, 0.718833, 0.072638, -0.052056, 1.516054, 0.718782, 0.085274,
+ -0.061039, 1.515628, 0.718714, 0.098938, -0.070676, 1.515199, 0.718623, 0.113607, -0.080679,
+ 1.514222, 0.718483, 0.129329, -0.091485, 1.513354, 0.718316, 0.146077, -0.102931, 1.512301,
+ 0.718096, 0.163856, -0.114986, 1.510977, 0.717818, 0.182640, -0.127305, 1.509225, 0.717432,
+ 0.202432, -0.140147, 1.507152, 0.716939, 0.223229, -0.153468, 1.504780, 0.716331, 0.244943,
+ -0.166875, 1.501612, 0.715527, 0.267559, -0.180658, 1.497898, 0.714523, 0.290926, -0.194405,
+ 1.493208, 0.713266, 0.314863, -0.208302, 1.487388, 0.711758, 0.339053, -0.222020, 1.479677,
+ 0.709982, 0.363627, -0.235683, 1.470950, 0.707958, 0.388887, -0.248723, 1.459907, 0.705346,
+ 0.415474, -0.260563, 1.446579, 0.701644, 0.442065, -0.271352, 1.429962, 0.697134, 0.469418,
+ -0.281541, 1.414343, 0.691665, 0.496419, -0.290429, 1.395681, 0.685227, 0.523071, -0.298032,
+ 1.375347, 0.677815, 0.549641, -0.304679, 1.354816, 0.669063, 0.575489, -0.309902, 1.332505,
+ 0.659071, 0.601108, -0.313771, 1.309752, 0.647799, 0.627199, -0.316225, 1.288381, 0.634856,
+ 0.653243, -0.316679, 1.265785, 0.619627, 0.678960, -0.315816, 1.244333, 0.603244, 0.704055,
+ -0.313776, 1.223315, 0.585191, 0.728713, -0.310417, 1.203142, 0.565969, 0.753301, -0.305786,
+ 1.184323, 0.545347, 0.777890, -0.299262, 1.166070, 0.522753, 0.802354, -0.291830, 1.149599,
+ 0.499017, 0.826005, -0.283281, 1.133655, 0.474335, 0.848920, -0.273512, 1.118132, 0.449019,
+ 0.872765, -0.262525, 1.105606, 0.422329, 0.895950, -0.250769, 1.093539, 0.395057, 0.918816,
+ -0.238257, 1.082388, 0.367709, 0.941089, -0.224381, 1.072484, 0.339350, 0.964514, -0.210289,
+ 1.064054, 0.311239, 0.987128, -0.195488, 1.056645, 0.283272, 1.009064, -0.179491, 1.049549,
+ 0.255163, 1.030163, -0.163172, 1.042741, 0.227757, 1.052502, -0.146457, 1.038270, 0.200970,
+ 1.072971, -0.129054, 1.035014, 0.175767, 1.091223, -0.111285, 1.032231, 0.151118, 1.106518,
+ -0.092617, 1.028211, 0.126196, 1.119235, -0.074168, 1.023686, 0.100828, 1.129311, -0.055212,
+ 1.018311, 0.075240, 1.135983, -0.036571, 1.011485, 0.049558, 1.141648, -0.017954, 1.004952,
+ 0.024273, 1.147938, 0.000125, 1.000009, -0.000048, 0.000199, -0.000151, 1.566887, 0.757466,
+ 0.000504, -0.000382, 1.574111, 0.757466, 0.002016, -0.001527, 1.573735, 0.757466, 0.004535,
+ -0.003435, 1.573737, 0.757466, 0.008062, -0.006107, 1.573782, 0.757464, 0.012599, -0.009542,
+ 1.573796, 0.757460, 0.018142, -0.013739, 1.573710, 0.757455, 0.024694, -0.018697, 1.573562,
+ 0.757446, 0.032259, -0.024418, 1.573667, 0.757429, 0.040834, -0.030895, 1.573555, 0.757407,
+ 0.050422, -0.038127, 1.573383, 0.757376, 0.061025, -0.046108, 1.573086, 0.757332, 0.072650,
+ -0.054835, 1.572833, 0.757274, 0.085296, -0.064294, 1.572395, 0.757195, 0.098962, -0.074376,
+ 1.571729, 0.757087, 0.113649, -0.084955, 1.570571, 0.756925, 0.129389, -0.096334, 1.569582,
+ 0.756729, 0.146167, -0.108406, 1.568444, 0.756481, 0.163973, -0.121056, 1.566905, 0.756158,
+ 0.182798, -0.133970, 1.564939, 0.755715, 0.202650, -0.147522, 1.562666, 0.755167, 0.223502,
+ -0.161466, 1.559877, 0.754465, 0.245269, -0.175539, 1.556008, 0.753552, 0.268010, -0.189957,
+ 1.552013, 0.752420, 0.291474, -0.204361, 1.546509, 0.751008, 0.315527, -0.218714, 1.539575,
+ 0.749266, 0.339954, -0.233029, 1.530968, 0.747232, 0.364649, -0.247149, 1.520994, 0.744906,
+ 0.389520, -0.260672, 1.507748, 0.742123, 0.415717, -0.272873, 1.491777, 0.738187, 0.442862,
+ -0.284317, 1.475658, 0.733189, 0.469939, -0.294552, 1.456572, 0.727165, 0.496916, -0.303517,
+ 1.435237, 0.720043, 0.523480, -0.311061, 1.412192, 0.711640, 0.550092, -0.317596, 1.389033,
+ 0.702174, 0.576384, -0.322921, 1.365086, 0.691225, 0.602280, -0.326806, 1.341317, 0.678841,
+ 0.627676, -0.329057, 1.316518, 0.664815, 0.653458, -0.329372, 1.291877, 0.648548, 0.679227,
+ -0.328067, 1.268126, 0.630676, 0.704476, -0.325585, 1.244424, 0.611585, 0.729232, -0.321775,
+ 1.223010, 0.590803, 0.753405, -0.316713, 1.201297, 0.568653, 0.777274, -0.309858, 1.181071,
+ 0.544763, 0.801882, -0.301866, 1.162826, 0.519747, 0.826030, -0.292861, 1.145704, 0.493531,
+ 0.849359, -0.282794, 1.129629, 0.466900, 0.871837, -0.271197, 1.114155, 0.439230, 0.895896,
+ -0.258954, 1.102334, 0.410570, 0.918951, -0.245878, 1.090163, 0.381314, 0.941148, -0.231897,
+ 1.078738, 0.352268, 0.963464, -0.216743, 1.068862, 0.322688, 0.986628, -0.201486, 1.061077,
+ 0.293523, 1.009289, -0.185521, 1.053561, 0.264125, 1.030659, -0.168429, 1.046627, 0.235706,
+ 1.052382, -0.151210, 1.040953, 0.208022, 1.073476, -0.133289, 1.036534, 0.181245, 1.092237,
+ -0.114768, 1.033580, 0.155661, 1.108200, -0.095917, 1.029997, 0.130223, 1.121435, -0.076492,
+ 1.025374, 0.104098, 1.131382, -0.057204, 1.019485, 0.077776, 1.137994, -0.037747, 1.012188,
+ 0.051250, 1.143441, -0.018673, 1.005309, 0.025245, 1.149714, 0.000216, 1.000004, -0.000120,
+ 0.000200, -0.000159, 1.633988, 0.797469, 0.000504, -0.000402, 1.636076, 0.797469, 0.002016,
+ -0.001607, 1.635679, 0.797467, 0.004535, -0.003617, 1.636040, 0.797468, 0.008063, -0.006430,
+ 1.636159, 0.797467, 0.012599, -0.010046, 1.636128, 0.797462, 0.018141, -0.014464, 1.635730,
+ 0.797457, 0.024696, -0.019685, 1.635836, 0.797445, 0.032259, -0.025705, 1.635719, 0.797426,
+ 0.040835, -0.032523, 1.635610, 0.797401, 0.050425, -0.040135, 1.635460, 0.797363, 0.061033,
+ -0.048536, 1.635182, 0.797313, 0.072661, -0.057718, 1.634817, 0.797243, 0.085315, -0.067666,
+ 1.634314, 0.797150, 0.098985, -0.078179, 1.633350, 0.797016, 0.113699, -0.089383, 1.632253,
+ 0.796839, 0.129456, -0.101364, 1.631025, 0.796623, 0.146275, -0.114081, 1.629867, 0.796331,
+ 0.164108, -0.127318, 1.628043, 0.795956, 0.182983, -0.140901, 1.625813, 0.795458, 0.202891,
+ -0.155174, 1.623149, 0.794834, 0.223787, -0.169654, 1.619686, 0.794015, 0.245678, -0.184540,
+ 1.615694, 0.793013, 0.268495, -0.199543, 1.610812, 0.791727, 0.292093, -0.214639, 1.604629,
+ 0.790107, 0.316184, -0.229499, 1.596061, 0.788154, 0.340986, -0.244407, 1.587195, 0.785797,
+ 0.365808, -0.258907, 1.575031, 0.783093, 0.390528, -0.272746, 1.559448, 0.779970, 0.416510,
+ -0.285845, 1.543294, 0.775852, 0.443443, -0.297404, 1.523476, 0.770323, 0.470442, -0.307757,
+ 1.501515, 0.763721, 0.497499, -0.316846, 1.477841, 0.755889, 0.524316, -0.324561, 1.452427,
+ 0.746662, 0.551212, -0.331060, 1.427421, 0.736004, 0.577323, -0.335956, 1.400369, 0.723810,
+ 0.602976, -0.339501, 1.373093, 0.710184, 0.628357, -0.341577, 1.345853, 0.695017, 0.653642,
+ -0.342031, 1.319040, 0.677972, 0.679440, -0.340342, 1.292490, 0.658877, 0.704744, -0.337356,
+ 1.267182, 0.638085, 0.729692, -0.333042, 1.243280, 0.615615, 0.753920, -0.327504, 1.219751,
+ 0.592054, 0.777695, -0.320537, 1.197796, 0.566967, 0.801426, -0.311880, 1.176872, 0.540643,
+ 0.825649, -0.302211, 1.158160, 0.512906, 0.849282, -0.291665, 1.141257, 0.484587, 0.872341,
+ -0.280050, 1.125469, 0.455556, 0.895110, -0.266978, 1.110222, 0.425652, 0.918841, -0.253326,
+ 1.097419, 0.395015, 0.941209, -0.238899, 1.086101, 0.364948, 0.963142, -0.223523, 1.075023,
+ 0.334151, 0.985996, -0.207346, 1.065628, 0.303708, 1.008718, -0.190889, 1.057256, 0.273008,
+ 1.030554, -0.173517, 1.049720, 0.243221, 1.053085, -0.155645, 1.043837, 0.214426, 1.074267,
+ -0.137472, 1.039312, 0.187036, 1.093591, -0.118385, 1.035457, 0.160512, 1.109850, -0.098883,
+ 1.031630, 0.134384, 1.123516, -0.079050, 1.026762, 0.107424, 1.133578, -0.058977, 1.020640,
+ 0.080317, 1.140289, -0.039013, 1.013096, 0.052944, 1.145610, -0.019228, 1.005694, 0.025989,
+ 1.151704, 0.000105, 0.999981, -0.000019, 0.000200, -0.000168, 1.704841, 0.839096, 0.000504,
+ -0.000423, 1.704242, 0.839097, 0.002016, -0.001691, 1.703821, 0.839091, 0.004534, -0.003805,
+ 1.703804, 0.839094, 0.008063, -0.006765, 1.704224, 0.839092, 0.012598, -0.010570, 1.704013,
+ 0.839087, 0.018142, -0.015219, 1.703889, 0.839079, 0.024697, -0.020712, 1.704023, 0.839066,
+ 0.032261, -0.027046, 1.703836, 0.839045, 0.040837, -0.034218, 1.703608, 0.839014, 0.050429,
+ -0.042224, 1.703414, 0.838972, 0.061041, -0.051061, 1.703148, 0.838912, 0.072676, -0.060717,
+ 1.702744, 0.838831, 0.085340, -0.071175, 1.702223, 0.838724, 0.099023, -0.082182, 1.700984,
+ 0.838567, 0.113759, -0.094007, 1.699764, 0.838367, 0.129546, -0.106621, 1.698462, 0.838112,
+ 0.146382, -0.119956, 1.696938, 0.837782, 0.164260, -0.133760, 1.694868, 0.837346, 0.183188,
+ -0.148108, 1.692262, 0.836780, 0.203158, -0.163075, 1.689251, 0.836073, 0.224147, -0.178255,
+ 1.685408, 0.835148, 0.246147, -0.193900, 1.680946, 0.833992, 0.269072, -0.209553, 1.675277,
+ 0.832546, 0.292718, -0.225226, 1.667626, 0.830727, 0.317159, -0.240836, 1.658952, 0.828510,
+ 0.341979, -0.256103, 1.647624, 0.825843, 0.366844, -0.270887, 1.633014, 0.822760, 0.392043,
+ -0.285324, 1.617191, 0.819159, 0.417356, -0.298817, 1.597501, 0.814788, 0.444093, -0.310711,
+ 1.575184, 0.808751, 0.471379, -0.321410, 1.551590, 0.801294, 0.498267, -0.330421, 1.524134,
+ 0.792711, 0.525401, -0.338331, 1.496672, 0.782480, 0.551846, -0.344430, 1.467062, 0.770659,
+ 0.578009, -0.349047, 1.436943, 0.757348, 0.604054, -0.352490, 1.407611, 0.742541, 0.629387,
+ -0.354158, 1.377441, 0.726071, 0.654435, -0.354422, 1.347651, 0.707524, 0.679845, -0.352663,
+ 1.318769, 0.687067, 0.704892, -0.348994, 1.290600, 0.664637, 0.729763, -0.344105, 1.263997,
+ 0.640663, 0.754345, -0.338129, 1.239273, 0.615484, 0.778629, -0.330905, 1.215858, 0.589210,
+ 0.801939, -0.322113, 1.192318, 0.561550, 0.825723, -0.311673, 1.171380, 0.532175, 0.849387,
+ -0.300410, 1.152991, 0.502055, 0.872792, -0.288328, 1.136139, 0.471308, 0.895083, -0.275087,
+ 1.119534, 0.440427, 0.918335, -0.260700, 1.105542, 0.409260, 0.941577, -0.245717, 1.093070,
+ 0.377142, 0.963992, -0.230079, 1.081207, 0.345289, 0.986510, -0.213523, 1.071488, 0.313508,
+ 1.008806, -0.196157, 1.062011, 0.281962, 1.030724, -0.178467, 1.053240, 0.251177, 1.053782,
+ -0.160291, 1.047057, 0.220986, 1.075451, -0.141308, 1.041842, 0.192256, 1.094947, -0.121975,
+ 1.037704, 0.165023, 1.111783, -0.101744, 1.033300, 0.138228, 1.125525, -0.081476, 1.028234,
+ 0.110679, 1.135873, -0.060770, 1.021695, 0.082672, 1.142478, -0.040207, 1.013838, 0.054506,
+ 1.147889, -0.019908, 1.006166, 0.026938, 1.153852, 0.000204, 0.999983, -0.000123, 0.000199,
+ -0.000176, 1.771601, 0.882501, 0.000504, -0.000445, 1.779195, 0.882504, 0.002016, -0.001779,
+ 1.779635, 0.882498, 0.004536, -0.004003, 1.779586, 0.882499, 0.008062, -0.007115, 1.778613,
+ 0.882496, 0.012598, -0.011116, 1.778678, 0.882492, 0.018142, -0.016005, 1.778531, 0.882481,
+ 0.024696, -0.021782, 1.778556, 0.882466, 0.032262, -0.028444, 1.778507, 0.882442, 0.040842,
+ -0.035987, 1.778385, 0.882408, 0.050436, -0.044404, 1.778034, 0.882364, 0.061053, -0.053695,
+ 1.777761, 0.882287, 0.072692, -0.063842, 1.777256, 0.882190, 0.085364, -0.074821, 1.776518,
+ 0.882067, 0.099064, -0.086368, 1.775080, 0.881884, 0.113828, -0.098805, 1.773836, 0.881657,
+ 0.129649, -0.112090, 1.772370, 0.881361, 0.146518, -0.126067, 1.770594, 0.880982, 0.164440,
+ -0.140493, 1.768089, 0.880484, 0.183437, -0.155646, 1.765301, 0.879843, 0.203468, -0.171266,
+ 1.761698, 0.879035, 0.224562, -0.187231, 1.757518, 0.877982, 0.246665, -0.203540, 1.752318,
+ 0.876667, 0.269652, -0.219916, 1.745356, 0.875028, 0.293531, -0.236255, 1.737186, 0.872977,
+ 0.318048, -0.252410, 1.726709, 0.870448, 0.342963, -0.268192, 1.713109, 0.867400, 0.368336,
+ -0.283587, 1.698087, 0.863882, 0.393512, -0.298186, 1.678638, 0.859724, 0.418602, -0.311882,
+ 1.655604, 0.854835, 0.445080, -0.324500, 1.632250, 0.848353, 0.472289, -0.335295, 1.605069,
+ 0.840218, 0.499128, -0.344256, 1.573846, 0.830556, 0.525834, -0.351716, 1.541120, 0.819269,
+ 0.553177, -0.358241, 1.511385, 0.806222, 0.579480, -0.362640, 1.477866, 0.791647, 0.605205,
+ -0.365513, 1.444218, 0.775398, 0.630617, -0.366822, 1.410954, 0.757144, 0.655730, -0.366785,
+ 1.379010, 0.737323, 0.680529, -0.364904, 1.347280, 0.715601, 0.705800, -0.360990, 1.316416,
+ 0.691547, 0.730550, -0.355397, 1.286344, 0.666141, 0.754970, -0.348664, 1.258954, 0.638929,
+ 0.779042, -0.340774, 1.232965, 0.611015, 0.802839, -0.331767, 1.209775, 0.581877, 0.825793,
+ -0.321054, 1.185813, 0.551509, 0.849512, -0.309016, 1.165080, 0.519698, 0.873120, -0.296369,
+ 1.147091, 0.487506, 0.895942, -0.282704, 1.129658, 0.455320, 0.917996, -0.268007, 1.113463,
+ 0.422605, 0.941281, -0.252329, 1.100040, 0.389347, 0.964584, -0.236203, 1.087973, 0.356430,
+ 0.986371, -0.219209, 1.075983, 0.323089, 1.009522, -0.201588, 1.066940, 0.290806, 1.031976,
+ -0.183296, 1.057999, 0.258682, 1.053461, -0.164509, 1.049542, 0.227722, 1.076121, -0.145165,
+ 1.043718, 0.197439, 1.096597, -0.125199, 1.039607, 0.169578, 1.113908, -0.104921, 1.035528,
+ 0.142222, 1.127939, -0.083623, 1.029807, 0.113802, 1.138391, -0.062589, 1.023312, 0.085164,
+ 1.145110, -0.041376, 1.014806, 0.056186, 1.150141, -0.020433, 1.006501, 0.027654, 1.156069,
+ 0.000097, 0.999949, -0.000046, 0.000200, -0.000185, 1.858268, 0.927857, 0.000504, -0.000468,
+ 1.861583, 0.927859, 0.002016, -0.001870, 1.860659, 0.927855, 0.004535, -0.004208, 1.860963,
+ 0.927867, 0.008063, -0.007480, 1.860766, 0.927855, 0.012594, -0.011683, 1.859996, 0.927851,
+ 0.018142, -0.016828, 1.860739, 0.927839, 0.024698, -0.022901, 1.860763, 0.927818, 0.032263,
+ -0.029903, 1.860501, 0.927791, 0.040846, -0.037834, 1.860431, 0.927751, 0.050440, -0.046680,
+ 1.859827, 0.927690, 0.061066, -0.056446, 1.859624, 0.927610, 0.072713, -0.067109, 1.859039,
+ 0.927505, 0.085393, -0.078613, 1.858144, 0.927357, 0.099120, -0.090747, 1.856618, 0.927145,
+ 0.113910, -0.103850, 1.855221, 0.926884, 0.129755, -0.117777, 1.853470, 0.926546, 0.146669,
+ -0.132441, 1.851413, 0.926104, 0.164648, -0.147565, 1.848498, 0.925530, 0.183708, -0.163470,
+ 1.845281, 0.924802, 0.203832, -0.179763, 1.841273, 0.923871, 0.225029, -0.196564, 1.836481,
+ 0.922691, 0.247221, -0.213537, 1.830273, 0.921198, 0.270343, -0.230662, 1.822374, 0.919320,
+ 0.294399, -0.247740, 1.812975, 0.917008, 0.319040, -0.264448, 1.800693, 0.914141, 0.344269,
+ -0.280831, 1.785923, 0.910707, 0.369625, -0.296478, 1.767203, 0.906585, 0.394925, -0.311287,
+ 1.744434, 0.901918, 0.420583, -0.325578, 1.720938, 0.896240, 0.446200, -0.338384, 1.693005,
+ 0.889335, 0.472969, -0.349187, 1.660901, 0.880394, 0.500490, -0.358687, 1.628806, 0.869705,
+ 0.527312, -0.366042, 1.593001, 0.857145, 0.554207, -0.372045, 1.557046, 0.842943, 0.580620,
+ -0.376134, 1.520192, 0.826837, 0.606480, -0.378636, 1.482947, 0.808891, 0.631815, -0.379414,
+ 1.445954, 0.789119, 0.657021, -0.378972, 1.410833, 0.767564, 0.681686, -0.376728, 1.376575,
+ 0.744338, 0.706498, -0.372844, 1.342935, 0.718799, 0.731258, -0.366649, 1.311052, 0.691756,
+ 0.755937, -0.359354, 1.280478, 0.662683, 0.779259, -0.350487, 1.250585, 0.632892, 0.803295,
+ -0.340941, 1.225722, 0.602160, 0.826570, -0.330174, 1.201003, 0.570520, 0.849954, -0.317854,
+ 1.178488, 0.537651, 0.873696, -0.304426, 1.158302, 0.503799, 0.896695, -0.290120, 1.139886,
+ 0.469645, 0.919149, -0.275106, 1.122884, 0.435625, 0.942121, -0.259282, 1.107691, 0.401228,
+ 0.964627, -0.242123, 1.093661, 0.367086, 0.986614, -0.224575, 1.081580, 0.332885, 1.009623,
+ -0.206837, 1.071375, 0.299209, 1.033126, -0.188092, 1.062241, 0.266187, 1.054954, -0.168637,
+ 1.052912, 0.233733, 1.077660, -0.149166, 1.047047, 0.203192, 1.097983, -0.128587, 1.041607,
+ 0.173918, 1.115586, -0.107339, 1.036850, 0.145531, 1.130170, -0.086203, 1.031427, 0.116890,
+ 1.141018, -0.064171, 1.024395, 0.087388, 1.147681, -0.042530, 1.015719, 0.057733, 1.152560,
+ -0.021011, 1.006883, 0.028413, 1.158406, 0.000158, 0.999897, -0.000106, 0.000200, -0.000195,
+ 1.950982, 0.975366, 0.000504, -0.000491, 1.950207, 0.975365, 0.002015, -0.001966, 1.950675,
+ 0.975362, 0.004535, -0.004423, 1.951281, 0.975370, 0.008062, -0.007863, 1.951045, 0.975362,
+ 0.012597, -0.012285, 1.951199, 0.975356, 0.018145, -0.017692, 1.951528, 0.975340, 0.024699,
+ -0.024074, 1.951194, 0.975321, 0.032266, -0.031434, 1.950865, 0.975288, 0.040853, -0.039771,
+ 1.951038, 0.975244, 0.050452, -0.049067, 1.950336, 0.975173, 0.061077, -0.059324, 1.949805,
+ 0.975078, 0.072736, -0.070526, 1.949133, 0.974951, 0.085431, -0.082528, 1.947947, 0.974777,
+ 0.099182, -0.095345, 1.946337, 0.974540, 0.113999, -0.109118, 1.944725, 0.974241, 0.129888,
+ -0.123741, 1.942857, 0.973852, 0.146842, -0.139071, 1.940251, 0.973342, 0.164890, -0.154986,
+ 1.937086, 0.972684, 0.184025, -0.171661, 1.933404, 0.971856, 0.204245, -0.188672, 1.928770,
+ 0.970785, 0.225528, -0.206252, 1.923041, 0.969448, 0.247841, -0.223972, 1.915788, 0.967742,
+ 0.271157, -0.241827, 1.907008, 0.965607, 0.295297, -0.259562, 1.895854, 0.963007, 0.320121,
+ -0.276909, 1.881289, 0.959722, 0.345566, -0.293883, 1.864528, 0.955831, 0.371012, -0.309816,
+ 1.842062, 0.951127, 0.396834, -0.325157, 1.818068, 0.945725, 0.422277, -0.339357, 1.788874,
+ 0.939318, 0.447928, -0.352387, 1.758283, 0.931470, 0.474315, -0.363680, 1.723668, 0.921900,
+ 0.501560, -0.372963, 1.686081, 0.909996, 0.528391, -0.380159, 1.645816, 0.896244, 0.554754,
+ -0.385545, 1.603709, 0.880326, 0.581888, -0.389778, 1.565475, 0.862716, 0.607791, -0.391839,
+ 1.524196, 0.843146, 0.633511, -0.392331, 1.483921, 0.821554, 0.658621, -0.391193, 1.445013,
+ 0.798336, 0.683160, -0.388424, 1.406963, 0.773299, 0.707429, -0.384104, 1.370996, 0.746668,
+ 0.732212, -0.377945, 1.335879, 0.717502, 0.756871, -0.369856, 1.302489, 0.686954, 0.781065,
+ -0.360707, 1.271815, 0.655372, 0.804167, -0.350091, 1.242416, 0.622683, 0.827948, -0.338941,
+ 1.217208, 0.589185, 0.850901, -0.326427, 1.192354, 0.555005, 0.873589, -0.312199, 1.169639,
+ 0.519594, 0.897085, -0.297374, 1.150181, 0.484105, 0.920459, -0.281932, 1.132858, 0.448661,
+ 0.942637, -0.265625, 1.115401, 0.413051, 0.965341, -0.248332, 1.101078, 0.377329, 0.987530,
+ -0.229983, 1.087377, 0.342349, 1.010739, -0.211647, 1.076582, 0.307824, 1.033449, -0.192725,
+ 1.065900, 0.273368, 1.055618, -0.172726, 1.056958, 0.240238, 1.079345, -0.152640, 1.049620,
+ 0.208322, 1.100058, -0.131931, 1.044084, 0.178242, 1.118547, -0.110351, 1.039387, 0.149493,
+ 1.132748, -0.088128, 1.033049, 0.119673, 1.143419, -0.066069, 1.025521, 0.089728, 1.150316,
+ -0.043513, 1.016378, 0.059253, 1.155208, -0.021593, 1.007506, 0.029140, 1.160871, 0.000111,
+ 0.999916, -0.000035, 0.000201, -0.000206, 2.061000, 1.025243, 0.000504, -0.000516, 2.049647,
+ 1.025237, 0.002015, -0.002066, 2.050169, 1.025237, 0.004535, -0.004650, 2.051254, 1.025255,
+ 0.008063, -0.008266, 2.051302, 1.025236, 0.012600, -0.012915, 2.051508, 1.025226, 0.018144,
+ -0.018594, 2.050981, 1.025215, 0.024700, -0.025304, 2.050841, 1.025190, 0.032267, -0.033038,
+ 2.050537, 1.025152, 0.040852, -0.041795, 2.050660, 1.025090, 0.050460, -0.051570, 2.049921,
+ 1.025017, 0.061094, -0.062347, 2.049350, 1.024908, 0.072762, -0.074111, 2.048517, 1.024760,
+ 0.085475, -0.086661, 2.047009, 1.024555, 0.099249, -0.100160, 2.045261, 1.024278, 0.114106,
+ -0.114628, 2.043508, 1.023941, 0.130032, -0.130002, 2.041321, 1.023488, 0.147050, -0.145985,
+ 2.038299, 1.022905, 0.165164, -0.162762, 2.034658, 1.022151, 0.184380, -0.180172, 2.030312,
+ 1.021200, 0.204704, -0.198022, 2.024944, 1.019966, 0.226129, -0.216359, 2.018546, 1.018424,
+ 0.248582, -0.234923, 2.010153, 1.016519, 0.272011, -0.253474, 1.999659, 1.014072, 0.296259,
+ -0.271820, 1.986076, 1.011071, 0.321423, -0.289959, 1.970618, 1.007389, 0.346897, -0.307283,
+ 1.949667, 1.002955, 0.372750, -0.323817, 1.925287, 0.997633, 0.398603, -0.339241, 1.896006,
+ 0.991354, 0.424351, -0.353633, 1.863658, 0.983937, 0.449887, -0.366660, 1.827430, 0.975254,
+ 0.475715, -0.378213, 1.789521, 0.964753, 0.502204, -0.387133, 1.745632, 0.951594, 0.530179,
+ -0.394976, 1.705347, 0.936344, 0.556732, -0.400134, 1.658928, 0.918907, 0.583123, -0.403439,
+ 1.613077, 0.899504, 0.609477, -0.405285, 1.567884, 0.878172, 0.634927, -0.405055, 1.523507,
+ 0.854396, 0.660357, -0.403494, 1.481712, 0.829259, 0.684851, -0.400104, 1.439000, 0.802359,
+ 0.709654, -0.395536, 1.400956, 0.773534, 0.733472, -0.388996, 1.362156, 0.743230, 0.757502,
+ -0.380263, 1.325113, 0.711090, 0.782249, -0.370594, 1.292913, 0.677166, 0.806017, -0.359509,
+ 1.262088, 0.642527, 0.828687, -0.347126, 1.232059, 0.607589, 0.852372, -0.334474, 1.207160,
+ 0.571938, 0.874266, -0.320074, 1.181978, 0.535518, 0.898168, -0.304719, 1.161156, 0.498375,
+ 0.920456, -0.288246, 1.140667, 0.461179, 0.942832, -0.271311, 1.122780, 0.424533, 0.966458,
+ -0.254154, 1.108743, 0.387784, 0.988907, -0.235659, 1.093872, 0.351689, 1.011557, -0.216322,
+ 1.081959, 0.315743, 1.035099, -0.197007, 1.070885, 0.280402, 1.056354, -0.176878, 1.059968,
+ 0.246472, 1.079854, -0.156058, 1.051815, 0.212818, 1.101494, -0.134772, 1.045757, 0.182143,
+ 1.120587, -0.113071, 1.041169, 0.152867, 1.135399, -0.090411, 1.034844, 0.122796, 1.146612,
+ -0.067477, 1.026974, 0.091888, 1.153168, -0.044849, 1.017303, 0.060779, 1.157912, -0.021998,
+ 1.007735, 0.029919, 1.163607, 0.000121, 0.999959, 0.000003, 0.000200, -0.000216, 2.163956,
+ 1.077737, 0.000504, -0.000543, 2.161128, 1.077732, 0.002016, -0.002173, 2.162732, 1.077729,
+ 0.004535, -0.004887, 2.161402, 1.077749, 0.008066, -0.008692, 2.163252, 1.077732, 0.012599,
+ -0.013576, 2.161300, 1.077727, 0.018145, -0.019546, 2.161151, 1.077702, 0.024702, -0.026599,
+ 2.161223, 1.077675, 0.032272, -0.034729, 2.160949, 1.077632, 0.040862, -0.043936, 2.160967,
+ 1.077575, 0.050470, -0.054203, 2.160035, 1.077473, 0.061113, -0.065528, 2.159490, 1.077348,
+ 0.072794, -0.077882, 2.158517, 1.077178, 0.085528, -0.091030, 2.156605, 1.076937, 0.099337,
+ -0.105251, 2.154828, 1.076631, 0.114228, -0.120456, 2.152812, 1.076229, 0.130202, -0.136573,
+ 2.150298, 1.075713, 0.147284, -0.153306, 2.146752, 1.075031, 0.165480, -0.170931, 2.142744,
+ 1.074173, 0.184793, -0.189083, 2.137475, 1.073063, 0.205224, -0.207840, 2.131320, 1.071683,
+ 0.226743, -0.226939, 2.123154, 1.069914, 0.249401, -0.246344, 2.114086, 1.067718, 0.272955,
+ -0.265640, 2.101599, 1.064924, 0.297494, -0.284846, 2.086612, 1.061512, 0.322731, -0.303452,
+ 2.067356, 1.057359, 0.348451, -0.321330, 2.043711, 1.052294, 0.374451, -0.338201, 2.015033,
+ 1.046153, 0.400454, -0.353816, 1.981139, 1.039003, 0.426434, -0.368216, 1.944128, 1.030498,
+ 0.452088, -0.381251, 1.903094, 1.020454, 0.477901, -0.392833, 1.860402, 1.008793, 0.504173,
+ -0.402408, 1.814402, 0.994791, 0.531520, -0.409545, 1.766273, 0.977733, 0.558049, -0.414351,
+ 1.714119, 0.958625, 0.584778, -0.417437, 1.664612, 0.937189, 0.610808, -0.418519, 1.613793,
+ 0.913543, 0.636915, -0.418094, 1.565942, 0.888137, 0.662204, -0.415742, 1.518783, 0.860728,
+ 0.686848, -0.411746, 1.473306, 0.831793, 0.710992, -0.406153, 1.430153, 0.800862, 0.735382,
+ -0.399519, 1.389824, 0.768768, 0.759079, -0.390927, 1.350744, 0.734825, 0.782912, -0.380111,
+ 1.313559, 0.699450, 0.806746, -0.368383, 1.280028, 0.663191, 0.830269, -0.355606, 1.249814,
+ 0.625927, 0.853305, -0.341988, 1.221138, 0.588644, 0.876326, -0.327545, 1.195837, 0.550849,
+ 0.898322, -0.311779, 1.171844, 0.512694, 0.921811, -0.294944, 1.150671, 0.474225, 0.944563,
+ -0.277333, 1.132224, 0.435772, 0.967089, -0.259340, 1.115422, 0.398001, 0.989754, -0.240836,
+ 1.100405, 0.360802, 1.012470, -0.221293, 1.086533, 0.323566, 1.036426, -0.201191, 1.075496,
+ 0.287387, 1.058709, -0.180590, 1.064233, 0.252184, 1.081593, -0.159810, 1.055296, 0.218441,
+ 1.103146, -0.137772, 1.047978, 0.186223, 1.122814, -0.115347, 1.042693, 0.156019, 1.137790,
+ -0.092582, 1.036049, 0.125579, 1.149184, -0.069152, 1.027944, 0.093986, 1.156062, -0.045661,
+ 1.018039, 0.062122, 1.160733, -0.022719, 1.008072, 0.030650, 1.166487, 0.000231, 1.000063,
+ -0.000120, 0.000201, -0.000228, 2.308308, 1.133128, 0.000504, -0.000571, 2.283756, 1.133123,
+ 0.002016, -0.002284, 2.283756, 1.133123, 0.004535, -0.005138, 2.283310, 1.133144, 0.008048,
+ -0.009119, 2.266192, 1.133138, 0.012600, -0.014274, 2.284377, 1.133110, 0.018147, -0.020553,
+ 2.284204, 1.133093, 0.024702, -0.027964, 2.283517, 1.133060, 0.032272, -0.036510, 2.282997,
+ 1.133007, 0.040866, -0.046188, 2.282986, 1.132930, 0.050481, -0.056979, 2.282260, 1.132824,
+ 0.061133, -0.068881, 2.281533, 1.132678, 0.072830, -0.081850, 2.280504, 1.132481, 0.085592,
+ -0.095657, 2.278304, 1.132202, 0.099431, -0.110594, 2.276269, 1.131845, 0.114360, -0.126590,
+ 2.273890, 1.131383, 0.130388, -0.143454, 2.270761, 1.130784, 0.147547, -0.161029, 2.266794,
+ 1.130003, 0.165836, -0.179523, 2.262332, 1.129016, 0.185269, -0.198527, 2.256326, 1.127738,
+ 0.205822, -0.218138, 2.249031, 1.126156, 0.227527, -0.238141, 2.239993, 1.124132, 0.250325,
+ -0.258302, 2.228878, 1.121594, 0.274070, -0.278329, 2.214204, 1.118449, 0.298793, -0.298310,
+ 2.196654, 1.114528, 0.324131, -0.317462, 2.173394, 1.109783, 0.350101, -0.335853, 2.146395,
+ 1.103901, 0.376293, -0.353064, 2.112341, 1.096954, 0.402547, -0.368950, 2.073700, 1.088642,
+ 0.428791, -0.383462, 2.031152, 1.078946, 0.454976, -0.396635, 1.986661, 1.067536, 0.480566,
+ -0.407873, 1.937038, 1.054403, 0.506154, -0.417303, 1.885155, 1.038894, 0.532862, -0.424194,
+ 1.830369, 1.020535, 0.560354, -0.429344, 1.776976, 0.999295, 0.587114, -0.431949, 1.721214,
+ 0.975990, 0.613345, -0.432547, 1.665739, 0.950239, 0.639335, -0.431338, 1.612200, 0.922467,
+ 0.664996, -0.428473, 1.561035, 0.892593, 0.688947, -0.423355, 1.508240, 0.861325, 0.713403,
+ -0.417235, 1.461776, 0.828289, 0.737649, -0.409848, 1.418888, 0.793863, 0.761275, -0.400901,
+ 1.376807, 0.758074, 0.784778, -0.390174, 1.337204, 0.721974, 0.808762, -0.377683, 1.301527,
+ 0.682718, 0.831993, -0.364037, 1.267144, 0.644001, 0.854696, -0.349494, 1.236023, 0.605478,
+ 0.877933, -0.334499, 1.209284, 0.565588, 0.900180, -0.318435, 1.183967, 0.526138, 0.923039,
+ -0.301669, 1.161513, 0.486524, 0.945895, -0.283298, 1.140838, 0.446747, 0.968069, -0.264438,
+ 1.122475, 0.408041, 0.991179, -0.245463, 1.106968, 0.369477, 1.012926, -0.225680, 1.091435,
+ 0.331626, 1.036995, -0.205401, 1.079561, 0.294288, 1.060909, -0.184310, 1.068215, 0.257696,
+ 1.083531, -0.162846, 1.058133, 0.223343, 1.105644, -0.141040, 1.050851, 0.190541, 1.125691,
+ -0.117965, 1.045001, 0.159310, 1.141297, -0.094377, 1.038028, 0.128238, 1.152672, -0.070831,
+ 1.029694, 0.096282, 1.159333, -0.046853, 1.019136, 0.063720, 1.163819, -0.022991, 1.008518,
+ 0.031234, 1.169564, 0.000125, 1.000069, -0.000024, 0.000202, -0.000241, 2.458341, 1.191742,
+ 0.000504, -0.000600, 2.418738, 1.191740, 0.002015, -0.002401, 2.418821, 1.191730, 0.004535,
+ -0.005405, 2.421986, 1.191756, 0.008071, -0.009618, 2.424988, 1.191753, 0.012600, -0.015012,
+ 2.420242, 1.191727, 0.018145, -0.021612, 2.419937, 1.191703, 0.024704, -0.029410, 2.419746,
+ 1.191662, 0.032278, -0.038398, 2.419409, 1.191604, 0.040874, -0.048574, 2.418995, 1.191515,
+ 0.050496, -0.059920, 2.418190, 1.191389, 0.061160, -0.072432, 2.417487, 1.191221, 0.072871,
+ -0.086009, 2.415853, 1.190984, 0.085664, -0.100559, 2.413669, 1.190664, 0.099543, -0.116283,
+ 2.411423, 1.190256, 0.114520, -0.133071, 2.408711, 1.189719, 0.130616, -0.150670, 2.404900,
+ 1.189019, 0.147856, -0.169197, 2.400512, 1.188125, 0.166235, -0.188545, 2.394939, 1.186972,
+ 0.185804, -0.208480, 2.388232, 1.185515, 0.206488, -0.228883, 2.379190, 1.183673, 0.228383,
+ -0.249897, 2.369208, 1.181382, 0.251305, -0.270851, 2.355459, 1.178478, 0.275349, -0.291780,
+ 2.339142, 1.174857, 0.300106, -0.312257, 2.316655, 1.170411, 0.325849, -0.332225, 2.291540,
+ 1.164883, 0.351782, -0.350862, 2.257242, 1.158196, 0.378248, -0.368431, 2.218671, 1.150173,
+ 0.404674, -0.384428, 2.173680, 1.140703, 0.431385, -0.399230, 2.127083, 1.129555, 0.457407,
+ -0.411875, 2.073236, 1.116436, 0.483275, -0.423013, 2.018223, 1.101373, 0.509278, -0.432624,
+ 1.962674, 1.084257, 0.534751, -0.439261, 1.900814, 1.064592, 0.561895, -0.443801, 1.839558,
+ 1.040881, 0.588677, -0.445872, 1.777763, 1.015208, 0.614900, -0.445896, 1.716550, 0.987252,
+ 0.641051, -0.444148, 1.657984, 0.957271, 0.666409, -0.440299, 1.600832, 0.924841, 0.691872,
+ -0.435318, 1.548237, 0.891185, 0.716638, -0.428631, 1.497572, 0.855929, 0.739864, -0.419872,
+ 1.447043, 0.819676, 0.763707, -0.410456, 1.403648, 0.781455, 0.786744, -0.399390, 1.360844,
+ 0.742965, 0.809585, -0.386381, 1.320529, 0.703260, 0.834164, -0.372622, 1.286467, 0.662385,
+ 0.856713, -0.357177, 1.252306, 0.621379, 0.879820, -0.341458, 1.223070, 0.580238, 0.902721,
+ -0.325024, 1.197115, 0.539028, 0.924650, -0.307543, 1.172314, 0.498592, 0.947613, -0.289557,
+ 1.151171, 0.457980, 0.969590, -0.269799, 1.129986, 0.417696, 0.992961, -0.250111, 1.113321,
+ 0.377529, 1.014582, -0.229761, 1.097149, 0.339096, 1.038069, -0.209375, 1.083913, 0.301119,
+ 1.061661, -0.188038, 1.071241, 0.263506, 1.085069, -0.165874, 1.060508, 0.227921, 1.107744,
+ -0.143437, 1.052930, 0.194062, 1.127982, -0.120574, 1.046396, 0.162506, 1.144541, -0.096569,
+ 1.039880, 0.130788, 1.155876, -0.072039, 1.030946, 0.098057, 1.162719, -0.047888, 1.020124,
+ 0.064956, 1.167089, -0.023740, 1.008953, 0.031966, 1.172775, 0.000277, 1.000067, -0.000111,
+ 0.000200, -0.000251, 2.573709, 1.253951, 0.000504, -0.000632, 2.572401, 1.253940, 0.002015,
+ -0.002527, 2.571267, 1.253927, 0.004535, -0.005687, 2.572481, 1.253948, 0.008062, -0.010108,
+ 2.571851, 1.253941, 0.012588, -0.015780, 2.568431, 1.253934, 0.018139, -0.022731, 2.569765,
+ 1.253893, 0.024709, -0.030948, 2.572115, 1.253853, 0.032283, -0.040401, 2.571456, 1.253785,
+ 0.040883, -0.051105, 2.571041, 1.253683, 0.050514, -0.063041, 2.570153, 1.253538, 0.061188,
+ -0.076195, 2.569085, 1.253336, 0.072926, -0.090402, 2.567184, 1.253065, 0.085746, -0.105745,
+ 2.564731, 1.252697, 0.099661, -0.122296, 2.561995, 1.252218, 0.114699, -0.139912, 2.559019,
+ 1.251590, 0.130882, -0.158362, 2.555017, 1.250766, 0.148202, -0.177856, 2.549419, 1.249744,
+ 0.166706, -0.198049, 2.542908, 1.248423, 0.186404, -0.219014, 2.535205, 1.246741, 0.207272,
+ -0.240376, 2.524893, 1.244596, 0.229345, -0.262230, 2.512804, 1.241917, 0.252494, -0.284134,
+ 2.496923, 1.238610, 0.276690, -0.305828, 2.476583, 1.234474, 0.301798, -0.327107, 2.451548,
+ 1.229292, 0.327423, -0.347300, 2.418630, 1.222997, 0.353848, -0.366699, 2.381002, 1.215366,
+ 0.380342, -0.384421, 2.334413, 1.206199, 0.407390, -0.400855, 2.285660, 1.195374, 0.433913,
+ -0.415241, 2.228604, 1.182290, 0.460837, -0.428275, 2.171532, 1.167385, 0.486381, -0.438573,
+ 2.105639, 1.150401, 0.511959, -0.447348, 2.040835, 1.130990, 0.537586, -0.454152, 1.974797,
+ 1.109302, 0.564035, -0.458684, 1.907895, 1.084131, 0.590690, -0.460058, 1.839482, 1.055803,
+ 0.617250, -0.459662, 1.772332, 1.025103, 0.643406, -0.457260, 1.707313, 0.992502, 0.668794,
+ -0.452666, 1.644722, 0.957657, 0.693930, -0.446641, 1.586832, 0.921340, 0.718708, -0.439121,
+ 1.531197, 0.883841, 0.743469, -0.430429, 1.480765, 0.844931, 0.766080, -0.419622, 1.430338,
+ 0.804786, 0.789801, -0.408368, 1.386295, 0.764206, 0.812718, -0.395392, 1.343758, 0.722565,
+ 0.835453, -0.380699, 1.304655, 0.680585, 0.858801, -0.364834, 1.269287, 0.637235, 0.881537,
+ -0.348092, 1.237493, 0.594579, 0.904656, -0.331087, 1.208862, 0.552313, 0.926357, -0.312966,
+ 1.182365, 0.510080, 0.949001, -0.294684, 1.159452, 0.468677, 0.971598, -0.275361, 1.138706,
+ 0.426723, 0.994905, -0.254947, 1.120552, 0.385875, 1.017981, -0.234109, 1.104215, 0.345751,
+ 1.040840, -0.213040, 1.089276, 0.306762, 1.063893, -0.191616, 1.075845, 0.269066, 1.086907,
+ -0.169272, 1.063788, 0.232171, 1.109937, -0.146076, 1.054977, 0.197826, 1.130808, -0.122544,
+ 1.048572, 0.165272, 1.146831, -0.098492, 1.040742, 0.133280, 1.158955, -0.073710, 1.031818,
+ 0.100262, 1.166161, -0.048610, 1.020747, 0.066165, 1.170491, -0.024209, 1.009380, 0.032741,
+ 1.176111, 0.000010, 1.000042, 0.000056, 0.000202, -0.000267, 2.786357, 1.320169, 0.000504,
+ -0.000665, 2.741889, 1.320168, 0.002015, -0.002660, 2.740000, 1.320143, 0.004536, -0.005987,
+ 2.744276, 1.320161, 0.008063, -0.010644, 2.743432, 1.320162, 0.012600, -0.016628, 2.741741,
+ 1.320148, 0.018144, -0.023937, 2.741314, 1.320127, 0.024708, -0.032577, 2.741916, 1.320061,
+ 0.032290, -0.042536, 2.742132, 1.319976, 0.040894, -0.053799, 2.741199, 1.319861, 0.050533,
+ -0.066361, 2.740258, 1.319691, 0.061223, -0.080202, 2.739045, 1.319458, 0.072985, -0.095109,
+ 2.736519, 1.319138, 0.085841, -0.111296, 2.733903, 1.318715, 0.099808, -0.128685, 2.730944,
+ 1.318156, 0.114903, -0.147202, 2.727293, 1.317424, 0.131164, -0.166575, 2.722169, 1.316485,
+ 0.148599, -0.187019, 2.716148, 1.315274, 0.167245, -0.208240, 2.708701, 1.313733, 0.187078,
+ -0.230151, 2.698998, 1.311792, 0.208153, -0.252538, 2.687341, 1.309343, 0.230418, -0.275295,
+ 2.672621, 1.306247, 0.253802, -0.298066, 2.653619, 1.302374, 0.278261, -0.320673, 2.629943,
+ 1.297573, 0.303527, -0.342528, 2.599228, 1.291625, 0.329571, -0.363531, 2.562226, 1.284374,
+ 0.355939, -0.382963, 2.515491, 1.275478, 0.382987, -0.401306, 2.464858, 1.264866, 0.409917,
+ -0.417455, 2.404877, 1.252184, 0.437015, -0.432067, 2.341408, 1.237415, 0.463474, -0.444204,
+ 2.271837, 1.220687, 0.489835, -0.454631, 2.200593, 1.200973, 0.516054, -0.463338, 2.129733,
+ 1.179346, 0.541397, -0.469425, 2.055635, 1.155039, 0.566798, -0.473526, 1.980812, 1.127866,
+ 0.593114, -0.474632, 1.904723, 1.097304, 0.619945, -0.473597, 1.832456, 1.063603, 0.646325,
+ -0.470656, 1.761501, 1.027971, 0.672320, -0.465675, 1.694248, 0.990692, 0.697163, -0.458527,
+ 1.629227, 0.951582, 0.721472, -0.449904, 1.568132, 0.911197, 0.745855, -0.440140, 1.512084,
+ 0.869745, 0.770089, -0.429338, 1.460694, 0.827648, 0.792546, -0.416701, 1.410739, 0.784728,
+ 0.815161, -0.403151, 1.365438, 0.741884, 0.837994, -0.388714, 1.324811, 0.697800, 0.861220,
+ -0.372573, 1.287723, 0.653341, 0.883737, -0.355024, 1.252491, 0.609455, 0.906784, -0.337092,
+ 1.221844, 0.565275, 0.928493, -0.318370, 1.192881, 0.521558, 0.951495, -0.299605, 1.169131,
+ 0.478149, 0.973586, -0.280067, 1.146316, 0.436325, 0.996400, -0.259823, 1.127860, 0.394409,
+ 1.019780, -0.238313, 1.110521, 0.353045, 1.042775, -0.216506, 1.093915, 0.312803, 1.066822,
+ -0.194695, 1.080326, 0.274100, 1.089869, -0.172290, 1.067722, 0.236657, 1.113606, -0.149264,
+ 1.058471, 0.201603, 1.134229, -0.124814, 1.050701, 0.168398, 1.150922, -0.100070, 1.043051,
+ 0.135616, 1.163224, -0.075155, 1.033742, 0.102144, 1.169965, -0.049933, 1.021818, 0.067532,
+ 1.174200, -0.024461, 1.009916, 0.033215, 1.179766, 0.000188, 1.000045, -0.000014, 0.000202,
+ -0.000281, 2.964186, 1.390880, 0.000505, -0.000702, 2.945157, 1.390903, 0.002015, -0.002802,
+ 2.931184, 1.390863, 0.004535, -0.006307, 2.935673, 1.390900, 0.008063, -0.011213, 2.934274,
+ 1.390890, 0.012598, -0.017516, 2.932216, 1.390876, 0.018147, -0.025221, 2.933324, 1.390832,
+ 0.024711, -0.034322, 2.933945, 1.390769, 0.032295, -0.044810, 2.933496, 1.390674, 0.040904,
+ -0.056673, 2.932487, 1.390538, 0.050555, -0.069906, 2.931571, 1.390342, 0.061259, -0.084468,
+ 2.929914, 1.390064, 0.073053, -0.100152, 2.927039, 1.389695, 0.085948, -0.117202, 2.924241,
+ 1.389201, 0.099968, -0.135531, 2.920760, 1.388548, 0.115135, -0.154906, 2.915998, 1.387692,
+ 0.131496, -0.175352, 2.910285, 1.386611, 0.149049, -0.196783, 2.903174, 1.385190, 0.167848,
+ -0.219066, 2.894584, 1.383407, 0.187879, -0.241983, 2.883171, 1.381148, 0.209143, -0.265398,
+ 2.869102, 1.378261, 0.231689, -0.289254, 2.852238, 1.374690, 0.255223, -0.312776, 2.828264,
+ 1.370166, 0.279952, -0.336260, 2.800175, 1.364591, 0.305572, -0.358865, 2.764282, 1.357758,
+ 0.331650, -0.380223, 2.717845, 1.349413, 0.358491, -0.400252, 2.665326, 1.339084, 0.385445,
+ -0.418422, 2.602293, 1.326773, 0.412947, -0.434993, 2.536973, 1.312141, 0.439681, -0.448757,
+ 2.459463, 1.295205, 0.467272, -0.461427, 2.386250, 1.275573, 0.493568, -0.471102, 2.303225,
+ 1.253400, 0.519743, -0.478930, 2.221945, 1.228890, 0.544882, -0.484098, 2.136425, 1.201730,
+ 0.570690, -0.488125, 2.057093, 1.172022, 0.595905, -0.489185, 1.975334, 1.139312, 0.622747,
+ -0.487535, 1.895055, 1.103038, 0.648695, -0.483482, 1.815995, 1.064364, 0.675159, -0.478096,
+ 1.744272, 1.024098, 0.700714, -0.470492, 1.675257, 0.982186, 0.725641, -0.461398, 1.609135,
+ 0.939137, 0.748552, -0.449825, 1.545091, 0.894791, 0.772808, -0.438185, 1.489394, 0.850373,
+ 0.795928, -0.425073, 1.437026, 0.805287, 0.818900, -0.411028, 1.389654, 0.760003, 0.841633,
+ -0.396047, 1.345873, 0.714914, 0.863213, -0.379637, 1.305185, 0.669271, 0.886662, -0.362227,
+ 1.269147, 0.622935, 0.908504, -0.343068, 1.234714, 0.577757, 0.931425, -0.323982, 1.204997,
+ 0.532922, 0.953835, -0.304347, 1.178871, 0.488154, 0.975813, -0.284219, 1.155019, 0.444885,
+ 0.997662, -0.263544, 1.133941, 0.402224, 1.021167, -0.242611, 1.116100, 0.360530, 1.044038,
+ -0.220065, 1.098348, 0.318968, 1.068837, -0.197580, 1.084605, 0.279107, 1.092548, -0.174779,
+ 1.071217, 0.241111, 1.116157, -0.151596, 1.060486, 0.204913, 1.137486, -0.127478, 1.052751,
+ 0.171410, 1.154694, -0.101915, 1.044807, 0.137999, 1.166867, -0.076246, 1.034824, 0.103807,
+ 1.173715, -0.050661, 1.022501, 0.068802, 1.178236, -0.025355, 1.010324, 0.034155, 1.183545,
+ 0.000205, 1.000059, -0.000110, 0.000201, -0.000294, 3.161080, 1.466721, 0.000505, -0.000740,
+ 3.155526, 1.466737, 0.002016, -0.002957, 3.152852, 1.466688, 0.004537, -0.006655, 3.150654,
+ 1.466667, 0.008066, -0.011828, 3.153109, 1.466694, 0.012604, -0.018479, 3.152143, 1.466721,
+ 0.018150, -0.026598, 3.151025, 1.466636, 0.024714, -0.036191, 3.150300, 1.466562, 0.032301,
+ -0.047249, 3.149861, 1.466450, 0.040924, -0.059766, 3.149548, 1.466289, 0.050579, -0.073703,
+ 3.147516, 1.466055, 0.061306, -0.089022, 3.145680, 1.465738, 0.073135, -0.105563, 3.142428,
+ 1.465301, 0.086075, -0.123544, 3.139113, 1.464715, 0.100153, -0.142853, 3.135064, 1.463956,
+ 0.115411, -0.163183, 3.129509, 1.462962, 0.131876, -0.184760, 3.122959, 1.461670, 0.149570,
+ -0.207172, 3.114153, 1.460045, 0.168523, -0.230578, 3.103626, 1.457945, 0.188784, -0.254658,
+ 3.090818, 1.455279, 0.210264, -0.279114, 3.073352, 1.451998, 0.233030, -0.303930, 3.052592,
+ 1.447780, 0.256959, -0.328517, 3.025187, 1.442568, 0.281901, -0.352755, 2.990341, 1.436026,
+ 0.307728, -0.375894, 2.946820, 1.427979, 0.334197, -0.397924, 2.892845, 1.418249, 0.360966,
+ -0.417914, 2.827937, 1.406370, 0.388478, -0.436526, 2.758006, 1.392134, 0.415567, -0.452366,
+ 2.674696, 1.375244, 0.443518, -0.466917, 2.595136, 1.355660, 0.470631, -0.478417, 2.504173,
+ 1.333123, 0.497419, -0.487825, 2.413227, 1.308181, 0.523961, -0.495064, 2.321239, 1.280227,
+ 0.549708, -0.499844, 2.228911, 1.249894, 0.575296, -0.502844, 2.138834, 1.217130, 0.600168,
+ -0.503368, 2.049030, 1.181412, 0.625874, -0.501622, 1.962267, 1.142648, 0.652164, -0.496936,
+ 1.876900, 1.101268, 0.678029, -0.490319, 1.796344, 1.057782, 0.703248, -0.481575, 1.718925,
+ 1.012884, 0.728520, -0.471822, 1.648358, 0.966487, 0.752577, -0.460134, 1.581989, 0.919880,
+ 0.776163, -0.447164, 1.520109, 0.873087, 0.800016, -0.433601, 1.465081, 0.825803, 0.822176,
+ -0.418388, 1.412564, 0.778249, 0.844873, -0.402704, 1.366184, 0.730849, 0.865955, -0.385633,
+ 1.321865, 0.684037, 0.888173, -0.368255, 1.283464, 0.637192, 0.910994, -0.349332, 1.249215,
+ 0.590131, 0.934270, -0.329612, 1.218366, 0.543213, 0.956653, -0.309228, 1.189808, 0.497752,
+ 0.978476, -0.288310, 1.163674, 0.452837, 1.000755, -0.267243, 1.141389, 0.409481, 1.023827,
+ -0.246015, 1.122012, 0.367354, 1.045572, -0.223777, 1.103303, 0.325171, 1.070445, -0.200837,
+ 1.088010, 0.284442, 1.094268, -0.177211, 1.073650, 0.245138, 1.118639, -0.153531, 1.063051,
+ 0.208289, 1.139786, -0.129074, 1.053921, 0.173607, 1.157848, -0.104051, 1.045968, 0.140467,
+ 1.170697, -0.077694, 1.035782, 0.105594, 1.177874, -0.051393, 1.023483, 0.069898, 1.182242,
+ -0.025392, 1.010620, 0.034532, 1.187612, -0.000032, 1.000062, -0.000035, 0.000202, -0.000313,
+ 3.450327, 1.548291, 0.000504, -0.000780, 3.396162, 1.548289, 0.002015, -0.003120, 3.395621,
+ 1.548260, 0.004533, -0.007019, 3.394299, 1.548217, 0.008066, -0.012486, 3.398803, 1.548274,
+ 0.012600, -0.019500, 3.396363, 1.548245, 0.018151, -0.028076, 3.396805, 1.548192, 0.024722,
+ -0.038209, 3.396384, 1.548109, 0.032306, -0.049868, 3.395158, 1.547979, 0.040936, -0.063077,
+ 3.394303, 1.547785, 0.050610, -0.077791, 3.392979, 1.547513, 0.061360, -0.093869, 3.389910,
+ 1.547134, 0.073227, -0.111380, 3.386669, 1.546619, 0.086217, -0.130371, 3.382974, 1.545938,
+ 0.100364, -0.150684, 3.378046, 1.545039, 0.115733, -0.172116, 3.371719, 1.543880, 0.132309,
+ -0.194809, 3.363764, 1.542380, 0.150174, -0.218431, 3.353699, 1.540462, 0.169340, -0.242954,
+ 3.341397, 1.538002, 0.189788, -0.268175, 3.324957, 1.534894, 0.211581, -0.293776, 3.304776,
+ 1.530954, 0.234561, -0.319619, 3.278192, 1.526033, 0.258776, -0.345089, 3.244910, 1.519926,
+ 0.284059, -0.370176, 3.203338, 1.512296, 0.310312, -0.394171, 3.152477, 1.502956, 0.336748,
+ -0.416137, 3.083616, 1.491463, 0.364029, -0.436752, 3.010481, 1.477493, 0.391575, -0.455102,
+ 2.925454, 1.460933, 0.419409, -0.471378, 2.834380, 1.441554, 0.446811, -0.484714, 2.733329,
+ 1.418861, 0.474489, -0.496021, 2.633630, 1.393405, 0.501751, -0.504991, 2.530935, 1.364633,
+ 0.528488, -0.511392, 2.426653, 1.333234, 0.554428, -0.515395, 2.323633, 1.299138, 0.580434,
+ -0.517761, 2.224964, 1.262462, 0.605474, -0.517598, 2.127228, 1.223784, 0.629888, -0.514946,
+ 2.030545, 1.182321, 0.655579, -0.510177, 1.939070, 1.138515, 0.681940, -0.503097, 1.852355,
+ 1.091502, 0.707228, -0.493537, 1.768084, 1.043464, 0.731894, -0.482372, 1.690840, 0.994242,
+ 0.756741, -0.470312, 1.619277, 0.944749, 0.780160, -0.456412, 1.553430, 0.894816, 0.803384,
+ -0.441492, 1.493357, 0.845202, 0.826347, -0.425944, 1.437830, 0.795954, 0.849145, -0.409532,
+ 1.388578, 0.746915, 0.870617, -0.391988, 1.341527, 0.698025, 0.892943, -0.374229, 1.302188,
+ 0.649579, 0.913828, -0.355148, 1.262877, 0.601833, 0.936830, -0.335238, 1.230136, 0.554521,
+ 0.958687, -0.313939, 1.199596, 0.507208, 0.982008, -0.292741, 1.173619, 0.461357, 1.003691,
+ -0.270940, 1.149015, 0.416031, 1.027223, -0.249102, 1.128689, 0.372457, 1.050048, -0.226899,
+ 1.109444, 0.330281, 1.074105, -0.204329, 1.092943, 0.288987, 1.098971, -0.180560, 1.078591,
+ 0.249075, 1.123324, -0.155987, 1.066885, 0.211519, 1.145445, -0.130929, 1.057617, 0.176506,
+ 1.162856, -0.105269, 1.048453, 0.142345, 1.175360, -0.079267, 1.037439, 0.107452, 1.182514,
+ -0.052547, 1.024393, 0.071252, 1.186575, -0.025744, 1.011093, 0.035019, 1.192050, 0.000318,
+ 1.000013, -0.000152, 0.000204, -0.000334, 3.909175, 1.636412, 0.000504, -0.000825, 3.678647,
+ 1.636410, 0.002015, -0.003298, 3.678315, 1.636387, 0.004533, -0.007417, 3.674126, 1.636310,
+ 0.008062, -0.013190, 3.676771, 1.636376, 0.012603, -0.020613, 3.678135, 1.636369, 0.018153,
+ -0.029675, 3.677315, 1.636299, 0.024723, -0.040378, 3.676872, 1.636196, 0.032318, -0.052708,
+ 3.675750, 1.636038, 0.040955, -0.066660, 3.674803, 1.635810, 0.050645, -0.082203, 3.672735,
+ 1.635494, 0.061429, -0.099150, 3.669047, 1.635048, 0.073333, -0.117679, 3.665401, 1.634437,
+ 0.086388, -0.137725, 3.661315, 1.633634, 0.100620, -0.159081, 3.654992, 1.632571, 0.116087,
+ -0.181721, 3.647341, 1.631202, 0.132820, -0.205611, 3.637877, 1.629432, 0.150867, -0.230542,
+ 3.626333, 1.627161, 0.170234, -0.256239, 3.610671, 1.624266, 0.190981, -0.282751, 3.591685,
+ 1.620589, 0.213013, -0.309430, 3.565864, 1.615999, 0.236387, -0.336427, 3.534826, 1.610216,
+ 0.260943, -0.362931, 3.493984, 1.603047, 0.286497, -0.388644, 3.442075, 1.593920, 0.312769,
+ -0.412912, 3.375973, 1.582961, 0.339832, -0.435635, 3.299355, 1.569343, 0.367214, -0.456181,
+ 3.208994, 1.553137, 0.394935, -0.474325, 3.108910, 1.533791, 0.422935, -0.490318, 3.001767,
+ 1.511093, 0.451166, -0.503827, 2.891735, 1.485145, 0.478695, -0.514185, 2.773430, 1.455617,
+ 0.506313, -0.522502, 2.657639, 1.422946, 0.533427, -0.528119, 2.541132, 1.387843, 0.559942,
+ -0.531430, 2.426950, 1.349542, 0.585150, -0.531978, 2.312437, 1.309303, 0.610500, -0.531054,
+ 2.205966, 1.266280, 0.635380, -0.528058, 2.101993, 1.221709, 0.659852, -0.522751, 2.002950,
+ 1.175062, 0.685151, -0.515026, 1.908647, 1.125078, 0.710920, -0.505020, 1.819389, 1.074296,
+ 0.736066, -0.493268, 1.735806, 1.022420, 0.760503, -0.480032, 1.658607, 0.970230, 0.785091,
+ -0.465986, 1.589424, 0.917077, 0.807523, -0.449721, 1.522533, 0.864888, 0.830974, -0.433461,
+ 1.465416, 0.813006, 0.852659, -0.415808, 1.409076, 0.761689, 0.874841, -0.397855, 1.360758,
+ 0.711258, 0.896322, -0.379041, 1.316829, 0.661721, 0.918134, -0.360048, 1.278574, 0.612263,
+ 0.939356, -0.340108, 1.242200, 0.564369, 0.961025, -0.318877, 1.210305, 0.516506, 0.984371,
+ -0.297130, 1.183689, 0.469342, 1.006905, -0.274661, 1.157466, 0.423080, 1.029941, -0.252234,
+ 1.135066, 0.378315, 1.052751, -0.229268, 1.114518, 0.335169, 1.077981, -0.206662, 1.097760,
+ 0.293336, 1.102542, -0.183331, 1.082051, 0.252984, 1.126539, -0.158797, 1.068935, 0.214990,
+ 1.149023, -0.133014, 1.058996, 0.178903, 1.167550, -0.106641, 1.050245, 0.144559, 1.179994,
+ -0.079952, 1.038648, 0.108667, 1.187104, -0.053316, 1.025284, 0.072209, 1.191406, -0.026826,
+ 1.011453, 0.035833, 1.196748, 0.000226, 1.000034, -0.000061, 0.000200, -0.000346, 3.996419,
+ 1.732034, 0.000504, -0.000873, 4.000138, 1.732038, 0.002016, -0.003492, 4.002078, 1.732012,
+ 0.004538, -0.007859, 4.005626, 1.731962, 0.008064, -0.013963, 3.998500, 1.731999, 0.012590,
+ -0.021794, 3.995024, 1.732004, 0.018154, -0.031406, 3.999233, 1.731901, 0.024727, -0.042733,
+ 3.998497, 1.731774, 0.032327, -0.055781, 3.997064, 1.731599, 0.040974, -0.070543, 3.995856,
+ 1.731325, 0.050685, -0.086984, 3.993839, 1.730945, 0.061506, -0.104897, 3.989519, 1.730417,
+ 0.073458, -0.124506, 3.985313, 1.729697, 0.086573, -0.145706, 3.979984, 1.728747, 0.100909,
+ -0.168211, 3.972562, 1.727491, 0.116509, -0.192198, 3.963836, 1.725854, 0.133404, -0.217280,
+ 3.951919, 1.723749, 0.151659, -0.243556, 3.937734, 1.721093, 0.171288, -0.270611, 3.919021,
+ 1.717640, 0.192301, -0.298389, 3.895171, 1.713272, 0.214683, -0.326338, 3.864171, 1.707825,
+ 0.238392, -0.354394, 3.824682, 1.700956, 0.263151, -0.381636, 3.771168, 1.692392, 0.289155,
+ -0.408266, 3.709961, 1.681769, 0.315832, -0.433070, 3.630302, 1.668539, 0.342942, -0.455741,
+ 3.534719, 1.652513, 0.370892, -0.476655, 3.431531, 1.633428, 0.398985, -0.494692, 3.314933,
+ 1.610694, 0.427206, -0.510313, 3.189741, 1.584240, 0.455266, -0.522760, 3.058325, 1.554195,
+ 0.483472, -0.532872, 2.927213, 1.520805, 0.511192, -0.540229, 2.794112, 1.484026, 0.538706,
+ -0.545105, 2.663786, 1.443796, 0.565422, -0.547251, 2.534841, 1.401429, 0.591270, -0.547115,
+ 2.408437, 1.356231, 0.616787, -0.545113, 2.291284, 1.308887, 0.641380, -0.540853, 2.177478,
+ 1.260447, 0.665344, -0.534561, 2.069265, 1.210634, 0.690147, -0.527115, 1.969776, 1.158569,
+ 0.714578, -0.516171, 1.870847, 1.104593, 0.740349, -0.504048, 1.782674, 1.049578, 0.764563,
+ -0.489683, 1.698614, 0.994458, 0.788710, -0.474541, 1.624447, 0.938612, 0.812154, -0.458099,
+ 1.554453, 0.883694, 0.834566, -0.440345, 1.490045, 0.830220, 0.857486, -0.422491, 1.432889,
+ 0.776499, 0.879224, -0.403588, 1.380669, 0.724257, 0.899971, -0.383819, 1.333124, 0.673311,
+ 0.922111, -0.364250, 1.292648, 0.622999, 0.942842, -0.343873, 1.253933, 0.573304, 0.964398,
+ -0.323206, 1.221027, 0.525090, 0.986860, -0.301711, 1.191806, 0.477580, 1.009760, -0.278695,
+ 1.165162, 0.430624, 1.033347, -0.255591, 1.141715, 0.384482, 1.055937, -0.232039, 1.119739,
+ 0.340532, 1.081178, -0.208664, 1.102117, 0.297311, 1.105696, -0.184935, 1.085062, 0.256227,
+ 1.129575, -0.160673, 1.070918, 0.217709, 1.152135, -0.135414, 1.060642, 0.181471, 1.171221,
+ -0.108462, 1.051041, 0.146380, 1.184412, -0.081008, 1.039694, 0.110120, 1.191820, -0.053710,
+ 1.025903, 0.073052, 1.196195, -0.026625, 1.011816, 0.036129, 1.201677, -0.000175, 0.999945,
+ 0.000098, 0.000196, -0.000360, 4.100786, 1.836290, 0.000504, -0.000925, 4.370184, 1.836295,
+ 0.002018, -0.003706, 4.385247, 1.836243, 0.004534, -0.008324, 4.370146, 1.836210, 0.008064,
+ -0.014805, 4.372335, 1.836256, 0.012597, -0.023116, 4.359918, 1.836259, 0.018158, -0.033299,
+ 4.371503, 1.836123, 0.024732, -0.045301, 4.370533, 1.835988, 0.032344, -0.059143, 4.369649,
+ 1.835768, 0.040999, -0.074779, 4.367861, 1.835454, 0.050739, -0.092178, 4.364322, 1.834974,
+ 0.061594, -0.111161, 4.359221, 1.834355, 0.073604, -0.131958, 4.354620, 1.833499, 0.086796,
+ -0.154393, 4.347915, 1.832355, 0.101246, -0.178201, 4.339152, 1.830880, 0.116990, -0.203531,
+ 4.328327, 1.828936, 0.134086, -0.230043, 4.314240, 1.826442, 0.152589, -0.257718, 4.296795,
+ 1.823230, 0.172514, -0.286176, 4.273985, 1.819124, 0.193853, -0.315295, 4.244136, 1.813909,
+ 0.216582, -0.344507, 4.205152, 1.807410, 0.240668, -0.373646, 4.154781, 1.799084, 0.265904,
+ -0.401897, 4.091563, 1.788905, 0.292226, -0.429136, 4.013199, 1.776206, 0.319045, -0.454057,
+ 3.912886, 1.760500, 0.346721, -0.477219, 3.800927, 1.741586, 0.374849, -0.497883, 3.675652,
+ 1.718818, 0.403078, -0.515504, 3.536892, 1.692138, 0.431597, -0.530621, 3.391351, 1.661434,
+ 0.460246, -0.542852, 3.242817, 1.626989, 0.488899, -0.552238, 3.093685, 1.588582, 0.517215,
+ -0.559045, 2.944163, 1.546300, 0.544480, -0.562351, 2.794189, 1.501299, 0.571542, -0.563394,
+ 2.650239, 1.453758, 0.598167, -0.562590, 2.513757, 1.403321, 0.624104, -0.559636, 2.384203,
+ 1.352431, 0.648789, -0.554148, 2.259149, 1.298758, 0.672715, -0.546779, 2.140250, 1.244943,
+ 0.696258, -0.537896, 2.030401, 1.189971, 0.720048, -0.527401, 1.928311, 1.134526, 0.744078,
+ -0.514142, 1.830175, 1.076504, 0.768895, -0.499352, 1.740731, 1.018032, 0.792551, -0.482982,
+ 1.658911, 0.960250, 0.817007, -0.466406, 1.586579, 0.903029, 0.839035, -0.447616, 1.516969,
+ 0.846484, 0.862742, -0.429261, 1.458675, 0.791420, 0.884307, -0.409479, 1.402989, 0.737125,
+ 0.905641, -0.389303, 1.352817, 0.683912, 0.926185, -0.368344, 1.306684, 0.632690, 0.947229,
+ -0.347366, 1.267395, 0.581739, 0.969502, -0.326720, 1.233192, 0.532305, 0.990758, -0.304973,
+ 1.201017, 0.484166, 1.012749, -0.282816, 1.173018, 0.437385, 1.035533, -0.259084, 1.147184,
+ 0.390755, 1.059915, -0.235239, 1.125388, 0.345399, 1.084348, -0.211044, 1.105859, 0.301356,
+ 1.109544, -0.186698, 1.088888, 0.259708, 1.133770, -0.161900, 1.073848, 0.220324, 1.157553,
+ -0.136604, 1.063190, 0.183857, 1.176461, -0.110428, 1.053110, 0.148521, 1.190137, -0.082898,
+ 1.041484, 0.112124, 1.197215, -0.054554, 1.026844, 0.074160, 1.201654, -0.026744, 1.012264,
+ 0.036527, 1.207085, 0.000399, 1.000034, -0.000201, 0.000191, -0.000373, 4.194318, 1.950551,
+ 0.000504, -0.000983, 4.804350, 1.950552, 0.002015, -0.003931, 4.802820, 1.950518, 0.004536,
+ -0.008847, 4.805254, 1.950472, 0.008064, -0.015725, 4.804152, 1.950517, 0.012693, -0.024740,
+ 4.826828, 1.949914, 0.018159, -0.035365, 4.803103, 1.950349, 0.024740, -0.048122, 4.803220,
+ 1.950183, 0.032361, -0.062822, 4.801522, 1.949917, 0.041034, -0.079430, 4.799593, 1.949538,
+ 0.050815, -0.097841, 4.797179, 1.948972, 0.061702, -0.118026, 4.789557, 1.948246, 0.073766,
+ -0.140112, 4.783293, 1.947204, 0.087066, -0.163819, 4.775698, 1.945855, 0.101637, -0.189122,
+ 4.764612, 1.944052, 0.117558, -0.215884, 4.751486, 1.941710, 0.134884, -0.243968, 4.734791,
+ 1.938727, 0.153637, -0.273170, 4.712078, 1.934891, 0.173890, -0.303146, 4.683575, 1.929976,
+ 0.195643, -0.333704, 4.646766, 1.923740, 0.218767, -0.364170, 4.596814, 1.915888, 0.243337,
+ -0.394530, 4.535509, 1.905970, 0.268860, -0.423512, 4.452006, 1.893623, 0.295173, -0.450609,
+ 4.345682, 1.878286, 0.322784, -0.476488, 4.231632, 1.859391, 0.350616, -0.499420, 4.093553,
+ 1.836912, 0.379127, -0.519862, 3.944127, 1.809625, 0.407860, -0.537373, 3.782223, 1.778529,
+ 0.436717, -0.551802, 3.615563, 1.742684, 0.465345, -0.562951, 3.440672, 1.702289, 0.494158,
+ -0.571334, 3.268070, 1.658666, 0.522896, -0.577227, 3.100668, 1.611027, 0.551379, -0.580514,
+ 2.937615, 1.559742, 0.578992, -0.580610, 2.778703, 1.507257, 0.605095, -0.577729, 2.621626,
+ 1.451941, 0.630653, -0.573000, 2.476506, 1.395218, 0.656175, -0.566944, 2.341592, 1.337862,
+ 0.681036, -0.558988, 2.216478, 1.279275, 0.704713, -0.549211, 2.096972, 1.220526, 0.726894,
+ -0.537190, 1.983311, 1.161709, 0.749865, -0.524167, 1.881100, 1.102095, 0.773553, -0.508991,
+ 1.785637, 1.042039, 0.797102, -0.491658, 1.697234, 0.981588, 0.821187, -0.474093, 1.620250,
+ 0.921265, 0.843848, -0.454980, 1.547071, 0.862757, 0.866662, -0.435421, 1.482008, 0.804700,
+ 0.888696, -0.414990, 1.424116, 0.749432, 0.910945, -0.394472, 1.372658, 0.694767, 0.932300,
+ -0.373239, 1.325157, 0.641106, 0.952850, -0.351347, 1.282217, 0.589689, 0.974718, -0.329809,
+ 1.244897, 0.539322, 0.996445, -0.307902, 1.212306, 0.490083, 1.017580, -0.285392, 1.181402,
+ 0.442702, 1.040342, -0.262782, 1.155996, 0.395911, 1.064399, -0.238995, 1.131708, 0.350206,
+ 1.089464, -0.214297, 1.111215, 0.305175, 1.115565, -0.189293, 1.093094, 0.262686, 1.140640,
+ -0.163843, 1.077994, 0.223078, 1.163824, -0.137789, 1.066014, 0.185651, 1.182577, -0.111087,
+ 1.055615, 0.150045, 1.195775, -0.083945, 1.042940, 0.113457, 1.203175, -0.056145, 1.028015,
+ 0.075453, 1.207282, -0.027685, 1.012552, 0.037217, 1.213019, 0.000362, 0.999938, -0.000293,
+ 0.000187, -0.000388, 4.316009, 2.076500, 0.000504, -0.001048, 5.317799, 2.076499, 0.002014,
+ -0.004182, 5.306557, 2.076523, 0.004539, -0.009425, 5.317505, 2.076453, 0.008063, -0.016737,
+ 5.312143, 2.076410, 0.012614, -0.026171, 5.316434, 2.076389, 0.018158, -0.037641, 5.307836,
+ 2.076265, 0.024767, -0.051266, 5.315297, 2.076044, 0.032372, -0.066859, 5.307433, 2.075743,
+ 0.041066, -0.084538, 5.304809, 2.075270, 0.050871, -0.104062, 5.299277, 2.074622, 0.061821,
+ -0.125613, 5.293419, 2.073708, 0.073970, -0.149085, 5.286629, 2.072457, 0.087375, -0.174214,
+ 5.275937, 2.070804, 0.102105, -0.201136, 5.263267, 2.068647, 0.118223, -0.229505, 5.246309,
+ 2.065846, 0.135814, -0.259217, 5.225496, 2.062189, 0.154887, -0.289990, 5.196580, 2.057566,
+ 0.175510, -0.321618, 5.160716, 2.051593, 0.197636, -0.353632, 5.112202, 2.043949, 0.221168,
+ -0.385303, 5.046981, 2.034445, 0.246099, -0.416511, 4.965386, 2.022368, 0.272070, -0.446377,
+ 4.860735, 2.007160, 0.299090, -0.474279, 4.735140, 1.988598, 0.326702, -0.499809, 4.584962,
+ 1.965865, 0.355017, -0.522790, 4.420447, 1.938705, 0.383856, -0.542755, 4.241942, 1.906370,
+ 0.413059, -0.559903, 4.053302, 1.869455, 0.441882, -0.573174, 3.852753, 1.827946, 0.471516,
+ -0.584151, 3.660377, 1.781652, 0.500872, -0.591843, 3.466027, 1.730885, 0.529677, -0.596253,
+ 3.272812, 1.676821, 0.557683, -0.597604, 3.084286, 1.620064, 0.585652, -0.596591, 2.906111,
+ 1.560909, 0.612819, -0.593138, 2.738258, 1.500318, 0.639848, -0.588245, 2.584172, 1.438127,
+ 0.664758, -0.580140, 2.430697, 1.375746, 0.688754, -0.570189, 2.290701, 1.312727, 0.712848,
+ -0.559420, 2.162679, 1.250063, 0.735111, -0.546570, 2.042186, 1.187840, 0.757521, -0.532944,
+ 1.933435, 1.125513, 0.780056, -0.517981, 1.833524, 1.063827, 0.802513, -0.500724, 1.739053,
+ 1.002154, 0.825462, -0.481625, 1.652381, 0.939811, 0.848973, -0.462327, 1.577560, 0.878279,
+ 0.871521, -0.441928, 1.509291, 0.819200, 0.892325, -0.420297, 1.443799, 0.761607, 0.914935,
+ -0.399072, 1.389647, 0.705351, 0.936429, -0.377232, 1.339903, 0.650213, 0.957614, -0.355091,
+ 1.295467, 0.597773, 0.979578, -0.332767, 1.256692, 0.545914, 1.000860, -0.310147, 1.221666,
+ 0.495661, 1.022550, -0.287395, 1.190775, 0.448026, 1.045005, -0.264582, 1.162641, 0.400490,
+ 1.068703, -0.241464, 1.138358, 0.354088, 1.093098, -0.217504, 1.115973, 0.309812, 1.119230,
+ -0.192140, 1.096284, 0.266297, 1.144608, -0.165975, 1.080042, 0.225831, 1.168599, -0.139174,
+ 1.067749, 0.187761, 1.187970, -0.111910, 1.056635, 0.151322, 1.201240, -0.083978, 1.043566,
+ 0.114337, 1.208895, -0.056089, 1.028366, 0.076083, 1.213344, -0.028369, 1.013074, 0.037735,
+ 1.219220, -0.000534, 0.999968, 0.000076, 0.000182, -0.000404, 4.433519, 2.216201, 0.000504,
+ -0.001117, 5.911693, 2.216198, 0.002017, -0.004469, 5.919142, 2.216190, 0.004536, -0.010051,
+ 5.913172, 2.216130, 0.008065, -0.017867, 5.911791, 2.216145, 0.012467, -0.027603, 5.785357,
+ 2.216447, 0.018156, -0.040159, 5.901121, 2.215958, 0.024758, -0.054670, 5.908781, 2.215654,
+ 0.032395, -0.071352, 5.906098, 2.215283, 0.041108, -0.090201, 5.902558, 2.214715, 0.050955,
+ -0.111004, 5.895707, 2.213905, 0.061968, -0.134002, 5.888736, 2.212807, 0.074206, -0.159038,
+ 5.880633, 2.211303, 0.087742, -0.185801, 5.867001, 2.209297, 0.102652, -0.214368, 5.851446,
+ 2.206657, 0.119006, -0.244573, 5.830722, 2.203232, 0.136883, -0.276067, 5.802688, 2.198778,
+ 0.156335, -0.308660, 5.767185, 2.193091, 0.177396, -0.341940, 5.719726, 2.185858, 0.200070,
+ -0.375591, 5.658792, 2.176584, 0.224067, -0.408564, 5.573508, 2.164759, 0.249420, -0.440668,
+ 5.465696, 2.149777, 0.275879, -0.471138, 5.332207, 2.131225, 0.303307, -0.499204, 5.173339,
+ 2.108794, 0.331189, -0.524547, 4.985102, 2.080585, 0.359932, -0.547256, 4.785788, 2.047792,
+ 0.389063, -0.566479, 4.569344, 2.009518, 0.418725, -0.583031, 4.349557, 1.965601, 0.448181,
+ -0.595809, 4.121278, 1.916911, 0.477703, -0.605102, 3.892291, 1.863530, 0.507999, -0.612462,
+ 3.676557, 1.806286, 0.536889, -0.615451, 3.456241, 1.745841, 0.565778, -0.616029, 3.249464,
+ 1.681137, 0.593863, -0.613644, 3.050273, 1.615238, 0.620770, -0.608268, 2.859599, 1.548003,
+ 0.647171, -0.601116, 2.683287, 1.480447, 0.673458, -0.592840, 2.524036, 1.412084, 0.698064,
+ -0.581973, 2.371046, 1.345130, 0.721011, -0.568963, 2.229104, 1.278440, 0.744293, -0.555642,
+ 2.103213, 1.212448, 0.766314, -0.540934, 1.985370, 1.146287, 0.788164, -0.525271, 1.878842,
+ 1.082600, 0.809019, -0.507986, 1.779821, 1.019978, 0.830947, -0.489717, 1.691630, 0.956931,
+ 0.853732, -0.469345, 1.607513, 0.894207, 0.874904, -0.447618, 1.531176, 0.833436, 0.897289,
+ -0.426124, 1.467302, 0.773611, 0.919226, -0.404025, 1.408321, 0.716016, 0.940860, -0.381454,
+ 1.356209, 0.659515, 0.962764, -0.358901, 1.310082, 0.604629, 0.984322, -0.335983, 1.268485,
+ 0.552335, 1.005343, -0.312533, 1.230662, 0.501591, 1.028153, -0.289452, 1.199168, 0.452032,
+ 1.049283, -0.265754, 1.168575, 0.404347, 1.073687, -0.242571, 1.143533, 0.357445, 1.097546,
+ -0.218681, 1.119859, 0.312534, 1.123340, -0.194465, 1.099634, 0.269437, 1.148166, -0.168797,
+ 1.081968, 0.228586, 1.172518, -0.141552, 1.068789, 0.189866, 1.192930, -0.113325, 1.057548,
+ 0.152772, 1.206816, -0.084800, 1.044145, 0.115390, 1.215045, -0.056019, 1.028938, 0.076493,
+ 1.220048, -0.027733, 1.013338, 0.037767, 1.225852, 0.000050, 0.999927, -0.000160, 0.000178,
+ -0.000422, 4.587902, 2.372253, 0.000504, -0.001195, 6.624675, 2.372248, 0.002016, -0.004782,
+ 6.626884, 2.372187, 0.004531, -0.010746, 6.607379, 2.372318, 0.008081, -0.019161, 6.640102,
+ 2.372084, 0.012637, -0.029945, 6.653708, 2.372128, 0.018167, -0.042999, 6.623837, 2.371902,
+ 0.024769, -0.058516, 6.624484, 2.371595, 0.032421, -0.076370, 6.620877, 2.371120, 0.041164,
+ -0.096474, 6.615235, 2.370428, 0.051057, -0.118786, 6.607844, 2.369440, 0.062136, -0.143390,
+ 6.599216, 2.368075, 0.074490, -0.170034, 6.588018, 2.366218, 0.088179, -0.198717, 6.572526,
+ 2.363747, 0.103307, -0.229147, 6.551868, 2.360517, 0.119964, -0.261253, 6.526089, 2.356304,
+ 0.138173, -0.294703, 6.489593, 2.350797, 0.158072, -0.329261, 6.443573, 2.343783, 0.179592,
+ -0.364298, 6.379764, 2.334673, 0.202709, -0.399375, 6.295845, 2.323125, 0.227335, -0.433616,
+ 6.184929, 2.308547, 0.253230, -0.466794, 6.045905, 2.289980, 0.280100, -0.497509, 5.871803,
+ 2.266964, 0.308146, -0.525956, 5.672422, 2.239074, 0.336544, -0.551101, 5.443256, 2.204809,
+ 0.365223, -0.572471, 5.188034, 2.164827, 0.395484, -0.592088, 4.943783, 2.119489, 0.424416,
+ -0.606026, 4.666400, 2.067262, 0.455641, -0.619671, 4.418961, 2.009937, 0.485298, -0.627583,
+ 4.152737, 1.948900, 0.514774, -0.632072, 3.893344, 1.882692, 0.544172, -0.634033, 3.645332,
+ 1.814073, 0.573283, -0.633239, 3.414651, 1.742717, 0.602155, -0.630008, 3.195712, 1.669703,
+ 0.630520, -0.624550, 2.994536, 1.596021, 0.657121, -0.615749, 2.799373, 1.522572, 0.682071,
+ -0.604738, 2.616102, 1.448978, 0.707605, -0.593301, 2.456112, 1.376250, 0.731492, -0.579628,
+ 2.303517, 1.305297, 0.754139, -0.564473, 2.165340, 1.235548, 0.776505, -0.548787, 2.041646,
+ 1.167051, 0.796833, -0.531415, 1.923334, 1.100534, 0.817565, -0.513778, 1.818176, 1.035144,
+ 0.837981, -0.495167, 1.723830, 0.971583, 0.858513, -0.475690, 1.638448, 0.908841, 0.879892,
+ -0.454099, 1.559420, 0.846701, 0.902258, -0.432038, 1.491471, 0.785332, 0.924114, -0.409316,
+ 1.428878, 0.726409, 0.944230, -0.385618, 1.370785, 0.668588, 0.967001, -0.362604, 1.323529,
+ 0.612943, 0.988579, -0.339117, 1.279679, 0.559038, 1.010210, -0.315355, 1.240104, 0.506867,
+ 1.032084, -0.291408, 1.205261, 0.456934, 1.054671, -0.267387, 1.175197, 0.407792, 1.078314,
+ -0.243346, 1.148153, 0.360992, 1.102443, -0.219205, 1.123799, 0.315577, 1.128524, -0.194996,
+ 1.102624, 0.271742, 1.153989, -0.169897, 1.085134, 0.230702, 1.179420, -0.143960, 1.071699,
+ 0.192146, 1.200098, -0.116173, 1.060179, 0.155164, 1.214837, -0.086655, 1.046290, 0.117071,
+ 1.222749, -0.056956, 1.030040, 0.077450, 1.227273, -0.027883, 1.013650, 0.038092, 1.233293,
+ 0.000831, 1.000043, -0.000462, 0.000173, -0.000442, 4.741539, 2.547922, 0.000504, -0.001284,
+ 7.491127, 2.547919, 0.002014, -0.005132, 7.484889, 2.547844, 0.004523, -0.011521, 7.439875,
+ 2.547587, 0.008059, -0.020524, 7.483694, 2.547725, 0.012586, -0.032029, 7.470912, 2.547685,
+ 0.018081, -0.045948, 7.422534, 2.547686, 0.024783, -0.062844, 7.487581, 2.547107, 0.032451,
+ -0.082011, 7.483603, 2.546522, 0.041233, -0.103540, 7.475124, 2.545684, 0.051181, -0.127537,
+ 7.467521, 2.544438, 0.062347, -0.153921, 7.456266, 2.542744, 0.074829, -0.182427, 7.440422,
+ 2.540459, 0.088703, -0.213134, 7.420694, 2.537380, 0.104080, -0.245750, 7.394875, 2.533347,
+ 0.121050, -0.279941, 7.358515, 2.528069, 0.139697, -0.315591, 7.313001, 2.521237, 0.160036,
+ -0.351980, 7.246342, 2.512378, 0.182147, -0.388993, 7.163688, 2.500993, 0.205799, -0.425570,
+ 7.048339, 2.486450, 0.231091, -0.461093, 6.902586, 2.468174, 0.257405, -0.494668, 6.712721,
+ 2.444774, 0.284956, -0.525889, 6.491261, 2.415538, 0.313180, -0.553693, 6.232833, 2.380610,
+ 0.342327, -0.578724, 5.953834, 2.338525, 0.371689, -0.599706, 5.649698, 2.290256, 0.401919,
+ -0.617615, 5.347900, 2.235157, 0.432204, -0.631632, 5.036417, 2.173932, 0.463151, -0.643082,
+ 4.735976, 2.107298, 0.493388, -0.649970, 4.432044, 2.036121, 0.524128, -0.654188, 4.145472,
+ 1.961595, 0.553930, -0.654671, 3.866877, 1.883602, 0.583856, -0.653051, 3.607848, 1.804521,
+ 0.611762, -0.646994, 3.356237, 1.724047, 0.639117, -0.638860, 3.122531, 1.643016, 0.666279,
+ -0.629093, 2.913178, 1.563932, 0.692936, -0.617862, 2.722675, 1.484614, 0.716498, -0.603279,
+ 2.536926, 1.406734, 0.742273, -0.589878, 2.381054, 1.331469, 0.764031, -0.572744, 2.228312,
+ 1.256796, 0.786601, -0.555933, 2.095451, 1.185290, 0.807776, -0.537992, 1.972866, 1.115940,
+ 0.828400, -0.519596, 1.863394, 1.048371, 0.847412, -0.499847, 1.760630, 0.982934, 0.866850,
+ -0.479920, 1.670998, 0.919972, 0.886340, -0.459434, 1.587962, 0.858100, 0.906933, -0.437767,
+ 1.515505, 0.796714, 0.927490, -0.414068, 1.448243, 0.736162, 0.950217, -0.390910, 1.390505,
+ 0.677613, 0.971545, -0.366964, 1.337865, 0.620477, 0.992901, -0.342603, 1.291104, 0.565807,
+ 1.015460, -0.318596, 1.251138, 0.513086, 1.037859, -0.294242, 1.214291, 0.461573, 1.060535,
+ -0.269601, 1.182517, 0.411838, 1.086885, -0.245608, 1.155300, 0.363221, 1.111237, -0.220589,
+ 1.129715, 0.317174, 1.138718, -0.196008, 1.108103, 0.273213, 1.164223, -0.170408, 1.089640,
+ 0.231968, 1.187256, -0.144205, 1.074145, 0.192987, 1.207851, -0.116945, 1.061615, 0.156118,
+ 1.222217, -0.088852, 1.047599, 0.118674, 1.230315, -0.059381, 1.030869, 0.078993, 1.235052,
+ -0.029145, 1.014126, 0.038924, 1.241359, 0.000479, 1.000114, -0.000211, 0.000169, -0.000465,
+ 4.953966, 2.747437, 0.000504, -0.001384, 8.544530, 2.747430, 0.002015, -0.005537, 8.545147,
+ 2.747339, 0.004542, -0.012477, 8.557734, 2.747125, 0.008064, -0.022143, 8.530193, 2.747341,
+ 0.012543, -0.034411, 8.465151, 2.747411, 0.018178, -0.049792, 8.543328, 2.746874, 0.024810,
+ -0.067784, 8.547247, 2.746396, 0.032489, -0.088416, 8.537436, 2.745730, 0.041313, -0.111580,
+ 8.526655, 2.744596, 0.051332, -0.137462, 8.517438, 2.743082, 0.062603, -0.165860, 8.502803,
+ 2.740950, 0.075240, -0.196548, 8.481507, 2.738057, 0.089341, -0.229440, 8.454287, 2.734174,
+ 0.105021, -0.264395, 8.420289, 2.729086, 0.122399, -0.301020, 8.373503, 2.722420, 0.141526,
+ -0.338997, 8.309059, 2.713686, 0.162451, -0.377589, 8.221539, 2.702492, 0.185098, -0.416349,
+ 8.100116, 2.687893, 0.209406, -0.454284, 7.941704, 2.669386, 0.235098, -0.490450, 7.733318,
+ 2.645590, 0.262100, -0.524592, 7.486120, 2.615709, 0.290103, -0.555558, 7.193498, 2.579231,
+ 0.319135, -0.583516, 6.874796, 2.534957, 0.348286, -0.606714, 6.516118, 2.483017, 0.378840,
+ -0.627850, 6.163912, 2.424214, 0.409608, -0.644715, 5.801404, 2.357563, 0.440553, -0.657657,
+ 5.435955, 2.285835, 0.470599, -0.665621, 5.063481, 2.207940, 0.503172, -0.673767, 4.743532,
+ 2.126440, 0.533884, -0.676009, 4.413409, 2.040694, 0.563808, -0.674536, 4.092169, 1.953979,
+ 0.591849, -0.668913, 3.787057, 1.865897, 0.621474, -0.663159, 3.520578, 1.777762, 0.650500,
+ -0.655018, 3.275065, 1.689902, 0.678011, -0.643949, 3.043141, 1.603528, 0.703490, -0.630030,
+ 2.827104, 1.519484, 0.728250, -0.614910, 2.632620, 1.436677, 0.752165, -0.598649, 2.455570,
+ 1.355753, 0.775894, -0.581771, 2.295932, 1.278884, 0.797650, -0.563193, 2.152291, 1.202767,
+ 0.818505, -0.543750, 2.022099, 1.130338, 0.838596, -0.524017, 1.903562, 1.060263, 0.858396,
+ -0.504064, 1.797204, 0.993077, 0.877088, -0.483418, 1.701208, 0.928606, 0.896606, -0.462786,
+ 1.617736, 0.866039, 0.914342, -0.440943, 1.539227, 0.804293, 0.933550, -0.419129, 1.470383,
+ 0.745206, 0.955237, -0.396100, 1.409100, 0.685832, 0.976700, -0.371743, 1.354930, 0.627953,
+ 0.997681, -0.346882, 1.305249, 0.572127, 1.020784, -0.322391, 1.262603, 0.517941, 1.043840,
+ -0.297564, 1.225115, 0.466188, 1.067224, -0.272639, 1.190817, 0.415499, 1.092358, -0.247664,
+ 1.161265, 0.366782, 1.117573, -0.222260, 1.133935, 0.319377, 1.145730, -0.196933, 1.111750,
+ 0.275293, 1.170822, -0.170577, 1.091981, 0.233306, 1.194559, -0.143878, 1.075810, 0.193950,
+ 1.214819, -0.116347, 1.062438, 0.156724, 1.229830, -0.088233, 1.048092, 0.118984, 1.238185,
+ -0.059408, 1.031325, 0.079385, 1.243527, -0.030703, 1.014698, 0.039893, 1.249724, -0.001520,
+ 0.999819, 0.000760, 0.000164, -0.000489, 5.157359, 2.976300, 0.000505, -0.001502, 9.891415,
+ 2.976286, 0.002016, -0.006000, 9.857730, 2.976197, 0.004543, -0.013519, 9.870651, 2.975832,
+ 0.008064, -0.023985, 9.855780, 2.976170, 0.012611, -0.037471, 9.850209, 2.975941, 0.018162,
+ -0.053866, 9.827134, 2.974968, 0.024820, -0.073390, 9.849955, 2.975010, 0.032545, -0.095758,
+ 9.842021, 2.974073, 0.041418, -0.120834, 9.829989, 2.972700, 0.051511, -0.148861, 9.817421,
+ 2.970736, 0.062920, -0.179456, 9.797347, 2.968033, 0.075744, -0.212674, 9.771533, 2.964371,
+ 0.090131, -0.248193, 9.735924, 2.959437, 0.106187, -0.285748, 9.687707, 2.952881, 0.124035,
+ -0.325017, 9.622684, 2.944273, 0.143733, -0.365463, 9.531452, 2.933093, 0.165262, -0.406157,
+ 9.401732, 2.918484, 0.188622, -0.446833, 9.232451, 2.899529, 0.213693, -0.486209, 9.013432,
+ 2.875137, 0.239987, -0.522925, 8.725671, 2.844166, 0.267796, -0.557452, 8.400028, 2.805649,
+ 0.296547, -0.588266, 8.023041, 2.758720, 0.325838, -0.614837, 7.606773, 2.702676, 0.355479,
+ -0.636760, 7.160680, 2.638483, 0.386984, -0.657230, 6.736765, 2.566849, 0.418853, -0.673592,
+ 6.313742, 2.488091, 0.450302, -0.684966, 5.884479, 2.402458, 0.481149, -0.691591, 5.455771,
+ 2.311816, 0.512177, -0.695337, 5.055698, 2.217330, 0.543437, -0.696370, 4.681506, 2.121285,
+ 0.574309, -0.694186, 4.334716, 2.024160, 0.604787, -0.689158, 4.008524, 1.927738, 0.633483,
+ -0.680580, 3.703505, 1.830456, 0.660766, -0.669088, 3.418386, 1.734934, 0.688471, -0.656673,
+ 3.168101, 1.642316, 0.715729, -0.642820, 2.941735, 1.550744, 0.740435, -0.626155, 2.730570,
+ 1.463345, 0.764114, -0.608299, 2.537561, 1.378151, 0.787028, -0.589519, 2.364323, 1.297630,
+ 0.807985, -0.569257, 2.207970, 1.217830, 0.830663, -0.550055, 2.076646, 1.142746, 0.850416,
+ -0.528812, 1.948085, 1.070757, 0.869609, -0.507478, 1.834684, 1.001282, 0.888324, -0.486131,
+ 1.734879, 0.934987, 0.907482, -0.464910, 1.645974, 0.871203, 0.924829, -0.442742, 1.563550,
+ 0.809260, 0.942958, -0.420777, 1.491264, 0.750037, 0.961999, -0.398842, 1.428069, 0.691715,
+ 0.981043, -0.375967, 1.369668, 0.635669, 1.002371, -0.351469, 1.318588, 0.578689, 1.025343,
+ -0.326601, 1.273628, 0.524424, 1.048511, -0.301395, 1.234572, 0.471403, 1.072242, -0.275835,
+ 1.198354, 0.419950, 1.096758, -0.250200, 1.166392, 0.370733, 1.122781, -0.224474, 1.138991,
+ 0.322864, 1.150871, -0.198592, 1.114313, 0.277723, 1.177319, -0.171805, 1.093534, 0.234950,
+ 1.201765, -0.144291, 1.077462, 0.195376, 1.222629, -0.115949, 1.063288, 0.157315, 1.237334,
+ -0.087140, 1.048366, 0.118843, 1.246153, -0.058094, 1.031224, 0.079207, 1.252570, -0.029194,
+ 1.014695, 0.039376, 1.259060, -0.000418, 0.999881, 0.000307, 0.000159, -0.000515, 5.393984,
+ 3.241865, 0.000505, -0.001636, 11.548038, 3.241848, 0.002016, -0.006534, 11.506640, 3.241718,
+ 0.004537, -0.014706, 11.513460, 3.241196, 0.008068, -0.026134, 11.510533, 3.241693, 0.012573,
+ -0.040676, 11.428978, 3.241030, 0.018212, -0.058794, 11.510745, 3.240924, 0.024847, -0.079926,
+ 11.497339, 3.240201, 0.032603, -0.104160, 11.484607, 3.238994, 0.041543, -0.131552, 11.470801,
+ 3.237182, 0.051738, -0.162012, 11.453219, 3.234635, 0.063313, -0.195260, 11.427244, 3.231153,
+ 0.076381, -0.231205, 11.388534, 3.226361, 0.091096, -0.269678, 11.340406, 3.219943, 0.107600,
+ -0.310170, 11.270127, 3.211448, 0.126017, -0.352435, 11.178583, 3.200168, 0.146411, -0.395551,
+ 11.046559, 3.185328, 0.168663, -0.438627, 10.858624, 3.165972, 0.192730, -0.480660, 10.606379,
+ 3.140735, 0.218497, -0.520987, 10.288093, 3.108388, 0.245752, -0.558483, 9.907480, 3.067586,
+ 0.273993, -0.592090, 9.453246, 3.016931, 0.303495, -0.622416, 8.966138, 2.956444, 0.333717,
+ -0.648303, 8.443776, 2.885116, 0.363928, -0.668640, 7.894122, 2.805963, 0.396240, -0.687748,
+ 7.385728, 2.718338, 0.427161, -0.699903, 6.838511, 2.622346, 0.460175, -0.711210, 6.356371,
+ 2.522476, 0.492593, -0.717734, 5.878312, 2.417984, 0.524449, -0.719956, 5.423285, 2.310941,
+ 0.556010, -0.719127, 4.997909, 2.201885, 0.587032, -0.715077, 4.600426, 2.093330, 0.617030,
+ -0.707574, 4.235885, 1.986585, 0.644684, -0.695781, 3.881712, 1.881279, 0.674483, -0.685313,
+ 3.590960, 1.777918, 0.700290, -0.669619, 3.303138, 1.678004, 0.727892, -0.654728, 3.057771,
+ 1.581162, 0.751694, -0.635727, 2.826642, 1.487769, 0.776271, -0.617343, 2.622178, 1.399628,
+ 0.799502, -0.597683, 2.441265, 1.313195, 0.821768, -0.577090, 2.276954, 1.232316, 0.841960,
+ -0.555165, 2.125744, 1.153914, 0.861582, -0.532983, 1.991236, 1.079598, 0.881460, -0.510933,
+ 1.874027, 1.008883, 0.899952, -0.488321, 1.766812, 0.940802, 0.918954, -0.466405, 1.673436,
+ 0.875653, 0.936130, -0.443623, 1.586986, 0.813130, 0.954799, -0.421532, 1.513558, 0.752241,
+ 0.972435, -0.398897, 1.445787, 0.694711, 0.990147, -0.376302, 1.384382, 0.638770, 1.009189,
+ -0.353623, 1.331934, 0.583826, 1.029687, -0.330635, 1.284478, 0.530476, 1.052604, -0.305698,
+ 1.243632, 0.477187, 1.076524, -0.279917, 1.204997, 0.425349, 1.101701, -0.253951, 1.171750,
+ 0.375165, 1.127264, -0.227541, 1.142519, 0.326869, 1.156397, -0.201265, 1.116817, 0.280912,
+ 1.183020, -0.173943, 1.095289, 0.237447, 1.208448, -0.145860, 1.078296, 0.196694, 1.230417,
+ -0.116901, 1.064416, 0.158409, 1.248617, -0.087507, 1.050504, 0.119483, 1.257310, -0.057353,
+ 1.032796, 0.079092, 1.263076, -0.027785, 1.015128, 0.038883, 1.269870, 0.001331, 0.999935,
+ -0.000557, 0.000154, -0.000549, 5.705205, 3.554136, 0.000506, -0.001797, 13.703335, 3.554133,
+ 0.002014, -0.007156, 13.614074, 3.553937, 0.004544, -0.016145, 13.657344, 3.553096, 0.008070,
+ -0.028652, 13.627997, 3.553894, 0.012584, -0.044617, 13.606235, 3.554000, 0.018180, -0.064288,
+ 13.581339, 3.549637, 0.024887, -0.087627, 13.608851, 3.552006, 0.032690, -0.114134, 13.599099,
+ 3.550341, 0.041705, -0.144154, 13.579829, 3.547982, 0.052035, -0.177400, 13.552845, 3.544641,
+ 0.063810, -0.213813, 13.515619, 3.539941, 0.077171, -0.252978, 13.460460, 3.533696, 0.092329,
+ -0.294852, 13.393559, 3.524977, 0.109390, -0.338688, 13.292376, 3.513655, 0.128455, -0.384018,
+ 13.147332, 3.498484, 0.149661, -0.429960, 12.945774, 3.478323, 0.172694, -0.475024, 12.658979,
+ 3.451862, 0.197650, -0.518614, 12.289564, 3.417602, 0.224156, -0.559298, 11.828307, 3.372913,
+ 0.252008, -0.596110, 11.285162, 3.317454, 0.281165, -0.629292, 10.684922, 3.251171, 0.311434,
+ -0.658379, 10.052939, 3.172222, 0.342741, -0.683455, 9.405296, 3.082825, 0.373543, -0.701674,
+ 8.716078, 2.983976, 0.407008, -0.719664, 8.108425, 2.876244, 0.438623, -0.729882, 7.461252,
+ 2.763279, 0.471872, -0.738696, 6.880182, 2.645590, 0.504700, -0.743136, 6.324308, 2.524680,
+ 0.537118, -0.743676, 5.808302, 2.402723, 0.569412, -0.741181, 5.332306, 2.281437, 0.598202,
+ -0.732348, 4.857402, 2.161401, 0.629640, -0.724832, 4.465554, 2.043872, 0.659239, -0.713435,
+ 4.093661, 1.930129, 0.686547, -0.698539, 3.752593, 1.817654, 0.715529, -0.684471, 3.457593,
+ 1.712567, 0.739456, -0.664983, 3.171220, 1.610687, 0.764892, -0.646322, 2.929674, 1.512031,
+ 0.789301, -0.626393, 2.710719, 1.419033, 0.809881, -0.603498, 2.506139, 1.330115, 0.833385,
+ -0.582934, 2.336089, 1.245859, 0.854254, -0.560419, 2.178470, 1.165042, 0.873964, -0.537294,
+ 2.040087, 1.086633, 0.893433, -0.514264, 1.911969, 1.015028, 0.911756, -0.490657, 1.799840,
+ 0.944938, 0.930894, -0.467601, 1.703188, 0.878743, 0.948078, -0.444043, 1.612092, 0.815356,
+ 0.966162, -0.421155, 1.534444, 0.753883, 0.984166, -0.398238, 1.462397, 0.695534, 1.002184,
+ -0.375278, 1.400793, 0.638806, 1.019669, -0.352159, 1.344172, 0.584549, 1.039571, -0.329651,
+ 1.295227, 0.531660, 1.059989, -0.306804, 1.251281, 0.480529, 1.081116, -0.283345, 1.211504,
+ 0.430071, 1.105742, -0.258568, 1.176400, 0.380277, 1.133080, -0.232146, 1.144519, 0.331076,
+ 1.161888, -0.205244, 1.118059, 0.284040, 1.192408, -0.177932, 1.097561, 0.239958, 1.221043,
+ -0.149532, 1.082021, 0.198751, 1.244141, -0.120046, 1.067634, 0.160114, 1.259465, -0.089542,
+ 1.051626, 0.121101, 1.268124, -0.058593, 1.033296, 0.079898, 1.274330, -0.028011, 1.015382,
+ 0.039038, 1.281590, 0.002330, 1.000087, -0.001259, 0.000149, -0.000587, 6.059834, 3.927143,
+ 0.000507, -0.001992, 16.560400, 3.927149, 0.002014, -0.007910, 16.406326, 3.926821, 0.004549,
+ -0.017856, 16.545532, 3.927027, 0.008064, -0.031632, 16.375853, 3.925487, 0.012450, -0.048749,
+ 15.928564, 3.928272, 0.018030, -0.070371, 16.072989, 3.917862, 0.024964, -0.096897, 16.458925,
+ 3.924489, 0.032807, -0.126073, 16.377851, 3.921896, 0.041917, -0.159205, 16.351561, 3.918860,
+ 0.052416, -0.195762, 16.307037, 3.914339, 0.064464, -0.235784, 16.255514, 3.907954, 0.078225,
+ -0.278812, 16.176226, 3.899254, 0.093900, -0.324457, 16.066530, 3.887455, 0.111657, -0.372174,
+ 15.913818, 3.871777, 0.131478, -0.420530, 15.669197, 3.850776, 0.153574, -0.469330, 15.355453,
+ 3.822348, 0.177505, -0.516029, 14.908978, 3.785168, 0.203383, -0.560585, 14.352687, 3.736602,
+ 0.230569, -0.600607, 13.666022, 3.675046, 0.259188, -0.636296, 12.900244, 3.599811, 0.289272,
+ -0.668312, 12.111226, 3.510550, 0.320490, -0.695986, 11.292102, 3.408535, 0.353031, -0.719848,
+ 10.493485, 3.295667, 0.385228, -0.737073, 9.661955, 3.171998, 0.419219, -0.752419, 8.909942,
+ 3.042428, 0.452096, -0.761179, 8.155107, 2.907108, 0.484909, -0.766166, 7.450609, 2.769858,
+ 0.518306, -0.768596, 6.811866, 2.631935, 0.550067, -0.765683, 6.205275, 2.492870, 0.582562,
+ -0.761197, 5.663215, 2.358645, 0.614450, -0.753834, 5.165358, 2.227377, 0.644563, -0.742860,
+ 4.712554, 2.097547, 0.673658, -0.729294, 4.306101, 1.974920, 0.702857, -0.714839, 3.943352,
+ 1.857613, 0.729350, -0.696774, 3.609432, 1.743601, 0.754958, -0.677394, 3.308389, 1.636607,
+ 0.779575, -0.657018, 3.043803, 1.533841, 0.800491, -0.633342, 2.793592, 1.437092, 0.825030,
+ -0.612471, 2.590307, 1.344272, 0.847535, -0.589882, 2.406477, 1.256436, 0.865979, -0.564850,
+ 2.231999, 1.173938, 0.886254, -0.541357, 2.083556, 1.094722, 0.905566, -0.517353, 1.950928,
+ 1.021107, 0.924607, -0.493320, 1.835979, 0.948941, 0.943365, -0.469366, 1.731417, 0.881060,
+ 0.960405, -0.444745, 1.635838, 0.816479, 0.977893, -0.420493, 1.552981, 0.754604, 0.996573,
+ -0.397150, 1.481595, 0.694917, 1.014000, -0.373483, 1.414070, 0.638445, 1.031807, -0.349985,
+ 1.356031, 0.584035, 1.051877, -0.327062, 1.305041, 0.530010, 1.071701, -0.304134, 1.258836,
+ 0.479439, 1.093109, -0.280962, 1.217297, 0.429763, 1.116681, -0.258121, 1.182063, 0.381050,
+ 1.143886, -0.235365, 1.150039, 0.333395, 1.175163, -0.211621, 1.125074, 0.287477, 1.203675,
+ -0.184061, 1.102339, 0.243301, 1.230477, -0.154815, 1.083927, 0.201826, 1.253134, -0.124513,
+ 1.067989, 0.162271, 1.270092, -0.093383, 1.052032, 0.122855, 1.279576, -0.061770, 1.033685,
+ 0.081639, 1.286472, -0.030317, 1.015583, 0.040411, 1.294476, 0.000964, 1.000206, -0.000454,
+ 0.000144, -0.000630, 6.467978, 4.381146, 0.000504, -0.002208, 20.193617, 4.381151, 0.002017,
+ -0.008834, 20.206446, 4.380687, 0.004536, -0.019864, 20.183254, 4.380550, 0.008174, -0.035759,
+ 20.564249, 4.381247, 0.012608, -0.055034, 20.111612, 4.382390, 0.018198, -0.079119, 20.106096,
+ 4.379815, 0.025057, -0.108067, 20.215635, 4.376874, 0.032962, -0.140630, 20.153549, 4.374143,
+ 0.042199, -0.177350, 20.084061, 4.369558, 0.052928, -0.218094, 20.026609, 4.363287, 0.065327,
+ -0.262407, 19.940054, 4.354386, 0.079568, -0.309833, 19.806814, 4.342127, 0.095961, -0.360074,
+ 19.641878, 4.325533, 0.114516, -0.411747, 19.370914, 4.302950, 0.135349, -0.463726, 18.983900,
+ 4.271991, 0.158293, -0.514211, 18.433926, 4.230856, 0.183348, -0.562511, 17.733471, 4.176250,
+ 0.209959, -0.606310, 16.864214, 4.105895, 0.238736, -0.646958, 15.935207, 4.020104, 0.268543,
+ -0.681574, 14.890014, 3.916094, 0.299996, -0.712458, 13.846786, 3.798239, 0.331930, -0.737130,
+ 12.758296, 3.664191, 0.365222, -0.758156, 11.732940, 3.521867, 0.399061, -0.774364, 10.741743,
+ 3.369831, 0.433480, -0.786412, 9.812527, 3.212079, 0.467002, -0.792373, 8.915130, 3.053715,
+ 0.500754, -0.795410, 8.094276, 2.894526, 0.534023, -0.794617, 7.342067, 2.735959, 0.566988,
+ -0.790689, 6.664186, 2.581160, 0.599960, -0.784433, 6.052983, 2.432318, 0.630599, -0.773378,
+ 5.486277, 2.287630, 0.660807, -0.760334, 4.982516, 2.150183, 0.690103, -0.745430, 4.531104,
+ 2.017266, 0.717315, -0.727511, 4.120734, 1.891699, 0.743819, -0.708376, 3.759599, 1.772680,
+ 0.770147, -0.688632, 3.441912, 1.660620, 0.793510, -0.665931, 3.152600, 1.553166, 0.816535,
+ -0.643045, 2.898883, 1.452080, 0.839163, -0.619917, 2.674488, 1.355544, 0.859066, -0.594923,
+ 2.469262, 1.267232, 0.879489, -0.570343, 2.292209, 1.181702, 0.898525, -0.544975, 2.131086,
+ 1.102089, 0.918359, -0.520585, 1.994526, 1.024744, 0.937502, -0.496044, 1.873079, 0.951712,
+ 0.955573, -0.471010, 1.761232, 0.883374, 0.972957, -0.445712, 1.661604, 0.818008, 0.991248,
+ -0.421201, 1.577169, 0.754446, 1.008997, -0.396444, 1.499653, 0.694518, 1.028127, -0.372362,
+ 1.432030, 0.637259, 1.045710, -0.347895, 1.369870, 0.581515, 1.065977, -0.324409, 1.317341,
+ 0.527713, 1.087469, -0.301181, 1.270447, 0.476281, 1.109943, -0.277866, 1.228398, 0.426403,
+ 1.134440, -0.254849, 1.190986, 0.377822, 1.160986, -0.231754, 1.157681, 0.330740, 1.188458,
+ -0.207973, 1.128665, 0.286014, 1.214405, -0.183424, 1.103711, 0.243600, 1.239504, -0.157972,
+ 1.084253, 0.203686, 1.262961, -0.130607, 1.068258, 0.165214, 1.280340, -0.099652, 1.051919,
+ 0.126067, 1.292129, -0.067363, 1.034016, 0.084791, 1.299876, -0.035026, 1.015775, 0.042786,
+ 1.308328, -0.002944, 0.999963, 0.001385, 0.000138, -0.000681, 6.943771, 4.946556, 0.000503,
+ -0.002486, 25.346689, 4.946532, 0.002016, -0.009973, 25.494320, 4.946311, 0.004539, -0.022440,
+ 25.484949, 4.945823, 0.008069, -0.039836, 25.420902, 4.945311, 0.012628, -0.062172, 25.394403,
+ 4.945041, 0.018294, -0.089609, 25.440279, 4.943295, 0.025079, -0.121584, 25.399988, 4.939368,
+ 0.033142, -0.158595, 25.356537, 4.936200, 0.042596, -0.199971, 25.295067, 4.929842, 0.053628,
+ -0.245624, 25.196465, 4.920586, 0.066496, -0.295240, 25.055311, 4.907700, 0.081434, -0.348006,
+ 24.846170, 4.889647, 0.098640, -0.403167, 24.527803, 4.864680, 0.118231, -0.459106, 24.051735,
+ 4.830574, 0.140139, -0.513907, 23.352467, 4.783530, 0.164198, -0.565953, 22.418245, 4.720530,
+ 0.190502, -0.614858, 21.324049, 4.638075, 0.218530, -0.658304, 20.038671, 4.535464, 0.248094,
+ -0.696133, 18.639786, 4.411646, 0.279435, -0.729388, 17.234526, 4.268872, 0.312002, -0.757534,
+ 15.830426, 4.109603, 0.346173, -0.781866, 14.495901, 3.938782, 0.379435, -0.797579, 13.136444,
+ 3.756138, 0.414945, -0.812334, 11.946491, 3.571258, 0.449991, -0.821119, 10.811908, 3.384217,
+ 0.484636, -0.825066, 9.763482, 3.198076, 0.518675, -0.824728, 8.796811, 3.015808, 0.552559,
+ -0.821710, 7.932528, 2.836886, 0.587272, -0.817478, 7.185156, 2.664995, 0.616960, -0.804441,
+ 6.445302, 2.502223, 0.648054, -0.792063, 5.818812, 2.345851, 0.678575, -0.777793, 5.264731,
+ 2.197150, 0.707287, -0.760476, 4.766033, 2.056042, 0.735851, -0.742541, 4.335871, 1.922805,
+ 0.760594, -0.720503, 3.928021, 1.798585, 0.784534, -0.697719, 3.579153, 1.680605, 0.811029,
+ -0.677036, 3.285307, 1.568942, 0.831809, -0.651479, 3.001423, 1.465496, 0.854364, -0.627376,
+ 2.760672, 1.367849, 0.872639, -0.600496, 2.540697, 1.275644, 0.894296, -0.576297, 2.355273,
+ 1.188638, 0.913123, -0.550377, 2.188563, 1.105652, 0.932025, -0.524640, 2.040739, 1.028614,
+ 0.949876, -0.498402, 1.910315, 0.954421, 0.968933, -0.473220, 1.795750, 0.884061, 0.985366,
+ -0.447086, 1.690336, 0.817765, 1.004940, -0.422394, 1.599626, 0.753295, 1.022217, -0.396726,
+ 1.519055, 0.693380, 1.041490, -0.371854, 1.448745, 0.635747, 1.059920, -0.346769, 1.384292,
+ 0.579508, 1.080408, -0.322343, 1.328798, 0.525045, 1.101632, -0.297979, 1.279898, 0.473773,
+ 1.124812, -0.274059, 1.234005, 0.422949, 1.148503, -0.249954, 1.195373, 0.374609, 1.174554,
+ -0.225988, 1.160362, 0.327350, 1.202931, -0.201932, 1.131307, 0.283494, 1.229335, -0.176886,
+ 1.105885, 0.241092, 1.254254, -0.151225, 1.085802, 0.201514, 1.275743, -0.124282, 1.068524,
+ 0.162866, 1.292929, -0.097122, 1.051493, 0.124991, 1.305805, -0.068939, 1.033890, 0.085521,
+ 1.314991, -0.040082, 1.015927, 0.045247, 1.324033, -0.009923, 0.999893, 0.004738, 0.000131,
+ -0.000745, 7.562414, 5.671075, 0.000473, -0.002681, 27.216688, 5.670949, 0.002021, -0.011462,
+ 32.962402, 5.670177, 0.004540, -0.025728, 33.183949, 5.670197, 0.008087, -0.045746, 33.185688,
+ 5.667313, 0.012673, -0.071427, 33.170441, 5.668396, 0.018358, -0.102673, 33.145138, 5.665252,
+ 0.025299, -0.139780, 33.303326, 5.653404, 0.033469, -0.181718, 33.107243, 5.652829, 0.043139,
+ -0.228698, 32.859524, 5.645676, 0.054622, -0.280648, 32.694893, 5.631547, 0.068115, -0.336524,
+ 32.422569, 5.611561, 0.083957, -0.395671, 32.035511, 5.583449, 0.102259, -0.456164, 31.415047,
+ 5.543651, 0.123021, -0.515765, 30.470440, 5.488278, 0.146127, -0.572309, 29.186451, 5.413118,
+ 0.171749, -0.625710, 27.653852, 5.312369, 0.199549, -0.673853, 25.902435, 5.185774, 0.229188,
+ -0.715905, 23.978609, 5.030582, 0.260421, -0.751533, 21.999035, 4.853484, 0.293421, -0.782309,
+ 20.087366, 4.656137, 0.327077, -0.806332, 18.186535, 4.443975, 0.361892, -0.825818, 16.418409,
+ 4.223844, 0.397146, -0.840019, 14.774344, 3.998959, 0.434169, -0.852434, 13.321097, 3.775443,
+ 0.469288, -0.856632, 11.929448, 3.552818, 0.504319, -0.857130, 10.675201, 3.338825, 0.540067,
+ -0.855903, 9.591900, 3.130547, 0.575404, -0.851565, 8.607655, 2.932930, 0.606782, -0.839818,
+ 7.690560, 2.743876, 0.638660, -0.827508, 6.900781, 2.565115, 0.670577, -0.814154, 6.216821,
+ 2.395215, 0.696718, -0.793162, 5.551886, 2.238233, 0.725990, -0.775291, 5.015406, 2.090264,
+ 0.754140, -0.755758, 4.546843, 1.950834, 0.775992, -0.729824, 4.094254, 1.820582, 0.802990,
+ -0.708909, 3.732984, 1.699191, 0.828291, -0.686483, 3.413194, 1.583805, 0.847406, -0.659162,
+ 3.103861, 1.478093, 0.864951, -0.631051, 2.832976, 1.378496, 0.887154, -0.606590, 2.616645,
+ 1.282127, 0.906337, -0.580124, 2.413988, 1.194643, 0.927184, -0.554835, 2.244380, 1.110354,
+ 0.943810, -0.527583, 2.081964, 1.031996, 0.963630, -0.502243, 1.948979, 0.956718, 0.979691,
+ -0.475006, 1.822701, 0.886957, 0.997690, -0.448815, 1.715714, 0.819006, 1.016460, -0.423044,
+ 1.621868, 0.754892, 1.035485, -0.397637, 1.539537, 0.693707, 1.053165, -0.371775, 1.462285,
+ 0.634867, 1.072394, -0.346372, 1.396193, 0.578574, 1.093397, -0.321291, 1.338344, 0.524341,
+ 1.115194, -0.296102, 1.287594, 0.472059, 1.137943, -0.271023, 1.240495, 0.421674, 1.164163,
+ -0.246367, 1.201224, 0.371963, 1.191457, -0.221414, 1.164472, 0.325040, 1.220253, -0.196228,
+ 1.134325, 0.280343, 1.245456, -0.169991, 1.108214, 0.238098, 1.270647, -0.143314, 1.087277,
+ 0.197886, 1.292124, -0.115881, 1.069397, 0.159560, 1.309091, -0.087816, 1.051426, 0.120547,
+ 1.321130, -0.059301, 1.032904, 0.080834, 1.332484, -0.030912, 1.015767, 0.040933, 1.342834,
+ -0.002172, 0.999591, 0.001185, 0.000125, -0.000830, 8.392562, 6.634228, 0.000443, -0.002936,
+ 29.687805, 6.634032, 0.002016, -0.013374, 45.025234, 6.633008, 0.004540, -0.030089, 45.020294,
+ 6.633056, 0.008092, -0.053499, 45.066029, 6.626466, 0.012710, -0.083610, 44.810101, 6.630330,
+ 0.018485, -0.120260, 45.216747, 6.614516, 0.025134, -0.161031, 44.674168, 6.600349, 0.033897,
+ -0.212161, 44.819195, 6.610186, 0.043978, -0.266661, 44.450245, 6.593605, 0.056094, -0.326582,
+ 44.134544, 6.570142, 0.070528, -0.390342, 43.591648, 6.536712, 0.087498, -0.456162, 42.708160,
+ 6.488329, 0.107138, -0.521609, 41.365093, 6.420198, 0.129461, -0.584225, 39.525822, 6.323702,
+ 0.154245, -0.641931, 37.186111, 6.193606, 0.181228, -0.692829, 34.478470, 6.026897, 0.210711,
+ -0.738440, 31.680904, 5.825769, 0.242181, -0.777397, 28.828054, 5.595428, 0.275337, -0.809980,
+ 26.042755, 5.342321, 0.309698, -0.835990, 23.376804, 5.073076, 0.345702, -0.858077, 20.965754,
+ 4.794572, 0.382135, -0.874122, 18.710079, 4.516676, 0.419871, -0.887133, 16.713011, 4.241767,
+ 0.455609, -0.891199, 14.819674, 3.972124, 0.492617, -0.894082, 13.187921, 3.717271, 0.528186,
+ -0.891270, 11.708584, 3.471719, 0.563462, -0.885719, 10.422834, 3.237760, 0.596013, -0.874241,
+ 9.237741, 3.019060, 0.629455, -0.862814, 8.248549, 2.813572, 0.661110, -0.848126, 7.358398,
+ 2.621046, 0.690314, -0.829798, 6.569392, 2.441627, 0.720589, -0.812314, 5.905934, 2.274629,
+ 0.745631, -0.788704, 5.276800, 2.119423, 0.771488, -0.766133, 4.752773, 1.974380, 0.798704,
+ -0.744726, 4.306095, 1.839482, 0.820172, -0.718062, 3.889792, 1.713244, 0.844368, -0.693972,
+ 3.545456, 1.594809, 0.863128, -0.665748, 3.212762, 1.487512, 0.880094, -0.637003, 2.926572,
+ 1.386724, 0.904252, -0.613728, 2.704260, 1.288131, 0.920506, -0.585217, 2.483164, 1.199845,
+ 0.940919, -0.559603, 2.300348, 1.114958, 0.957044, -0.531597, 2.130516, 1.034754, 0.972648,
+ -0.503583, 1.979313, 0.960912, 0.994318, -0.478813, 1.859664, 0.889786, 1.008754, -0.450943,
+ 1.742705, 0.820833, 1.028667, -0.425516, 1.645220, 0.756332, 1.046145, -0.398977, 1.557184,
+ 0.693921, 1.067212, -0.373657, 1.480814, 0.635955, 1.084111, -0.346657, 1.408762, 0.578832,
+ 1.106749, -0.321392, 1.350468, 0.523561, 1.128440, -0.295773, 1.294865, 0.471146, 1.151073,
+ -0.270028, 1.246118, 0.420298, 1.178601, -0.244816, 1.204226, 0.370575, 1.206845, -0.219027,
+ 1.166896, 0.323716, 1.235963, -0.192622, 1.135756, 0.278058, 1.263030, -0.165331, 1.109240,
+ 0.235743, 1.288937, -0.137489, 1.088379, 0.195390, 1.310681, -0.108685, 1.068987, 0.156439,
+ 1.334352, -0.079710, 1.054273, 0.117096, 1.344847, -0.049947, 1.034598, 0.076554, 1.354943,
+ -0.020272, 1.016079, 0.035585, 1.365515, 0.009170, 0.999969, -0.004771, 0.000117, -0.000935,
+ 9.424866, 7.979243, 0.000410, -0.003275, 33.013195, 7.979422, 0.002009, -0.016024, 64.370331,
+ 7.977156, 0.004541, -0.036176, 64.655952, 7.976128, 0.008109, -0.064384, 64.864494, 7.964988,
+ 0.012694, -0.099984, 64.487198, 7.971348, 0.018554, -0.143991, 64.637970, 7.923116, 0.025303,
+ -0.192040, 61.930538, 7.953975, 0.035297, -0.259442, 66.274422, 7.921861, 0.045226, -0.318370,
+ 63.334690, 7.909609, 0.058370, -0.388821, 62.686401, 7.864696, 0.074083, -0.461667, 61.332054,
+ 7.801843, 0.092537, -0.533744, 59.125607, 7.708949, 0.113781, -0.601905, 55.997845, 7.575799,
+ 0.137786, -0.664409, 52.177567, 7.393524, 0.164770, -0.721193, 48.019485, 7.161756, 0.193894,
+ -0.768842, 43.460278, 6.882018, 0.225586, -0.810332, 39.086590, 6.564607, 0.259311, -0.845096,
+ 34.896049, 6.221983, 0.294517, -0.872849, 30.952213, 5.865831, 0.331163, -0.895159, 27.375792,
+ 5.507064, 0.368964, -0.912860, 24.213310, 5.149763, 0.407255, -0.925338, 21.364958, 4.806172,
+ 0.444704, -0.930956, 18.791691, 4.472272, 0.482041, -0.932576, 16.521160, 4.160864, 0.519572,
+ -0.931547, 14.589918, 3.865206, 0.556236, -0.926554, 12.887797, 3.590445, 0.590431, -0.915839,
+ 11.352402, 3.332747, 0.622723, -0.901266, 10.002660, 3.093264, 0.657029, -0.888747, 8.905210,
+ 2.873842, 0.686164, -0.868666, 7.876704, 2.666740, 0.719168, -0.853152, 7.051816, 2.479017,
+ 0.742294, -0.826169, 6.226034, 2.306498, 0.770320, -0.804936, 5.590831, 2.141328, 0.792337,
+ -0.777772, 4.984083, 1.994663, 0.819050, -0.755478, 4.507655, 1.853950, 0.837684, -0.726072,
+ 4.049884, 1.725590, 0.861324, -0.701424, 3.678201, 1.606303, 0.880741, -0.673615, 3.337163,
+ 1.495452, 0.903335, -0.648506, 3.055720, 1.391162, 0.920311, -0.619640, 2.792068, 1.294734,
+ 0.935769, -0.590245, 2.554566, 1.204518, 0.956592, -0.564944, 2.366468, 1.118630, 0.972424,
+ -0.536842, 2.187863, 1.038323, 0.986269, -0.508020, 2.023480, 0.963803, 1.006122, -0.482411,
+ 1.895137, 0.890986, 1.022504, -0.455110, 1.775886, 0.820936, 1.037905, -0.427450, 1.665951,
+ 0.758556, 1.059281, -0.402198, 1.577363, 0.696126, 1.076613, -0.375156, 1.493391, 0.636676,
+ 1.097828, -0.349577, 1.421129, 0.579947, 1.116671, -0.322955, 1.355205, 0.525140, 1.140514,
+ -0.297406, 1.299979, 0.471460, 1.166473, -0.271786, 1.249847, 0.420473, 1.192591, -0.245461,
+ 1.204625, 0.371118, 1.223349, -0.219412, 1.166686, 0.322600, 1.254833, -0.192660, 1.134121,
+ 0.277572, 1.285808, -0.165167, 1.108617, 0.234417, 1.322015, -0.137236, 1.093841, 0.194640,
+ 1.342172, -0.106871, 1.074616, 0.155001, 1.357238, -0.075759, 1.053550, 0.114648, 1.367725,
+ -0.044279, 1.033851, 0.073254, 1.379461, -0.013001, 1.015713, 0.031895, 1.391625, 0.018075,
+ 1.000203, -0.009397, 0.000109, -0.001093, 10.986820, 9.992467, 0.000378, -0.003779, 37.989063,
+ 9.992861, 0.002028, -0.020252, 101.850441, 9.988345, 0.004557, -0.045429, 101.106750, 9.983879,
+ 0.008115, -0.080453, 100.646606, 9.953411, 0.012864, -0.125836, 101.366592, 9.943727, 0.018734,
+ -0.179350, 100.786118, 9.908408, 0.026314, -0.243680, 99.779343, 9.821631, 0.035500, -0.313552,
+ 98.608231, 9.782450, 0.047562, -0.394644, 97.689568, 9.845875, 0.062065, -0.476697, 95.177795,
+ 9.755218, 0.079552, -0.557933, 91.095581, 9.615121, 0.099905, -0.632818, 85.110382, 9.408299,
+ 0.123231, -0.699926, 77.948921, 9.120996, 0.149980, -0.760671, 70.491119, 8.764173, 0.179550,
+ -0.812251, 62.821407, 8.341752, 0.211839, -0.855909, 55.512890, 7.876337, 0.246434, -0.892023,
+ 48.744549, 7.386268, 0.282317, -0.919200, 42.462059, 6.886009, 0.319580, -0.940333, 36.901031,
+ 6.400318, 0.360135, -0.962176, 32.353752, 5.937503, 0.397805, -0.969755, 27.996445, 5.489783,
+ 0.437077, -0.976494, 24.359192, 5.072855, 0.474388, -0.975265, 21.124300, 4.684682, 0.513695,
+ -0.975335, 18.476677, 4.326597, 0.551542, -0.970264, 16.167391, 3.999049, 0.587525, -0.960365,
+ 14.143442, 3.696317, 0.621251, -0.945944, 12.374341, 3.414176, 0.654738, -0.930709, 10.877112,
+ 3.160455, 0.685794, -0.911702, 9.580887, 2.921461, 0.717135, -0.892948, 8.481939, 2.707478,
+ 0.740798, -0.865086, 7.435941, 2.510382, 0.770920, -0.845137, 6.650625, 2.329648, 0.792303,
+ -0.815956, 5.879976, 2.163206, 0.818363, -0.792225, 5.274404, 2.008042, 0.837362, -0.762396,
+ 4.700960, 1.867576, 0.862266, -0.738465, 4.254798, 1.735819, 0.880069, -0.708890, 3.828697,
+ 1.614690, 0.896021, -0.678588, 3.451655, 1.503477, 0.920156, -0.654832, 3.168722, 1.395800,
+ 0.934948, -0.624740, 2.879533, 1.299955, 0.949686, -0.595203, 2.628258, 1.208597, 0.970989,
+ -0.570041, 2.433689, 1.122310, 0.985606, -0.541116, 2.241461, 1.042168, 1.000819, -0.512835,
+ 2.075567, 0.966543, 1.012209, -0.483024, 1.919932, 0.895758, 1.035320, -0.459125, 1.807884,
+ 0.825668, 1.052077, -0.432333, 1.695689, 0.760812, 1.070459, -0.406131, 1.595491, 0.699897,
+ 1.088704, -0.379721, 1.508512, 0.640575, 1.103817, -0.352104, 1.428159, 0.583765, 1.131711,
+ -0.328122, 1.366565, 0.528240, 1.156448, -0.302568, 1.306843, 0.473988, 1.181821, -0.276487,
+ 1.252861, 0.422189, 1.211347, -0.250540, 1.205265, 0.372005, 1.243636, -0.224264, 1.165943,
+ 0.324184, 1.283038, -0.198289, 1.137772, 0.278419, 1.316722, -0.170179, 1.115057, 0.235425,
+ 1.342715, -0.140095, 1.092994, 0.195084, 1.363288, -0.108794, 1.071875, 0.155439, 1.380656,
+ -0.076774, 1.052475, 0.114636, 1.394826, -0.044509, 1.032525, 0.072890, 1.408830, -0.011968,
+ 1.015459, 0.031101, 1.422370, 0.020555, 0.999808, -0.011002, 0.000100, -0.001334, 13.377127,
+ 13.342275, 0.000342, -0.004563, 45.758434, 13.342710, 0.002026, -0.027004, 179.672058,
+ 13.331846, 0.004559, -0.060563, 179.294235, 13.314877, 0.008232, -0.108154, 181.242035,
+ 13.222856, 0.013031, -0.167590, 179.684509, 13.153860, 0.019526, -0.242041, 181.004608,
+ 12.986094, 0.026364, -0.309289, 159.606293, 13.247752, 0.037670, -0.409755, 179.468521,
+ 12.368877, 0.051804, -0.512051, 167.955582, 12.981333, 0.068214, -0.601994, 156.278793,
+ 12.704532, 0.088295, -0.686849, 143.096878, 12.316531, 0.111478, -0.758670, 127.423111,
+ 11.793048, 0.138336, -0.821348, 111.763031, 11.157992, 0.168447, -0.873616, 96.887924,
+ 10.447472, 0.201411, -0.916322, 83.225327, 9.696606, 0.237443, -0.953090, 71.403137, 8.949244,
+ 0.274234, -0.977751, 60.739277, 8.225874, 0.314566, -1.003135, 52.115578, 7.547433, 0.353932,
+ -1.016312, 44.341869, 6.910326, 0.393858, -1.024848, 37.827263, 6.324401, 0.433805, -1.028950,
+ 32.380932, 5.790555, 0.475812, -1.034084, 27.955982, 5.312826, 0.513254, -1.026743, 23.977417,
+ 4.866118, 0.549965, -1.016740, 20.628025, 4.468437, 0.590300, -1.012030, 18.036856, 4.105483,
+ 0.626420, -0.998919, 15.669224, 3.780593, 0.658897, -0.979874, 13.603898, 3.482054, 0.687252,
+ -0.955238, 11.788331, 3.211213, 0.718941, -0.935663, 10.355552, 2.962083, 0.749877, -0.915206,
+ 9.131123, 2.741382, 0.772094, -0.884837, 7.973935, 2.536501, 0.799495, -0.861214, 7.086230,
+ 2.347282, 0.820136, -0.830976, 6.240769, 2.179332, 0.846715, -0.807408, 5.604792, 2.018005,
+ 0.865176, -0.776657, 4.975034, 1.877021, 0.881100, -0.744657, 4.442767, 1.743528, 0.907637,
+ -0.722088, 4.035177, 1.621563, 0.922239, -0.690432, 3.633160, 1.506158, 0.936558, -0.659650,
+ 3.281798, 1.403606, 0.950047, -0.629105, 2.974179, 1.304276, 0.961959, -0.598277, 2.704483,
+ 1.213888, 0.987410, -0.576085, 2.510453, 1.125569, 0.999996, -0.546494, 2.304016, 1.045567,
+ 1.014127, -0.518186, 2.127867, 0.970718, 1.036275, -0.494009, 1.985804, 0.897557, 1.049695,
+ -0.465659, 1.845074, 0.830584, 1.064617, -0.438159, 1.725130, 0.766083, 1.077131, -0.409813,
+ 1.613818, 0.705101, 1.101054, -0.385632, 1.528694, 0.644828, 1.122361, -0.360045, 1.447086,
+ 0.587878, 1.147359, -0.335186, 1.377588, 0.532130, 1.169881, -0.309040, 1.313673, 0.478843,
+ 1.200554, -0.284590, 1.257256, 0.426855, 1.232047, -0.259332, 1.208431, 0.376125, 1.275402,
+ -0.235215, 1.174692, 0.326614, 1.306595, -0.207508, 1.141042, 0.281524, 1.334304, -0.178290,
+ 1.111778, 0.238694, 1.364678, -0.148530, 1.090976, 0.198549, 1.387168, -0.117114, 1.069308,
+ 0.158529, 1.408657, -0.084977, 1.050625, 0.118042, 1.426214, -0.052052, 1.031444, 0.076541,
+ 1.444257, -0.018653, 1.014298, 0.034061, 1.460618, 0.015206, 0.999413, -0.008132, 0.000100,
+ -0.002003, 20.052612, 20.032721, 0.000297, -0.005947, 59.540512, 20.033842, 0.002022,
+ -0.040439, 404.848511, 20.032743, 0.004588, -0.090999, 403.741241, 19.910591, 0.008769,
+ -0.169802, 441.471558, 19.572552, 0.013708, -0.253629, 411.667816, 19.145721, 0.020331,
+ -0.349396, 371.322571, 18.591049, 0.030259, -0.468121, 385.816498, 18.331083, 0.045190,
+ -0.611444, 391.924133, 15.807686, 0.058476, -0.676875, 319.638641, 16.947781, 0.079894,
+ -0.781421, 278.804260, 17.512903, 0.103871, -0.855116, 235.999786, 16.290295, 0.131756,
+ -0.915747, 197.168076, 14.956566, 0.163487, -0.966333, 163.452347, 13.608010, 0.198693,
+ -1.008386, 135.632706, 12.299661, 0.236157, -1.039862, 111.919281, 11.088790, 0.274579,
+ -1.059988, 92.136581, 9.983883, 0.317164, -1.084069, 77.063034, 9.008505, 0.357624, -1.092124,
+ 63.963051, 8.127298, 0.399009, -1.097560, 53.483341, 7.347628, 0.441182, -1.100981, 45.052429,
+ 6.658191, 0.481606, -1.097318, 37.932640, 6.047333, 0.524253, -1.096570, 32.395638, 5.505878,
+ 0.564351, -1.088739, 27.679380, 5.018494, 0.600843, -1.073396, 23.611519, 4.580770, 0.635527,
+ -1.055024, 20.207081, 4.194785, 0.672045, -1.039775, 17.469036, 3.847436, 0.698372, -1.009545,
+ 14.928226, 3.532546, 0.729336, -0.987168, 12.953170, 3.248834, 0.761147, -0.966299, 11.346271,
+ 2.994166, 0.782270, -0.932841, 9.813129, 2.762244, 0.811832, -0.910431, 8.672224, 2.549933,
+ 0.832053, -0.878369, 7.578633, 2.363132, 0.849383, -0.844673, 6.648379, 2.189266, 0.866020,
+ -0.811703, 5.850784, 2.031716, 0.893083, -0.789181, 5.273372, 1.884480, 0.909212, -0.757541,
+ 4.700618, 1.750298, 0.923169, -0.725157, 4.196640, 1.627590, 0.937112, -0.693769, 3.764841,
+ 1.514906, 0.961901, -0.670828, 3.444598, 1.406839, 0.975245, -0.640240, 3.120745, 1.307873,
+ 0.989696, -0.611032, 2.840732, 1.216417, 1.002057, -0.581144, 2.591596, 1.132553, 1.014022,
+ -0.551620, 2.373820, 1.051695, 1.025307, -0.522268, 2.177992, 0.977500, 1.052190, -0.500826,
+ 2.042511, 0.904301, 1.064408, -0.472355, 1.891934, 0.837557, 1.077876, -0.444815, 1.761054,
+ 0.773004, 1.088939, -0.416531, 1.638939, 0.713958, 1.118551, -0.395057, 1.555724, 0.652485,
+ 1.134469, -0.368289, 1.465490, 0.596330, 1.162778, -0.345095, 1.390977, 0.539703, 1.185298,
+ -0.319527, 1.321225, 0.486250, 1.208419, -0.293590, 1.259318, 0.434178, 1.261013, -0.273471,
+ 1.219767, 0.382032, 1.297811, -0.248226, 1.176422, 0.334190, 1.326591, -0.220354, 1.139881,
+ 0.289075, 1.357918, -0.191937, 1.111418, 0.246259, 1.387590, -0.162282, 1.086511, 0.205129,
+ 1.415797, -0.131515, 1.067072, 0.165601, 1.440194, -0.099555, 1.047799, 0.125462, 1.465600,
+ -0.066957, 1.030406, 0.084082, 1.487714, -0.033496, 1.013889, 0.041981, 1.509947, 0.000663,
+ 0.998773, -0.000485, 0.000100, -0.004009, 40.102047, 40.087105, 0.000228, -0.009141, 91.431366,
+ 40.074432, 0.001522, -0.060544, 605.651733, 39.918827, 0.004919, -0.188871, 1712.982300,
+ 38.873421, 0.009053, -0.320325, 1583.453125, 39.715633, 0.015375, -0.471415, 1486.033691,
+ 39.162876, 0.029306, -0.735111, 1751.701050, 28.083200, 0.043450, -0.859759, 1392.475220,
+ 24.599945, 0.079075, -1.220033, 1629.972656, 18.507019, 0.090130, -1.091255, 940.347351,
+ 17.961655, 0.098008, -0.945965, 425.901093, 24.478010, 0.138246, -1.084105, 416.823944,
+ 20.003433, 0.174489, -1.133148, 302.730042, 18.550846, 0.207969, -1.138483, 242.853577,
+ 15.923334, 0.249132, -1.168197, 191.649445, 13.940813, 0.291391, -1.187038, 152.910309,
+ 12.263267, 0.332856, -1.192793, 121.905075, 10.822873, 0.377473, -1.202846, 99.145561,
+ 9.618412, 0.422601, -1.208871, 81.343315, 8.591735, 0.465276, -1.204545, 66.742569, 7.692911,
+ 0.504710, -1.190839, 54.787876, 6.915612, 0.544909, -1.178827, 45.507313, 6.242786, 0.582125,
+ -1.160590, 37.819912, 5.651690, 0.620694, -1.145481, 31.926588, 5.123660, 0.659127, -1.130178,
+ 27.147310, 4.669475, 0.684358, -1.093728, 22.650702, 4.258717, 0.719453, -1.074591, 19.454103,
+ 3.901225, 0.751695, -1.051678, 16.735672, 3.576870, 0.775082, -1.017716, 14.281039, 3.287471,
+ 0.796233, -0.982759, 12.261332, 3.023708, 0.827404, -0.961227, 10.767912, 2.787740, 0.848149,
+ -0.928433, 9.371350, 2.570737, 0.864891, -0.892838, 8.142364, 2.379204, 0.880979, -0.858193,
+ 7.118954, 2.204470, 0.910434, -0.837281, 6.389041, 2.041554, 0.925396, -0.803638, 5.643217,
+ 1.893353, 0.942463, -0.772925, 5.031223, 1.757331, 0.955217, -0.739720, 4.486978, 1.633572,
+ 0.968570, -0.708048, 4.014621, 1.520414, 0.981672, -0.677109, 3.617768, 1.412506, 0.992829,
+ -0.645712, 3.258773, 1.317079, 1.021270, -0.625746, 3.006640, 1.222611, 1.031247, -0.594628,
+ 2.733073, 1.137911, 1.043581, -0.565540, 2.498495, 1.058439, 1.055930, -0.536962, 2.289843,
+ 0.984428, 1.066727, -0.508076, 2.108603, 0.912794, 1.081225, -0.481297, 1.951454, 0.845536,
+ 1.088198, -0.451563, 1.801891, 0.782718, 1.123316, -0.433247, 1.704316, 0.721664, 1.133206,
+ -0.404812, 1.586153, 0.662761, 1.152889, -0.379901, 1.490958, 0.606866, 1.188158, -0.359421,
+ 1.415730, 0.550666, 1.217064, -0.336049, 1.344172, 0.496748, 1.257727, -0.314816, 1.283196,
+ 0.443538, 1.286647, -0.289530, 1.225903, 0.394018, 1.308729, -0.262053, 1.173928, 0.346255,
+ 1.351453, -0.237704, 1.139992, 0.300393, 1.380284, -0.209733, 1.105997, 0.256661, 1.414621,
+ -0.181613, 1.082109, 0.215429, 1.453045, -0.152797, 1.063853, 0.177098, 1.481066, -0.121803,
+ 1.043185, 0.137203, 1.514113, -0.090250, 1.027072, 0.096998, 1.547317, -0.057603, 1.012551,
+ 0.055328, 1.577983, -0.023799, 0.999267, 0.013094, 0.000108, -0.124970, 1249.704346,
+ 1249.703491, 0.000140, -0.119585, 1195.855469, 1195.854370, 0.003995, -0.927433, 9274.246094,
+ 232.443573, 0.012013, -1.131580, 11315.999023, 98.211105, 0.023892, -1.216018, 12162.739258,
+ 67.214500, 0.047506, -1.517865, 15186.294922, 42.410069, 0.082523, -1.812564, 18145.718750,
+ 24.421545, 0.112452, -1.805072, 11112.966797, 18.450365, 0.164460, -2.016784, 8086.032715,
+ 14.043465, 0.195870, -1.898199, 4245.658203, 13.178202, 0.197797, -1.556158, 1315.561768,
+ 30.760096, 0.219540, -1.433455, 802.380371, 25.037956, 0.268696, -1.483235, 579.715515,
+ 20.975695, 0.265968, -1.261051, 386.583649, 12.017023, 0.325369, -1.343349, 316.795959,
+ 12.612406, 0.387968, -1.411606, 232.491623, 13.296940, 0.435543, -1.411236, 181.515228,
+ 11.646996, 0.482729, -1.405722, 143.425354, 10.265131, 0.531742, -1.402782, 114.920082,
+ 9.114828, 0.559383, -1.346165, 88.589005, 8.089214, 0.607851, -1.342407, 73.056610, 7.249064,
+ 0.656928, -1.338238, 60.826897, 6.531094, 0.681212, -1.285692, 48.727219, 5.868711, 0.729238,
+ -1.279951, 41.256016, 5.324553, 0.751172, -1.230045, 33.728260, 4.816513, 0.773107, -1.184288,
+ 27.913816, 4.377203, 0.815726, -1.171653, 24.065962, 3.999965, 0.837886, -1.130636, 20.254860,
+ 3.658493, 0.857674, -1.089071, 17.138168, 3.347930, 0.876120, -1.048303, 14.572968, 3.072666,
+ 0.893935, -1.009040, 12.496377, 2.825165, 0.927998, -0.989064, 11.040731, 2.605520, 0.928445,
+ -0.935017, 9.365102, 2.401481, 0.945279, -0.899993, 8.177711, 2.222282, 0.959378, -0.863854,
+ 7.155303, 2.059342, 0.971761, -0.827684, 6.284632, 1.909314, 0.987812, -0.795878, 5.583837,
+ 1.771094, 1.001958, -0.763540, 4.962345, 1.645968, 1.014357, -0.730897, 4.435898, 1.527438,
+ 1.025946, -0.698675, 3.973241, 1.421337, 1.036435, -0.666662, 3.568025, 1.323677, 1.046807,
+ -0.635466, 3.218647, 1.232678, 1.052974, -0.602660, 2.902273, 1.147675, 1.086089, -0.585364,
+ 2.694939, 1.068352, 1.094660, -0.554784, 2.454491, 0.993445, 1.117131, -0.531500, 2.270746,
+ 0.923758, 1.114009, -0.496581, 2.063934, 0.858381, 1.137328, -0.473914, 1.917990, 0.794980,
+ 1.158671, -0.450127, 1.786523, 0.735697, 1.177878, -0.425306, 1.662454, 0.677498, 1.207510,
+ -0.403797, 1.559058, 0.621762, 1.244496, -0.383812, 1.466801, 0.566190, 1.240412, -0.351080,
+ 1.366853, 0.514288, 1.321257, -0.341200, 1.309808, 0.464621, 1.336512, -0.312710, 1.241822,
+ 0.413228, 1.365047, -0.286935, 1.186612, 0.366092, 1.418984, -0.265184, 1.152120, 0.321528,
+ 1.388864, -0.227750, 1.089937, 0.271827, 1.464383, -0.207168, 1.077271, 0.232838, 1.473125,
+ -0.175770, 1.041835, 0.193289, 1.542908, -0.150424, 1.036794, 0.156153, 1.563005, -0.118748,
+ 1.013029, 0.114866, 1.637048, -0.089604, 1.013493, 0.076804, 1.670777, -0.056398, 0.999208,
+ 0.032691,
+};
+static float ltc_mag_ggx[64 * 64] = {
+ 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
+ 1.000000, 1.000000, 1.000000, 0.999995, 0.999990, 0.999971, 0.999937, 0.999853, 0.999670,
+ 0.999138, 0.996746, 0.979578, 0.979309, 0.978836, 0.977972, 0.976223, 0.972205, 0.962466,
+ 0.953919, 0.949829, 0.942492, 0.929870, 0.921319, 0.911112, 0.896015, 0.885105, 0.869971,
+ 0.855017, 0.838328, 0.821241, 0.802352, 0.783873, 0.763309, 0.743058, 0.721929, 0.699755,
+ 0.677721, 0.655456, 0.632681, 0.609629, 0.586831, 0.564287, 0.541772, 0.519428, 0.497353,
+ 0.475624, 0.454606, 0.434099, 0.414085, 0.394605, 0.375698, 0.357386, 0.339871, 0.323085,
+ 0.306905, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
+ 0.999999, 0.999999, 0.999998, 0.999995, 0.999990, 0.999980, 0.999959, 0.999923, 0.999842,
+ 0.999660, 0.999119, 0.996613, 0.981824, 0.979298, 0.978826, 0.977957, 0.976184, 0.972091,
+ 0.962188, 0.953875, 0.949746, 0.942335, 0.930166, 0.921211, 0.910927, 0.896979, 0.884940,
+ 0.869864, 0.854835, 0.838200, 0.821049, 0.802552, 0.783659, 0.763512, 0.742927, 0.721715,
+ 0.699938, 0.677775, 0.655246, 0.632555, 0.609805, 0.586996, 0.564225, 0.541606, 0.519346,
+ 0.497419, 0.475863, 0.454738, 0.434099, 0.414003, 0.394547, 0.375747, 0.357564, 0.340012,
+ 0.323099, 0.306861, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
+ 1.000000, 1.000000, 0.999999, 0.999998, 0.999995, 0.999991, 0.999979, 0.999959, 0.999917,
+ 0.999839, 0.999648, 0.999074, 0.996168, 0.983770, 0.979279, 0.978800, 0.977905, 0.976058,
+ 0.971727, 0.962120, 0.953901, 0.949485, 0.941859, 0.930911, 0.920853, 0.910394, 0.897600,
+ 0.884427, 0.870101, 0.854522, 0.838325, 0.820754, 0.802707, 0.783223, 0.763605, 0.742872,
+ 0.721565, 0.699935, 0.677726, 0.655242, 0.632580, 0.609766, 0.586946, 0.564275, 0.541759,
+ 0.519467, 0.497478, 0.475886, 0.454794, 0.434233, 0.414207, 0.394751, 0.375892, 0.357683,
+ 0.340146, 0.323287, 0.307095, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
+ 1.000000, 0.999999, 0.999999, 0.999998, 0.999996, 0.999992, 0.999987, 0.999975, 0.999953,
+ 0.999913, 0.999830, 0.999630, 0.998993, 0.995279, 0.985142, 0.979252, 0.978754, 0.977821,
+ 0.975838, 0.971088, 0.962563, 0.954785, 0.949048, 0.941052, 0.931420, 0.920812, 0.909750,
+ 0.897867, 0.883856, 0.870091, 0.854353, 0.838166, 0.820661, 0.802465, 0.783308, 0.763346,
+ 0.742734, 0.721608, 0.699747, 0.677626, 0.655245, 0.632547, 0.609793, 0.587044, 0.564340,
+ 0.541779, 0.519529, 0.497633, 0.476114, 0.455030, 0.434430, 0.414406, 0.394974, 0.376154,
+ 0.357979, 0.340443, 0.323572, 0.307379, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
+ 1.000000, 1.000000, 1.000000, 0.999998, 0.999998, 0.999996, 0.999991, 0.999984, 0.999970,
+ 0.999946, 0.999905, 0.999815, 0.999599, 0.998856, 0.993704, 0.986135, 0.979212, 0.978690,
+ 0.977691, 0.975504, 0.970133, 0.962951, 0.955649, 0.948405, 0.940418, 0.931660, 0.920881,
+ 0.909376, 0.897785, 0.883844, 0.869756, 0.854326, 0.837732, 0.820617, 0.802053, 0.783195,
+ 0.763119, 0.742610, 0.721344, 0.699709, 0.677624, 0.655114, 0.632523, 0.609812, 0.587052,
+ 0.564417, 0.541966, 0.519751, 0.497824, 0.476309, 0.455271, 0.434735, 0.414736, 0.395317,
+ 0.376524, 0.358364, 0.340852, 0.323988, 0.307786, 1.000000, 1.000000, 1.000000, 1.000000,
+ 1.000000, 1.000000, 0.999999, 0.999999, 0.999997, 0.999996, 0.999994, 0.999989, 0.999980,
+ 0.999965, 0.999940, 0.999895, 0.999796, 0.999559, 0.998638, 0.992774, 0.986878, 0.980297,
+ 0.978602, 0.977514, 0.975026, 0.969169, 0.963214, 0.956267, 0.947689, 0.940054, 0.931637,
+ 0.920678, 0.908990, 0.897349, 0.883905, 0.869139, 0.854177, 0.837476, 0.820295, 0.801977,
+ 0.782798, 0.762978, 0.742418, 0.721193, 0.699560, 0.677402, 0.655108, 0.632543, 0.609804,
+ 0.587158, 0.564557, 0.542096, 0.519908, 0.498088, 0.476632, 0.455623, 0.435104, 0.415161,
+ 0.395783, 0.377005, 0.358843, 0.341345, 0.324529, 0.308355, 1.000000, 1.000000, 1.000000,
+ 1.000000, 1.000000, 0.999999, 0.999999, 0.999998, 0.999997, 0.999992, 0.999991, 0.999985,
+ 0.999977, 0.999959, 0.999935, 0.999878, 0.999773, 0.999505, 0.998284, 0.992353, 0.987457,
+ 0.981665, 0.978492, 0.977277, 0.974360, 0.968716, 0.963373, 0.956629, 0.947397, 0.939657,
+ 0.931339, 0.920588, 0.908975, 0.896712, 0.883763, 0.868890, 0.853731, 0.837333, 0.819702,
+ 0.801738, 0.782454, 0.762712, 0.742024, 0.721037, 0.699325, 0.677359, 0.655030, 0.632439,
+ 0.609869, 0.587221, 0.564663, 0.542328, 0.520220, 0.498400, 0.476997, 0.456053, 0.435593,
+ 0.415658, 0.396300, 0.377577, 0.359473, 0.342004, 0.325170, 0.308997, 1.000000, 1.000000,
+ 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999998, 0.999996, 0.999993, 0.999988,
+ 0.999981, 0.999971, 0.999951, 0.999921, 0.999863, 0.999748, 0.999433, 0.997681, 0.992120,
+ 0.987920, 0.982864, 0.978353, 0.976961, 0.973451, 0.968396, 0.963400, 0.956680, 0.947529,
+ 0.939151, 0.930747, 0.920511, 0.908867, 0.896142, 0.883335, 0.868764, 0.853025, 0.837015,
+ 0.819452, 0.801249, 0.782176, 0.762345, 0.741843, 0.720721, 0.699135, 0.677194, 0.654889,
+ 0.632487, 0.609902, 0.587328, 0.564891, 0.542567, 0.520501, 0.498793, 0.477442, 0.456528,
+ 0.436131, 0.416273, 0.396980, 0.378276, 0.360176, 0.342738, 0.325950, 0.309803, 1.000000,
+ 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999999, 0.999997, 0.999995, 0.999991,
+ 0.999985, 0.999978, 0.999963, 0.999942, 0.999907, 0.999844, 0.999715, 0.999332, 0.996612,
+ 0.991974, 0.988297, 0.983843, 0.978349, 0.976540, 0.972351, 0.968109, 0.963280, 0.956464,
+ 0.947779, 0.938754, 0.929952, 0.920253, 0.908530, 0.895785, 0.882679, 0.868456, 0.852669,
+ 0.836406, 0.819138, 0.800708, 0.781803, 0.761855, 0.741534, 0.720405, 0.698959, 0.676964,
+ 0.654827, 0.632411, 0.609922, 0.587477, 0.565051, 0.542829, 0.520889, 0.499225, 0.477951,
+ 0.457148, 0.436792, 0.416963, 0.397723, 0.379068, 0.361025, 0.343608, 0.326842, 0.310718,
+ 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999995, 0.999994,
+ 0.999990, 0.999983, 0.999971, 0.999954, 0.999932, 0.999892, 0.999820, 0.999675, 0.999190,
+ 0.995492, 0.991911, 0.988610, 0.984662, 0.979221, 0.975975, 0.971671, 0.967788, 0.963002,
+ 0.955938, 0.947965, 0.938692, 0.929309, 0.919781, 0.908268, 0.895518, 0.882022, 0.867884,
+ 0.852346, 0.835746, 0.818607, 0.800261, 0.781335, 0.761539, 0.741063, 0.720116, 0.698617,
+ 0.676815, 0.654700, 0.632389, 0.610037, 0.587591, 0.565328, 0.543205, 0.521293, 0.499745,
+ 0.478562, 0.457776, 0.437515, 0.417776, 0.398586, 0.379963, 0.361984, 0.344616, 0.327857,
+ 0.311751, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997, 0.999996,
+ 0.999992, 0.999986, 0.999977, 0.999965, 0.999947, 0.999916, 0.999873, 0.999794, 0.999628,
+ 0.998966, 0.994914, 0.991849, 0.988873, 0.985288, 0.980170, 0.975207, 0.971156, 0.967476,
+ 0.962538, 0.955601, 0.947978, 0.938542, 0.928618, 0.919056, 0.907890, 0.895098, 0.881352,
+ 0.867263, 0.851806, 0.835168, 0.818003, 0.799785, 0.780633, 0.761080, 0.740618, 0.719795,
+ 0.698332, 0.676629, 0.654544, 0.632411, 0.610042, 0.587805, 0.565593, 0.543549, 0.521793,
+ 0.500309, 0.479195, 0.458546, 0.438353, 0.418669, 0.399557, 0.381012, 0.363049, 0.345710,
+ 0.329006, 0.312948, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997,
+ 0.999993, 0.999990, 0.999984, 0.999972, 0.999960, 0.999939, 0.999906, 0.999853, 0.999765,
+ 0.999567, 0.998603, 0.994519, 0.991794, 0.989089, 0.985781, 0.980956, 0.974161, 0.970688,
+ 0.967064, 0.961890, 0.955292, 0.947848, 0.938359, 0.928226, 0.918214, 0.907361, 0.894702,
+ 0.880834, 0.866500, 0.851209, 0.834627, 0.817211, 0.799250, 0.780131, 0.760512, 0.740218,
+ 0.719264, 0.698063, 0.676325, 0.654450, 0.632316, 0.610170, 0.587988, 0.565891, 0.544013,
+ 0.522305, 0.500958, 0.479971, 0.459376, 0.439271, 0.419699, 0.400620, 0.382126, 0.364246,
+ 0.346967, 0.330273, 0.314236, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998,
+ 0.999996, 0.999994, 0.999988, 0.999979, 0.999967, 0.999952, 0.999924, 0.999888, 0.999833,
+ 0.999733, 0.999490, 0.997946, 0.994192, 0.991812, 0.989274, 0.986224, 0.981547, 0.974000,
+ 0.970269, 0.966545, 0.961031, 0.954921, 0.947416, 0.938226, 0.928003, 0.917390, 0.906553,
+ 0.894191, 0.880329, 0.865540, 0.850476, 0.834058, 0.816467, 0.798509, 0.779561, 0.759828,
+ 0.739738, 0.718878, 0.697718, 0.676138, 0.654342, 0.632317, 0.610292, 0.588207, 0.566289,
+ 0.544443, 0.522927, 0.501674, 0.480765, 0.460314, 0.440304, 0.420782, 0.401824, 0.383410,
+ 0.365538, 0.348312, 0.331692, 0.315688, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999,
+ 0.999998, 0.999996, 0.999993, 0.999985, 0.999976, 0.999961, 0.999943, 0.999913, 0.999872,
+ 0.999807, 0.999691, 0.999390, 0.996859, 0.994003, 0.991808, 0.989423, 0.986523, 0.981783,
+ 0.974511, 0.969791, 0.965933, 0.960377, 0.954434, 0.946803, 0.938026, 0.927620, 0.916545,
+ 0.905639, 0.893489, 0.879820, 0.864852, 0.849513, 0.833311, 0.815878, 0.797621, 0.778938,
+ 0.759253, 0.739142, 0.718479, 0.697274, 0.675902, 0.654135, 0.632357, 0.610364, 0.588497,
+ 0.566631, 0.545012, 0.523579, 0.502429, 0.481680, 0.461304, 0.441425, 0.422039, 0.403135,
+ 0.384779, 0.366976, 0.349796, 0.333231, 0.317277, 1.000000, 1.000000, 1.000000, 1.000000,
+ 0.999999, 0.999998, 0.999996, 0.999991, 0.999983, 0.999974, 0.999956, 0.999932, 0.999901,
+ 0.999852, 0.999780, 0.999646, 0.999248, 0.996193, 0.993784, 0.991782, 0.989539, 0.986694,
+ 0.981765, 0.975135, 0.969309, 0.965128, 0.959788, 0.953831, 0.946255, 0.937664, 0.927351,
+ 0.916044, 0.904715, 0.892528, 0.879111, 0.864256, 0.848452, 0.832434, 0.815129, 0.796806,
+ 0.778118, 0.758668, 0.738466, 0.718024, 0.696958, 0.675642, 0.654067, 0.632325, 0.610546,
+ 0.588786, 0.567123, 0.545617, 0.524312, 0.503348, 0.482637, 0.462418, 0.442657, 0.423338,
+ 0.404564, 0.386277, 0.368545, 0.351448, 0.334906, 0.318961, 1.000000, 1.000000, 1.000000,
+ 0.999999, 0.999999, 0.999998, 0.999994, 0.999989, 0.999979, 0.999968, 0.999949, 0.999921,
+ 0.999886, 0.999833, 0.999747, 0.999596, 0.999029, 0.995749, 0.993677, 0.991724, 0.989620,
+ 0.986723, 0.981515, 0.975767, 0.969056, 0.964124, 0.959142, 0.953036, 0.945650, 0.937022,
+ 0.926971, 0.915515, 0.903584, 0.891603, 0.878212, 0.863472, 0.847652, 0.831398, 0.814299,
+ 0.796105, 0.777231, 0.757977, 0.737895, 0.717415, 0.696595, 0.675317, 0.653980, 0.632343,
+ 0.610735, 0.589076, 0.567620, 0.546251, 0.525165, 0.504255, 0.483759, 0.463666, 0.443987,
+ 0.424783, 0.406042, 0.387891, 0.370293, 0.353221, 0.336715, 0.320806, 1.000000, 1.000000,
+ 1.000000, 0.999999, 0.999998, 0.999998, 0.999993, 0.999987, 0.999977, 0.999964, 0.999943,
+ 0.999911, 0.999867, 0.999807, 0.999714, 0.999531, 0.998645, 0.995399, 0.993512, 0.991717,
+ 0.989661, 0.986652, 0.981559, 0.976183, 0.969411, 0.963317, 0.958457, 0.952091, 0.944951,
+ 0.936307, 0.926454, 0.915043, 0.902668, 0.890462, 0.877245, 0.862672, 0.846823, 0.830201,
+ 0.813293, 0.795306, 0.776393, 0.757199, 0.737324, 0.716808, 0.696187, 0.675094, 0.653814,
+ 0.632453, 0.610885, 0.589483, 0.568099, 0.546975, 0.525953, 0.505268, 0.484936, 0.464988,
+ 0.445458, 0.426314, 0.407750, 0.389670, 0.372098, 0.355105, 0.338682, 0.322825, 1.000000,
+ 1.000000, 1.000000, 1.000000, 0.999999, 0.999996, 0.999992, 0.999983, 0.999976, 0.999959,
+ 0.999933, 0.999898, 0.999849, 0.999780, 0.999676, 0.999454, 0.997884, 0.995166, 0.993394,
+ 0.991723, 0.989654, 0.986389, 0.981632, 0.976607, 0.969701, 0.962555, 0.957605, 0.951232,
+ 0.944099, 0.935556, 0.925699, 0.914492, 0.902027, 0.889116, 0.876093, 0.861649, 0.845956,
+ 0.829238, 0.812220, 0.794420, 0.775657, 0.756265, 0.736673, 0.716372, 0.695669, 0.674886,
+ 0.653728, 0.632568, 0.611217, 0.589929, 0.568783, 0.547752, 0.526931, 0.506425, 0.486238,
+ 0.466425, 0.446945, 0.428026, 0.409536, 0.391551, 0.374087, 0.357155, 0.340787, 0.324974,
+ 1.000000, 1.000000, 1.000000, 1.000000, 0.999998, 0.999996, 0.999990, 0.999984, 0.999970,
+ 0.999952, 0.999925, 0.999886, 0.999831, 0.999757, 0.999633, 0.999356, 0.997017, 0.994868,
+ 0.993337, 0.991710, 0.989580, 0.985848, 0.981640, 0.976711, 0.969755, 0.962166, 0.956609,
+ 0.950365, 0.943026, 0.934693, 0.924880, 0.913729, 0.901350, 0.887966, 0.874726, 0.860474,
+ 0.844905, 0.828269, 0.810905, 0.793364, 0.774812, 0.755478, 0.735886, 0.715847, 0.695231,
+ 0.674537, 0.653667, 0.632527, 0.611475, 0.590363, 0.569462, 0.548571, 0.527976, 0.507634,
+ 0.487632, 0.467901, 0.448680, 0.429833, 0.411467, 0.393568, 0.376197, 0.359374, 0.343034,
+ 0.327273, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999993, 0.999989, 0.999980,
+ 0.999965, 0.999945, 0.999913, 0.999869, 0.999810, 0.999723, 0.999583, 0.999213, 0.996540,
+ 0.994740, 0.993244, 0.991671, 0.989411, 0.985533, 0.981616, 0.976847, 0.969968, 0.962315,
+ 0.955468, 0.949420, 0.942016, 0.933617, 0.923949, 0.912899, 0.900495, 0.887022, 0.873283,
+ 0.859153, 0.843830, 0.827325, 0.809888, 0.792172, 0.773832, 0.754686, 0.735035, 0.715297,
+ 0.694955, 0.674242, 0.653660, 0.632752, 0.611804, 0.590993, 0.570154, 0.549539, 0.529087,
+ 0.508974, 0.489030, 0.469599, 0.450466, 0.431761, 0.413508, 0.395761, 0.378480, 0.361679,
+ 0.345465, 0.329752, 1.000000, 1.000000, 1.000000, 1.000000, 0.999997, 0.999994, 0.999987,
+ 0.999978, 0.999961, 0.999936, 0.999903, 0.999855, 0.999786, 0.999689, 0.999527, 0.998988,
+ 0.996137, 0.994527, 0.993108, 0.991599, 0.989084, 0.985308, 0.981527, 0.976677, 0.970079,
+ 0.962535, 0.954490, 0.948271, 0.940942, 0.932422, 0.922836, 0.911896, 0.899632, 0.886118,
+ 0.871864, 0.857719, 0.842536, 0.826163, 0.808849, 0.790860, 0.772802, 0.753860, 0.734335,
+ 0.714582, 0.694543, 0.674071, 0.653544, 0.632922, 0.612153, 0.591573, 0.570951, 0.550520,
+ 0.530352, 0.510311, 0.490707, 0.471359, 0.452396, 0.433837, 0.415736, 0.398052, 0.380874,
+ 0.364232, 0.348023, 0.332368, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999994,
+ 0.999988, 0.999976, 0.999957, 0.999928, 0.999891, 0.999837, 0.999759, 0.999650, 0.999463,
+ 0.998551, 0.995879, 0.994366, 0.992964, 0.991479, 0.988521, 0.985101, 0.981482, 0.976168,
+ 0.970242, 0.962585, 0.953950, 0.946973, 0.939686, 0.931248, 0.921614, 0.910765, 0.898617,
+ 0.885183, 0.870772, 0.856138, 0.841120, 0.824962, 0.807732, 0.789813, 0.771638, 0.753008,
+ 0.733686, 0.713927, 0.694082, 0.673967, 0.653549, 0.633135, 0.612702, 0.592200, 0.571904,
+ 0.551679, 0.531678, 0.511898, 0.492437, 0.473239, 0.454451, 0.436067, 0.418054, 0.400542,
+ 0.383486, 0.366848, 0.350781, 0.335182, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997,
+ 0.999993, 0.999985, 0.999972, 0.999951, 0.999919, 0.999877, 0.999817, 0.999733, 0.999608,
+ 0.999380, 0.997685, 0.995603, 0.994264, 0.992911, 0.991287, 0.987923, 0.984871, 0.981239,
+ 0.975933, 0.970149, 0.962511, 0.953824, 0.945699, 0.938285, 0.929907, 0.920343, 0.909537,
+ 0.897435, 0.884056, 0.869626, 0.854490, 0.839459, 0.823511, 0.806511, 0.788752, 0.770440,
+ 0.751995, 0.732962, 0.713424, 0.693525, 0.673798, 0.653622, 0.633301, 0.613224, 0.592938,
+ 0.572833, 0.552904, 0.533030, 0.513556, 0.494215, 0.475279, 0.456673, 0.438411, 0.420583,
+ 0.403178, 0.386178, 0.369728, 0.353688, 0.338147, 1.000000, 1.000000, 1.000000, 0.999999,
+ 0.999997, 0.999991, 0.999984, 0.999967, 0.999944, 0.999912, 0.999863, 0.999796, 0.999703,
+ 0.999563, 0.999279, 0.997104, 0.995394, 0.994111, 0.992825, 0.990979, 0.987529, 0.984661,
+ 0.980774, 0.975758, 0.969866, 0.962465, 0.953678, 0.944489, 0.936886, 0.928356, 0.918820,
+ 0.908073, 0.896092, 0.882833, 0.868463, 0.853212, 0.837744, 0.822048, 0.805333, 0.787643,
+ 0.769414, 0.750830, 0.732178, 0.712972, 0.693227, 0.673569, 0.653744, 0.633739, 0.613735,
+ 0.593822, 0.573916, 0.554158, 0.534652, 0.515248, 0.496233, 0.477436, 0.459009, 0.440929,
+ 0.423259, 0.405951, 0.389136, 0.372690, 0.356789, 0.341329, 1.000000, 1.000000, 1.000000,
+ 0.999999, 0.999996, 0.999991, 0.999981, 0.999966, 0.999939, 0.999903, 0.999847, 0.999771,
+ 0.999666, 0.999510, 0.999131, 0.996690, 0.995147, 0.993882, 0.992696, 0.990474, 0.987227,
+ 0.984334, 0.980153, 0.975438, 0.969406, 0.962238, 0.953598, 0.943868, 0.935356, 0.926721,
+ 0.917122, 0.906430, 0.894550, 0.881354, 0.867131, 0.851954, 0.835972, 0.820331, 0.803911,
+ 0.786452, 0.768420, 0.749821, 0.731298, 0.712393, 0.692979, 0.673418, 0.653859, 0.634232,
+ 0.614327, 0.594732, 0.575131, 0.555584, 0.536346, 0.517175, 0.498323, 0.479744, 0.461485,
+ 0.443645, 0.426061, 0.408969, 0.392155, 0.375921, 0.360060, 0.344677, 1.000000, 1.000000,
+ 1.000000, 0.999999, 0.999997, 0.999991, 0.999979, 0.999960, 0.999931, 0.999891, 0.999832,
+ 0.999748, 0.999629, 0.999449, 0.998880, 0.996305, 0.995024, 0.993812, 0.992508, 0.989721,
+ 0.986936, 0.983936, 0.979629, 0.974979, 0.968928, 0.961970, 0.953291, 0.943458, 0.933644,
+ 0.925007, 0.915388, 0.904755, 0.892932, 0.879831, 0.865794, 0.850672, 0.834591, 0.818398,
+ 0.802304, 0.785151, 0.767450, 0.748987, 0.730325, 0.711758, 0.692761, 0.673417, 0.653908,
+ 0.634686, 0.615168, 0.595707, 0.576393, 0.557198, 0.538018, 0.519253, 0.500555, 0.482220,
+ 0.464197, 0.446414, 0.429106, 0.412035, 0.395508, 0.379284, 0.363538, 0.348220, 1.000000,
+ 1.000000, 1.000000, 0.999999, 0.999995, 0.999989, 0.999977, 0.999955, 0.999924, 0.999879,
+ 0.999813, 0.999722, 0.999590, 0.999381, 0.998335, 0.996088, 0.994814, 0.993709, 0.992220,
+ 0.989209, 0.986575, 0.983383, 0.979084, 0.974272, 0.968359, 0.961275, 0.953025, 0.943098,
+ 0.932434, 0.923101, 0.913477, 0.902861, 0.891059, 0.878072, 0.864118, 0.849188, 0.833281,
+ 0.816808, 0.800596, 0.783745, 0.766331, 0.748123, 0.729686, 0.711078, 0.692527, 0.673491,
+ 0.654296, 0.635113, 0.616048, 0.596847, 0.577720, 0.558879, 0.540028, 0.521371, 0.502996,
+ 0.484858, 0.466997, 0.449477, 0.432217, 0.415426, 0.398924, 0.382890, 0.367206, 0.351955,
+ 1.000000, 1.000000, 1.000000, 0.999998, 0.999996, 0.999988, 0.999974, 0.999953, 0.999918,
+ 0.999865, 0.999791, 0.999690, 0.999542, 0.999293, 0.997535, 0.995790, 0.994609, 0.993557,
+ 0.991766, 0.988767, 0.986255, 0.982544, 0.978541, 0.973528, 0.967700, 0.960596, 0.952299,
+ 0.942684, 0.931653, 0.921211, 0.911489, 0.900818, 0.889018, 0.876245, 0.862406, 0.847517,
+ 0.831852, 0.815367, 0.798719, 0.782224, 0.765167, 0.747304, 0.729133, 0.710485, 0.692196,
+ 0.673589, 0.654770, 0.635717, 0.616986, 0.598119, 0.579298, 0.560560, 0.542163, 0.523669,
+ 0.505564, 0.487642, 0.469991, 0.452658, 0.435620, 0.418937, 0.402612, 0.386633, 0.371091,
+ 0.355949, 1.000000, 1.000000, 0.999999, 0.999998, 0.999995, 0.999986, 0.999973, 0.999948,
+ 0.999909, 0.999852, 0.999769, 0.999656, 0.999490, 0.999186, 0.997059, 0.995624, 0.994510,
+ 0.993327, 0.991020, 0.988379, 0.985771, 0.981971, 0.978051, 0.972892, 0.967020, 0.959965,
+ 0.951625, 0.941902, 0.930951, 0.919370, 0.909285, 0.898562, 0.886809, 0.874251, 0.860597,
+ 0.845808, 0.830365, 0.813972, 0.797260, 0.780597, 0.763854, 0.746401, 0.728519, 0.710203,
+ 0.691882, 0.673687, 0.655275, 0.636621, 0.617909, 0.599473, 0.581032, 0.562560, 0.544295,
+ 0.526228, 0.508293, 0.490652, 0.473242, 0.456004, 0.439212, 0.422663, 0.406476, 0.390647,
+ 0.375204, 0.360129, 1.000000, 1.000000, 1.000000, 0.999999, 0.999994, 0.999984, 0.999969,
+ 0.999940, 0.999898, 0.999837, 0.999746, 0.999617, 0.999438, 0.999016, 0.996703, 0.995302,
+ 0.994356, 0.992993, 0.990390, 0.988072, 0.985152, 0.981447, 0.977273, 0.972234, 0.966113,
+ 0.959033, 0.950869, 0.941217, 0.930175, 0.918279, 0.906941, 0.896201, 0.884509, 0.871920,
+ 0.858420, 0.843906, 0.828730, 0.812524, 0.795978, 0.778979, 0.762450, 0.745459, 0.727966,
+ 0.710046, 0.691808, 0.673739, 0.655756, 0.637574, 0.619153, 0.600887, 0.582796, 0.564748,
+ 0.546636, 0.528904, 0.511252, 0.493791, 0.476563, 0.459695, 0.442942, 0.426632, 0.410558,
+ 0.394895, 0.379517, 0.364560, 1.000000, 1.000000, 1.000000, 0.999998, 0.999994, 0.999984,
+ 0.999966, 0.999934, 0.999887, 0.999819, 0.999720, 0.999578, 0.999367, 0.998696, 0.996353,
+ 0.995201, 0.994115, 0.992665, 0.989948, 0.987633, 0.984331, 0.980827, 0.976390, 0.971327,
+ 0.965201, 0.957977, 0.949712, 0.940128, 0.929187, 0.917237, 0.904645, 0.893711, 0.882112,
+ 0.869516, 0.856236, 0.841929, 0.826924, 0.810991, 0.794686, 0.777761, 0.760980, 0.744384,
+ 0.727314, 0.709877, 0.691988, 0.674098, 0.656243, 0.638603, 0.620606, 0.602574, 0.584694,
+ 0.567018, 0.549311, 0.531673, 0.514403, 0.497148, 0.480177, 0.463439, 0.446998, 0.430743,
+ 0.414943, 0.399304, 0.384121, 0.369251, 1.000000, 1.000000, 1.000000, 0.999997, 0.999992,
+ 0.999981, 0.999962, 0.999927, 0.999874, 0.999798, 0.999691, 0.999533, 0.999291, 0.997909,
+ 0.996117, 0.995029, 0.993880, 0.992142, 0.989576, 0.987185, 0.983587, 0.980055, 0.975487,
+ 0.970172, 0.963998, 0.956738, 0.948637, 0.939083, 0.928169, 0.916144, 0.903147, 0.890916,
+ 0.879389, 0.866895, 0.853826, 0.839729, 0.824957, 0.809472, 0.793341, 0.776743, 0.759808,
+ 0.743277, 0.726643, 0.709685, 0.692249, 0.674639, 0.657008, 0.639576, 0.622114, 0.604471,
+ 0.586851, 0.569340, 0.552135, 0.534806, 0.517599, 0.500765, 0.484035, 0.467440, 0.451212,
+ 0.435240, 0.419399, 0.404083, 0.388944, 0.374182, 1.000000, 1.000000, 1.000000, 0.999998,
+ 0.999993, 0.999979, 0.999958, 0.999919, 0.999861, 0.999774, 0.999656, 0.999482, 0.999195,
+ 0.997307, 0.995837, 0.994722, 0.993707, 0.991391, 0.989169, 0.986461, 0.982904, 0.979062,
+ 0.974536, 0.969035, 0.962653, 0.955486, 0.947243, 0.937747, 0.926861, 0.914936, 0.901835,
+ 0.888472, 0.876571, 0.864223, 0.851252, 0.837374, 0.822985, 0.807788, 0.791927, 0.775702,
+ 0.758928, 0.742347, 0.725914, 0.709495, 0.692569, 0.675363, 0.658085, 0.640639, 0.623698,
+ 0.606505, 0.589267, 0.572008, 0.554939, 0.538132, 0.521211, 0.504487, 0.488048, 0.471807,
+ 0.455651, 0.439858, 0.424332, 0.408983, 0.394071, 0.379402, 1.000000, 1.000000, 1.000000,
+ 0.999997, 0.999992, 0.999978, 0.999954, 0.999913, 0.999844, 0.999753, 0.999618, 0.999424,
+ 0.999067, 0.996875, 0.995659, 0.994603, 0.993420, 0.990874, 0.988713, 0.985585, 0.982193,
+ 0.978145, 0.973416, 0.967801, 0.961483, 0.954069, 0.945704, 0.936138, 0.925374, 0.913395,
+ 0.900339, 0.886675, 0.873512, 0.861326, 0.848513, 0.834956, 0.820820, 0.805943, 0.790574,
+ 0.774677, 0.758279, 0.741807, 0.725271, 0.709231, 0.692874, 0.676189, 0.659352, 0.642296,
+ 0.625250, 0.608700, 0.591823, 0.575012, 0.558143, 0.541491, 0.525075, 0.508558, 0.492277,
+ 0.476270, 0.460459, 0.444740, 0.429400, 0.414309, 0.399421, 0.384907, 1.000000, 1.000000,
+ 1.000000, 0.999997, 0.999990, 0.999977, 0.999947, 0.999902, 0.999832, 0.999730, 0.999577,
+ 0.999359, 0.998845, 0.996554, 0.995328, 0.994442, 0.992919, 0.990393, 0.988170, 0.984855,
+ 0.981312, 0.977149, 0.972137, 0.966207, 0.959967, 0.952454, 0.943873, 0.934434, 0.923813,
+ 0.911942, 0.898928, 0.885120, 0.871043, 0.858248, 0.845666, 0.832346, 0.818482, 0.804029,
+ 0.788982, 0.773571, 0.757700, 0.741484, 0.725186, 0.708915, 0.693244, 0.677028, 0.660656,
+ 0.644079, 0.627377, 0.610804, 0.594542, 0.578112, 0.561650, 0.545163, 0.528962, 0.512926,
+ 0.496893, 0.481007, 0.465397, 0.450042, 0.434740, 0.419831, 0.405156, 0.390692, 1.000000,
+ 1.000000, 0.999999, 0.999997, 0.999989, 0.999973, 0.999942, 0.999891, 0.999813, 0.999698,
+ 0.999532, 0.999285, 0.998286, 0.996295, 0.995215, 0.994182, 0.992032, 0.989855, 0.987415,
+ 0.984047, 0.980050, 0.976017, 0.970845, 0.964767, 0.958269, 0.950600, 0.942033, 0.932501,
+ 0.921807, 0.910017, 0.897149, 0.883414, 0.869182, 0.855055, 0.842687, 0.829548, 0.816162,
+ 0.802072, 0.787436, 0.772533, 0.757043, 0.741263, 0.725330, 0.709262, 0.693497, 0.678038,
+ 0.662128, 0.646068, 0.629824, 0.613437, 0.597334, 0.581401, 0.565372, 0.549288, 0.533182,
+ 0.517405, 0.501765, 0.486143, 0.470675, 0.455465, 0.440532, 0.425630, 0.411113, 0.396887,
+ 1.000000, 1.000000, 0.999999, 0.999996, 0.999989, 0.999970, 0.999934, 0.999879, 0.999793,
+ 0.999665, 0.999481, 0.999192, 0.997506, 0.995926, 0.995009, 0.993736, 0.991298, 0.989326,
+ 0.986371, 0.983199, 0.979032, 0.974596, 0.969364, 0.963198, 0.956385, 0.948509, 0.939993,
+ 0.930421, 0.919590, 0.908140, 0.895349, 0.881699, 0.867456, 0.852784, 0.839500, 0.826629,
+ 0.813602, 0.799983, 0.785873, 0.771340, 0.756480, 0.741190, 0.725687, 0.709997, 0.694192,
+ 0.678975, 0.663673, 0.648135, 0.632442, 0.616477, 0.600565, 0.584772, 0.569202, 0.553595,
+ 0.537881, 0.522193, 0.506784, 0.491554, 0.476349, 0.461278, 0.446419, 0.431913, 0.417443,
+ 0.403271, 1.000000, 1.000000, 0.999999, 0.999995, 0.999986, 0.999966, 0.999927, 0.999867,
+ 0.999772, 0.999629, 0.999423, 0.999075, 0.997024, 0.995773, 0.994651, 0.993353, 0.990822,
+ 0.988569, 0.985596, 0.982182, 0.977871, 0.973140, 0.967584, 0.961408, 0.954294, 0.946398,
+ 0.937603, 0.927937, 0.917305, 0.905833, 0.893138, 0.879770, 0.865720, 0.851023, 0.836801,
+ 0.823784, 0.810909, 0.797886, 0.784177, 0.770243, 0.755925, 0.741144, 0.726214, 0.710971,
+ 0.695563, 0.680212, 0.665304, 0.650297, 0.635168, 0.619796, 0.604217, 0.588692, 0.573254,
+ 0.557998, 0.542839, 0.527470, 0.512162, 0.497115, 0.482296, 0.467477, 0.452812, 0.438310,
+ 0.424184, 0.410163, 1.000000, 1.000000, 0.999999, 0.999996, 0.999984, 0.999962, 0.999920,
+ 0.999852, 0.999745, 0.999586, 0.999354, 0.998894, 0.996686, 0.995485, 0.994493, 0.992573,
+ 0.990323, 0.987772, 0.984692, 0.980887, 0.976446, 0.971625, 0.965717, 0.959421, 0.951975,
+ 0.944086, 0.935066, 0.925403, 0.914814, 0.903208, 0.890958, 0.877817, 0.863828, 0.849289,
+ 0.834872, 0.820889, 0.808183, 0.795660, 0.782556, 0.769066, 0.755386, 0.741229, 0.726726,
+ 0.712170, 0.697209, 0.682170, 0.667203, 0.652689, 0.637938, 0.623262, 0.608190, 0.593002,
+ 0.577817, 0.562737, 0.547836, 0.533036, 0.518052, 0.503135, 0.488422, 0.473986, 0.459552,
+ 0.445282, 0.431149, 0.417407, 1.000000, 1.000000, 0.999999, 0.999994, 0.999983, 0.999957,
+ 0.999914, 0.999835, 0.999718, 0.999538, 0.999275, 0.998454, 0.996341, 0.995246, 0.994222,
+ 0.991844, 0.989829, 0.986688, 0.983562, 0.979638, 0.974932, 0.969827, 0.963621, 0.957146,
+ 0.949365, 0.941398, 0.932245, 0.922556, 0.911949, 0.900627, 0.888440, 0.875544, 0.862005,
+ 0.847810, 0.833372, 0.819134, 0.805508, 0.793339, 0.780916, 0.767837, 0.754858, 0.741307,
+ 0.727496, 0.713386, 0.699131, 0.684542, 0.669878, 0.655261, 0.641035, 0.626685, 0.612377,
+ 0.597625, 0.582805, 0.568030, 0.553204, 0.538684, 0.524269, 0.509662, 0.495119, 0.480735,
+ 0.466634, 0.452593, 0.438748, 0.424915, 1.000000, 1.000000, 0.999998, 0.999994, 0.999982,
+ 0.999956, 0.999901, 0.999818, 0.999683, 0.999487, 0.999185, 0.997584, 0.996004, 0.995050,
+ 0.993715, 0.991212, 0.989057, 0.985879, 0.982243, 0.978206, 0.973119, 0.967919, 0.961343,
+ 0.954603, 0.946712, 0.938378, 0.929266, 0.919443, 0.908911, 0.897725, 0.885589, 0.873254,
+ 0.859889, 0.846123, 0.832094, 0.817898, 0.803866, 0.791061, 0.779235, 0.766885, 0.754292,
+ 0.741565, 0.728331, 0.714861, 0.701179, 0.687166, 0.673012, 0.658716, 0.644442, 0.630472,
+ 0.616519, 0.602514, 0.588172, 0.573689, 0.559281, 0.544768, 0.530543, 0.516485, 0.502303,
+ 0.488100, 0.474095, 0.460245, 0.446598, 0.433169, 1.000000, 1.000000, 0.999997, 0.999993,
+ 0.999980, 0.999947, 0.999891, 0.999794, 0.999647, 0.999425, 0.999062, 0.997049, 0.995778,
+ 0.994652, 0.992778, 0.990482, 0.988004, 0.984893, 0.980881, 0.976605, 0.971199, 0.965610,
+ 0.958925, 0.951746, 0.943791, 0.935200, 0.926018, 0.916028, 0.905724, 0.894528, 0.882914,
+ 0.870740, 0.857802, 0.844552, 0.830857, 0.816921, 0.803102, 0.789625, 0.777480, 0.765891,
+ 0.753908, 0.741795, 0.729390, 0.716440, 0.703411, 0.690068, 0.676438, 0.662586, 0.648697,
+ 0.634732, 0.620997, 0.607451, 0.593765, 0.579748, 0.565661, 0.551594, 0.537396, 0.523433,
+ 0.509708, 0.495972, 0.482082, 0.468427, 0.454890, 0.441623, 1.000000, 1.000000, 0.999999,
+ 0.999991, 0.999977, 0.999940, 0.999875, 0.999769, 0.999605, 0.999352, 0.998882, 0.996665,
+ 0.995459, 0.994380, 0.992014, 0.989912, 0.986796, 0.983537, 0.979326, 0.974792, 0.969140,
+ 0.963160, 0.956222, 0.948807, 0.940518, 0.931755, 0.922452, 0.912319, 0.902227, 0.891142,
+ 0.879838, 0.868047, 0.855745, 0.842718, 0.829827, 0.816398, 0.802786, 0.789396, 0.776581,
+ 0.764901, 0.753710, 0.742102, 0.730448, 0.718337, 0.705768, 0.693172, 0.680153, 0.666882,
+ 0.653401, 0.639837, 0.626152, 0.612676, 0.599435, 0.586109, 0.572473, 0.558715, 0.544964,
+ 0.531112, 0.517416, 0.503992, 0.490653, 0.477162, 0.463832, 0.450645, 1.000000, 1.000000,
+ 0.999999, 0.999992, 0.999973, 0.999933, 0.999861, 0.999741, 0.999554, 0.999267, 0.998411,
+ 0.996303, 0.995191, 0.993945, 0.991406, 0.989019, 0.985720, 0.982057, 0.977501, 0.972605,
+ 0.966697, 0.960340, 0.953031, 0.945347, 0.936866, 0.927917, 0.918562, 0.908598, 0.898486,
+ 0.887794, 0.876545, 0.865379, 0.853428, 0.841167, 0.828649, 0.815967, 0.802957, 0.789865,
+ 0.777077, 0.764695, 0.753544, 0.742694, 0.731571, 0.720304, 0.708490, 0.696351, 0.684134,
+ 0.671470, 0.658541, 0.645376, 0.632209, 0.618776, 0.605511, 0.592527, 0.579546, 0.566310,
+ 0.552860, 0.539492, 0.526005, 0.512564, 0.499340, 0.486360, 0.473357, 0.460306, 1.000000,
+ 1.000000, 0.999998, 0.999991, 0.999970, 0.999926, 0.999842, 0.999710, 0.999498, 0.999164,
+ 0.997464, 0.995870, 0.994917, 0.992911, 0.990682, 0.987816, 0.984410, 0.980551, 0.975693,
+ 0.970263, 0.963946, 0.957248, 0.949765, 0.941571, 0.932941, 0.923873, 0.914332, 0.904560,
+ 0.894394, 0.884127, 0.873294, 0.862503, 0.851335, 0.839566, 0.827776, 0.815708, 0.803370,
+ 0.790821, 0.778386, 0.766121, 0.754193, 0.743420, 0.732975, 0.722326, 0.711376, 0.699992,
+ 0.688180, 0.676354, 0.664004, 0.651449, 0.638600, 0.625776, 0.612660, 0.599603, 0.586719,
+ 0.574078, 0.561273, 0.548129, 0.535155, 0.522015, 0.508851, 0.495837, 0.483190, 0.470624,
+ 1.000000, 1.000000, 0.999998, 0.999988, 0.999965, 0.999916, 0.999823, 0.999669, 0.999425,
+ 0.999025, 0.996874, 0.995670, 0.994415, 0.991991, 0.989766, 0.986646, 0.982812, 0.978356,
+ 0.973317, 0.967612, 0.960820, 0.953603, 0.945969, 0.937323, 0.928661, 0.919507, 0.909833,
+ 0.900245, 0.890390, 0.880252, 0.870000, 0.859518, 0.849163, 0.838101, 0.826960, 0.815688,
+ 0.804126, 0.792234, 0.780356, 0.768474, 0.756678, 0.745159, 0.734601, 0.724624, 0.714339,
+ 0.703751, 0.692766, 0.681267, 0.669799, 0.657871, 0.645577, 0.633102, 0.620560, 0.607737,
+ 0.594890, 0.582143, 0.569779, 0.557360, 0.544651, 0.531942, 0.519228, 0.506467, 0.493710,
+ 0.481143, 1.000000, 1.000000, 0.999998, 0.999988, 0.999961, 0.999902, 0.999798, 0.999622,
+ 0.999341, 0.998801, 0.996397, 0.995225, 0.993927, 0.991338, 0.988500, 0.985327, 0.981195,
+ 0.976383, 0.970726, 0.964471, 0.957386, 0.949813, 0.941694, 0.932681, 0.923974, 0.914755,
+ 0.905026, 0.895649, 0.886178, 0.876277, 0.866629, 0.856890, 0.846934, 0.836887, 0.826373,
+ 0.815885, 0.805169, 0.794133, 0.782812, 0.771547, 0.760175, 0.748896, 0.737687, 0.727152,
+ 0.717601, 0.707670, 0.697425, 0.686788, 0.675664, 0.664513, 0.652962, 0.640965, 0.628851,
+ 0.616551, 0.604168, 0.591559, 0.579009, 0.566648, 0.554597, 0.542382, 0.529999, 0.517655,
+ 0.505254, 0.492894, 1.000000, 1.000000, 0.999997, 0.999986, 0.999956, 0.999889, 0.999766,
+ 0.999562, 0.999240, 0.997952, 0.996094, 0.994979, 0.992773, 0.990536, 0.987214, 0.983322,
+ 0.978938, 0.973714, 0.967681, 0.960981, 0.953144, 0.945475, 0.936909, 0.927734, 0.918826,
+ 0.909590, 0.900085, 0.890867, 0.881801, 0.872565, 0.863236, 0.854239, 0.845060, 0.835686,
+ 0.826251, 0.816284, 0.806586, 0.796419, 0.785914, 0.775210, 0.764461, 0.753599, 0.742805,
+ 0.731872, 0.721370, 0.711898, 0.702337, 0.692383, 0.682137, 0.671365, 0.660479, 0.649314,
+ 0.637685, 0.625899, 0.613898, 0.601865, 0.589582, 0.577285, 0.565013, 0.553106, 0.541280,
+ 0.529367, 0.517320, 0.505411, 1.000000, 1.000000, 0.999997, 0.999983, 0.999948, 0.999869,
+ 0.999732, 0.999499, 0.999111, 0.997167, 0.995720, 0.994349, 0.991727, 0.989197, 0.985883,
+ 0.981483, 0.976618, 0.970597, 0.964122, 0.956994, 0.948639, 0.940500, 0.931606, 0.922385,
+ 0.913291, 0.904205, 0.894938, 0.885890, 0.877334, 0.868754, 0.860053, 0.851683, 0.843447,
+ 0.834889, 0.826304, 0.817441, 0.808285, 0.799141, 0.789570, 0.779600, 0.769510, 0.759155,
+ 0.748882, 0.738346, 0.727629, 0.717273, 0.707467, 0.698283, 0.688609, 0.678748, 0.668371,
+ 0.657739, 0.646951, 0.635765, 0.624254, 0.612647, 0.600900, 0.589061, 0.576998, 0.564991,
+ 0.553102, 0.541517, 0.530027, 0.518495, 1.000000, 1.000000, 0.999997, 0.999983, 0.999939,
+ 0.999851, 0.999684, 0.999412, 0.998925, 0.996597, 0.995207, 0.993603, 0.990903, 0.987594,
+ 0.983814, 0.979016, 0.973647, 0.967048, 0.960109, 0.952123, 0.943560, 0.934900, 0.925747,
+ 0.916566, 0.907305, 0.898441, 0.889629, 0.881042, 0.872874, 0.865064, 0.857225, 0.849446,
+ 0.842063, 0.834561, 0.826814, 0.818875, 0.810748, 0.802316, 0.793699, 0.784704, 0.775198,
+ 0.765643, 0.755735, 0.745873, 0.735526, 0.725229, 0.714892, 0.704807, 0.695502, 0.686241,
+ 0.676633, 0.666688, 0.656384, 0.645871, 0.635174, 0.624113, 0.612788, 0.601426, 0.589925,
+ 0.578399, 0.566612, 0.554931, 0.543383, 0.532065, 1.000000, 1.000000, 0.999996, 0.999977,
+ 0.999928, 0.999824, 0.999633, 0.999306, 0.998429, 0.996133, 0.994890, 0.992316, 0.989752,
+ 0.986095, 0.981564, 0.976234, 0.970081, 0.962779, 0.955232, 0.946702, 0.937716, 0.928604,
+ 0.919281, 0.910167, 0.901046, 0.892446, 0.884183, 0.876253, 0.868619, 0.861545, 0.854673,
+ 0.847885, 0.841074, 0.834610, 0.827984, 0.820945, 0.813648, 0.806232, 0.798444, 0.790232,
+ 0.781853, 0.772897, 0.763648, 0.754227, 0.744542, 0.734689, 0.724526, 0.714204, 0.704152,
+ 0.694222, 0.685143, 0.675860, 0.666319, 0.656415, 0.646273, 0.635902, 0.625399, 0.614563,
+ 0.603490, 0.592413, 0.581217, 0.570000, 0.558608, 0.547242, 1.000000, 0.999999, 0.999995,
+ 0.999972, 0.999915, 0.999790, 0.999562, 0.999168, 0.997237, 0.995672, 0.994074, 0.991220,
+ 0.987792, 0.983822, 0.978599, 0.972804, 0.965718, 0.958053, 0.949460, 0.940503, 0.931011,
+ 0.921608, 0.912409, 0.903378, 0.894606, 0.886369, 0.878756, 0.871573, 0.864862, 0.858421,
+ 0.852541, 0.846802, 0.841027, 0.835206, 0.829628, 0.823730, 0.817415, 0.810655, 0.803873,
+ 0.796659, 0.788887, 0.780940, 0.772537, 0.763507, 0.754487, 0.745163, 0.735572, 0.725687,
+ 0.715611, 0.705398, 0.695418, 0.685592, 0.676518, 0.667304, 0.657875, 0.648182, 0.638235,
+ 0.628062, 0.617813, 0.607283, 0.596552, 0.585770, 0.575033, 0.564153, 1.000000, 1.000000,
+ 0.999995, 0.999970, 0.999898, 0.999748, 0.999472, 0.998969, 0.996528, 0.995102, 0.992701,
+ 0.989963, 0.985981, 0.981194, 0.975183, 0.968501, 0.960502, 0.952012, 0.942861, 0.933376,
+ 0.923506, 0.914042, 0.904921, 0.896282, 0.887987, 0.880341, 0.873536, 0.867293, 0.861556,
+ 0.856148, 0.850987, 0.846352, 0.841684, 0.836880, 0.832036, 0.827091, 0.821900, 0.816206,
+ 0.810042, 0.803629, 0.796918, 0.789653, 0.781915, 0.774014, 0.765530, 0.756526, 0.747669,
+ 0.738342, 0.728770, 0.718942, 0.708942, 0.698855, 0.688933, 0.679131, 0.669855, 0.660811,
+ 0.651549, 0.642127, 0.632454, 0.622651, 0.612709, 0.602606, 0.592344, 0.581877, 1.000000,
+ 0.999999, 0.999993, 0.999963, 0.999874, 0.999691, 0.999350, 0.998431, 0.995873, 0.994456,
+ 0.991327, 0.987798, 0.983232, 0.977500, 0.970828, 0.962815, 0.954228, 0.944752, 0.935126,
+ 0.925179, 0.915102, 0.905763, 0.897087, 0.888933, 0.881452, 0.874687, 0.868716, 0.863585,
+ 0.858931, 0.854662, 0.850569, 0.846719, 0.843151, 0.839426, 0.835588, 0.831443, 0.827004,
+ 0.822395, 0.817254, 0.811630, 0.805464, 0.799124, 0.792382, 0.785091, 0.777315, 0.769360,
+ 0.760908, 0.751957, 0.743128, 0.733917, 0.724340, 0.714713, 0.704721, 0.694835, 0.684862,
+ 0.675099, 0.665570, 0.656644, 0.647651, 0.638581, 0.629337, 0.619926, 0.610358, 0.600707,
+ 1.000000, 1.000000, 0.999990, 0.999953, 0.999843, 0.999613, 0.999186, 0.997025, 0.995317,
+ 0.992850, 0.989760, 0.985270, 0.979807, 0.973049, 0.965228, 0.956248, 0.946394, 0.936324,
+ 0.926124, 0.915808, 0.905942, 0.897060, 0.889001, 0.881755, 0.875351, 0.869688, 0.864736,
+ 0.860745, 0.857305, 0.854190, 0.851261, 0.848484, 0.845642, 0.842948, 0.840060, 0.836901,
+ 0.833379, 0.829393, 0.825103, 0.820431, 0.815288, 0.809575, 0.803326, 0.796949, 0.790174,
+ 0.782873, 0.775048, 0.767139, 0.758772, 0.750019, 0.741120, 0.732127, 0.722743, 0.713225,
+ 0.703637, 0.693768, 0.684016, 0.674277, 0.664703, 0.655328, 0.646550, 0.637812, 0.629036,
+ 0.620129, 1.000000, 1.000000, 0.999988, 0.999933, 0.999800, 0.999508, 0.998917, 0.996236,
+ 0.994617, 0.991176, 0.987089, 0.981880, 0.974966, 0.967156, 0.957914, 0.947585, 0.936937,
+ 0.926318, 0.915662, 0.905567, 0.896223, 0.888166, 0.881117, 0.875079, 0.869981, 0.865675,
+ 0.862091, 0.859183, 0.856981, 0.855065, 0.853273, 0.851572, 0.849782, 0.847768, 0.845668,
+ 0.843345, 0.840703, 0.837646, 0.834094, 0.830030, 0.825631, 0.820873, 0.815619, 0.809856,
+ 0.803578, 0.797096, 0.790359, 0.783152, 0.775507, 0.767504, 0.759411, 0.750982, 0.742208,
+ 0.733383, 0.724445, 0.715190, 0.705827, 0.696440, 0.686773, 0.677242, 0.667735, 0.658471,
+ 0.649236, 0.640305, 1.000000, 0.999999, 0.999984, 0.999918, 0.999737, 0.999350, 0.997576,
+ 0.995476, 0.992614, 0.988817, 0.983601, 0.976880, 0.968694, 0.959092, 0.948297, 0.936831,
+ 0.925592, 0.914494, 0.904159, 0.894643, 0.886417, 0.879620, 0.874023, 0.869533, 0.865967,
+ 0.863238, 0.861113, 0.859527, 0.858367, 0.857594, 0.856882, 0.856172, 0.855316, 0.854197,
+ 0.852818, 0.851062, 0.849046, 0.846747, 0.844043, 0.840842, 0.837164, 0.832985, 0.828344,
+ 0.823544, 0.818276, 0.812543, 0.806374, 0.799838, 0.793170, 0.786246, 0.778956, 0.771297,
+ 0.763278, 0.755252, 0.746984, 0.738445, 0.729688, 0.721045, 0.712189, 0.703099, 0.694045,
+ 0.684930, 0.675601, 0.666480, 1.000000, 0.999999, 0.999978, 0.999888, 0.999639, 0.999093,
+ 0.996310, 0.994405, 0.990527, 0.985186, 0.978518, 0.969748, 0.959597, 0.948104, 0.935724,
+ 0.923704, 0.912023, 0.901356, 0.891850, 0.883847, 0.877280, 0.872289, 0.868583, 0.865913,
+ 0.864098, 0.862993, 0.862356, 0.862125, 0.862107, 0.862168, 0.862359, 0.862490, 0.862430,
+ 0.862063, 0.861431, 0.860386, 0.858950, 0.857090, 0.854848, 0.852381, 0.849503, 0.846167,
+ 0.842399, 0.838194, 0.833566, 0.828579, 0.823464, 0.817951, 0.812079, 0.805873, 0.799320,
+ 0.792533, 0.785715, 0.778636, 0.771260, 0.763618, 0.755719, 0.747815, 0.739825, 0.731602,
+ 0.723212, 0.714845, 0.706465, 0.697933, 1.000000, 0.999998, 0.999969, 0.999836, 0.999475,
+ 0.997943, 0.995219, 0.991760, 0.986663, 0.979592, 0.970218, 0.959155, 0.946575, 0.933047,
+ 0.920022, 0.907749, 0.896801, 0.887506, 0.880077, 0.874322, 0.870126, 0.867481, 0.865949,
+ 0.865293, 0.865287, 0.865746, 0.866502, 0.867439, 0.868442, 0.869382, 0.870161, 0.870782,
+ 0.871303, 0.871511, 0.871427, 0.870978, 0.870136, 0.868892, 0.867248, 0.865209, 0.862775,
+ 0.859944, 0.857004, 0.853671, 0.849984, 0.845927, 0.841518, 0.836774, 0.831750, 0.826407,
+ 0.821001, 0.815333, 0.809412, 0.803238, 0.796802, 0.790204, 0.783457, 0.776713, 0.769749,
+ 0.762596, 0.755239, 0.747690, 0.740127, 0.732595, 1.000000, 0.999997, 0.999950, 0.999744,
+ 0.999162, 0.996124, 0.992844, 0.987757, 0.980062, 0.969642, 0.957087, 0.942735, 0.927747,
+ 0.913622, 0.900889, 0.890115, 0.881584, 0.875288, 0.870926, 0.868307, 0.867033, 0.866972,
+ 0.867692, 0.868950, 0.870549, 0.872320, 0.874144, 0.875947, 0.877674, 0.879192, 0.880478,
+ 0.881539, 0.882307, 0.882739, 0.882902, 0.882847, 0.882461, 0.881725, 0.880636, 0.879197,
+ 0.877422, 0.875296, 0.872849, 0.870076, 0.866988, 0.863637, 0.860159, 0.856475, 0.852525,
+ 0.848328, 0.843883, 0.839198, 0.834322, 0.829221, 0.823907, 0.818461, 0.812972, 0.807316,
+ 0.801474, 0.795459, 0.789276, 0.783025, 0.776615, 0.770223, 0.999999, 0.999994, 0.999909,
+ 0.999536, 0.997195, 0.994123, 0.988168, 0.979344, 0.967003, 0.951763, 0.934724, 0.917948,
+ 0.902918, 0.890432, 0.880902, 0.874401, 0.870394, 0.868503, 0.868209, 0.869062, 0.870725,
+ 0.873006, 0.875558, 0.878230, 0.880893, 0.883445, 0.885832, 0.888059, 0.890058, 0.891782,
+ 0.893247, 0.894460, 0.895397, 0.896023, 0.896380, 0.896433, 0.896198, 0.895673, 0.894865,
+ 0.893908, 0.892700, 0.891224, 0.889501, 0.887539, 0.885336, 0.882903, 0.880244, 0.877373,
+ 0.874296, 0.871019, 0.867549, 0.863933, 0.860153, 0.856355, 0.852395, 0.848277, 0.844006,
+ 0.839587, 0.835045, 0.830378, 0.825579, 0.820649, 0.815592, 0.810432, 0.999998, 0.999988,
+ 0.999795, 0.998892, 0.994635, 0.987290, 0.975397, 0.958508, 0.938352, 0.917733, 0.899800,
+ 0.885878, 0.876516, 0.871200, 0.869099, 0.869317, 0.871112, 0.873870, 0.877160, 0.880682,
+ 0.884228, 0.887737, 0.891076, 0.894161, 0.896981, 0.899543, 0.901847, 0.903882, 0.905672,
+ 0.907188, 0.908451, 0.909480, 0.910289, 0.910878, 0.911259, 0.911430, 0.911396, 0.911154,
+ 0.910712, 0.910081, 0.909266, 0.908264, 0.907094, 0.905752, 0.904244, 0.902577, 0.900799,
+ 0.898931, 0.896923, 0.894782, 0.892513, 0.890117, 0.887600, 0.884968, 0.882222, 0.879369,
+ 0.876408, 0.873345, 0.870183, 0.866926, 0.863575, 0.860160, 0.856672, 0.853098, 0.999991,
+ 0.999947, 0.999158, 0.992842, 0.980107, 0.957230, 0.928231, 0.901539, 0.882688, 0.872588,
+ 0.869394, 0.870671, 0.874458, 0.879378, 0.884639, 0.889770, 0.894601, 0.898972, 0.902930,
+ 0.906456, 0.909568, 0.912329, 0.914750, 0.916893, 0.918774, 0.920429, 0.921868, 0.923110,
+ 0.924185, 0.925089, 0.925842, 0.926457, 0.926934, 0.927285, 0.927522, 0.927639, 0.927650,
+ 0.927553, 0.927356, 0.927061, 0.926671, 0.926187, 0.925617, 0.924962, 0.924224, 0.923409,
+ 0.922519, 0.921555, 0.920521, 0.919419, 0.918252, 0.917021, 0.915729, 0.914377, 0.912967,
+ 0.911503, 0.909984, 0.908414, 0.906791, 0.905122, 0.903401, 0.901637, 0.899826, 0.897972,
+ 0.987461, 0.940121, 0.871507, 0.898572, 0.916705, 0.926425, 0.931922, 0.935265, 0.937431,
+ 0.938899, 0.939950, 0.940717, 0.941301, 0.941754, 0.942111, 0.942397, 0.942631, 0.942823,
+ 0.942983, 0.943117, 0.943231, 0.943329, 0.943412, 0.943484, 0.943545, 0.943599, 0.943644,
+ 0.943682, 0.943716, 0.943744, 0.943766, 0.943785, 0.943799, 0.943808, 0.943815, 0.943818,
+ 0.943818, 0.943814, 0.943807, 0.943797, 0.943784, 0.943769, 0.943751, 0.943730, 0.943707,
+ 0.943681, 0.943652, 0.943623, 0.943589, 0.943554, 0.943518, 0.943479, 0.943438, 0.943396,
+ 0.943351, 0.943305, 0.943257, 0.943207, 0.943156, 0.943104, 0.943049, 0.942993, 0.942936,
+ 0.942877,
+};
+
+static float bsdf_split_sum_ggx[64 * 64 * 2] = {
+ 1.000000f, 0.000000f, 1.000000f, 0.000000f, 1.000000f, 0.000000f, 1.000000f, 0.000000f,
+ 1.000000f, 0.000000f, 1.000000f, 0.000000f, 0.999512f, 0.000000f, 0.999512f, 0.000000f,
+ 0.999512f, 0.000000f, 0.999023f, 0.000001f, 0.999023f, 0.000001f, 0.998535f, 0.000001f,
+ 0.998047f, 0.000001f, 0.997559f, 0.000002f, 0.997070f, 0.000003f, 0.996094f, 0.000004f,
+ 0.994629f, 0.000004f, 0.993652f, 0.000006f, 0.991699f, 0.000007f, 0.989746f, 0.000008f,
+ 0.987305f, 0.000010f, 0.984375f, 0.000012f, 0.980957f, 0.000013f, 0.977539f, 0.000016f,
+ 0.973145f, 0.000018f, 0.967773f, 0.000020f, 0.961914f, 0.000023f, 0.955566f, 0.000025f,
+ 0.947754f, 0.000028f, 0.939941f, 0.000031f, 0.930664f, 0.000033f, 0.920410f, 0.000036f,
+ 0.909180f, 0.000039f, 0.896973f, 0.000042f, 0.884277f, 0.000044f, 0.870117f, 0.000047f,
+ 0.854980f, 0.000049f, 0.838867f, 0.000051f, 0.821777f, 0.000053f, 0.803711f, 0.000055f,
+ 0.785156f, 0.000057f, 0.765625f, 0.000058f, 0.745605f, 0.000059f, 0.724609f, 0.000060f,
+ 0.703613f, 0.000061f, 0.681641f, 0.000061f, 0.659668f, 0.000061f, 0.637695f, 0.000061f,
+ 0.615234f, 0.000061f, 0.592773f, 0.000060f, 0.570801f, 0.000060f, 0.548340f, 0.000059f,
+ 0.526855f, 0.000058f, 0.504883f, 0.000057f, 0.483887f, 0.000055f, 0.462891f, 0.000054f,
+ 0.442627f, 0.000053f, 0.422607f, 0.000051f, 0.403320f, 0.000050f, 0.384766f, 0.000048f,
+ 0.366455f, 0.000046f, 0.348877f, 0.000045f, 0.332031f, 0.000043f, 0.315918f, 0.000041f,
+ 0.999512f, 0.000000f, 0.999512f, 0.000000f, 1.000000f, 0.000000f, 1.000000f, 0.000000f,
+ 0.999512f, 0.000000f, 1.000000f, 0.000000f, 0.999512f, 0.000000f, 0.999512f, 0.000000f,
+ 0.999512f, 0.000000f, 0.999023f, 0.000001f, 0.999023f, 0.000001f, 0.998535f, 0.000002f,
+ 0.998047f, 0.000003f, 0.997559f, 0.000004f, 0.997070f, 0.000005f, 0.996094f, 0.000006f,
+ 0.994629f, 0.000008f, 0.993164f, 0.000010f, 0.991699f, 0.000012f, 0.989746f, 0.000015f,
+ 0.987305f, 0.000018f, 0.984375f, 0.000020f, 0.980957f, 0.000024f, 0.977051f, 0.000027f,
+ 0.972168f, 0.000031f, 0.967285f, 0.000035f, 0.961426f, 0.000039f, 0.954590f, 0.000043f,
+ 0.947266f, 0.000048f, 0.938965f, 0.000052f, 0.929199f, 0.000057f, 0.919434f, 0.000061f,
+ 0.908203f, 0.000065f, 0.895996f, 0.000069f, 0.882812f, 0.000073f, 0.868652f, 0.000077f,
+ 0.853027f, 0.000080f, 0.837402f, 0.000083f, 0.820312f, 0.000086f, 0.802246f, 0.000088f,
+ 0.783691f, 0.000090f, 0.764160f, 0.000092f, 0.744141f, 0.000093f, 0.723633f, 0.000093f,
+ 0.702637f, 0.000094f, 0.681152f, 0.000094f, 0.659180f, 0.000093f, 0.637207f, 0.000093f,
+ 0.615234f, 0.000091f, 0.593262f, 0.000090f, 0.571289f, 0.000088f, 0.549316f, 0.000087f,
+ 0.527344f, 0.000085f, 0.505859f, 0.000082f, 0.485107f, 0.000080f, 0.464355f, 0.000078f,
+ 0.444336f, 0.000075f, 0.424561f, 0.000072f, 0.405273f, 0.000070f, 0.386719f, 0.000067f,
+ 0.368652f, 0.000065f, 0.351318f, 0.000062f, 0.334473f, 0.000059f, 0.318115f, 0.000057f,
+ 0.999512f, 0.000000f, 0.999512f, 0.000000f, 0.999512f, 0.000000f, 1.000000f, 0.000000f,
+ 0.999512f, 0.000000f, 0.999512f, 0.000000f, 0.999512f, 0.000001f, 0.999512f, 0.000001f,
+ 0.999512f, 0.000001f, 0.999512f, 0.000003f, 0.999023f, 0.000002f, 0.998535f, 0.000004f,
+ 0.998047f, 0.000005f, 0.997559f, 0.000007f, 0.997070f, 0.000009f, 0.996094f, 0.000011f,
+ 0.994629f, 0.000013f, 0.993164f, 0.000017f, 0.991211f, 0.000020f, 0.989258f, 0.000024f,
+ 0.986816f, 0.000028f, 0.983887f, 0.000033f, 0.980469f, 0.000038f, 0.976562f, 0.000043f,
+ 0.971680f, 0.000049f, 0.966797f, 0.000055f, 0.960449f, 0.000062f, 0.953613f, 0.000068f,
+ 0.946289f, 0.000075f, 0.937500f, 0.000081f, 0.928223f, 0.000088f, 0.917969f, 0.000094f,
+ 0.906738f, 0.000100f, 0.894531f, 0.000106f, 0.880859f, 0.000111f, 0.866699f, 0.000116f,
+ 0.851562f, 0.000120f, 0.835449f, 0.000124f, 0.818359f, 0.000127f, 0.800781f, 0.000130f,
+ 0.782227f, 0.000132f, 0.762695f, 0.000134f, 0.742676f, 0.000134f, 0.722656f, 0.000135f,
+ 0.701660f, 0.000134f, 0.680176f, 0.000133f, 0.658691f, 0.000132f, 0.636719f, 0.000130f,
+ 0.615234f, 0.000128f, 0.593262f, 0.000125f, 0.571289f, 0.000123f, 0.549805f, 0.000119f,
+ 0.528320f, 0.000116f, 0.507324f, 0.000112f, 0.486328f, 0.000109f, 0.466064f, 0.000105f,
+ 0.446045f, 0.000101f, 0.426514f, 0.000097f, 0.407471f, 0.000093f, 0.388916f, 0.000089f,
+ 0.370850f, 0.000085f, 0.353516f, 0.000082f, 0.336914f, 0.000078f, 0.320557f, 0.000074f,
+ 1.000000f, 0.000000f, 0.999512f, 0.000000f, 0.999512f, 0.000000f, 0.999512f, 0.000000f,
+ 1.000000f, 0.000000f, 1.000000f, 0.000001f, 0.999512f, 0.000001f, 0.999512f, 0.000002f,
+ 0.999512f, 0.000002f, 0.999023f, 0.000003f, 0.999023f, 0.000005f, 0.998535f, 0.000006f,
+ 0.998535f, 0.000008f, 0.997559f, 0.000011f, 0.997070f, 0.000014f, 0.996094f, 0.000017f,
+ 0.994629f, 0.000020f, 0.993164f, 0.000026f, 0.991211f, 0.000030f, 0.989258f, 0.000036f,
+ 0.986816f, 0.000043f, 0.983398f, 0.000050f, 0.979980f, 0.000058f, 0.976074f, 0.000066f,
+ 0.971191f, 0.000074f, 0.965820f, 0.000082f, 0.959961f, 0.000093f, 0.952637f, 0.000101f,
+ 0.945312f, 0.000111f, 0.936523f, 0.000120f, 0.927246f, 0.000129f, 0.916504f, 0.000137f,
+ 0.905273f, 0.000145f, 0.892578f, 0.000153f, 0.879395f, 0.000160f, 0.865234f, 0.000166f,
+ 0.850098f, 0.000171f, 0.833984f, 0.000176f, 0.816895f, 0.000179f, 0.799316f, 0.000182f,
+ 0.780762f, 0.000184f, 0.761230f, 0.000185f, 0.741699f, 0.000185f, 0.721191f, 0.000184f,
+ 0.700684f, 0.000183f, 0.679688f, 0.000181f, 0.658203f, 0.000178f, 0.636719f, 0.000175f,
+ 0.615234f, 0.000171f, 0.593262f, 0.000167f, 0.571777f, 0.000162f, 0.550293f, 0.000158f,
+ 0.529297f, 0.000152f, 0.508301f, 0.000147f, 0.487793f, 0.000142f, 0.467529f, 0.000136f,
+ 0.447754f, 0.000131f, 0.428223f, 0.000125f, 0.409424f, 0.000120f, 0.391113f, 0.000115f,
+ 0.373291f, 0.000109f, 0.355957f, 0.000104f, 0.339355f, 0.000099f, 0.323242f, 0.000094f,
+ 0.999512f, 0.000002f, 0.999512f, 0.000002f, 1.000000f, 0.000002f, 0.999512f, 0.000002f,
+ 1.000000f, 0.000002f, 0.999512f, 0.000002f, 0.999512f, 0.000002f, 0.999512f, 0.000003f,
+ 0.999512f, 0.000004f, 0.999512f, 0.000005f, 0.999023f, 0.000007f, 0.998535f, 0.000010f,
+ 0.998047f, 0.000012f, 0.997559f, 0.000017f, 0.996582f, 0.000020f, 0.995605f, 0.000025f,
+ 0.994629f, 0.000032f, 0.993164f, 0.000038f, 0.991211f, 0.000047f, 0.988770f, 0.000055f,
+ 0.986328f, 0.000063f, 0.983398f, 0.000074f, 0.979492f, 0.000085f, 0.975586f, 0.000095f,
+ 0.970703f, 0.000108f, 0.965332f, 0.000121f, 0.958984f, 0.000132f, 0.952148f, 0.000145f,
+ 0.944336f, 0.000157f, 0.935547f, 0.000170f, 0.925781f, 0.000181f, 0.915039f, 0.000192f,
+ 0.903809f, 0.000203f, 0.891113f, 0.000212f, 0.877930f, 0.000220f, 0.863281f, 0.000227f,
+ 0.848145f, 0.000234f, 0.832031f, 0.000239f, 0.814941f, 0.000242f, 0.797363f, 0.000245f,
+ 0.778809f, 0.000247f, 0.759766f, 0.000247f, 0.740234f, 0.000246f, 0.720215f, 0.000244f,
+ 0.699707f, 0.000241f, 0.678711f, 0.000237f, 0.657715f, 0.000233f, 0.636230f, 0.000228f,
+ 0.614746f, 0.000222f, 0.593750f, 0.000216f, 0.572266f, 0.000209f, 0.551270f, 0.000202f,
+ 0.530273f, 0.000195f, 0.509277f, 0.000187f, 0.489014f, 0.000180f, 0.468994f, 0.000172f,
+ 0.449463f, 0.000165f, 0.430176f, 0.000157f, 0.411377f, 0.000150f, 0.393311f, 0.000143f,
+ 0.375488f, 0.000136f, 0.358398f, 0.000129f, 0.341797f, 0.000123f, 0.325684f, 0.000116f,
+ 0.999512f, 0.000005f, 0.999512f, 0.000005f, 0.999512f, 0.000005f, 0.999512f, 0.000005f,
+ 0.999512f, 0.000005f, 0.999512f, 0.000005f, 0.999512f, 0.000006f, 0.999512f, 0.000007f,
+ 0.999512f, 0.000008f, 0.999512f, 0.000011f, 0.999023f, 0.000013f, 0.998535f, 0.000015f,
+ 0.998047f, 0.000019f, 0.997559f, 0.000026f, 0.996582f, 0.000033f, 0.995605f, 0.000040f,
+ 0.994141f, 0.000047f, 0.993164f, 0.000058f, 0.991211f, 0.000069f, 0.988770f, 0.000080f,
+ 0.985840f, 0.000093f, 0.982910f, 0.000106f, 0.979004f, 0.000121f, 0.975098f, 0.000137f,
+ 0.970215f, 0.000153f, 0.964355f, 0.000169f, 0.958008f, 0.000186f, 0.951172f, 0.000201f,
+ 0.943359f, 0.000218f, 0.934082f, 0.000233f, 0.924316f, 0.000248f, 0.914062f, 0.000262f,
+ 0.902344f, 0.000275f, 0.889648f, 0.000286f, 0.875977f, 0.000295f, 0.861816f, 0.000304f,
+ 0.846680f, 0.000311f, 0.830566f, 0.000316f, 0.813477f, 0.000319f, 0.795898f, 0.000321f,
+ 0.777344f, 0.000322f, 0.758301f, 0.000320f, 0.739258f, 0.000318f, 0.719238f, 0.000314f,
+ 0.698730f, 0.000309f, 0.678223f, 0.000303f, 0.657227f, 0.000296f, 0.636230f, 0.000288f,
+ 0.614746f, 0.000280f, 0.593750f, 0.000271f, 0.572754f, 0.000262f, 0.551758f, 0.000252f,
+ 0.531250f, 0.000243f, 0.510742f, 0.000233f, 0.490479f, 0.000223f, 0.470703f, 0.000213f,
+ 0.451172f, 0.000203f, 0.432129f, 0.000194f, 0.413574f, 0.000184f, 0.395508f, 0.000175f,
+ 0.377930f, 0.000166f, 0.360840f, 0.000157f, 0.344238f, 0.000149f, 0.328125f, 0.000141f,
+ 0.999512f, 0.000011f, 0.999512f, 0.000011f, 0.999512f, 0.000011f, 0.999512f, 0.000011f,
+ 0.999512f, 0.000011f, 0.999512f, 0.000012f, 0.999512f, 0.000014f, 0.999512f, 0.000015f,
+ 0.999512f, 0.000017f, 0.999023f, 0.000020f, 0.998535f, 0.000022f, 0.998535f, 0.000028f,
+ 0.998047f, 0.000034f, 0.997559f, 0.000042f, 0.996582f, 0.000050f, 0.995605f, 0.000060f,
+ 0.994141f, 0.000072f, 0.992676f, 0.000084f, 0.990723f, 0.000099f, 0.988281f, 0.000115f,
+ 0.985840f, 0.000133f, 0.982422f, 0.000150f, 0.978516f, 0.000171f, 0.974609f, 0.000191f,
+ 0.969238f, 0.000211f, 0.963867f, 0.000232f, 0.957520f, 0.000253f, 0.950195f, 0.000274f,
+ 0.941895f, 0.000294f, 0.933105f, 0.000314f, 0.922852f, 0.000332f, 0.912109f, 0.000348f,
+ 0.900879f, 0.000363f, 0.888184f, 0.000377f, 0.874512f, 0.000387f, 0.859863f, 0.000397f,
+ 0.844727f, 0.000404f, 0.828613f, 0.000408f, 0.811523f, 0.000411f, 0.793945f, 0.000412f,
+ 0.775879f, 0.000411f, 0.756836f, 0.000407f, 0.737793f, 0.000403f, 0.717773f, 0.000396f,
+ 0.697754f, 0.000389f, 0.677246f, 0.000380f, 0.656738f, 0.000370f, 0.635742f, 0.000359f,
+ 0.614746f, 0.000347f, 0.594238f, 0.000335f, 0.573242f, 0.000323f, 0.552734f, 0.000310f,
+ 0.532227f, 0.000297f, 0.511719f, 0.000284f, 0.491943f, 0.000272f, 0.472412f, 0.000259f,
+ 0.453125f, 0.000246f, 0.434082f, 0.000234f, 0.415771f, 0.000222f, 0.397705f, 0.000211f,
+ 0.380127f, 0.000199f, 0.363281f, 0.000189f, 0.346680f, 0.000178f, 0.330811f, 0.000168f,
+ 0.999512f, 0.000022f, 0.999512f, 0.000022f, 0.999512f, 0.000022f, 0.999512f, 0.000022f,
+ 0.999512f, 0.000023f, 0.999512f, 0.000025f, 0.999512f, 0.000024f, 0.999512f, 0.000028f,
+ 0.999023f, 0.000030f, 0.999023f, 0.000035f, 0.999023f, 0.000040f, 0.998535f, 0.000046f,
+ 0.998047f, 0.000056f, 0.997559f, 0.000063f, 0.996094f, 0.000077f, 0.995605f, 0.000089f,
+ 0.994141f, 0.000106f, 0.992188f, 0.000123f, 0.990234f, 0.000143f, 0.987793f, 0.000163f,
+ 0.985352f, 0.000185f, 0.981934f, 0.000211f, 0.978027f, 0.000236f, 0.973633f, 0.000261f,
+ 0.968750f, 0.000288f, 0.962891f, 0.000314f, 0.956055f, 0.000341f, 0.949219f, 0.000366f,
+ 0.940918f, 0.000391f, 0.931641f, 0.000414f, 0.921875f, 0.000436f, 0.910645f, 0.000455f,
+ 0.898926f, 0.000471f, 0.886230f, 0.000487f, 0.872559f, 0.000499f, 0.858398f, 0.000509f,
+ 0.842773f, 0.000515f, 0.826660f, 0.000518f, 0.810059f, 0.000520f, 0.792480f, 0.000519f,
+ 0.774414f, 0.000515f, 0.755371f, 0.000509f, 0.736328f, 0.000501f, 0.716797f, 0.000492f,
+ 0.696777f, 0.000480f, 0.676758f, 0.000468f, 0.656250f, 0.000454f, 0.635742f, 0.000439f,
+ 0.615234f, 0.000424f, 0.594238f, 0.000408f, 0.573730f, 0.000392f, 0.553223f, 0.000375f,
+ 0.533203f, 0.000359f, 0.513184f, 0.000342f, 0.493408f, 0.000326f, 0.474121f, 0.000310f,
+ 0.455078f, 0.000294f, 0.436279f, 0.000279f, 0.417969f, 0.000264f, 0.400146f, 0.000250f,
+ 0.382812f, 0.000237f, 0.365723f, 0.000223f, 0.349365f, 0.000211f, 0.333496f, 0.000199f,
+ 0.999512f, 0.000041f, 0.999512f, 0.000041f, 0.999512f, 0.000041f, 0.999512f, 0.000042f,
+ 0.999512f, 0.000042f, 0.999512f, 0.000044f, 0.999512f, 0.000046f, 0.999512f, 0.000049f,
+ 0.999512f, 0.000054f, 0.999512f, 0.000059f, 0.999023f, 0.000065f, 0.998535f, 0.000076f,
+ 0.998047f, 0.000087f, 0.997070f, 0.000098f, 0.996582f, 0.000117f, 0.995117f, 0.000135f,
+ 0.993652f, 0.000152f, 0.992188f, 0.000176f, 0.989746f, 0.000201f, 0.987793f, 0.000228f,
+ 0.984863f, 0.000256f, 0.981445f, 0.000286f, 0.977539f, 0.000318f, 0.973145f, 0.000352f,
+ 0.967773f, 0.000384f, 0.961914f, 0.000417f, 0.955566f, 0.000451f, 0.947754f, 0.000481f,
+ 0.939453f, 0.000510f, 0.930176f, 0.000537f, 0.919922f, 0.000563f, 0.909180f, 0.000585f,
+ 0.897461f, 0.000604f, 0.884766f, 0.000620f, 0.871094f, 0.000632f, 0.856445f, 0.000641f,
+ 0.841309f, 0.000647f, 0.825195f, 0.000648f, 0.808105f, 0.000648f, 0.790527f, 0.000643f,
+ 0.772949f, 0.000637f, 0.754395f, 0.000627f, 0.735352f, 0.000615f, 0.715820f, 0.000601f,
+ 0.695801f, 0.000585f, 0.675781f, 0.000568f, 0.655762f, 0.000550f, 0.635742f, 0.000530f,
+ 0.615234f, 0.000510f, 0.594727f, 0.000490f, 0.574707f, 0.000469f, 0.554199f, 0.000448f,
+ 0.534180f, 0.000428f, 0.514648f, 0.000407f, 0.495117f, 0.000387f, 0.475830f, 0.000367f,
+ 0.456787f, 0.000348f, 0.438232f, 0.000329f, 0.420166f, 0.000311f, 0.402344f, 0.000294f,
+ 0.385254f, 0.000277f, 0.368408f, 0.000262f, 0.352051f, 0.000246f, 0.336182f, 0.000232f,
+ 0.999512f, 0.000072f, 0.999512f, 0.000072f, 0.999512f, 0.000072f, 0.999512f, 0.000072f,
+ 0.999512f, 0.000073f, 0.999512f, 0.000076f, 0.999512f, 0.000078f, 0.999512f, 0.000082f,
+ 0.999023f, 0.000086f, 0.999023f, 0.000095f, 0.998535f, 0.000102f, 0.998047f, 0.000116f,
+ 0.998047f, 0.000131f, 0.997070f, 0.000147f, 0.996094f, 0.000167f, 0.995117f, 0.000195f,
+ 0.993652f, 0.000219f, 0.991699f, 0.000246f, 0.989746f, 0.000278f, 0.987305f, 0.000315f,
+ 0.984375f, 0.000350f, 0.980957f, 0.000385f, 0.976562f, 0.000427f, 0.972168f, 0.000467f,
+ 0.967285f, 0.000509f, 0.960938f, 0.000548f, 0.954102f, 0.000587f, 0.946777f, 0.000623f,
+ 0.937988f, 0.000657f, 0.928711f, 0.000690f, 0.918457f, 0.000718f, 0.907715f, 0.000741f,
+ 0.895508f, 0.000762f, 0.882812f, 0.000778f, 0.869141f, 0.000791f, 0.854492f, 0.000798f,
+ 0.839355f, 0.000802f, 0.823242f, 0.000801f, 0.806152f, 0.000796f, 0.789062f, 0.000788f,
+ 0.770996f, 0.000777f, 0.752930f, 0.000762f, 0.733887f, 0.000745f, 0.714844f, 0.000726f,
+ 0.695312f, 0.000704f, 0.675293f, 0.000682f, 0.655273f, 0.000658f, 0.635254f, 0.000633f,
+ 0.615234f, 0.000607f, 0.595215f, 0.000582f, 0.575195f, 0.000556f, 0.555176f, 0.000530f,
+ 0.535645f, 0.000504f, 0.515625f, 0.000479f, 0.496582f, 0.000455f, 0.477539f, 0.000431f,
+ 0.458984f, 0.000407f, 0.440430f, 0.000385f, 0.422363f, 0.000363f, 0.404785f, 0.000343f,
+ 0.387695f, 0.000323f, 0.370850f, 0.000304f, 0.354736f, 0.000286f, 0.338867f, 0.000268f,
+ 0.999512f, 0.000119f, 0.999512f, 0.000119f, 0.999512f, 0.000119f, 0.999512f, 0.000119f,
+ 0.999512f, 0.000121f, 0.999512f, 0.000122f, 0.999512f, 0.000128f, 0.999512f, 0.000131f,
+ 0.999512f, 0.000139f, 0.999023f, 0.000149f, 0.998535f, 0.000161f, 0.998047f, 0.000179f,
+ 0.998047f, 0.000194f, 0.997070f, 0.000220f, 0.996094f, 0.000247f, 0.994629f, 0.000275f,
+ 0.993652f, 0.000309f, 0.991699f, 0.000344f, 0.989746f, 0.000385f, 0.986816f, 0.000429f,
+ 0.983887f, 0.000471f, 0.980469f, 0.000519f, 0.976074f, 0.000565f, 0.971680f, 0.000614f,
+ 0.966309f, 0.000664f, 0.959961f, 0.000710f, 0.953125f, 0.000754f, 0.945312f, 0.000797f,
+ 0.936523f, 0.000837f, 0.927246f, 0.000873f, 0.916992f, 0.000902f, 0.905762f, 0.000929f,
+ 0.893555f, 0.000950f, 0.880859f, 0.000966f, 0.866699f, 0.000977f, 0.852539f, 0.000981f,
+ 0.836914f, 0.000981f, 0.821289f, 0.000977f, 0.804688f, 0.000968f, 0.787109f, 0.000955f,
+ 0.769531f, 0.000937f, 0.751465f, 0.000917f, 0.732422f, 0.000894f, 0.713379f, 0.000868f,
+ 0.694336f, 0.000840f, 0.674805f, 0.000811f, 0.655273f, 0.000780f, 0.635254f, 0.000749f,
+ 0.615723f, 0.000716f, 0.595703f, 0.000685f, 0.575684f, 0.000653f, 0.556152f, 0.000621f,
+ 0.536621f, 0.000590f, 0.517090f, 0.000559f, 0.498291f, 0.000530f, 0.479492f, 0.000501f,
+ 0.460938f, 0.000473f, 0.442627f, 0.000446f, 0.424805f, 0.000420f, 0.407227f, 0.000396f,
+ 0.390137f, 0.000373f, 0.373535f, 0.000350f, 0.357422f, 0.000329f, 0.341553f, 0.000309f,
+ 0.999512f, 0.000187f, 0.999512f, 0.000187f, 0.999512f, 0.000188f, 0.999512f, 0.000188f,
+ 0.999512f, 0.000190f, 0.999512f, 0.000194f, 0.999512f, 0.000201f, 0.999023f, 0.000204f,
+ 0.999023f, 0.000213f, 0.999023f, 0.000228f, 0.998535f, 0.000242f, 0.998535f, 0.000264f,
+ 0.997559f, 0.000285f, 0.997070f, 0.000311f, 0.996094f, 0.000351f, 0.995117f, 0.000386f,
+ 0.993164f, 0.000429f, 0.991211f, 0.000470f, 0.989258f, 0.000520f, 0.986328f, 0.000575f,
+ 0.983398f, 0.000628f, 0.979492f, 0.000683f, 0.975586f, 0.000741f, 0.970703f, 0.000801f,
+ 0.965332f, 0.000855f, 0.958984f, 0.000910f, 0.951660f, 0.000961f, 0.943848f, 0.001009f,
+ 0.935059f, 0.001053f, 0.925781f, 0.001090f, 0.915039f, 0.001123f, 0.903809f, 0.001152f,
+ 0.891602f, 0.001172f, 0.878906f, 0.001186f, 0.864746f, 0.001194f, 0.850586f, 0.001195f,
+ 0.835449f, 0.001191f, 0.819336f, 0.001181f, 0.802734f, 0.001164f, 0.785645f, 0.001144f,
+ 0.768066f, 0.001121f, 0.750000f, 0.001092f, 0.731445f, 0.001061f, 0.712402f, 0.001027f,
+ 0.693359f, 0.000992f, 0.674316f, 0.000955f, 0.654785f, 0.000916f, 0.635254f, 0.000877f,
+ 0.615723f, 0.000838f, 0.596191f, 0.000799f, 0.576660f, 0.000760f, 0.557129f, 0.000721f,
+ 0.538086f, 0.000684f, 0.518555f, 0.000648f, 0.500000f, 0.000612f, 0.481445f, 0.000578f,
+ 0.462891f, 0.000545f, 0.444824f, 0.000513f, 0.427246f, 0.000483f, 0.409912f, 0.000454f,
+ 0.392822f, 0.000427f, 0.376221f, 0.000401f, 0.360107f, 0.000376f, 0.344482f, 0.000353f,
+ 0.999512f, 0.000284f, 0.999512f, 0.000284f, 0.999512f, 0.000284f, 0.999512f, 0.000285f,
+ 0.999512f, 0.000287f, 0.999512f, 0.000292f, 0.999512f, 0.000296f, 0.999023f, 0.000307f,
+ 0.999023f, 0.000320f, 0.999023f, 0.000338f, 0.998535f, 0.000349f, 0.998047f, 0.000381f,
+ 0.997559f, 0.000407f, 0.996582f, 0.000447f, 0.995605f, 0.000480f, 0.994629f, 0.000531f,
+ 0.992676f, 0.000579f, 0.990723f, 0.000637f, 0.988770f, 0.000693f, 0.985840f, 0.000755f,
+ 0.982422f, 0.000824f, 0.979004f, 0.000889f, 0.975098f, 0.000958f, 0.969727f, 0.001024f,
+ 0.963867f, 0.001090f, 0.957520f, 0.001152f, 0.950684f, 0.001211f, 0.942383f, 0.001263f,
+ 0.933594f, 0.001309f, 0.923828f, 0.001353f, 0.913086f, 0.001387f, 0.901855f, 0.001413f,
+ 0.889648f, 0.001432f, 0.876465f, 0.001443f, 0.862793f, 0.001446f, 0.848145f, 0.001442f,
+ 0.833008f, 0.001431f, 0.817383f, 0.001413f, 0.800781f, 0.001390f, 0.783691f, 0.001362f,
+ 0.766113f, 0.001328f, 0.748535f, 0.001291f, 0.729980f, 0.001250f, 0.711426f, 0.001207f,
+ 0.692871f, 0.001163f, 0.673828f, 0.001116f, 0.654785f, 0.001068f, 0.635254f, 0.001020f,
+ 0.616211f, 0.000973f, 0.596680f, 0.000926f, 0.577637f, 0.000878f, 0.558105f, 0.000833f,
+ 0.539062f, 0.000788f, 0.520508f, 0.000745f, 0.501465f, 0.000702f, 0.483154f, 0.000663f,
+ 0.465088f, 0.000624f, 0.447266f, 0.000587f, 0.429443f, 0.000552f, 0.412354f, 0.000518f,
+ 0.395508f, 0.000486f, 0.378906f, 0.000456f, 0.363037f, 0.000427f, 0.347168f, 0.000400f,
+ 0.999512f, 0.000417f, 0.999512f, 0.000417f, 0.999512f, 0.000418f, 0.999512f, 0.000419f,
+ 0.999512f, 0.000422f, 0.999512f, 0.000425f, 0.999023f, 0.000434f, 0.999023f, 0.000447f,
+ 0.999023f, 0.000462f, 0.999023f, 0.000480f, 0.998047f, 0.000508f, 0.998047f, 0.000538f,
+ 0.997070f, 0.000576f, 0.996582f, 0.000621f, 0.995605f, 0.000669f, 0.993652f, 0.000721f,
+ 0.992188f, 0.000784f, 0.990723f, 0.000849f, 0.987793f, 0.000918f, 0.985840f, 0.000996f,
+ 0.982422f, 0.001071f, 0.978516f, 0.001148f, 0.973633f, 0.001225f, 0.968750f, 0.001304f,
+ 0.962891f, 0.001378f, 0.956543f, 0.001447f, 0.948730f, 0.001511f, 0.940918f, 0.001568f,
+ 0.931641f, 0.001617f, 0.921875f, 0.001660f, 0.911621f, 0.001697f, 0.899902f, 0.001719f,
+ 0.887695f, 0.001735f, 0.874512f, 0.001740f, 0.860840f, 0.001738f, 0.846191f, 0.001725f,
+ 0.831055f, 0.001706f, 0.815430f, 0.001679f, 0.798828f, 0.001646f, 0.782227f, 0.001607f,
+ 0.764648f, 0.001562f, 0.747070f, 0.001514f, 0.729004f, 0.001462f, 0.710449f, 0.001409f,
+ 0.691895f, 0.001352f, 0.673340f, 0.001295f, 0.654297f, 0.001237f, 0.635254f, 0.001179f,
+ 0.616211f, 0.001122f, 0.597168f, 0.001065f, 0.578125f, 0.001010f, 0.559570f, 0.000955f,
+ 0.540527f, 0.000902f, 0.521973f, 0.000852f, 0.503418f, 0.000803f, 0.485352f, 0.000755f,
+ 0.467285f, 0.000710f, 0.449463f, 0.000668f, 0.431885f, 0.000626f, 0.414795f, 0.000587f,
+ 0.398193f, 0.000551f, 0.381836f, 0.000516f, 0.365723f, 0.000483f, 0.350098f, 0.000452f,
+ 0.999023f, 0.000597f, 0.999023f, 0.000597f, 0.999023f, 0.000597f, 0.999023f, 0.000598f,
+ 0.999023f, 0.000602f, 0.999023f, 0.000610f, 0.999023f, 0.000618f, 0.999023f, 0.000632f,
+ 0.998535f, 0.000651f, 0.998535f, 0.000675f, 0.998047f, 0.000704f, 0.997559f, 0.000742f,
+ 0.997070f, 0.000787f, 0.996094f, 0.000843f, 0.995117f, 0.000902f, 0.993652f, 0.000966f,
+ 0.992188f, 0.001039f, 0.990234f, 0.001117f, 0.987793f, 0.001197f, 0.984863f, 0.001286f,
+ 0.981445f, 0.001372f, 0.977539f, 0.001464f, 0.972656f, 0.001553f, 0.967773f, 0.001639f,
+ 0.961914f, 0.001722f, 0.955078f, 0.001798f, 0.947754f, 0.001868f, 0.938965f, 0.001928f,
+ 0.930176f, 0.001982f, 0.920410f, 0.002026f, 0.909668f, 0.002056f, 0.897949f, 0.002075f,
+ 0.885254f, 0.002085f, 0.872559f, 0.002083f, 0.858398f, 0.002071f, 0.844238f, 0.002048f,
+ 0.828613f, 0.002018f, 0.812988f, 0.001980f, 0.796875f, 0.001934f, 0.780273f, 0.001883f,
+ 0.763184f, 0.001824f, 0.745605f, 0.001763f, 0.728027f, 0.001698f, 0.709473f, 0.001632f,
+ 0.691406f, 0.001563f, 0.672852f, 0.001494f, 0.654297f, 0.001422f, 0.635254f, 0.001355f,
+ 0.616699f, 0.001286f, 0.598145f, 0.001218f, 0.579102f, 0.001152f, 0.560547f, 0.001089f,
+ 0.541992f, 0.001027f, 0.523438f, 0.000968f, 0.505371f, 0.000911f, 0.487305f, 0.000857f,
+ 0.469482f, 0.000804f, 0.451904f, 0.000755f, 0.434570f, 0.000708f, 0.417480f, 0.000663f,
+ 0.400879f, 0.000621f, 0.384521f, 0.000581f, 0.368652f, 0.000544f, 0.353027f, 0.000508f,
+ 0.999023f, 0.000833f, 0.999023f, 0.000833f, 0.999023f, 0.000834f, 0.999023f, 0.000835f,
+ 0.999023f, 0.000840f, 0.999023f, 0.000845f, 0.998535f, 0.000861f, 0.998535f, 0.000875f,
+ 0.998535f, 0.000897f, 0.998047f, 0.000928f, 0.997559f, 0.000965f, 0.997070f, 0.001007f,
+ 0.996582f, 0.001061f, 0.995605f, 0.001128f, 0.994629f, 0.001195f, 0.993164f, 0.001276f,
+ 0.991699f, 0.001362f, 0.989258f, 0.001453f, 0.986816f, 0.001539f, 0.983887f, 0.001645f,
+ 0.980469f, 0.001747f, 0.976562f, 0.001849f, 0.971680f, 0.001945f, 0.966309f, 0.002045f,
+ 0.959961f, 0.002136f, 0.953613f, 0.002218f, 0.945801f, 0.002291f, 0.937500f, 0.002357f,
+ 0.928223f, 0.002407f, 0.917969f, 0.002447f, 0.907227f, 0.002472f, 0.895508f, 0.002487f,
+ 0.883301f, 0.002485f, 0.870117f, 0.002474f, 0.856445f, 0.002451f, 0.841797f, 0.002417f,
+ 0.826660f, 0.002373f, 0.811035f, 0.002317f, 0.794922f, 0.002258f, 0.778320f, 0.002190f,
+ 0.761230f, 0.002117f, 0.744141f, 0.002041f, 0.726562f, 0.001961f, 0.708496f, 0.001880f,
+ 0.690430f, 0.001796f, 0.672363f, 0.001713f, 0.654297f, 0.001630f, 0.635742f, 0.001547f,
+ 0.617188f, 0.001466f, 0.598633f, 0.001387f, 0.580078f, 0.001310f, 0.561523f, 0.001235f,
+ 0.543457f, 0.001164f, 0.524902f, 0.001095f, 0.507324f, 0.001029f, 0.489258f, 0.000967f,
+ 0.471680f, 0.000906f, 0.454346f, 0.000850f, 0.437012f, 0.000796f, 0.420166f, 0.000745f,
+ 0.403564f, 0.000698f, 0.387451f, 0.000652f, 0.371582f, 0.000609f, 0.356201f, 0.000569f,
+ 0.998535f, 0.001139f, 0.998535f, 0.001139f, 0.998535f, 0.001140f, 0.998535f, 0.001142f,
+ 0.998535f, 0.001147f, 0.998535f, 0.001159f, 0.998535f, 0.001168f, 0.998047f, 0.001190f,
+ 0.998047f, 0.001217f, 0.997559f, 0.001254f, 0.997559f, 0.001301f, 0.997070f, 0.001356f,
+ 0.996094f, 0.001416f, 0.995605f, 0.001493f, 0.994141f, 0.001574f, 0.992676f, 0.001663f,
+ 0.990723f, 0.001759f, 0.988770f, 0.001867f, 0.986328f, 0.001980f, 0.982910f, 0.002087f,
+ 0.979492f, 0.002199f, 0.975586f, 0.002319f, 0.970703f, 0.002422f, 0.965332f, 0.002531f,
+ 0.958496f, 0.002628f, 0.952148f, 0.002714f, 0.944336f, 0.002792f, 0.935547f, 0.002851f,
+ 0.926270f, 0.002903f, 0.916016f, 0.002935f, 0.904785f, 0.002954f, 0.893066f, 0.002956f,
+ 0.880859f, 0.002947f, 0.867676f, 0.002920f, 0.853516f, 0.002882f, 0.839355f, 0.002831f,
+ 0.824219f, 0.002769f, 0.809082f, 0.002699f, 0.792969f, 0.002619f, 0.776367f, 0.002533f,
+ 0.759766f, 0.002443f, 0.742676f, 0.002350f, 0.725586f, 0.002251f, 0.708008f, 0.002151f,
+ 0.689941f, 0.002052f, 0.671875f, 0.001953f, 0.653809f, 0.001854f, 0.635742f, 0.001758f,
+ 0.617676f, 0.001663f, 0.599121f, 0.001572f, 0.581055f, 0.001482f, 0.562988f, 0.001395f,
+ 0.544922f, 0.001313f, 0.526855f, 0.001234f, 0.508789f, 0.001158f, 0.491455f, 0.001086f,
+ 0.473877f, 0.001018f, 0.456787f, 0.000954f, 0.439697f, 0.000892f, 0.422852f, 0.000834f,
+ 0.406494f, 0.000780f, 0.390381f, 0.000729f, 0.374512f, 0.000680f, 0.359131f, 0.000635f,
+ 0.998047f, 0.001528f, 0.998047f, 0.001528f, 0.998047f, 0.001529f, 0.998047f, 0.001532f,
+ 0.998047f, 0.001539f, 0.998047f, 0.001546f, 0.998047f, 0.001562f, 0.998047f, 0.001589f,
+ 0.997559f, 0.001621f, 0.997559f, 0.001668f, 0.996582f, 0.001715f, 0.996582f, 0.001777f,
+ 0.995605f, 0.001859f, 0.994629f, 0.001939f, 0.993652f, 0.002035f, 0.992188f, 0.002140f,
+ 0.990234f, 0.002243f, 0.987793f, 0.002369f, 0.985352f, 0.002489f, 0.981934f, 0.002621f,
+ 0.978516f, 0.002750f, 0.974121f, 0.002876f, 0.969238f, 0.002991f, 0.963867f, 0.003105f,
+ 0.957031f, 0.003206f, 0.950195f, 0.003300f, 0.942383f, 0.003374f, 0.933594f, 0.003431f,
+ 0.923828f, 0.003473f, 0.913574f, 0.003498f, 0.902344f, 0.003506f, 0.890625f, 0.003494f,
+ 0.878418f, 0.003468f, 0.865234f, 0.003426f, 0.851074f, 0.003366f, 0.836914f, 0.003296f,
+ 0.822266f, 0.003216f, 0.806641f, 0.003122f, 0.791016f, 0.003023f, 0.774902f, 0.002916f,
+ 0.758301f, 0.002804f, 0.741211f, 0.002689f, 0.724121f, 0.002573f, 0.707031f, 0.002453f,
+ 0.689453f, 0.002335f, 0.671875f, 0.002216f, 0.653809f, 0.002102f, 0.636230f, 0.001987f,
+ 0.618164f, 0.001878f, 0.600098f, 0.001771f, 0.582031f, 0.001668f, 0.564453f, 0.001569f,
+ 0.546387f, 0.001475f, 0.528809f, 0.001384f, 0.511230f, 0.001297f, 0.493652f, 0.001217f,
+ 0.476318f, 0.001139f, 0.459229f, 0.001065f, 0.442383f, 0.000996f, 0.425781f, 0.000930f,
+ 0.409424f, 0.000869f, 0.393311f, 0.000811f, 0.377686f, 0.000757f, 0.362305f, 0.000707f,
+ 0.997559f, 0.002018f, 0.997559f, 0.002018f, 0.997559f, 0.002018f, 0.997559f, 0.002022f,
+ 0.997559f, 0.002028f, 0.997559f, 0.002045f, 0.997559f, 0.002066f, 0.997559f, 0.002092f,
+ 0.997559f, 0.002129f, 0.996582f, 0.002176f, 0.996094f, 0.002235f, 0.995605f, 0.002312f,
+ 0.995605f, 0.002407f, 0.993652f, 0.002491f, 0.992676f, 0.002605f, 0.991211f, 0.002729f,
+ 0.989258f, 0.002846f, 0.987305f, 0.002987f, 0.984375f, 0.003120f, 0.980957f, 0.003263f,
+ 0.977051f, 0.003403f, 0.972656f, 0.003542f, 0.967285f, 0.003666f, 0.961914f, 0.003782f,
+ 0.955566f, 0.003889f, 0.947754f, 0.003967f, 0.939941f, 0.004044f, 0.931152f, 0.004097f,
+ 0.921387f, 0.004131f, 0.911133f, 0.004139f, 0.899902f, 0.004131f, 0.888184f, 0.004108f,
+ 0.875488f, 0.004055f, 0.862305f, 0.003990f, 0.848633f, 0.003914f, 0.834473f, 0.003819f,
+ 0.819824f, 0.003712f, 0.804199f, 0.003593f, 0.788574f, 0.003469f, 0.772949f, 0.003338f,
+ 0.756348f, 0.003201f, 0.739746f, 0.003063f, 0.723145f, 0.002924f, 0.706055f, 0.002781f,
+ 0.688965f, 0.002644f, 0.671387f, 0.002506f, 0.653809f, 0.002371f, 0.636230f, 0.002239f,
+ 0.618652f, 0.002111f, 0.601074f, 0.001989f, 0.583496f, 0.001871f, 0.565430f, 0.001759f,
+ 0.547852f, 0.001650f, 0.530273f, 0.001547f, 0.513184f, 0.001449f, 0.495850f, 0.001356f,
+ 0.478760f, 0.001269f, 0.461670f, 0.001185f, 0.445068f, 0.001107f, 0.428467f, 0.001035f,
+ 0.412354f, 0.000965f, 0.396240f, 0.000901f, 0.380615f, 0.000840f, 0.365479f, 0.000783f,
+ 0.997070f, 0.002625f, 0.997070f, 0.002625f, 0.997070f, 0.002626f, 0.997070f, 0.002630f,
+ 0.997070f, 0.002640f, 0.997070f, 0.002659f, 0.997070f, 0.002676f, 0.996582f, 0.002708f,
+ 0.996582f, 0.002752f, 0.996094f, 0.002813f, 0.995605f, 0.002886f, 0.995117f, 0.002956f,
+ 0.994141f, 0.003071f, 0.992676f, 0.003172f, 0.991699f, 0.003292f, 0.990234f, 0.003433f,
+ 0.988281f, 0.003580f, 0.985840f, 0.003727f, 0.982910f, 0.003870f, 0.979492f, 0.004028f,
+ 0.975586f, 0.004177f, 0.971191f, 0.004322f, 0.966309f, 0.004456f, 0.959961f, 0.004570f,
+ 0.953125f, 0.004669f, 0.945801f, 0.004757f, 0.937500f, 0.004826f, 0.928711f, 0.004864f,
+ 0.918945f, 0.004883f, 0.908691f, 0.004875f, 0.897461f, 0.004845f, 0.885254f, 0.004795f,
+ 0.872559f, 0.004723f, 0.859863f, 0.004631f, 0.846191f, 0.004520f, 0.832031f, 0.004398f,
+ 0.817383f, 0.004261f, 0.802246f, 0.004116f, 0.786621f, 0.003963f, 0.770996f, 0.003805f,
+ 0.754883f, 0.003639f, 0.738770f, 0.003475f, 0.722168f, 0.003307f, 0.705078f, 0.003143f,
+ 0.688477f, 0.002981f, 0.671387f, 0.002821f, 0.653809f, 0.002665f, 0.636719f, 0.002512f,
+ 0.619141f, 0.002367f, 0.602051f, 0.002226f, 0.584473f, 0.002090f, 0.566895f, 0.001963f,
+ 0.549805f, 0.001840f, 0.532227f, 0.001722f, 0.515137f, 0.001613f, 0.498047f, 0.001508f,
+ 0.481201f, 0.001409f, 0.464355f, 0.001316f, 0.447754f, 0.001228f, 0.431396f, 0.001145f,
+ 0.415283f, 0.001069f, 0.399414f, 0.000997f, 0.383789f, 0.000929f, 0.368652f, 0.000865f,
+ 0.996582f, 0.003370f, 0.996582f, 0.003370f, 0.996582f, 0.003372f, 0.996582f, 0.003378f,
+ 0.996582f, 0.003389f, 0.996094f, 0.003410f, 0.996094f, 0.003435f, 0.996094f, 0.003471f,
+ 0.996094f, 0.003523f, 0.995117f, 0.003588f, 0.995117f, 0.003664f, 0.994141f, 0.003754f,
+ 0.993164f, 0.003864f, 0.992676f, 0.003990f, 0.990723f, 0.004128f, 0.989746f, 0.004288f,
+ 0.987793f, 0.004429f, 0.984375f, 0.004601f, 0.981445f, 0.004757f, 0.978027f, 0.004925f,
+ 0.974121f, 0.005089f, 0.969727f, 0.005241f, 0.964355f, 0.005375f, 0.958008f, 0.005486f,
+ 0.951172f, 0.005596f, 0.943848f, 0.005665f, 0.935547f, 0.005718f, 0.925781f, 0.005737f,
+ 0.916016f, 0.005733f, 0.905762f, 0.005707f, 0.894531f, 0.005650f, 0.882324f, 0.005569f,
+ 0.870117f, 0.005466f, 0.856934f, 0.005341f, 0.843262f, 0.005199f, 0.829102f, 0.005043f,
+ 0.814941f, 0.004871f, 0.799805f, 0.004692f, 0.784668f, 0.004505f, 0.769043f, 0.004314f,
+ 0.753418f, 0.004116f, 0.737305f, 0.003922f, 0.721191f, 0.003729f, 0.704590f, 0.003536f,
+ 0.687988f, 0.003347f, 0.670898f, 0.003162f, 0.654297f, 0.002983f, 0.637207f, 0.002810f,
+ 0.620117f, 0.002642f, 0.603027f, 0.002481f, 0.585938f, 0.002329f, 0.568359f, 0.002182f,
+ 0.551270f, 0.002045f, 0.534180f, 0.001913f, 0.517090f, 0.001788f, 0.500488f, 0.001671f,
+ 0.483643f, 0.001560f, 0.467041f, 0.001456f, 0.450684f, 0.001358f, 0.434326f, 0.001266f,
+ 0.418213f, 0.001181f, 0.402588f, 0.001101f, 0.386963f, 0.001025f, 0.371826f, 0.000954f,
+ 0.995605f, 0.004276f, 0.995605f, 0.004276f, 0.995605f, 0.004280f, 0.995605f, 0.004284f,
+ 0.995605f, 0.004299f, 0.995117f, 0.004318f, 0.995117f, 0.004349f, 0.995117f, 0.004383f,
+ 0.994629f, 0.004456f, 0.994629f, 0.004524f, 0.994141f, 0.004612f, 0.993164f, 0.004704f,
+ 0.992676f, 0.004848f, 0.991699f, 0.004974f, 0.990234f, 0.005142f, 0.987793f, 0.005291f,
+ 0.986328f, 0.005474f, 0.982910f, 0.005638f, 0.980469f, 0.005825f, 0.976562f, 0.005989f,
+ 0.972656f, 0.006157f, 0.967773f, 0.006313f, 0.961914f, 0.006443f, 0.955566f, 0.006554f,
+ 0.948730f, 0.006645f, 0.940918f, 0.006702f, 0.932617f, 0.006733f, 0.923340f, 0.006733f,
+ 0.913574f, 0.006699f, 0.902832f, 0.006645f, 0.891602f, 0.006550f, 0.879395f, 0.006435f,
+ 0.867188f, 0.006294f, 0.854004f, 0.006130f, 0.840332f, 0.005951f, 0.826660f, 0.005756f,
+ 0.812500f, 0.005543f, 0.797363f, 0.005325f, 0.782715f, 0.005100f, 0.767090f, 0.004871f,
+ 0.751465f, 0.004642f, 0.735840f, 0.004414f, 0.719727f, 0.004185f, 0.703613f, 0.003960f,
+ 0.687500f, 0.003744f, 0.670898f, 0.003531f, 0.654297f, 0.003326f, 0.637695f, 0.003128f,
+ 0.620605f, 0.002939f, 0.604004f, 0.002756f, 0.586914f, 0.002584f, 0.569824f, 0.002420f,
+ 0.553223f, 0.002264f, 0.536133f, 0.002117f, 0.519531f, 0.001978f, 0.502930f, 0.001847f,
+ 0.486328f, 0.001723f, 0.469727f, 0.001607f, 0.453369f, 0.001498f, 0.437256f, 0.001395f,
+ 0.421387f, 0.001300f, 0.405762f, 0.001211f, 0.390381f, 0.001127f, 0.375244f, 0.001050f,
+ 0.994141f, 0.005367f, 0.994141f, 0.005367f, 0.994141f, 0.005371f, 0.994141f, 0.005375f,
+ 0.994141f, 0.005394f, 0.994141f, 0.005413f, 0.994141f, 0.005447f, 0.994141f, 0.005508f,
+ 0.993652f, 0.005558f, 0.993652f, 0.005650f, 0.992676f, 0.005741f, 0.991699f, 0.005848f,
+ 0.991211f, 0.006004f, 0.990234f, 0.006149f, 0.988281f, 0.006317f, 0.986328f, 0.006504f,
+ 0.984863f, 0.006687f, 0.981934f, 0.006866f, 0.978516f, 0.007050f, 0.974609f, 0.007233f,
+ 0.970215f, 0.007393f, 0.965820f, 0.007553f, 0.959961f, 0.007675f, 0.953125f, 0.007774f,
+ 0.946289f, 0.007843f, 0.938477f, 0.007889f, 0.929688f, 0.007889f, 0.920410f, 0.007858f,
+ 0.910156f, 0.007793f, 0.899414f, 0.007694f, 0.888672f, 0.007565f, 0.876465f, 0.007401f,
+ 0.864258f, 0.007214f, 0.851074f, 0.007008f, 0.837402f, 0.006779f, 0.823730f, 0.006535f,
+ 0.809570f, 0.006279f, 0.794922f, 0.006023f, 0.780273f, 0.005753f, 0.765137f, 0.005482f,
+ 0.750000f, 0.005215f, 0.734375f, 0.004944f, 0.718750f, 0.004681f, 0.703125f, 0.004425f,
+ 0.687012f, 0.004173f, 0.670898f, 0.003929f, 0.654297f, 0.003700f, 0.638184f, 0.003473f,
+ 0.621582f, 0.003260f, 0.604980f, 0.003056f, 0.588379f, 0.002861f, 0.571777f, 0.002676f,
+ 0.555176f, 0.002502f, 0.538574f, 0.002337f, 0.521973f, 0.002180f, 0.505371f, 0.002035f,
+ 0.488770f, 0.001898f, 0.472656f, 0.001769f, 0.456299f, 0.001649f, 0.440430f, 0.001534f,
+ 0.424561f, 0.001430f, 0.408936f, 0.001329f, 0.393555f, 0.001238f, 0.378418f, 0.001151f,
+ 0.993164f, 0.006672f, 0.993164f, 0.006672f, 0.993164f, 0.006676f, 0.993164f, 0.006687f,
+ 0.993164f, 0.006699f, 0.993164f, 0.006721f, 0.992676f, 0.006760f, 0.992676f, 0.006821f,
+ 0.992188f, 0.006897f, 0.991699f, 0.006973f, 0.991211f, 0.007099f, 0.990234f, 0.007206f,
+ 0.990234f, 0.007366f, 0.988281f, 0.007519f, 0.986328f, 0.007706f, 0.984863f, 0.007912f,
+ 0.982422f, 0.008087f, 0.979980f, 0.008286f, 0.977051f, 0.008476f, 0.972656f, 0.008667f,
+ 0.968262f, 0.008827f, 0.962891f, 0.008980f, 0.957520f, 0.009079f, 0.951172f, 0.009171f,
+ 0.943848f, 0.009216f, 0.935547f, 0.009224f, 0.926758f, 0.009193f, 0.917480f, 0.009125f,
+ 0.906738f, 0.009010f, 0.895996f, 0.008865f, 0.885254f, 0.008682f, 0.873047f, 0.008469f,
+ 0.860840f, 0.008232f, 0.847656f, 0.007973f, 0.834473f, 0.007690f, 0.820801f, 0.007397f,
+ 0.807129f, 0.007092f, 0.792969f, 0.006783f, 0.778320f, 0.006462f, 0.763184f, 0.006145f,
+ 0.748535f, 0.005833f, 0.733398f, 0.005524f, 0.717773f, 0.005219f, 0.702148f, 0.004925f,
+ 0.686523f, 0.004639f, 0.670898f, 0.004364f, 0.654785f, 0.004097f, 0.638672f, 0.003847f,
+ 0.622559f, 0.003605f, 0.605957f, 0.003376f, 0.589844f, 0.003157f, 0.573242f, 0.002951f,
+ 0.556641f, 0.002756f, 0.540527f, 0.002573f, 0.523926f, 0.002399f, 0.507812f, 0.002237f,
+ 0.491455f, 0.002085f, 0.475342f, 0.001943f, 0.459229f, 0.001809f, 0.443359f, 0.001684f,
+ 0.427734f, 0.001567f, 0.412109f, 0.001457f, 0.396973f, 0.001356f, 0.382080f, 0.001261f,
+ 0.991699f, 0.008217f, 0.991699f, 0.008217f, 0.991699f, 0.008217f, 0.991699f, 0.008232f,
+ 0.991211f, 0.008240f, 0.991211f, 0.008270f, 0.991211f, 0.008324f, 0.991211f, 0.008377f,
+ 0.990723f, 0.008461f, 0.990234f, 0.008553f, 0.989746f, 0.008682f, 0.988770f, 0.008820f,
+ 0.987793f, 0.008972f, 0.986816f, 0.009163f, 0.985352f, 0.009338f, 0.982910f, 0.009567f,
+ 0.980957f, 0.009758f, 0.977539f, 0.009956f, 0.974609f, 0.010155f, 0.970215f, 0.010330f,
+ 0.965820f, 0.010483f, 0.960449f, 0.010597f, 0.954590f, 0.010696f, 0.947754f, 0.010750f,
+ 0.940430f, 0.010757f, 0.932129f, 0.010735f, 0.923340f, 0.010651f, 0.913574f, 0.010536f,
+ 0.903809f, 0.010376f, 0.892578f, 0.010162f, 0.881348f, 0.009926f, 0.869629f, 0.009651f,
+ 0.857422f, 0.009354f, 0.844727f, 0.009026f, 0.831543f, 0.008690f, 0.817871f, 0.008331f,
+ 0.804199f, 0.007973f, 0.790527f, 0.007603f, 0.775879f, 0.007233f, 0.761719f, 0.006866f,
+ 0.747070f, 0.006500f, 0.731934f, 0.006145f, 0.716797f, 0.005798f, 0.701660f, 0.005466f,
+ 0.686523f, 0.005138f, 0.670898f, 0.004829f, 0.655273f, 0.004532f, 0.639160f, 0.004246f,
+ 0.623535f, 0.003975f, 0.607422f, 0.003719f, 0.591309f, 0.003477f, 0.575195f, 0.003246f,
+ 0.558594f, 0.003029f, 0.542480f, 0.002827f, 0.526367f, 0.002634f, 0.510254f, 0.002455f,
+ 0.494141f, 0.002285f, 0.478271f, 0.002129f, 0.462402f, 0.001980f, 0.446533f, 0.001843f,
+ 0.430908f, 0.001715f, 0.415527f, 0.001594f, 0.400391f, 0.001483f, 0.385498f, 0.001378f,
+ 0.989746f, 0.010040f, 0.989746f, 0.010040f, 0.989746f, 0.010040f, 0.989746f, 0.010048f,
+ 0.989746f, 0.010071f, 0.989746f, 0.010094f, 0.989258f, 0.010147f, 0.989258f, 0.010223f,
+ 0.988770f, 0.010300f, 0.988770f, 0.010406f, 0.987793f, 0.010529f, 0.986816f, 0.010696f,
+ 0.986328f, 0.010857f, 0.984863f, 0.011055f, 0.982422f, 0.011238f, 0.981445f, 0.011467f,
+ 0.978516f, 0.011673f, 0.975098f, 0.011871f, 0.972168f, 0.012062f, 0.967285f, 0.012215f,
+ 0.962402f, 0.012352f, 0.957031f, 0.012459f, 0.951172f, 0.012535f, 0.944336f, 0.012535f,
+ 0.937012f, 0.012520f, 0.928711f, 0.012428f, 0.919922f, 0.012299f, 0.910156f, 0.012115f,
+ 0.899414f, 0.011879f, 0.889160f, 0.011612f, 0.877441f, 0.011299f, 0.865723f, 0.010956f,
+ 0.853516f, 0.010582f, 0.841309f, 0.010193f, 0.828125f, 0.009773f, 0.814941f, 0.009361f,
+ 0.801270f, 0.008926f, 0.787598f, 0.008499f, 0.773926f, 0.008064f, 0.759766f, 0.007641f,
+ 0.745117f, 0.007225f, 0.730469f, 0.006817f, 0.716309f, 0.006424f, 0.701172f, 0.006042f,
+ 0.686035f, 0.005676f, 0.670898f, 0.005329f, 0.655273f, 0.004993f, 0.640137f, 0.004673f,
+ 0.624512f, 0.004372f, 0.608398f, 0.004086f, 0.592773f, 0.003817f, 0.576660f, 0.003561f,
+ 0.561035f, 0.003323f, 0.544922f, 0.003098f, 0.528809f, 0.002884f, 0.512695f, 0.002686f,
+ 0.497070f, 0.002501f, 0.481201f, 0.002327f, 0.465332f, 0.002165f, 0.449707f, 0.002014f,
+ 0.434326f, 0.001873f, 0.418945f, 0.001740f, 0.403809f, 0.001617f, 0.388916f, 0.001504f,
+ 0.987793f, 0.012169f, 0.987793f, 0.012169f, 0.987793f, 0.012169f, 0.987793f, 0.012184f,
+ 0.987305f, 0.012207f, 0.987305f, 0.012245f, 0.987305f, 0.012291f, 0.986816f, 0.012360f,
+ 0.986816f, 0.012459f, 0.986328f, 0.012573f, 0.985840f, 0.012695f, 0.984863f, 0.012878f,
+ 0.983887f, 0.013046f, 0.982422f, 0.013237f, 0.980469f, 0.013466f, 0.979004f, 0.013680f,
+ 0.976074f, 0.013878f, 0.972656f, 0.014069f, 0.969238f, 0.014259f, 0.964355f, 0.014397f,
+ 0.959961f, 0.014488f, 0.954102f, 0.014580f, 0.947754f, 0.014595f, 0.940430f, 0.014557f,
+ 0.933105f, 0.014481f, 0.925293f, 0.014328f, 0.915527f, 0.014122f, 0.906250f, 0.013870f,
+ 0.895996f, 0.013565f, 0.885254f, 0.013206f, 0.873535f, 0.012817f, 0.862305f, 0.012383f,
+ 0.850098f, 0.011932f, 0.837891f, 0.011452f, 0.824707f, 0.010963f, 0.812012f, 0.010460f,
+ 0.798828f, 0.009964f, 0.785156f, 0.009460f, 0.771484f, 0.008965f, 0.757812f, 0.008484f,
+ 0.743652f, 0.008003f, 0.729492f, 0.007542f, 0.715332f, 0.007095f, 0.700684f, 0.006668f,
+ 0.686035f, 0.006256f, 0.670898f, 0.005863f, 0.655762f, 0.005489f, 0.640625f, 0.005135f,
+ 0.625488f, 0.004799f, 0.609863f, 0.004478f, 0.594238f, 0.004181f, 0.578613f, 0.003901f,
+ 0.562988f, 0.003635f, 0.547363f, 0.003386f, 0.531250f, 0.003153f, 0.515625f, 0.002935f,
+ 0.500000f, 0.002729f, 0.484131f, 0.002539f, 0.468506f, 0.002361f, 0.453125f, 0.002195f,
+ 0.437744f, 0.002041f, 0.422363f, 0.001897f, 0.407471f, 0.001763f, 0.392578f, 0.001637f,
+ 0.985352f, 0.014641f, 0.985352f, 0.014641f, 0.984863f, 0.014648f, 0.984863f, 0.014656f,
+ 0.984863f, 0.014679f, 0.984863f, 0.014717f, 0.984863f, 0.014771f, 0.984375f, 0.014839f,
+ 0.984375f, 0.014938f, 0.983398f, 0.015060f, 0.983398f, 0.015244f, 0.981934f, 0.015388f,
+ 0.980957f, 0.015587f, 0.979492f, 0.015778f, 0.977539f, 0.015976f, 0.975586f, 0.016190f,
+ 0.972656f, 0.016388f, 0.969727f, 0.016571f, 0.965820f, 0.016739f, 0.961426f, 0.016861f,
+ 0.956055f, 0.016922f, 0.950684f, 0.016953f, 0.943848f, 0.016922f, 0.937012f, 0.016815f,
+ 0.929199f, 0.016663f, 0.920410f, 0.016434f, 0.911621f, 0.016144f, 0.901855f, 0.015793f,
+ 0.891602f, 0.015411f, 0.880859f, 0.014954f, 0.869629f, 0.014473f, 0.857910f, 0.013947f,
+ 0.846191f, 0.013390f, 0.833984f, 0.012825f, 0.821289f, 0.012253f, 0.809082f, 0.011665f,
+ 0.795898f, 0.011086f, 0.782715f, 0.010506f, 0.769531f, 0.009933f, 0.755859f, 0.009377f,
+ 0.742188f, 0.008842f, 0.728516f, 0.008316f, 0.714355f, 0.007812f, 0.700195f, 0.007336f,
+ 0.685547f, 0.006874f, 0.670898f, 0.006435f, 0.656250f, 0.006020f, 0.641602f, 0.005623f,
+ 0.626465f, 0.005253f, 0.611328f, 0.004902f, 0.596191f, 0.004570f, 0.580566f, 0.004261f,
+ 0.564941f, 0.003967f, 0.549316f, 0.003695f, 0.533691f, 0.003437f, 0.518066f, 0.003199f,
+ 0.502930f, 0.002975f, 0.487305f, 0.002766f, 0.471680f, 0.002571f, 0.456299f, 0.002388f,
+ 0.441162f, 0.002220f, 0.426025f, 0.002062f, 0.411133f, 0.001916f, 0.396240f, 0.001781f,
+ 0.982422f, 0.017502f, 0.982422f, 0.017502f, 0.982422f, 0.017502f, 0.982422f, 0.017517f,
+ 0.981934f, 0.017532f, 0.981934f, 0.017593f, 0.981934f, 0.017639f, 0.981934f, 0.017731f,
+ 0.981445f, 0.017838f, 0.980957f, 0.017960f, 0.979980f, 0.018112f, 0.979004f, 0.018295f,
+ 0.978027f, 0.018478f, 0.975586f, 0.018677f, 0.974609f, 0.018860f, 0.972168f, 0.019073f,
+ 0.969238f, 0.019287f, 0.965820f, 0.019455f, 0.962402f, 0.019562f, 0.958008f, 0.019653f,
+ 0.952637f, 0.019653f, 0.946289f, 0.019623f, 0.939453f, 0.019516f, 0.932617f, 0.019348f,
+ 0.924316f, 0.019089f, 0.916016f, 0.018784f, 0.907227f, 0.018387f, 0.897461f, 0.017944f,
+ 0.887207f, 0.017426f, 0.876465f, 0.016861f, 0.865234f, 0.016266f, 0.854004f, 0.015640f,
+ 0.842285f, 0.014999f, 0.830078f, 0.014320f, 0.818359f, 0.013641f, 0.805664f, 0.012962f,
+ 0.792969f, 0.012291f, 0.780273f, 0.011627f, 0.767090f, 0.010979f, 0.753906f, 0.010345f,
+ 0.740723f, 0.009735f, 0.727539f, 0.009155f, 0.713867f, 0.008591f, 0.699707f, 0.008049f,
+ 0.685547f, 0.007534f, 0.671387f, 0.007050f, 0.656738f, 0.006588f, 0.642578f, 0.006149f,
+ 0.627441f, 0.005737f, 0.612793f, 0.005352f, 0.597656f, 0.004986f, 0.582520f, 0.004642f,
+ 0.567383f, 0.004322f, 0.551758f, 0.004021f, 0.536621f, 0.003744f, 0.520996f, 0.003481f,
+ 0.505859f, 0.003235f, 0.490479f, 0.003006f, 0.475098f, 0.002794f, 0.459717f, 0.002596f,
+ 0.444580f, 0.002411f, 0.429688f, 0.002241f, 0.414795f, 0.002081f, 0.400146f, 0.001933f,
+ 0.979004f, 0.020798f, 0.979004f, 0.020798f, 0.979004f, 0.020798f, 0.979004f, 0.020813f,
+ 0.979004f, 0.020844f, 0.978516f, 0.020874f, 0.978516f, 0.020935f, 0.978027f, 0.021027f,
+ 0.978027f, 0.021149f, 0.977539f, 0.021286f, 0.977051f, 0.021454f, 0.975586f, 0.021622f,
+ 0.974121f, 0.021820f, 0.972656f, 0.021988f, 0.970215f, 0.022186f, 0.968750f, 0.022385f,
+ 0.965820f, 0.022552f, 0.961914f, 0.022675f, 0.958008f, 0.022736f, 0.953613f, 0.022751f,
+ 0.948242f, 0.022736f, 0.942383f, 0.022614f, 0.935547f, 0.022415f, 0.927734f, 0.022156f,
+ 0.919922f, 0.021790f, 0.911621f, 0.021362f, 0.901855f, 0.020859f, 0.892090f, 0.020279f,
+ 0.882324f, 0.019638f, 0.872070f, 0.018951f, 0.860840f, 0.018234f, 0.849609f, 0.017487f,
+ 0.838379f, 0.016708f, 0.826172f, 0.015930f, 0.814453f, 0.015144f, 0.802246f, 0.014359f,
+ 0.790527f, 0.013588f, 0.777832f, 0.012833f, 0.765137f, 0.012100f, 0.752441f, 0.011383f,
+ 0.739258f, 0.010696f, 0.726074f, 0.010040f, 0.712891f, 0.009415f, 0.699219f, 0.008812f,
+ 0.685547f, 0.008240f, 0.671875f, 0.007698f, 0.657715f, 0.007191f, 0.643555f, 0.006710f,
+ 0.628906f, 0.006252f, 0.614258f, 0.005829f, 0.599609f, 0.005428f, 0.584473f, 0.005051f,
+ 0.569336f, 0.004704f, 0.554199f, 0.004372f, 0.539062f, 0.004063f, 0.523926f, 0.003780f,
+ 0.508789f, 0.003513f, 0.493652f, 0.003263f, 0.478271f, 0.003033f, 0.463135f, 0.002817f,
+ 0.448242f, 0.002615f, 0.433350f, 0.002430f, 0.418457f, 0.002256f, 0.403809f, 0.002094f,
+ 0.975098f, 0.024582f, 0.975098f, 0.024567f, 0.975098f, 0.024582f, 0.975098f, 0.024597f,
+ 0.975098f, 0.024628f, 0.975098f, 0.024658f, 0.975098f, 0.024734f, 0.974609f, 0.024826f,
+ 0.973633f, 0.024933f, 0.973633f, 0.025055f, 0.972656f, 0.025223f, 0.972168f, 0.025421f,
+ 0.970215f, 0.025589f, 0.968262f, 0.025742f, 0.966309f, 0.025925f, 0.964355f, 0.026108f,
+ 0.960938f, 0.026230f, 0.957520f, 0.026321f, 0.953613f, 0.026352f, 0.948242f, 0.026260f,
+ 0.943848f, 0.026154f, 0.937500f, 0.025970f, 0.930664f, 0.025650f, 0.922852f, 0.025253f,
+ 0.915039f, 0.024765f, 0.906738f, 0.024200f, 0.897461f, 0.023560f, 0.887207f, 0.022827f,
+ 0.877441f, 0.022064f, 0.866699f, 0.021225f, 0.855957f, 0.020370f, 0.845215f, 0.019470f,
+ 0.833984f, 0.018570f, 0.822266f, 0.017654f, 0.811035f, 0.016754f, 0.799316f, 0.015854f,
+ 0.787109f, 0.014984f, 0.775391f, 0.014122f, 0.763184f, 0.013298f, 0.750488f, 0.012489f,
+ 0.737793f, 0.011726f, 0.725098f, 0.010986f, 0.712402f, 0.010284f, 0.699219f, 0.009621f,
+ 0.685547f, 0.008987f, 0.671875f, 0.008392f, 0.658203f, 0.007828f, 0.644531f, 0.007305f,
+ 0.630371f, 0.006802f, 0.615723f, 0.006336f, 0.601562f, 0.005898f, 0.586914f, 0.005489f,
+ 0.571777f, 0.005104f, 0.557129f, 0.004745f, 0.541992f, 0.004414f, 0.526855f, 0.004101f,
+ 0.511719f, 0.003809f, 0.496826f, 0.003538f, 0.481689f, 0.003286f, 0.466797f, 0.003052f,
+ 0.451904f, 0.002832f, 0.437012f, 0.002630f, 0.422363f, 0.002441f, 0.407715f, 0.002268f,
+ 0.970703f, 0.028870f, 0.970703f, 0.028870f, 0.970703f, 0.028885f, 0.970703f, 0.028900f,
+ 0.970703f, 0.028915f, 0.970703f, 0.028961f, 0.970215f, 0.029022f, 0.970215f, 0.029114f,
+ 0.969727f, 0.029251f, 0.968750f, 0.029373f, 0.968262f, 0.029526f, 0.966797f, 0.029678f,
+ 0.966309f, 0.029877f, 0.964844f, 0.030045f, 0.962402f, 0.030167f, 0.959473f, 0.030304f,
+ 0.956543f, 0.030411f, 0.953125f, 0.030411f, 0.948242f, 0.030319f, 0.943359f, 0.030197f,
+ 0.938477f, 0.029968f, 0.931641f, 0.029648f, 0.924805f, 0.029221f, 0.917969f, 0.028687f,
+ 0.909180f, 0.028030f, 0.900879f, 0.027313f, 0.891602f, 0.026505f, 0.881836f, 0.025620f,
+ 0.871582f, 0.024673f, 0.861816f, 0.023697f, 0.851074f, 0.022659f, 0.840820f, 0.021622f,
+ 0.829590f, 0.020569f, 0.818359f, 0.019516f, 0.807129f, 0.018478f, 0.795898f, 0.017456f,
+ 0.784180f, 0.016464f, 0.772461f, 0.015503f, 0.760742f, 0.014572f, 0.748535f, 0.013672f,
+ 0.736816f, 0.012817f, 0.724121f, 0.012001f, 0.711914f, 0.011215f, 0.698730f, 0.010483f,
+ 0.686035f, 0.009789f, 0.672852f, 0.009132f, 0.659180f, 0.008514f, 0.645508f, 0.007935f,
+ 0.631836f, 0.007389f, 0.617676f, 0.006878f, 0.603516f, 0.006397f, 0.588867f, 0.005951f,
+ 0.574219f, 0.005531f, 0.559570f, 0.005142f, 0.544922f, 0.004776f, 0.529785f, 0.004436f,
+ 0.515137f, 0.004120f, 0.500000f, 0.003828f, 0.485352f, 0.003555f, 0.470215f, 0.003302f,
+ 0.455566f, 0.003065f, 0.440918f, 0.002844f, 0.426270f, 0.002642f, 0.411621f, 0.002451f,
+ 0.965820f, 0.033752f, 0.965820f, 0.033752f, 0.965820f, 0.033752f, 0.965820f, 0.033783f,
+ 0.965820f, 0.033783f, 0.965820f, 0.033875f, 0.965332f, 0.033905f, 0.965332f, 0.033997f,
+ 0.964844f, 0.034088f, 0.963867f, 0.034241f, 0.963379f, 0.034393f, 0.962402f, 0.034546f,
+ 0.960938f, 0.034698f, 0.958496f, 0.034851f, 0.957520f, 0.034973f, 0.954102f, 0.035034f,
+ 0.951172f, 0.035034f, 0.947754f, 0.034943f, 0.942871f, 0.034821f, 0.937988f, 0.034576f,
+ 0.932129f, 0.034180f, 0.926270f, 0.033722f, 0.918945f, 0.033142f, 0.911133f, 0.032410f,
+ 0.902832f, 0.031616f, 0.894531f, 0.030685f, 0.885254f, 0.029694f, 0.876465f, 0.028641f,
+ 0.866699f, 0.027512f, 0.856445f, 0.026337f, 0.846191f, 0.025146f, 0.835449f, 0.023926f,
+ 0.825195f, 0.022720f, 0.814453f, 0.021515f, 0.803711f, 0.020340f, 0.792480f, 0.019165f,
+ 0.781250f, 0.018051f, 0.770020f, 0.016968f, 0.758789f, 0.015915f, 0.747070f, 0.014931f,
+ 0.735352f, 0.013977f, 0.723145f, 0.013069f, 0.710938f, 0.012215f, 0.698730f, 0.011398f,
+ 0.686035f, 0.010635f, 0.673340f, 0.009918f, 0.660156f, 0.009239f, 0.646484f, 0.008598f,
+ 0.633301f, 0.008003f, 0.619141f, 0.007446f, 0.605469f, 0.006927f, 0.591309f, 0.006439f,
+ 0.576660f, 0.005985f, 0.562500f, 0.005562f, 0.547852f, 0.005165f, 0.533203f, 0.004795f,
+ 0.518066f, 0.004456f, 0.503418f, 0.004135f, 0.488770f, 0.003841f, 0.474121f, 0.003565f,
+ 0.459229f, 0.003311f, 0.444580f, 0.003073f, 0.430176f, 0.002853f, 0.415771f, 0.002647f,
+ 0.960449f, 0.039276f, 0.960449f, 0.039276f, 0.960449f, 0.039276f, 0.960449f, 0.039307f,
+ 0.960449f, 0.039337f, 0.959961f, 0.039368f, 0.959961f, 0.039429f, 0.959961f, 0.039520f,
+ 0.959473f, 0.039612f, 0.958984f, 0.039764f, 0.958008f, 0.039886f, 0.956543f, 0.040009f,
+ 0.955566f, 0.040131f, 0.953125f, 0.040253f, 0.951172f, 0.040314f, 0.948242f, 0.040283f,
+ 0.945801f, 0.040222f, 0.940918f, 0.040039f, 0.936523f, 0.039764f, 0.931152f, 0.039368f,
+ 0.926270f, 0.038879f, 0.919434f, 0.038208f, 0.913086f, 0.037445f, 0.905273f, 0.036530f,
+ 0.897461f, 0.035522f, 0.888184f, 0.034393f, 0.879395f, 0.033173f, 0.870117f, 0.031891f,
+ 0.860352f, 0.030563f, 0.850586f, 0.029190f, 0.840820f, 0.027802f, 0.830566f, 0.026398f,
+ 0.820312f, 0.025009f, 0.810059f, 0.023636f, 0.799805f, 0.022308f, 0.789062f, 0.020996f,
+ 0.778809f, 0.019730f, 0.767578f, 0.018524f, 0.756348f, 0.017365f, 0.745605f, 0.016251f,
+ 0.733887f, 0.015213f, 0.722656f, 0.014206f, 0.710938f, 0.013260f, 0.698730f, 0.012367f,
+ 0.686523f, 0.011536f, 0.673828f, 0.010742f, 0.661133f, 0.010002f, 0.647949f, 0.009308f,
+ 0.634766f, 0.008659f, 0.621094f, 0.008057f, 0.607422f, 0.007488f, 0.593262f, 0.006958f,
+ 0.579102f, 0.006466f, 0.564941f, 0.006004f, 0.550781f, 0.005577f, 0.536133f, 0.005177f,
+ 0.521484f, 0.004807f, 0.506836f, 0.004463f, 0.492432f, 0.004143f, 0.477783f, 0.003847f,
+ 0.463135f, 0.003571f, 0.448730f, 0.003315f, 0.434082f, 0.003077f, 0.419922f, 0.002857f,
+ 0.954102f, 0.045502f, 0.954102f, 0.045502f, 0.954102f, 0.045502f, 0.954102f, 0.045532f,
+ 0.954102f, 0.045563f, 0.954102f, 0.045593f, 0.953613f, 0.045654f, 0.953613f, 0.045715f,
+ 0.953125f, 0.045868f, 0.952148f, 0.045990f, 0.951660f, 0.046082f, 0.950195f, 0.046143f,
+ 0.948242f, 0.046265f, 0.946777f, 0.046265f, 0.943848f, 0.046265f, 0.941895f, 0.046204f,
+ 0.938477f, 0.046021f, 0.935059f, 0.045685f, 0.929199f, 0.045258f, 0.925293f, 0.044708f,
+ 0.919434f, 0.044006f, 0.912109f, 0.043121f, 0.905273f, 0.042145f, 0.897949f, 0.041016f,
+ 0.890137f, 0.039734f, 0.881348f, 0.038391f, 0.872559f, 0.036926f, 0.863770f, 0.035431f,
+ 0.854004f, 0.033813f, 0.844727f, 0.032227f, 0.835449f, 0.030640f, 0.825195f, 0.029037f,
+ 0.815430f, 0.027451f, 0.806152f, 0.025909f, 0.795898f, 0.024399f, 0.785645f, 0.022934f,
+ 0.775391f, 0.021530f, 0.765137f, 0.020187f, 0.754883f, 0.018890f, 0.743652f, 0.017670f,
+ 0.732910f, 0.016510f, 0.721680f, 0.015411f, 0.710449f, 0.014374f, 0.698730f, 0.013405f,
+ 0.686523f, 0.012482f, 0.674316f, 0.011620f, 0.662109f, 0.010811f, 0.649414f, 0.010063f,
+ 0.636230f, 0.009354f, 0.623047f, 0.008698f, 0.609375f, 0.008080f, 0.595703f, 0.007507f,
+ 0.582031f, 0.006973f, 0.567871f, 0.006477f, 0.553711f, 0.006016f, 0.539551f, 0.005585f,
+ 0.524902f, 0.005180f, 0.510254f, 0.004810f, 0.496094f, 0.004463f, 0.481689f, 0.004147f,
+ 0.467041f, 0.003847f, 0.452637f, 0.003571f, 0.438232f, 0.003315f, 0.424072f, 0.003077f,
+ 0.947266f, 0.052490f, 0.947266f, 0.052490f, 0.947266f, 0.052490f, 0.947266f, 0.052521f,
+ 0.947266f, 0.052551f, 0.946777f, 0.052582f, 0.946777f, 0.052612f, 0.946289f, 0.052734f,
+ 0.945801f, 0.052795f, 0.945312f, 0.052887f, 0.944336f, 0.052948f, 0.942871f, 0.053040f,
+ 0.941406f, 0.053009f, 0.939941f, 0.053009f, 0.937012f, 0.052917f, 0.934570f, 0.052704f,
+ 0.931641f, 0.052399f, 0.926758f, 0.051971f, 0.922852f, 0.051331f, 0.917480f, 0.050568f,
+ 0.911133f, 0.049622f, 0.904297f, 0.048523f, 0.898438f, 0.047272f, 0.890137f, 0.045868f,
+ 0.882812f, 0.044312f, 0.874512f, 0.042694f, 0.865723f, 0.040955f, 0.856934f, 0.039154f,
+ 0.847656f, 0.037354f, 0.838867f, 0.035522f, 0.829590f, 0.033661f, 0.820312f, 0.031830f,
+ 0.811035f, 0.030060f, 0.801270f, 0.028305f, 0.791992f, 0.026611f, 0.782227f, 0.024994f,
+ 0.772461f, 0.023422f, 0.762695f, 0.021927f, 0.752441f, 0.020508f, 0.742188f, 0.019165f,
+ 0.731445f, 0.017883f, 0.721191f, 0.016678f, 0.709961f, 0.015556f, 0.698730f, 0.014488f,
+ 0.687012f, 0.013489f, 0.675293f, 0.012550f, 0.663086f, 0.011673f, 0.650879f, 0.010849f,
+ 0.638184f, 0.010086f, 0.625000f, 0.009369f, 0.611816f, 0.008705f, 0.598145f, 0.008087f,
+ 0.584961f, 0.007511f, 0.570801f, 0.006977f, 0.556641f, 0.006474f, 0.542480f, 0.006012f,
+ 0.528320f, 0.005581f, 0.514160f, 0.005180f, 0.499756f, 0.004807f, 0.485596f, 0.004459f,
+ 0.471191f, 0.004139f, 0.456787f, 0.003843f, 0.442383f, 0.003569f, 0.428467f, 0.003313f,
+ 0.939453f, 0.060333f, 0.939453f, 0.060333f, 0.939453f, 0.060333f, 0.939453f, 0.060333f,
+ 0.939453f, 0.060394f, 0.938965f, 0.060394f, 0.938965f, 0.060455f, 0.938477f, 0.060516f,
+ 0.937988f, 0.060577f, 0.937500f, 0.060638f, 0.936035f, 0.060669f, 0.935547f, 0.060669f,
+ 0.933594f, 0.060608f, 0.931641f, 0.060516f, 0.929688f, 0.060272f, 0.927246f, 0.059967f,
+ 0.922363f, 0.059448f, 0.918945f, 0.058868f, 0.914062f, 0.057953f, 0.908691f, 0.056946f,
+ 0.902832f, 0.055786f, 0.897461f, 0.054382f, 0.890137f, 0.052826f, 0.882324f, 0.051117f,
+ 0.874023f, 0.049255f, 0.866211f, 0.047302f, 0.858398f, 0.045288f, 0.849609f, 0.043213f,
+ 0.840820f, 0.041107f, 0.832031f, 0.038971f, 0.823730f, 0.036896f, 0.814453f, 0.034821f,
+ 0.806152f, 0.032806f, 0.796875f, 0.030853f, 0.788086f, 0.028961f, 0.778809f, 0.027161f,
+ 0.769531f, 0.025421f, 0.760254f, 0.023788f, 0.750488f, 0.022217f, 0.740723f, 0.020737f,
+ 0.730957f, 0.019333f, 0.720703f, 0.018021f, 0.709961f, 0.016785f, 0.698730f, 0.015625f,
+ 0.687500f, 0.014549f, 0.676270f, 0.013535f, 0.664551f, 0.012573f, 0.652344f, 0.011688f,
+ 0.640137f, 0.010864f, 0.627441f, 0.010086f, 0.614258f, 0.009369f, 0.601074f, 0.008698f,
+ 0.587402f, 0.008080f, 0.573730f, 0.007500f, 0.560059f, 0.006962f, 0.545898f, 0.006462f,
+ 0.531738f, 0.006001f, 0.517578f, 0.005569f, 0.503418f, 0.005165f, 0.489502f, 0.004795f,
+ 0.475098f, 0.004452f, 0.460938f, 0.004131f, 0.446777f, 0.003838f, 0.432861f, 0.003563f,
+ 0.930664f, 0.069031f, 0.930664f, 0.069031f, 0.930664f, 0.069031f, 0.930664f, 0.069031f,
+ 0.930664f, 0.069092f, 0.930664f, 0.069092f, 0.930176f, 0.069214f, 0.929688f, 0.069153f,
+ 0.929199f, 0.069214f, 0.929199f, 0.069275f, 0.927246f, 0.069214f, 0.926758f, 0.069153f,
+ 0.925293f, 0.069031f, 0.923340f, 0.068787f, 0.920410f, 0.068420f, 0.917480f, 0.067932f,
+ 0.914551f, 0.067261f, 0.911133f, 0.066345f, 0.905273f, 0.065247f, 0.900391f, 0.063965f,
+ 0.894043f, 0.062469f, 0.888184f, 0.060699f, 0.880859f, 0.058807f, 0.873535f, 0.056763f,
+ 0.866211f, 0.054565f, 0.858887f, 0.052277f, 0.850586f, 0.049896f, 0.841797f, 0.047485f,
+ 0.833496f, 0.045105f, 0.825684f, 0.042664f, 0.817383f, 0.040283f, 0.809082f, 0.037964f,
+ 0.800781f, 0.035706f, 0.792480f, 0.033539f, 0.784180f, 0.031433f, 0.775391f, 0.029449f,
+ 0.766602f, 0.027542f, 0.757812f, 0.025726f, 0.748535f, 0.024017f, 0.739258f, 0.022400f,
+ 0.729980f, 0.020874f, 0.719727f, 0.019440f, 0.709961f, 0.018097f, 0.699219f, 0.016830f,
+ 0.688477f, 0.015656f, 0.677246f, 0.014557f, 0.665527f, 0.013527f, 0.653809f, 0.012573f,
+ 0.641602f, 0.011681f, 0.629395f, 0.010841f, 0.616699f, 0.010071f, 0.603516f, 0.009346f,
+ 0.590332f, 0.008682f, 0.577148f, 0.008057f, 0.563477f, 0.007481f, 0.549316f, 0.006943f,
+ 0.535645f, 0.006443f, 0.521484f, 0.005978f, 0.507324f, 0.005550f, 0.493408f, 0.005150f,
+ 0.479248f, 0.004780f, 0.465332f, 0.004436f, 0.451172f, 0.004124f, 0.437256f, 0.003828f,
+ 0.920898f, 0.078735f, 0.920898f, 0.078735f, 0.920898f, 0.078735f, 0.920898f, 0.078735f,
+ 0.920898f, 0.078796f, 0.920898f, 0.078796f, 0.920410f, 0.078796f, 0.919922f, 0.078857f,
+ 0.919922f, 0.078857f, 0.918945f, 0.078796f, 0.917480f, 0.078735f, 0.916992f, 0.078613f,
+ 0.915039f, 0.078308f, 0.913086f, 0.077942f, 0.910645f, 0.077454f, 0.908691f, 0.076660f,
+ 0.905273f, 0.075745f, 0.899902f, 0.074585f, 0.895996f, 0.073181f, 0.889648f, 0.071533f,
+ 0.883789f, 0.069641f, 0.877930f, 0.067566f, 0.872070f, 0.065247f, 0.864258f, 0.062805f,
+ 0.856934f, 0.060242f, 0.849121f, 0.057556f, 0.841797f, 0.054810f, 0.833984f, 0.052063f,
+ 0.827148f, 0.049316f, 0.818848f, 0.046570f, 0.811035f, 0.043915f, 0.803223f, 0.041290f,
+ 0.795898f, 0.038788f, 0.788086f, 0.036377f, 0.779785f, 0.034058f, 0.771973f, 0.031830f,
+ 0.763672f, 0.029755f, 0.755371f, 0.027771f, 0.747070f, 0.025894f, 0.738281f, 0.024139f,
+ 0.729004f, 0.022476f, 0.719238f, 0.020935f, 0.709473f, 0.019470f, 0.699707f, 0.018097f,
+ 0.688965f, 0.016830f, 0.678223f, 0.015640f, 0.666992f, 0.014534f, 0.655762f, 0.013496f,
+ 0.643555f, 0.012535f, 0.631348f, 0.011642f, 0.619141f, 0.010803f, 0.606445f, 0.010033f,
+ 0.593262f, 0.009308f, 0.580078f, 0.008644f, 0.566406f, 0.008018f, 0.553223f, 0.007446f,
+ 0.539062f, 0.006908f, 0.525391f, 0.006413f, 0.511230f, 0.005951f, 0.497559f, 0.005527f,
+ 0.483643f, 0.005131f, 0.469482f, 0.004765f, 0.455566f, 0.004421f, 0.441650f, 0.004108f,
+ 0.910156f, 0.089539f, 0.910156f, 0.089539f, 0.910156f, 0.089539f, 0.910156f, 0.089539f,
+ 0.910156f, 0.089539f, 0.909668f, 0.089539f, 0.909668f, 0.089539f, 0.909180f, 0.089539f,
+ 0.908691f, 0.089478f, 0.907715f, 0.089417f, 0.907227f, 0.089233f, 0.905762f, 0.088989f,
+ 0.904297f, 0.088562f, 0.902832f, 0.088013f, 0.900391f, 0.087280f, 0.896973f, 0.086243f,
+ 0.895020f, 0.085083f, 0.889160f, 0.083557f, 0.884766f, 0.081787f, 0.878906f, 0.079712f,
+ 0.874512f, 0.077393f, 0.867676f, 0.074951f, 0.860840f, 0.072205f, 0.854492f, 0.069275f,
+ 0.848145f, 0.066223f, 0.840820f, 0.063171f, 0.833008f, 0.060059f, 0.826172f, 0.056885f,
+ 0.819336f, 0.053741f, 0.812012f, 0.050690f, 0.804688f, 0.047699f, 0.797852f, 0.044800f,
+ 0.790527f, 0.042023f, 0.783691f, 0.039337f, 0.776367f, 0.036804f, 0.768555f, 0.034393f,
+ 0.761230f, 0.032074f, 0.753418f, 0.029922f, 0.745117f, 0.027893f, 0.736816f, 0.025970f,
+ 0.728516f, 0.024170f, 0.719238f, 0.022491f, 0.709961f, 0.020905f, 0.700195f, 0.019440f,
+ 0.689941f, 0.018066f, 0.679688f, 0.016785f, 0.668457f, 0.015587f, 0.657227f, 0.014473f,
+ 0.645996f, 0.013443f, 0.633789f, 0.012474f, 0.621582f, 0.011581f, 0.609375f, 0.010750f,
+ 0.596191f, 0.009972f, 0.583496f, 0.009262f, 0.569824f, 0.008591f, 0.556641f, 0.007973f,
+ 0.542969f, 0.007404f, 0.529297f, 0.006874f, 0.515625f, 0.006378f, 0.501465f, 0.005920f,
+ 0.487793f, 0.005501f, 0.474121f, 0.005108f, 0.460205f, 0.004742f, 0.446289f, 0.004406f,
+ 0.898438f, 0.101440f, 0.898438f, 0.101440f, 0.898438f, 0.101440f, 0.898438f, 0.101440f,
+ 0.897949f, 0.101440f, 0.897949f, 0.101440f, 0.897461f, 0.101440f, 0.896973f, 0.101379f,
+ 0.896973f, 0.101318f, 0.895996f, 0.101135f, 0.895508f, 0.100830f, 0.894043f, 0.100464f,
+ 0.893066f, 0.099854f, 0.890625f, 0.099121f, 0.888184f, 0.098083f, 0.885254f, 0.096802f,
+ 0.882324f, 0.095215f, 0.878418f, 0.093323f, 0.872559f, 0.091125f, 0.869629f, 0.088623f,
+ 0.862793f, 0.085815f, 0.855957f, 0.082764f, 0.850098f, 0.079590f, 0.844727f, 0.076172f,
+ 0.837402f, 0.072693f, 0.831055f, 0.069092f, 0.824219f, 0.065491f, 0.817871f, 0.061981f,
+ 0.811035f, 0.058472f, 0.804688f, 0.055023f, 0.797852f, 0.051697f, 0.791992f, 0.048492f,
+ 0.785645f, 0.045410f, 0.778809f, 0.042480f, 0.771973f, 0.039673f, 0.765625f, 0.037018f,
+ 0.758789f, 0.034515f, 0.750977f, 0.032166f, 0.743652f, 0.029968f, 0.735840f, 0.027878f,
+ 0.727539f, 0.025940f, 0.718750f, 0.024124f, 0.709961f, 0.022430f, 0.700684f, 0.020844f,
+ 0.690918f, 0.019363f, 0.680664f, 0.017975f, 0.670410f, 0.016693f, 0.659180f, 0.015495f,
+ 0.647949f, 0.014389f, 0.636230f, 0.013359f, 0.624512f, 0.012398f, 0.611816f, 0.011505f,
+ 0.599609f, 0.010681f, 0.586426f, 0.009911f, 0.573730f, 0.009201f, 0.560547f, 0.008537f,
+ 0.546875f, 0.007927f, 0.533203f, 0.007355f, 0.519531f, 0.006828f, 0.505859f, 0.006340f,
+ 0.492432f, 0.005890f, 0.478516f, 0.005470f, 0.464844f, 0.005077f, 0.450928f, 0.004719f,
+ 0.885254f, 0.114624f, 0.885254f, 0.114624f, 0.885254f, 0.114624f, 0.885254f, 0.114624f,
+ 0.884766f, 0.114624f, 0.884766f, 0.114563f, 0.884766f, 0.114502f, 0.884277f, 0.114380f,
+ 0.883789f, 0.114258f, 0.883301f, 0.114014f, 0.882324f, 0.113525f, 0.881348f, 0.112976f,
+ 0.879395f, 0.112183f, 0.877441f, 0.111145f, 0.875977f, 0.109802f, 0.872559f, 0.108215f,
+ 0.869141f, 0.106201f, 0.865723f, 0.103821f, 0.860352f, 0.101196f, 0.854492f, 0.098145f,
+ 0.850586f, 0.094849f, 0.845215f, 0.091187f, 0.838379f, 0.087463f, 0.833496f, 0.083496f,
+ 0.826660f, 0.079468f, 0.820801f, 0.075378f, 0.814453f, 0.071289f, 0.809082f, 0.067322f,
+ 0.803711f, 0.063354f, 0.797363f, 0.059540f, 0.791992f, 0.055878f, 0.786133f, 0.052338f,
+ 0.780762f, 0.048950f, 0.774414f, 0.045746f, 0.768555f, 0.042664f, 0.762207f, 0.039795f,
+ 0.755859f, 0.037079f, 0.749023f, 0.034546f, 0.741699f, 0.032135f, 0.734863f, 0.029892f,
+ 0.727051f, 0.027802f, 0.718750f, 0.025833f, 0.710449f, 0.024002f, 0.701172f, 0.022293f,
+ 0.691895f, 0.020706f, 0.682129f, 0.019226f, 0.671875f, 0.017853f, 0.661133f, 0.016571f,
+ 0.650391f, 0.015381f, 0.639160f, 0.014282f, 0.626953f, 0.013252f, 0.615234f, 0.012299f,
+ 0.602539f, 0.011414f, 0.590332f, 0.010597f, 0.577148f, 0.009834f, 0.563965f, 0.009132f,
+ 0.550781f, 0.008476f, 0.537598f, 0.007866f, 0.523926f, 0.007309f, 0.510254f, 0.006786f,
+ 0.496826f, 0.006306f, 0.483154f, 0.005856f, 0.469482f, 0.005440f, 0.455811f, 0.005054f,
+ 0.870605f, 0.129028f, 0.870605f, 0.129028f, 0.870605f, 0.129028f, 0.870605f, 0.129028f,
+ 0.870605f, 0.129028f, 0.870605f, 0.129028f, 0.870117f, 0.128906f, 0.870117f, 0.128784f,
+ 0.869629f, 0.128540f, 0.869141f, 0.128052f, 0.868164f, 0.127563f, 0.867188f, 0.126709f,
+ 0.865723f, 0.125732f, 0.863281f, 0.124329f, 0.862305f, 0.122742f, 0.858887f, 0.120544f,
+ 0.854980f, 0.118103f, 0.850098f, 0.115173f, 0.847168f, 0.111938f, 0.843750f, 0.108276f,
+ 0.836426f, 0.104309f, 0.832031f, 0.100159f, 0.827148f, 0.095764f, 0.821289f, 0.091187f,
+ 0.815918f, 0.086609f, 0.810547f, 0.081970f, 0.806152f, 0.077393f, 0.800781f, 0.072937f,
+ 0.795410f, 0.068542f, 0.790039f, 0.064270f, 0.785645f, 0.060242f, 0.780762f, 0.056335f,
+ 0.775391f, 0.052643f, 0.770020f, 0.049133f, 0.765137f, 0.045807f, 0.759766f, 0.042694f,
+ 0.753906f, 0.039734f, 0.747559f, 0.036987f, 0.740723f, 0.034393f, 0.733887f, 0.031982f,
+ 0.726562f, 0.029739f, 0.719238f, 0.027618f, 0.710449f, 0.025650f, 0.702148f, 0.023834f,
+ 0.692871f, 0.022125f, 0.683594f, 0.020538f, 0.673828f, 0.019058f, 0.663574f, 0.017685f,
+ 0.652832f, 0.016418f, 0.641602f, 0.015244f, 0.629883f, 0.014153f, 0.618164f, 0.013138f,
+ 0.605957f, 0.012192f, 0.593750f, 0.011314f, 0.581055f, 0.010506f, 0.567871f, 0.009750f,
+ 0.555176f, 0.009056f, 0.541504f, 0.008408f, 0.528320f, 0.007809f, 0.514648f, 0.007252f,
+ 0.501465f, 0.006741f, 0.487793f, 0.006260f, 0.474365f, 0.005817f, 0.460938f, 0.005409f,
+ 0.854492f, 0.145020f, 0.854492f, 0.145020f, 0.854492f, 0.145020f, 0.854492f, 0.145020f,
+ 0.854492f, 0.144897f, 0.854492f, 0.144897f, 0.854004f, 0.144653f, 0.854492f, 0.144531f,
+ 0.854004f, 0.144165f, 0.853027f, 0.143555f, 0.852051f, 0.142822f, 0.851074f, 0.141724f,
+ 0.850586f, 0.140503f, 0.848145f, 0.138672f, 0.846191f, 0.136475f, 0.843262f, 0.133911f,
+ 0.839844f, 0.130859f, 0.835449f, 0.127319f, 0.832031f, 0.123474f, 0.828613f, 0.119141f,
+ 0.823242f, 0.114502f, 0.819824f, 0.109558f, 0.813477f, 0.104431f, 0.809570f, 0.099304f,
+ 0.804199f, 0.094055f, 0.799316f, 0.088867f, 0.794922f, 0.083740f, 0.791992f, 0.078735f,
+ 0.786621f, 0.073914f, 0.783203f, 0.069214f, 0.779297f, 0.064758f, 0.774902f, 0.060516f,
+ 0.770508f, 0.056488f, 0.765625f, 0.052673f, 0.761230f, 0.049072f, 0.756348f, 0.045715f,
+ 0.750977f, 0.042511f, 0.745605f, 0.039551f, 0.739746f, 0.036774f, 0.733398f, 0.034180f,
+ 0.726562f, 0.031738f, 0.719238f, 0.029495f, 0.711426f, 0.027390f, 0.703125f, 0.025421f,
+ 0.694336f, 0.023605f, 0.685059f, 0.021912f, 0.675781f, 0.020340f, 0.665527f, 0.018875f,
+ 0.655273f, 0.017517f, 0.644043f, 0.016251f, 0.632812f, 0.015091f, 0.621582f, 0.014008f,
+ 0.609375f, 0.013000f, 0.597168f, 0.012070f, 0.584473f, 0.011200f, 0.571777f, 0.010406f,
+ 0.559082f, 0.009659f, 0.545898f, 0.008972f, 0.532715f, 0.008339f, 0.519531f, 0.007748f,
+ 0.505859f, 0.007198f, 0.492676f, 0.006691f, 0.479248f, 0.006218f, 0.465820f, 0.005783f,
+ 0.837402f, 0.162476f, 0.837402f, 0.162476f, 0.837402f, 0.162476f, 0.837402f, 0.162354f,
+ 0.837402f, 0.162354f, 0.836914f, 0.162231f, 0.836914f, 0.161987f, 0.836426f, 0.161743f,
+ 0.836426f, 0.161133f, 0.835449f, 0.160522f, 0.835449f, 0.159546f, 0.834473f, 0.158203f,
+ 0.833496f, 0.156372f, 0.831055f, 0.154175f, 0.830078f, 0.151489f, 0.826660f, 0.148315f,
+ 0.823242f, 0.144531f, 0.821289f, 0.140381f, 0.817383f, 0.135620f, 0.812012f, 0.130615f,
+ 0.810547f, 0.125122f, 0.805176f, 0.119507f, 0.800293f, 0.113647f, 0.797852f, 0.107788f,
+ 0.792480f, 0.101868f, 0.788574f, 0.096008f, 0.785156f, 0.090332f, 0.782715f, 0.084839f,
+ 0.779297f, 0.079468f, 0.774902f, 0.074341f, 0.772461f, 0.069458f, 0.769531f, 0.064819f,
+ 0.765137f, 0.060486f, 0.761719f, 0.056366f, 0.758301f, 0.052490f, 0.753418f, 0.048828f,
+ 0.749023f, 0.045410f, 0.743652f, 0.042206f, 0.738770f, 0.039215f, 0.732422f, 0.036438f,
+ 0.726074f, 0.033844f, 0.719238f, 0.031433f, 0.711914f, 0.029190f, 0.704102f, 0.027100f,
+ 0.695801f, 0.025146f, 0.687012f, 0.023346f, 0.677734f, 0.021667f, 0.667969f, 0.020111f,
+ 0.657715f, 0.018646f, 0.646973f, 0.017319f, 0.636230f, 0.016068f, 0.624512f, 0.014923f,
+ 0.612793f, 0.013855f, 0.601074f, 0.012863f, 0.588379f, 0.011948f, 0.576172f, 0.011093f,
+ 0.563477f, 0.010300f, 0.550293f, 0.009567f, 0.537109f, 0.008896f, 0.523926f, 0.008263f,
+ 0.510742f, 0.007687f, 0.497559f, 0.007145f, 0.484375f, 0.006645f, 0.470947f, 0.006180f,
+ 0.818359f, 0.181519f, 0.818359f, 0.181519f, 0.818359f, 0.181519f, 0.817871f, 0.181519f,
+ 0.817871f, 0.181396f, 0.817871f, 0.181274f, 0.817871f, 0.181030f, 0.817871f, 0.180542f,
+ 0.817871f, 0.179932f, 0.817383f, 0.178955f, 0.816406f, 0.177612f, 0.815918f, 0.175903f,
+ 0.814941f, 0.173584f, 0.812500f, 0.170898f, 0.811035f, 0.167603f, 0.808594f, 0.163696f,
+ 0.805664f, 0.159180f, 0.802246f, 0.154175f, 0.799805f, 0.148560f, 0.796875f, 0.142700f,
+ 0.792480f, 0.136353f, 0.789551f, 0.129883f, 0.787598f, 0.123230f, 0.782227f, 0.116577f,
+ 0.780273f, 0.109985f, 0.777344f, 0.103516f, 0.774414f, 0.097168f, 0.771973f, 0.091125f,
+ 0.770508f, 0.085205f, 0.767578f, 0.079651f, 0.765625f, 0.074341f, 0.763184f, 0.069336f,
+ 0.760254f, 0.064636f, 0.757812f, 0.060181f, 0.754395f, 0.056000f, 0.750977f, 0.052063f,
+ 0.747559f, 0.048431f, 0.742188f, 0.044983f, 0.737793f, 0.041779f, 0.732422f, 0.038818f,
+ 0.726074f, 0.036041f, 0.719727f, 0.033447f, 0.712891f, 0.031052f, 0.705566f, 0.028824f,
+ 0.697266f, 0.026749f, 0.688965f, 0.024826f, 0.679688f, 0.023041f, 0.670410f, 0.021393f,
+ 0.660645f, 0.019852f, 0.649902f, 0.018433f, 0.639160f, 0.017105f, 0.627930f, 0.015869f,
+ 0.616211f, 0.014748f, 0.604492f, 0.013687f, 0.592773f, 0.012718f, 0.580078f, 0.011818f,
+ 0.567871f, 0.010979f, 0.554688f, 0.010201f, 0.541992f, 0.009483f, 0.528809f, 0.008812f,
+ 0.515625f, 0.008194f, 0.502441f, 0.007626f, 0.489502f, 0.007088f, 0.476318f, 0.006599f,
+ 0.797363f, 0.202393f, 0.797363f, 0.202393f, 0.797363f, 0.202393f, 0.797363f, 0.202393f,
+ 0.797363f, 0.202148f, 0.797363f, 0.202026f, 0.797363f, 0.201660f, 0.797363f, 0.201050f,
+ 0.796875f, 0.200195f, 0.796875f, 0.198975f, 0.796387f, 0.197266f, 0.795898f, 0.195068f,
+ 0.794922f, 0.192261f, 0.792969f, 0.188843f, 0.792480f, 0.184937f, 0.789551f, 0.180298f,
+ 0.787598f, 0.174927f, 0.785645f, 0.168823f, 0.782715f, 0.162231f, 0.779297f, 0.155273f,
+ 0.775879f, 0.148071f, 0.775391f, 0.140747f, 0.772461f, 0.133179f, 0.770508f, 0.125732f,
+ 0.767578f, 0.118347f, 0.766113f, 0.111206f, 0.764648f, 0.104248f, 0.763184f, 0.097595f,
+ 0.762695f, 0.091187f, 0.761719f, 0.085144f, 0.759277f, 0.079407f, 0.758301f, 0.073975f,
+ 0.755859f, 0.068909f, 0.754395f, 0.064087f, 0.751465f, 0.059631f, 0.748535f, 0.055450f,
+ 0.745117f, 0.051514f, 0.741211f, 0.047852f, 0.737305f, 0.044434f, 0.731934f, 0.041260f,
+ 0.726562f, 0.038300f, 0.720215f, 0.035553f, 0.713867f, 0.032990f, 0.706543f, 0.030624f,
+ 0.699219f, 0.028427f, 0.690918f, 0.026382f, 0.682129f, 0.024475f, 0.672852f, 0.022720f,
+ 0.663086f, 0.021088f, 0.652832f, 0.019577f, 0.642578f, 0.018173f, 0.631348f, 0.016876f,
+ 0.620117f, 0.015671f, 0.608398f, 0.014565f, 0.596680f, 0.013535f, 0.584473f, 0.012573f,
+ 0.572266f, 0.011681f, 0.559570f, 0.010857f, 0.546875f, 0.010101f, 0.533691f, 0.009392f,
+ 0.520996f, 0.008736f, 0.507812f, 0.008125f, 0.494629f, 0.007565f, 0.481689f, 0.007042f,
+ 0.774414f, 0.225098f, 0.774414f, 0.225098f, 0.774414f, 0.225098f, 0.774414f, 0.225098f,
+ 0.774414f, 0.224854f, 0.774902f, 0.224609f, 0.774414f, 0.224121f, 0.774414f, 0.223389f,
+ 0.774414f, 0.222290f, 0.773926f, 0.220581f, 0.773926f, 0.218628f, 0.773926f, 0.215942f,
+ 0.773438f, 0.212524f, 0.772461f, 0.208374f, 0.771484f, 0.203491f, 0.770508f, 0.197754f,
+ 0.769043f, 0.191284f, 0.766113f, 0.184204f, 0.763672f, 0.176514f, 0.760742f, 0.168457f,
+ 0.760742f, 0.160278f, 0.757812f, 0.151855f, 0.757812f, 0.143433f, 0.756836f, 0.135132f,
+ 0.754395f, 0.126953f, 0.755371f, 0.119141f, 0.755371f, 0.111511f, 0.754395f, 0.104309f,
+ 0.753418f, 0.097351f, 0.754395f, 0.090820f, 0.753906f, 0.084595f, 0.752441f, 0.078796f,
+ 0.751465f, 0.073303f, 0.750000f, 0.068176f, 0.748535f, 0.063354f, 0.746094f, 0.058899f,
+ 0.743164f, 0.054718f, 0.740234f, 0.050812f, 0.736816f, 0.047150f, 0.731934f, 0.043793f,
+ 0.727051f, 0.040649f, 0.721191f, 0.037720f, 0.714844f, 0.035004f, 0.708008f, 0.032501f,
+ 0.700684f, 0.030167f, 0.692871f, 0.027985f, 0.684570f, 0.025986f, 0.675781f, 0.024124f,
+ 0.666016f, 0.022385f, 0.656250f, 0.020782f, 0.645996f, 0.019302f, 0.635254f, 0.017929f,
+ 0.624023f, 0.016647f, 0.612793f, 0.015480f, 0.601074f, 0.014381f, 0.588867f, 0.013367f,
+ 0.576660f, 0.012428f, 0.563965f, 0.011559f, 0.551270f, 0.010750f, 0.539062f, 0.010002f,
+ 0.525879f, 0.009308f, 0.513184f, 0.008659f, 0.500000f, 0.008064f, 0.487061f, 0.007511f,
+ 0.750000f, 0.249878f, 0.749512f, 0.249878f, 0.750000f, 0.249878f, 0.750000f, 0.249756f,
+ 0.750000f, 0.249512f, 0.750000f, 0.249146f, 0.750000f, 0.248413f, 0.750488f, 0.247559f,
+ 0.750488f, 0.246094f, 0.750488f, 0.244141f, 0.750488f, 0.241577f, 0.750488f, 0.238281f,
+ 0.748535f, 0.234009f, 0.749512f, 0.229004f, 0.749023f, 0.223022f, 0.747070f, 0.216309f,
+ 0.745117f, 0.208496f, 0.743164f, 0.200195f, 0.744629f, 0.191406f, 0.741211f, 0.182251f,
+ 0.741699f, 0.172852f, 0.740234f, 0.163330f, 0.742676f, 0.154053f, 0.741211f, 0.144775f,
+ 0.743652f, 0.135864f, 0.744629f, 0.127197f, 0.743164f, 0.118958f, 0.744629f, 0.111145f,
+ 0.745605f, 0.103638f, 0.746582f, 0.096558f, 0.748047f, 0.089966f, 0.747559f, 0.083679f,
+ 0.747559f, 0.077820f, 0.746582f, 0.072327f, 0.745605f, 0.067261f, 0.744629f, 0.062469f,
+ 0.742676f, 0.058014f, 0.739746f, 0.053864f, 0.735840f, 0.049988f, 0.731934f, 0.046417f,
+ 0.727539f, 0.043091f, 0.722168f, 0.039978f, 0.716309f, 0.037079f, 0.709473f, 0.034424f,
+ 0.702637f, 0.031952f, 0.695312f, 0.029663f, 0.687012f, 0.027542f, 0.678223f, 0.025558f,
+ 0.668945f, 0.023743f, 0.659180f, 0.022049f, 0.649414f, 0.020477f, 0.638672f, 0.019028f,
+ 0.627930f, 0.017670f, 0.616699f, 0.016434f, 0.604980f, 0.015274f, 0.593262f, 0.014198f,
+ 0.581055f, 0.013206f, 0.568848f, 0.012283f, 0.556641f, 0.011429f, 0.543945f, 0.010643f,
+ 0.531250f, 0.009903f, 0.518066f, 0.009224f, 0.505371f, 0.008591f, 0.492676f, 0.008003f,
+ 0.723145f, 0.276611f, 0.723145f, 0.276611f, 0.723145f, 0.276611f, 0.723145f, 0.276611f,
+ 0.723145f, 0.276123f, 0.723145f, 0.275635f, 0.723145f, 0.274902f, 0.723633f, 0.273682f,
+ 0.723633f, 0.271973f, 0.724121f, 0.269531f, 0.724609f, 0.266113f, 0.725098f, 0.262207f,
+ 0.725098f, 0.257080f, 0.724609f, 0.250732f, 0.722656f, 0.243652f, 0.725586f, 0.235474f,
+ 0.724121f, 0.226685f, 0.723145f, 0.216919f, 0.722656f, 0.206787f, 0.720703f, 0.196289f,
+ 0.723145f, 0.185791f, 0.723633f, 0.175171f, 0.724121f, 0.164795f, 0.728027f, 0.154663f,
+ 0.730469f, 0.144897f, 0.731934f, 0.135498f, 0.734863f, 0.126587f, 0.737305f, 0.118103f,
+ 0.739258f, 0.110107f, 0.739746f, 0.102478f, 0.741699f, 0.095398f, 0.743164f, 0.088745f,
+ 0.743652f, 0.082520f, 0.743652f, 0.076660f, 0.743652f, 0.071228f, 0.742676f, 0.066101f,
+ 0.741211f, 0.061401f, 0.739258f, 0.057007f, 0.735840f, 0.052887f, 0.732422f, 0.049103f,
+ 0.728516f, 0.045563f, 0.723145f, 0.042297f, 0.717773f, 0.039246f, 0.711914f, 0.036438f,
+ 0.704590f, 0.033813f, 0.697754f, 0.031403f, 0.689453f, 0.029160f, 0.681152f, 0.027069f,
+ 0.671875f, 0.025146f, 0.662598f, 0.023346f, 0.652832f, 0.021698f, 0.642578f, 0.020157f,
+ 0.631836f, 0.018738f, 0.621094f, 0.017426f, 0.609375f, 0.016205f, 0.597656f, 0.015076f,
+ 0.585938f, 0.014023f, 0.573730f, 0.013054f, 0.561523f, 0.012146f, 0.548828f, 0.011314f,
+ 0.536621f, 0.010536f, 0.523926f, 0.009811f, 0.511230f, 0.009148f, 0.498291f, 0.008530f,
+ 0.693848f, 0.305664f, 0.693848f, 0.305664f, 0.693848f, 0.305664f, 0.693848f, 0.305664f,
+ 0.693848f, 0.305176f, 0.694336f, 0.304443f, 0.694824f, 0.303467f, 0.695312f, 0.302002f,
+ 0.695312f, 0.299561f, 0.696289f, 0.296631f, 0.696777f, 0.292725f, 0.696777f, 0.287598f,
+ 0.697754f, 0.281250f, 0.698242f, 0.273926f, 0.698730f, 0.265137f, 0.697266f, 0.255615f,
+ 0.699707f, 0.245239f, 0.699707f, 0.234131f, 0.700195f, 0.222412f, 0.702637f, 0.210693f,
+ 0.705078f, 0.198853f, 0.708496f, 0.187134f, 0.708984f, 0.175781f, 0.715332f, 0.164673f,
+ 0.718750f, 0.154053f, 0.722168f, 0.143921f, 0.724121f, 0.134277f, 0.727539f, 0.125244f,
+ 0.731934f, 0.116638f, 0.733398f, 0.108582f, 0.736816f, 0.101013f, 0.738281f, 0.093872f,
+ 0.740234f, 0.087219f, 0.741699f, 0.081055f, 0.741211f, 0.075256f, 0.741211f, 0.069885f,
+ 0.740723f, 0.064880f, 0.738281f, 0.060211f, 0.736328f, 0.055908f, 0.732910f, 0.051849f,
+ 0.729004f, 0.048157f, 0.724609f, 0.044678f, 0.719727f, 0.041473f, 0.713379f, 0.038483f,
+ 0.707031f, 0.035736f, 0.699707f, 0.033173f, 0.692383f, 0.030823f, 0.684082f, 0.028625f,
+ 0.675293f, 0.026596f, 0.666016f, 0.024704f, 0.656738f, 0.022964f, 0.646484f, 0.021347f,
+ 0.636230f, 0.019852f, 0.625488f, 0.018463f, 0.614258f, 0.017181f, 0.602539f, 0.015976f,
+ 0.590820f, 0.014877f, 0.578613f, 0.013855f, 0.566895f, 0.012901f, 0.554688f, 0.012024f,
+ 0.541992f, 0.011200f, 0.529297f, 0.010437f, 0.516602f, 0.009735f, 0.503906f, 0.009079f,
+ 0.662598f, 0.337158f, 0.662598f, 0.337158f, 0.662598f, 0.337158f, 0.662598f, 0.336914f,
+ 0.662598f, 0.336670f, 0.663086f, 0.335938f, 0.663086f, 0.334473f, 0.664062f, 0.332520f,
+ 0.665039f, 0.329834f, 0.666016f, 0.325928f, 0.665527f, 0.320801f, 0.667969f, 0.314697f,
+ 0.667480f, 0.306885f, 0.669922f, 0.298096f, 0.669434f, 0.287842f, 0.671387f, 0.276367f,
+ 0.675781f, 0.264404f, 0.675781f, 0.251465f, 0.677734f, 0.238403f, 0.681152f, 0.225342f,
+ 0.686035f, 0.212036f, 0.690430f, 0.199219f, 0.694824f, 0.186768f, 0.700684f, 0.174805f,
+ 0.702637f, 0.163330f, 0.708008f, 0.152466f, 0.714844f, 0.142212f, 0.718750f, 0.132446f,
+ 0.724609f, 0.123291f, 0.728516f, 0.114685f, 0.731445f, 0.106628f, 0.734375f, 0.099121f,
+ 0.736816f, 0.092102f, 0.738770f, 0.085510f, 0.740723f, 0.079407f, 0.740234f, 0.073730f,
+ 0.739258f, 0.068420f, 0.738770f, 0.063538f, 0.736328f, 0.058960f, 0.734375f, 0.054718f,
+ 0.730469f, 0.050781f, 0.726562f, 0.047150f, 0.721191f, 0.043762f, 0.715332f, 0.040619f,
+ 0.709473f, 0.037720f, 0.702637f, 0.035034f, 0.695312f, 0.032532f, 0.687500f, 0.030243f,
+ 0.678711f, 0.028107f, 0.669922f, 0.026123f, 0.660645f, 0.024277f, 0.650391f, 0.022583f,
+ 0.640137f, 0.021011f, 0.629395f, 0.019547f, 0.618652f, 0.018188f, 0.607422f, 0.016937f,
+ 0.595703f, 0.015778f, 0.583984f, 0.014694f, 0.572266f, 0.013695f, 0.560059f, 0.012764f,
+ 0.547852f, 0.011902f, 0.535156f, 0.011101f, 0.522461f, 0.010353f, 0.510254f, 0.009666f,
+ 0.628418f, 0.371338f, 0.628418f, 0.371338f, 0.628418f, 0.371094f, 0.628418f, 0.371094f,
+ 0.628418f, 0.370361f, 0.629395f, 0.369385f, 0.629883f, 0.367920f, 0.630859f, 0.365234f,
+ 0.631836f, 0.361816f, 0.633301f, 0.357178f, 0.634766f, 0.350830f, 0.635742f, 0.343262f,
+ 0.638184f, 0.333984f, 0.640137f, 0.322998f, 0.641113f, 0.311035f, 0.645508f, 0.297852f,
+ 0.647949f, 0.283691f, 0.652344f, 0.269043f, 0.657227f, 0.254395f, 0.662598f, 0.239868f,
+ 0.669922f, 0.225464f, 0.673340f, 0.211426f, 0.680664f, 0.197876f, 0.685547f, 0.184937f,
+ 0.693359f, 0.172729f, 0.700684f, 0.161011f, 0.705566f, 0.150146f, 0.711426f, 0.139771f,
+ 0.718750f, 0.130005f, 0.722168f, 0.120911f, 0.727051f, 0.112427f, 0.732422f, 0.104431f,
+ 0.733887f, 0.097046f, 0.737305f, 0.090088f, 0.738770f, 0.083618f, 0.740234f, 0.077637f,
+ 0.739258f, 0.072083f, 0.738281f, 0.066895f, 0.736816f, 0.062073f, 0.734375f, 0.057648f,
+ 0.731934f, 0.053497f, 0.728027f, 0.049683f, 0.723145f, 0.046112f, 0.717773f, 0.042816f,
+ 0.712402f, 0.039764f, 0.705566f, 0.036957f, 0.698242f, 0.034332f, 0.690430f, 0.031891f,
+ 0.682617f, 0.029663f, 0.673340f, 0.027573f, 0.664551f, 0.025650f, 0.654785f, 0.023865f,
+ 0.644531f, 0.022202f, 0.634277f, 0.020676f, 0.623535f, 0.019257f, 0.612305f, 0.017929f,
+ 0.601074f, 0.016708f, 0.589355f, 0.015579f, 0.577637f, 0.014526f, 0.565430f, 0.013550f,
+ 0.553223f, 0.012642f, 0.541016f, 0.011787f, 0.528809f, 0.011009f, 0.516113f, 0.010277f,
+ 0.591309f, 0.407959f, 0.591797f, 0.407959f, 0.591797f, 0.407959f, 0.591797f, 0.407471f,
+ 0.592285f, 0.406982f, 0.592773f, 0.405762f, 0.593750f, 0.403564f, 0.594727f, 0.400391f,
+ 0.596680f, 0.396240f, 0.598145f, 0.390137f, 0.600098f, 0.382568f, 0.602539f, 0.373047f,
+ 0.604980f, 0.361816f, 0.606934f, 0.348877f, 0.611816f, 0.334473f, 0.616699f, 0.319336f,
+ 0.620605f, 0.302979f, 0.627930f, 0.286865f, 0.634277f, 0.270508f, 0.638672f, 0.254150f,
+ 0.647949f, 0.238525f, 0.654297f, 0.223389f, 0.663086f, 0.208862f, 0.673828f, 0.195068f,
+ 0.680176f, 0.182007f, 0.689941f, 0.169678f, 0.696289f, 0.157959f, 0.705078f, 0.147095f,
+ 0.713867f, 0.136841f, 0.719727f, 0.127197f, 0.724121f, 0.118225f, 0.729980f, 0.109863f,
+ 0.731934f, 0.101990f, 0.735840f, 0.094727f, 0.737305f, 0.087952f, 0.738770f, 0.081604f,
+ 0.740234f, 0.075745f, 0.739258f, 0.070312f, 0.738281f, 0.065247f, 0.735840f, 0.060608f,
+ 0.733398f, 0.056274f, 0.729492f, 0.052246f, 0.725098f, 0.048523f, 0.720703f, 0.045074f,
+ 0.714355f, 0.041870f, 0.708496f, 0.038910f, 0.701660f, 0.036163f, 0.693848f, 0.033630f,
+ 0.686035f, 0.031281f, 0.677734f, 0.029099f, 0.668457f, 0.027069f, 0.659180f, 0.025192f,
+ 0.648926f, 0.023453f, 0.639160f, 0.021851f, 0.628418f, 0.020355f, 0.617676f, 0.018967f,
+ 0.605957f, 0.017685f, 0.594727f, 0.016495f, 0.583008f, 0.015388f, 0.571289f, 0.014366f,
+ 0.559570f, 0.013412f, 0.546875f, 0.012520f, 0.534668f, 0.011696f, 0.522461f, 0.010925f,
+ 0.551758f, 0.447754f, 0.551758f, 0.447754f, 0.552246f, 0.447510f, 0.552246f, 0.447266f,
+ 0.552734f, 0.446289f, 0.553223f, 0.444580f, 0.555176f, 0.441895f, 0.556152f, 0.438232f,
+ 0.558594f, 0.432617f, 0.561035f, 0.425049f, 0.563477f, 0.415527f, 0.566406f, 0.404053f,
+ 0.570312f, 0.390381f, 0.575195f, 0.375000f, 0.578613f, 0.358154f, 0.584473f, 0.340332f,
+ 0.593750f, 0.322266f, 0.600098f, 0.303955f, 0.611328f, 0.286133f, 0.617676f, 0.268555f,
+ 0.629395f, 0.251709f, 0.640625f, 0.235352f, 0.649902f, 0.219849f, 0.661621f, 0.205078f,
+ 0.671387f, 0.191284f, 0.678711f, 0.178223f, 0.688965f, 0.166016f, 0.699707f, 0.154419f,
+ 0.707031f, 0.143555f, 0.714844f, 0.133545f, 0.719727f, 0.124084f, 0.726074f, 0.115295f,
+ 0.731445f, 0.107056f, 0.734863f, 0.099365f, 0.737305f, 0.092285f, 0.739258f, 0.085632f,
+ 0.740234f, 0.079529f, 0.739746f, 0.073792f, 0.739258f, 0.068542f, 0.737793f, 0.063599f,
+ 0.734863f, 0.059082f, 0.731934f, 0.054871f, 0.727539f, 0.050964f, 0.723633f, 0.047394f,
+ 0.717773f, 0.044006f, 0.711426f, 0.040924f, 0.705078f, 0.038055f, 0.697754f, 0.035400f,
+ 0.689941f, 0.032928f, 0.681641f, 0.030655f, 0.672852f, 0.028534f, 0.663574f, 0.026581f,
+ 0.653809f, 0.024750f, 0.644043f, 0.023071f, 0.633301f, 0.021515f, 0.622559f, 0.020050f,
+ 0.611328f, 0.018707f, 0.600098f, 0.017456f, 0.588867f, 0.016296f, 0.577148f, 0.015221f,
+ 0.565430f, 0.014221f, 0.553223f, 0.013290f, 0.541504f, 0.012421f, 0.528809f, 0.011620f,
+ 0.509277f, 0.490234f, 0.509277f, 0.490234f, 0.509277f, 0.489990f, 0.509766f, 0.489502f,
+ 0.510254f, 0.488525f, 0.511230f, 0.486328f, 0.512695f, 0.482910f, 0.514160f, 0.478027f,
+ 0.517578f, 0.470947f, 0.520996f, 0.461670f, 0.523926f, 0.449707f, 0.528809f, 0.435303f,
+ 0.534180f, 0.418945f, 0.540527f, 0.400635f, 0.548340f, 0.381348f, 0.554688f, 0.361328f,
+ 0.566895f, 0.340820f, 0.577637f, 0.320801f, 0.588867f, 0.301270f, 0.601074f, 0.282471f,
+ 0.610352f, 0.264404f, 0.624023f, 0.247070f, 0.637207f, 0.230591f, 0.649414f, 0.215210f,
+ 0.662109f, 0.200562f, 0.672852f, 0.186768f, 0.685547f, 0.173828f, 0.693359f, 0.161743f,
+ 0.702148f, 0.150391f, 0.711426f, 0.139771f, 0.720703f, 0.129883f, 0.726074f, 0.120667f,
+ 0.730469f, 0.112061f, 0.733887f, 0.104065f, 0.738281f, 0.096619f, 0.739258f, 0.089722f,
+ 0.740234f, 0.083252f, 0.741699f, 0.077332f, 0.740723f, 0.071777f, 0.739258f, 0.066711f,
+ 0.736816f, 0.061951f, 0.734375f, 0.057556f, 0.730469f, 0.053497f, 0.726074f, 0.049713f,
+ 0.720703f, 0.046234f, 0.714844f, 0.042999f, 0.708496f, 0.039978f, 0.701172f, 0.037231f,
+ 0.693848f, 0.034637f, 0.685547f, 0.032257f, 0.677246f, 0.030060f, 0.667969f, 0.028000f,
+ 0.658691f, 0.026108f, 0.648926f, 0.024338f, 0.638672f, 0.022705f, 0.627930f, 0.021194f,
+ 0.617188f, 0.019775f, 0.605957f, 0.018463f, 0.594727f, 0.017258f, 0.583008f, 0.016129f,
+ 0.571289f, 0.015076f, 0.559570f, 0.014099f, 0.547852f, 0.013191f, 0.535645f, 0.012337f,
+ 0.463623f, 0.536133f, 0.463623f, 0.536133f, 0.463867f, 0.535645f, 0.464111f, 0.535156f,
+ 0.465088f, 0.533691f, 0.466064f, 0.530762f, 0.468506f, 0.526367f, 0.471191f, 0.520020f,
+ 0.474609f, 0.511230f, 0.478516f, 0.499268f, 0.483643f, 0.484375f, 0.489990f, 0.466797f,
+ 0.495361f, 0.447266f, 0.502441f, 0.425537f, 0.515137f, 0.403564f, 0.526855f, 0.380859f,
+ 0.540039f, 0.358887f, 0.553711f, 0.336914f, 0.564453f, 0.315918f, 0.587891f, 0.295898f,
+ 0.600098f, 0.276611f, 0.610840f, 0.258545f, 0.624512f, 0.241211f, 0.641113f, 0.225098f,
+ 0.657715f, 0.209717f, 0.668457f, 0.195312f, 0.678223f, 0.181763f, 0.687988f, 0.169067f,
+ 0.701172f, 0.157104f, 0.707031f, 0.146118f, 0.715332f, 0.135620f, 0.723145f, 0.125977f,
+ 0.728516f, 0.117126f, 0.734375f, 0.108704f, 0.736328f, 0.100952f, 0.739746f, 0.093750f,
+ 0.741699f, 0.087036f, 0.742188f, 0.080872f, 0.741699f, 0.075134f, 0.741211f, 0.069763f,
+ 0.739258f, 0.064819f, 0.736816f, 0.060272f, 0.733398f, 0.056030f, 0.729004f, 0.052124f,
+ 0.724121f, 0.048492f, 0.718750f, 0.045105f, 0.712402f, 0.041992f, 0.705078f, 0.039093f,
+ 0.698242f, 0.036407f, 0.689941f, 0.033905f, 0.681641f, 0.031616f, 0.672852f, 0.029480f,
+ 0.663574f, 0.027512f, 0.653809f, 0.025665f, 0.644043f, 0.023956f, 0.633301f, 0.022369f,
+ 0.622559f, 0.020889f, 0.611816f, 0.019516f, 0.601074f, 0.018250f, 0.589355f, 0.017059f,
+ 0.578125f, 0.015961f, 0.565918f, 0.014946f, 0.554199f, 0.013992f, 0.542480f, 0.013107f,
+ 0.414551f, 0.584961f, 0.414551f, 0.584961f, 0.414795f, 0.584961f, 0.415039f, 0.583984f,
+ 0.416260f, 0.582031f, 0.418457f, 0.578613f, 0.420166f, 0.572754f, 0.424072f, 0.563965f,
+ 0.428467f, 0.552246f, 0.433838f, 0.537109f, 0.441162f, 0.518066f, 0.448730f, 0.497070f,
+ 0.458984f, 0.473633f, 0.467773f, 0.449219f, 0.480713f, 0.424072f, 0.497559f, 0.399414f,
+ 0.511719f, 0.375244f, 0.529297f, 0.352051f, 0.543945f, 0.329834f, 0.566895f, 0.308838f,
+ 0.581543f, 0.288574f, 0.598633f, 0.269531f, 0.619629f, 0.251465f, 0.635742f, 0.234497f,
+ 0.646973f, 0.218506f, 0.659668f, 0.203369f, 0.674805f, 0.189331f, 0.684570f, 0.176025f,
+ 0.695801f, 0.163696f, 0.707031f, 0.152222f, 0.718750f, 0.141357f, 0.723145f, 0.131348f,
+ 0.729004f, 0.122009f, 0.734375f, 0.113342f, 0.738281f, 0.105286f, 0.741211f, 0.097778f,
+ 0.743164f, 0.090820f, 0.744629f, 0.084412f, 0.744629f, 0.078430f, 0.743652f, 0.072876f,
+ 0.742676f, 0.067749f, 0.739746f, 0.062988f, 0.735840f, 0.058624f, 0.731934f, 0.054535f,
+ 0.727539f, 0.050751f, 0.721680f, 0.047241f, 0.715820f, 0.044006f, 0.709473f, 0.040985f,
+ 0.702148f, 0.038208f, 0.694824f, 0.035614f, 0.686523f, 0.033234f, 0.677734f, 0.031006f,
+ 0.668457f, 0.028946f, 0.659180f, 0.027023f, 0.649414f, 0.025238f, 0.639160f, 0.023590f,
+ 0.628906f, 0.022049f, 0.618164f, 0.020630f, 0.606934f, 0.019287f, 0.595703f, 0.018051f,
+ 0.584473f, 0.016907f, 0.572754f, 0.015839f, 0.561035f, 0.014839f, 0.549316f, 0.013908f,
+ 0.361816f, 0.637695f, 0.361816f, 0.637695f, 0.362061f, 0.637207f, 0.362793f, 0.636230f,
+ 0.364258f, 0.633301f, 0.366455f, 0.628906f, 0.369873f, 0.621094f, 0.374512f, 0.609375f,
+ 0.378906f, 0.593750f, 0.387451f, 0.573730f, 0.396484f, 0.550293f, 0.407471f, 0.524414f,
+ 0.419189f, 0.497314f, 0.433594f, 0.469971f, 0.453613f, 0.442627f, 0.473633f, 0.416016f,
+ 0.488037f, 0.390381f, 0.509277f, 0.365967f, 0.528809f, 0.343262f, 0.549805f, 0.320801f,
+ 0.574707f, 0.299805f, 0.590332f, 0.280029f, 0.609375f, 0.261475f, 0.631836f, 0.243774f,
+ 0.641602f, 0.227173f, 0.659668f, 0.211426f, 0.671387f, 0.196777f, 0.685059f, 0.183105f,
+ 0.698730f, 0.170166f, 0.705078f, 0.158203f, 0.715820f, 0.146973f, 0.723145f, 0.136597f,
+ 0.730469f, 0.126831f, 0.737793f, 0.117920f, 0.740723f, 0.109558f, 0.741699f, 0.101807f,
+ 0.745117f, 0.094604f, 0.747559f, 0.087891f, 0.747070f, 0.081726f, 0.747070f, 0.075989f,
+ 0.744141f, 0.070679f, 0.742676f, 0.065796f, 0.739258f, 0.061218f, 0.735840f, 0.056976f,
+ 0.730957f, 0.053070f, 0.725586f, 0.049438f, 0.719727f, 0.046082f, 0.713867f, 0.042938f,
+ 0.706543f, 0.040070f, 0.699219f, 0.037384f, 0.690918f, 0.034882f, 0.682617f, 0.032562f,
+ 0.673828f, 0.030426f, 0.664551f, 0.028442f, 0.654785f, 0.026581f, 0.645020f, 0.024857f,
+ 0.634766f, 0.023254f, 0.624023f, 0.021774f, 0.613281f, 0.020386f, 0.602051f, 0.019089f,
+ 0.590820f, 0.017899f, 0.579590f, 0.016769f, 0.567871f, 0.015732f, 0.556641f, 0.014755f,
+ 0.305420f, 0.694336f, 0.305420f, 0.694336f, 0.305664f, 0.693848f, 0.306641f, 0.691895f,
+ 0.308105f, 0.687988f, 0.311279f, 0.681152f, 0.316162f, 0.669922f, 0.321777f, 0.654297f,
+ 0.330078f, 0.632812f, 0.344238f, 0.606934f, 0.353027f, 0.578125f, 0.367432f, 0.547852f,
+ 0.385498f, 0.517578f, 0.405273f, 0.487793f, 0.422852f, 0.458496f, 0.448730f, 0.431152f,
+ 0.473633f, 0.404541f, 0.493896f, 0.379639f, 0.519531f, 0.355469f, 0.539551f, 0.332520f,
+ 0.563477f, 0.310791f, 0.583008f, 0.290283f, 0.604004f, 0.270752f, 0.626953f, 0.252686f,
+ 0.642090f, 0.235352f, 0.657715f, 0.218994f, 0.672852f, 0.203857f, 0.686523f, 0.189575f,
+ 0.699219f, 0.176270f, 0.707031f, 0.163818f, 0.717285f, 0.152344f, 0.723633f, 0.141602f,
+ 0.730469f, 0.131592f, 0.739258f, 0.122375f, 0.741699f, 0.113708f, 0.745605f, 0.105713f,
+ 0.747559f, 0.098267f, 0.748047f, 0.091370f, 0.749023f, 0.085022f, 0.748535f, 0.079102f,
+ 0.747070f, 0.073608f, 0.746582f, 0.068542f, 0.742188f, 0.063843f, 0.739258f, 0.059448f,
+ 0.734375f, 0.055420f, 0.730469f, 0.051666f, 0.724609f, 0.048187f, 0.717773f, 0.044952f,
+ 0.710938f, 0.041962f, 0.704102f, 0.039154f, 0.695801f, 0.036591f, 0.687988f, 0.034180f,
+ 0.679199f, 0.031952f, 0.670410f, 0.029892f, 0.660645f, 0.027969f, 0.650879f, 0.026184f,
+ 0.640625f, 0.024521f, 0.630371f, 0.022964f, 0.619629f, 0.021515f, 0.608887f, 0.020172f,
+ 0.598145f, 0.018921f, 0.586914f, 0.017761f, 0.575195f, 0.016663f, 0.563965f, 0.015656f,
+ 0.244995f, 0.754395f, 0.245117f, 0.754395f, 0.245483f, 0.753418f, 0.246704f, 0.750977f,
+ 0.249634f, 0.745117f, 0.253662f, 0.734863f, 0.260010f, 0.717773f, 0.268555f, 0.694336f,
+ 0.277344f, 0.665527f, 0.292480f, 0.632812f, 0.309814f, 0.599121f, 0.331787f, 0.565918f,
+ 0.352539f, 0.533203f, 0.376465f, 0.501953f, 0.405518f, 0.472412f, 0.433838f, 0.444336f,
+ 0.456787f, 0.417236f, 0.488281f, 0.391357f, 0.510254f, 0.366211f, 0.540039f, 0.343018f,
+ 0.564941f, 0.320557f, 0.579590f, 0.299561f, 0.606445f, 0.279541f, 0.627441f, 0.260498f,
+ 0.638184f, 0.242676f, 0.666504f, 0.226074f, 0.670898f, 0.210327f, 0.687988f, 0.195801f,
+ 0.700684f, 0.182129f, 0.706055f, 0.169312f, 0.718262f, 0.157471f, 0.727539f, 0.146362f,
+ 0.735840f, 0.136108f, 0.738770f, 0.126587f, 0.743164f, 0.117737f, 0.746582f, 0.109497f,
+ 0.751953f, 0.101868f, 0.751953f, 0.094788f, 0.753906f, 0.088257f, 0.752930f, 0.082153f,
+ 0.750977f, 0.076538f, 0.749512f, 0.071289f, 0.745605f, 0.066406f, 0.742188f, 0.061951f,
+ 0.738281f, 0.057770f, 0.734375f, 0.053894f, 0.729004f, 0.050293f, 0.722656f, 0.046967f,
+ 0.715332f, 0.043854f, 0.708496f, 0.040985f, 0.701172f, 0.038330f, 0.693359f, 0.035828f,
+ 0.684570f, 0.033539f, 0.676270f, 0.031403f, 0.666992f, 0.029404f, 0.657227f, 0.027542f,
+ 0.646973f, 0.025818f, 0.636719f, 0.024200f, 0.626465f, 0.022705f, 0.615723f, 0.021301f,
+ 0.604980f, 0.020004f, 0.593750f, 0.018784f, 0.582520f, 0.017654f, 0.571289f, 0.016586f,
+ 0.180542f, 0.818848f, 0.180664f, 0.818848f, 0.181274f, 0.817383f, 0.183350f, 0.812988f,
+ 0.187134f, 0.802734f, 0.193237f, 0.784180f, 0.201416f, 0.757324f, 0.214355f, 0.723145f,
+ 0.231445f, 0.685547f, 0.248901f, 0.648438f, 0.272217f, 0.611816f, 0.302979f, 0.577148f,
+ 0.329834f, 0.544922f, 0.364258f, 0.514160f, 0.394043f, 0.484619f, 0.425781f, 0.456055f,
+ 0.456543f, 0.428467f, 0.481934f, 0.402344f, 0.512207f, 0.376709f, 0.540039f, 0.352783f,
+ 0.566406f, 0.329346f, 0.579102f, 0.307617f, 0.607910f, 0.286865f, 0.627930f, 0.267822f,
+ 0.645996f, 0.249512f, 0.661621f, 0.232178f, 0.677734f, 0.216309f, 0.691406f, 0.201172f,
+ 0.702637f, 0.187256f, 0.711426f, 0.174194f, 0.721680f, 0.161987f, 0.730957f, 0.150879f,
+ 0.736328f, 0.140259f, 0.742188f, 0.130493f, 0.746582f, 0.121582f, 0.750488f, 0.113159f,
+ 0.751953f, 0.105347f, 0.752930f, 0.098083f, 0.756836f, 0.091370f, 0.755859f, 0.085144f,
+ 0.755371f, 0.079346f, 0.752441f, 0.073975f, 0.750488f, 0.069031f, 0.746582f, 0.064392f,
+ 0.743652f, 0.060120f, 0.737793f, 0.056152f, 0.733398f, 0.052460f, 0.727051f, 0.049011f,
+ 0.720215f, 0.045837f, 0.713867f, 0.042847f, 0.706543f, 0.040100f, 0.699219f, 0.037537f,
+ 0.690430f, 0.035156f, 0.682129f, 0.032928f, 0.672852f, 0.030884f, 0.663086f, 0.028961f,
+ 0.653809f, 0.027161f, 0.644043f, 0.025497f, 0.633301f, 0.023941f, 0.622559f, 0.022491f,
+ 0.612305f, 0.021133f, 0.601074f, 0.019867f, 0.590332f, 0.018692f, 0.579102f, 0.017578f,
+ 0.111816f, 0.888184f, 0.112000f, 0.887207f, 0.112976f, 0.883789f, 0.115845f, 0.873047f,
+ 0.122864f, 0.849609f, 0.133301f, 0.813477f, 0.147217f, 0.770996f, 0.167236f, 0.728027f,
+ 0.196411f, 0.688965f, 0.222290f, 0.653320f, 0.258057f, 0.619629f, 0.293457f, 0.587402f,
+ 0.328613f, 0.556152f, 0.361328f, 0.524902f, 0.392578f, 0.495850f, 0.430420f, 0.466064f,
+ 0.459961f, 0.437744f, 0.482422f, 0.410889f, 0.511230f, 0.385010f, 0.536621f, 0.359863f,
+ 0.568848f, 0.336182f, 0.592773f, 0.313721f, 0.614258f, 0.293213f, 0.626953f, 0.273193f,
+ 0.646484f, 0.254639f, 0.657227f, 0.237427f, 0.683105f, 0.221191f, 0.693359f, 0.205933f,
+ 0.698242f, 0.191772f, 0.709473f, 0.178589f, 0.724609f, 0.166260f, 0.733398f, 0.154907f,
+ 0.739746f, 0.144165f, 0.745605f, 0.134399f, 0.750977f, 0.125122f, 0.753906f, 0.116577f,
+ 0.754883f, 0.108704f, 0.758301f, 0.101257f, 0.759766f, 0.094482f, 0.757812f, 0.088074f,
+ 0.759766f, 0.082092f, 0.758301f, 0.076660f, 0.756348f, 0.071594f, 0.752441f, 0.066833f,
+ 0.748047f, 0.062469f, 0.741699f, 0.058380f, 0.736816f, 0.054596f, 0.732910f, 0.051086f,
+ 0.726074f, 0.047791f, 0.719727f, 0.044769f, 0.711914f, 0.041901f, 0.704590f, 0.039276f,
+ 0.696289f, 0.036804f, 0.688477f, 0.034546f, 0.678711f, 0.032410f, 0.669922f, 0.030411f,
+ 0.660156f, 0.028564f, 0.650391f, 0.026840f, 0.640625f, 0.025223f, 0.630371f, 0.023727f,
+ 0.619629f, 0.022324f, 0.608887f, 0.020996f, 0.597656f, 0.019775f, 0.586914f, 0.018631f,
+ 0.038452f, 0.960938f, 0.039124f, 0.957520f, 0.042480f, 0.933594f, 0.051575f, 0.879395f,
+ 0.069275f, 0.824219f, 0.091064f, 0.785156f, 0.126343f, 0.753906f, 0.154419f, 0.725586f,
+ 0.192139f, 0.695312f, 0.234375f, 0.663086f, 0.273438f, 0.630371f, 0.305908f, 0.597656f,
+ 0.338379f, 0.565430f, 0.379150f, 0.532227f, 0.413818f, 0.501465f, 0.444336f, 0.471191f,
+ 0.471436f, 0.442383f, 0.504395f, 0.414795f, 0.531250f, 0.388672f, 0.547363f, 0.364014f,
+ 0.579590f, 0.340088f, 0.603516f, 0.317627f, 0.622559f, 0.297119f, 0.635742f, 0.276855f,
+ 0.669434f, 0.258301f, 0.670410f, 0.241089f, 0.685547f, 0.224854f, 0.699219f, 0.209717f,
+ 0.712402f, 0.195190f, 0.720703f, 0.182373f, 0.729980f, 0.169678f, 0.746582f, 0.158325f,
+ 0.744629f, 0.147705f, 0.748535f, 0.137695f, 0.760254f, 0.128296f, 0.757812f, 0.119629f,
+ 0.761230f, 0.111755f, 0.762207f, 0.104248f, 0.764160f, 0.097290f, 0.763184f, 0.090881f,
+ 0.762207f, 0.084900f, 0.760742f, 0.079285f, 0.759766f, 0.074097f, 0.755859f, 0.069275f,
+ 0.752930f, 0.064758f, 0.747559f, 0.060669f, 0.742676f, 0.056793f, 0.737305f, 0.053131f,
+ 0.731445f, 0.049774f, 0.725586f, 0.046661f, 0.718262f, 0.043732f, 0.710449f, 0.041077f,
+ 0.702637f, 0.038544f, 0.694336f, 0.036163f, 0.685547f, 0.033966f, 0.676758f, 0.031921f,
+ 0.667480f, 0.030014f, 0.657715f, 0.028229f, 0.647461f, 0.026566f, 0.637207f, 0.025009f,
+ 0.626953f, 0.023544f, 0.616699f, 0.022186f, 0.605957f, 0.020920f, 0.594727f, 0.019730f
+};
+#endif /* __EEVEE_LUT_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
new file mode 100644
index 00000000000..6a073e58a3e
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_private.h
+ * \ingroup DNA
+ */
+
+#ifndef __EEVEE_PRIVATE_H__
+#define __EEVEE_PRIVATE_H__
+
+struct Object;
+
+extern struct DrawEngineType draw_engine_eevee_type;
+
+/* Minimum UBO is 16384 bytes */
+#define MAX_LIGHT 128 /* TODO : find size by dividing UBO max size by light data size */
+#define MAX_SHADOW_CUBE 42 /* TODO : Make this depends on GL_MAX_ARRAY_TEXTURE_LAYERS */
+#define MAX_SHADOW_MAP 64
+#define MAX_SHADOW_CASCADE 8
+#define MAX_CASCADE_NUM 4
+#define MAX_BLOOM_STEP 16
+
+typedef struct EEVEE_PassList {
+ /* Shadows */
+ struct DRWPass *shadow_pass;
+ struct DRWPass *shadow_cube_pass;
+ struct DRWPass *shadow_cube_store_pass;
+ struct DRWPass *shadow_cascade_pass;
+
+ /* Probes */
+ struct DRWPass *probe_background;
+ struct DRWPass *probe_prefilter;
+ struct DRWPass *probe_sh_compute;
+
+ /* Effects */
+ struct DRWPass *motion_blur;
+ struct DRWPass *bloom_blit;
+ struct DRWPass *bloom_downsample_first;
+ struct DRWPass *bloom_downsample;
+ struct DRWPass *bloom_upsample;
+ struct DRWPass *bloom_resolve;
+ struct DRWPass *dof_down;
+ struct DRWPass *dof_scatter;
+ struct DRWPass *dof_resolve;
+
+ struct DRWPass *depth_pass;
+ struct DRWPass *depth_pass_cull;
+ struct DRWPass *default_pass;
+ struct DRWPass *material_pass;
+ struct DRWPass *background_pass;
+} EEVEE_PassList;
+
+typedef struct EEVEE_FramebufferList {
+ /* Effects */
+ struct GPUFrameBuffer *effect_fb; /* HDR */
+ struct GPUFrameBuffer *bloom_blit_fb; /* HDR */
+ struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP]; /* HDR */
+ struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP-1]; /* HDR */
+ struct GPUFrameBuffer *dof_down_fb;
+ struct GPUFrameBuffer *dof_scatter_far_fb;
+ struct GPUFrameBuffer *dof_scatter_near_fb;
+
+ struct GPUFrameBuffer *main; /* HDR */
+} EEVEE_FramebufferList;
+
+typedef struct EEVEE_TextureList {
+ /* Effects */
+ struct GPUTexture *color_post; /* R16_G16_B16 */
+ struct GPUTexture *dof_down_near; /* R16_G16_B16_A16 */
+ struct GPUTexture *dof_down_far; /* R16_G16_B16_A16 */
+ struct GPUTexture *dof_coc; /* R16_G16 */
+ struct GPUTexture *dof_near_blur; /* R16_G16_B16_A16 */
+ struct GPUTexture *dof_far_blur; /* R16_G16_B16_A16 */
+ struct GPUTexture *bloom_blit; /* R16_G16_B16 */
+ struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */
+ struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP-1]; /* R16_G16_B16 */
+
+ struct GPUTexture *color; /* R16_G16_B16 */
+} EEVEE_TextureList;
+
+typedef struct EEVEE_StorageList {
+ /* Effects */
+ struct EEVEE_EffectsInfo *effects;
+
+ struct EEVEE_PrivateData *g_data;
+} EEVEE_StorageList;
+
+/* ************ LIGHT UBO ************* */
+typedef struct EEVEE_Light {
+ float position[3], dist;
+ float color[3], spec;
+ float spotsize, spotblend, radius, shadowid;
+ float rightvec[3], sizex;
+ float upvec[3], sizey;
+ float forwardvec[3], lamptype;
+} EEVEE_Light;
+
+typedef struct EEVEE_ShadowCube {
+ float near, far, bias, pad;
+} EEVEE_ShadowCube;
+
+typedef struct EEVEE_ShadowMap {
+ float shadowmat[4][4]; /* World->Lamp->NDC->Tex : used for sampling the shadow map. */
+ float near, far, bias, pad;
+} EEVEE_ShadowMap;
+
+typedef struct EEVEE_ShadowCascade {
+ float shadowmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC->Tex : used for sampling the shadow map. */
+ float split[4];
+ float bias[4];
+} EEVEE_ShadowCascade;
+
+typedef struct EEVEE_ShadowRender {
+ float shadowmat[6][4][4]; /* World->Lamp->NDC : used to render the shadow map. 6 frustrum for cubemap shadow */
+ float position[3];
+ float pad;
+ int layer;
+} EEVEE_ShadowRender;
+
+/* ************ LIGHT DATA ************* */
+typedef struct EEVEE_LampsInfo {
+ int num_light, cache_num_light;
+ int num_cube, cache_num_cube;
+ int num_map, cache_num_map;
+ int num_cascade, cache_num_cascade;
+ /* List of lights in the scene. */
+ struct Object *light_ref[MAX_LIGHT];
+ struct Object *shadow_cube_ref[MAX_SHADOW_CUBE];
+ struct Object *shadow_map_ref[MAX_SHADOW_MAP];
+ struct Object *shadow_cascade_ref[MAX_SHADOW_CASCADE];
+ /* UBO Storage : data used by UBO */
+ struct EEVEE_Light light_data[MAX_LIGHT];
+ struct EEVEE_ShadowRender shadow_render_data;
+ struct EEVEE_ShadowCube shadow_cube_data[MAX_SHADOW_CUBE];
+ struct EEVEE_ShadowMap shadow_map_data[MAX_SHADOW_MAP];
+ struct EEVEE_ShadowCascade shadow_cascade_data[MAX_SHADOW_CASCADE];
+} EEVEE_LampsInfo;
+
+/* ************ PROBE DATA ************* */
+typedef struct EEVEE_ProbesInfo {
+ /* For rendering probes */
+ float probemat[6][4][4];
+ int layer;
+ float texel_size;
+ float padding_size;
+ float samples_ct;
+ float invsamples_ct;
+ float roughness;
+ float lodfactor;
+ float lodmax;
+ int shres;
+ int shnbr;
+ float shcoefs[9][3]; /* Temp */
+ struct GPUTexture *backgroundtex;
+} EEVEE_ProbesInfo;
+
+/* ************ EFFECTS DATA ************* */
+typedef struct EEVEE_EffectsInfo {
+ int enabled_effects;
+
+ /* Motion Blur */
+ float current_ndc_to_world[4][4];
+ float past_world_to_ndc[4][4];
+ float tmp_mat[4][4];
+ int motion_blur_samples;
+
+ /* Depth Of Field */
+ float dof_near_far[2];
+ float dof_params[3];
+ float dof_bokeh[4];
+ float dof_layer_select[2];
+ int dof_target_size[2];
+
+ /* Bloom */
+ int bloom_iteration_ct;
+ float source_texel_size[2];
+ float blit_texel_size[2];
+ float downsamp_texel_size[MAX_BLOOM_STEP][2];
+ float bloom_intensity;
+ float bloom_sample_scale;
+ float bloom_curve_threshold[4];
+ float unf_source_texel_size[2];
+ struct GPUTexture *unf_source_buffer; /* pointer copy */
+ struct GPUTexture *unf_base_buffer; /* pointer copy */
+
+ /* Not alloced, just a copy of a *GPUtexture in EEVEE_TextureList. */
+ struct GPUTexture *source_buffer; /* latest updated texture */
+ struct GPUFrameBuffer *target_buffer; /* next target to render to */
+} EEVEE_EffectsInfo;
+
+enum {
+ EFFECT_MOTION_BLUR = (1 << 0),
+ EFFECT_BLOOM = (1 << 1),
+ EFFECT_DOF = (1 << 2),
+};
+
+/* ************** SCENE LAYER DATA ************** */
+typedef struct EEVEE_SceneLayerData {
+ /* Lamps */
+ struct EEVEE_LampsInfo *lamps;
+
+ struct GPUUniformBuffer *light_ubo;
+ struct GPUUniformBuffer *shadow_ubo;
+ struct GPUUniformBuffer *shadow_render_ubo;
+
+ struct GPUFrameBuffer *shadow_cube_target_fb;
+ struct GPUFrameBuffer *shadow_cube_fb;
+ struct GPUFrameBuffer *shadow_map_fb;
+ struct GPUFrameBuffer *shadow_cascade_fb;
+
+ struct GPUTexture *shadow_depth_cube_target;
+ struct GPUTexture *shadow_color_cube_target;
+ struct GPUTexture *shadow_depth_cube_pool;
+ struct GPUTexture *shadow_depth_map_pool;
+ struct GPUTexture *shadow_depth_cascade_pool;
+
+ /* Probes */
+ struct EEVEE_ProbesInfo *probes;
+
+ struct GPUUniformBuffer *probe_ubo;
+
+ struct GPUFrameBuffer *probe_fb;
+ struct GPUFrameBuffer *probe_filter_fb;
+ struct GPUFrameBuffer *probe_sh_fb;
+
+ struct GPUTexture *probe_rt;
+ struct GPUTexture *probe_depth_rt;
+ struct GPUTexture *probe_pool;
+ struct GPUTexture *probe_sh;
+} EEVEE_SceneLayerData;
+
+/* *********************************** */
+
+typedef struct EEVEE_Data {
+ void *engine_type;
+ EEVEE_FramebufferList *fbl;
+ EEVEE_TextureList *txl;
+ EEVEE_PassList *psl;
+ EEVEE_StorageList *stl;
+} EEVEE_Data;
+
+/* Keep it sync with MAX_LAMP_DATA */
+typedef struct EEVEE_LampEngineData {
+ void *sto;
+ void *pad;
+} EEVEE_LampEngineData;
+
+typedef struct EEVEE_PrivateData {
+ struct DRWShadingGroup *shadow_shgrp;
+ struct DRWShadingGroup *depth_shgrp;
+ struct DRWShadingGroup *depth_shgrp_cull;
+
+ struct ListBase lamps; /* Lamps gathered during cache iteration */
+} EEVEE_PrivateData; /* Transient data */
+
+/* eevee_lights.c */
+void EEVEE_lights_init(EEVEE_SceneLayerData *sldata);
+void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
+void EEVEE_lights_cache_add(EEVEE_SceneLayerData *sldata, struct Object *ob);
+void EEVEE_lights_cache_shcaster_add(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, struct Batch *geom, float (*obmat)[4]);
+void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata);
+void EEVEE_lights_update(EEVEE_SceneLayerData *sldata);
+void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
+void EEVEE_lights_free(void);
+void EEVEE_scene_layer_lights_free(EEVEE_SceneLayerData *sldata);
+
+/* eevee_probes.c */
+void EEVEE_probes_init(EEVEE_SceneLayerData *sldata);
+void EEVEE_probes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
+void EEVEE_probes_cache_add(EEVEE_SceneLayerData *sldata, Object *ob);
+void EEVEE_probes_cache_finish(EEVEE_SceneLayerData *sldata);
+void EEVEE_probes_update(EEVEE_SceneLayerData *sldata);
+void EEVEE_refresh_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
+void EEVEE_probes_free(void);
+void EEVEE_scene_layer_probes_free(EEVEE_SceneLayerData *sldata);
+
+/* eevee_effects.c */
+void EEVEE_effects_init(EEVEE_Data *vedata);
+void EEVEE_effects_cache_init(EEVEE_Data *vedata);
+void EEVEE_draw_effects(EEVEE_Data *vedata);
+void EEVEE_effects_free(void);
+
+/* Shadow Matrix */
+static const float texcomat[4][4] = { /* From NDC to TexCo */
+ {0.5, 0.0, 0.0, 0.0},
+ {0.0, 0.5, 0.0, 0.0},
+ {0.0, 0.0, 0.5, 0.0},
+ {0.5, 0.5, 0.5, 1.0}
+};
+
+/* Cubemap Matrices */
+static const float cubefacemat[6][4][4] = {
+ /* Pos X */
+ {{0.0, 0.0, -1.0, 0.0},
+ {0.0, -1.0, 0.0, 0.0},
+ {-1.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}},
+ /* Neg X */
+ {{0.0, 0.0, 1.0, 0.0},
+ {0.0, -1.0, 0.0, 0.0},
+ {1.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}},
+ /* Pos Y */
+ {{1.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, -1.0, 0.0},
+ {0.0, 1.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}},
+ /* Neg Y */
+ {{1.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 1.0, 0.0},
+ {0.0, -1.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}},
+ /* Pos Z */
+ {{1.0, 0.0, 0.0, 0.0},
+ {0.0, -1.0, 0.0, 0.0},
+ {0.0, 0.0, -1.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}},
+ /* Neg Z */
+ {{-1.0, 0.0, 0.0, 0.0},
+ {0.0, -1.0, 0.0, 0.0},
+ {0.0, 0.0, 1.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}},
+};
+
+#endif /* __EEVEE_PRIVATE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_probes.c b/source/blender/draw/engines/eevee/eevee_probes.c
new file mode 100644
index 00000000000..9c9fc052b3f
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_probes.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_lights.c
+ * \ingroup DNA
+ */
+
+#include "DNA_world_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_image_types.h"
+
+#include "BLI_dynstr.h"
+
+#include "DRW_render.h"
+
+#include "eevee_engine.h"
+#include "eevee_private.h"
+#include "GPU_texture.h"
+#include "GPU_glew.h"
+
+typedef struct EEVEE_ProbeData {
+ short probe_id, shadow_id;
+} EEVEE_ProbeData;
+
+/* TODO Option */
+#define PROBE_CUBE_SIZE 512
+#define PROBE_SIZE 1024
+
+static struct {
+ struct GPUShader *probe_filter_sh;
+ struct GPUShader *probe_spherical_harmonic_sh;
+
+ struct GPUTexture *hammersley;
+
+ float camera_pos[3];
+} e_data = {NULL}; /* Engine data */
+
+extern char datatoc_probe_filter_frag_glsl[];
+extern char datatoc_probe_sh_frag_glsl[];
+extern char datatoc_probe_geom_glsl[];
+extern char datatoc_probe_vert_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_bsdf_sampling_lib_glsl[];
+
+/* *********** FUNCTIONS *********** */
+
+/* Van der Corput sequence */
+ /* From http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */
+static float radical_inverse(int i) {
+ unsigned int bits = (unsigned int)i;
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return (float)bits * 2.3283064365386963e-10f;
+}
+
+static struct GPUTexture *create_hammersley_sample_texture(int samples)
+{
+ struct GPUTexture *tex;
+ float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex");
+ int i;
+
+ for (i = 0; i < samples; i++) {
+ float phi = radical_inverse(i) * 2.0f * M_PI;
+ texels[i][0] = cos(phi);
+ texels[i][1] = sinf(phi);
+ }
+
+ tex = DRW_texture_create_1D(samples, DRW_TEX_RG_16, DRW_TEX_WRAP, (float *)texels);
+ MEM_freeN(texels);
+ return tex;
+}
+
+void EEVEE_probes_init(EEVEE_SceneLayerData *sldata)
+{
+ if (!e_data.probe_filter_sh) {
+ char *shader_str = NULL;
+
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_probe_filter_frag_glsl);
+ shader_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.probe_filter_sh = DRW_shader_create(
+ datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, shader_str,
+ "#define HAMMERSLEY_SIZE 1024\n"
+ "#define NOISE_SIZE 64\n");
+
+ MEM_freeN(shader_str);
+ }
+
+ if (!e_data.hammersley) {
+ e_data.hammersley = create_hammersley_sample_texture(1024);
+ }
+
+ if (!e_data.probe_spherical_harmonic_sh) {
+ e_data.probe_spherical_harmonic_sh = DRW_shader_create_fullscreen(datatoc_probe_sh_frag_glsl, NULL);
+ }
+
+ if (!sldata->probes) {
+ sldata->probes = MEM_callocN(sizeof(EEVEE_ProbesInfo), "EEVEE_ProbesInfo");
+ }
+
+ if (!sldata->probe_rt) {
+ sldata->probe_rt = DRW_texture_create_cube(PROBE_CUBE_SIZE, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ sldata->probe_depth_rt = DRW_texture_create_cube(PROBE_CUBE_SIZE, DRW_TEX_DEPTH_24, DRW_TEX_FILTER, NULL);
+ }
+
+ DRWFboTexture tex_probe[2] = {{&sldata->probe_depth_rt, DRW_TEX_DEPTH_24, DRW_TEX_FILTER},
+ {&sldata->probe_rt, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP}};
+
+ DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, PROBE_CUBE_SIZE, PROBE_CUBE_SIZE, tex_probe, 2);
+
+ if (!sldata->probe_pool) {
+ /* TODO array */
+ sldata->probe_pool = DRW_texture_create_2D(PROBE_SIZE, PROBE_SIZE, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ }
+
+ DRWFboTexture tex_filter = {&sldata->probe_pool, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
+
+ DRW_framebuffer_init(&sldata->probe_filter_fb, &draw_engine_eevee_type, PROBE_SIZE, PROBE_SIZE, &tex_filter, 1);
+
+ /* Spherical Harmonic Buffer */
+ DRWFboTexture tex_sh = {&sldata->probe_sh, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
+
+ DRW_framebuffer_init(&sldata->probe_sh_fb, &draw_engine_eevee_type, 9, 1, &tex_sh, 1);
+}
+
+void EEVEE_probes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
+{
+ {
+ psl->probe_prefilter = DRW_pass_create("Probe Filtering", DRW_STATE_WRITE_COLOR);
+
+ struct Batch *geom = DRW_cache_fullscreen_quad_get();
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_filter_sh, psl->probe_prefilter, geom);
+ DRW_shgroup_uniform_float(grp, "sampleCount", &sldata->probes->samples_ct, 1);
+ DRW_shgroup_uniform_float(grp, "invSampleCount", &sldata->probes->invsamples_ct, 1);
+ DRW_shgroup_uniform_float(grp, "roughnessSquared", &sldata->probes->roughness, 1);
+ DRW_shgroup_uniform_float(grp, "lodFactor", &sldata->probes->lodfactor, 1);
+ DRW_shgroup_uniform_float(grp, "lodMax", &sldata->probes->lodmax, 1);
+ DRW_shgroup_uniform_float(grp, "texelSize", &sldata->probes->texel_size, 1);
+ DRW_shgroup_uniform_float(grp, "paddingSize", &sldata->probes->padding_size, 1);
+ DRW_shgroup_uniform_int(grp, "Layer", &sldata->probes->layer, 1);
+ DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
+ // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
+ DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
+
+ DRW_shgroup_call_dynamic_add_empty(grp);
+ }
+
+ {
+ psl->probe_sh_compute = DRW_pass_create("Probe SH Compute", DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_spherical_harmonic_sh, psl->probe_sh_compute);
+ DRW_shgroup_uniform_int(grp, "probeSize", &sldata->probes->shres, 1);
+ DRW_shgroup_uniform_float(grp, "lodBias", &sldata->probes->lodfactor, 1);
+ DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
+
+ struct Batch *geom = DRW_cache_fullscreen_quad_get();
+ DRW_shgroup_call_add(grp, geom, NULL);
+ }
+}
+
+void EEVEE_probes_cache_add(EEVEE_SceneLayerData *UNUSED(sldata), Object *UNUSED(ob))
+{
+ return;
+}
+
+void EEVEE_probes_cache_finish(EEVEE_SceneLayerData *UNUSED(sldata))
+{
+ return;
+}
+
+void EEVEE_probes_update(EEVEE_SceneLayerData *UNUSED(sldata))
+{
+ return;
+}
+
+void EEVEE_refresh_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
+{
+ EEVEE_ProbesInfo *pinfo = sldata->probes;
+
+ float projmat[4][4];
+
+ /* 1 - Render to cubemap target using geometry shader. */
+ /* We don't need to clear since we render the background. */
+ pinfo->layer = 0;
+ perspective_m4(projmat, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 100.0f);
+ for (int i = 0; i < 6; ++i) {
+ mul_m4_m4m4(pinfo->probemat[i], projmat, cubefacemat[i]);
+ }
+
+ DRW_framebuffer_bind(sldata->probe_fb);
+ DRW_draw_pass(psl->probe_background);
+
+ /* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */
+ /* Bind next framebuffer to be able to gen. mips for probe_rt. */
+ DRW_framebuffer_bind(sldata->probe_filter_fb);
+ DRW_texture_generate_mipmaps(sldata->probe_rt);
+
+ /* 3 - Render to probe array to the specified layer, do prefiltering. */
+ /* Detach to rebind the right mipmap. */
+ DRW_framebuffer_texture_detach(sldata->probe_pool);
+ float mipsize = PROBE_SIZE;
+ const int maxlevel = (int)floorf(log2f(PROBE_SIZE));
+ const int min_lod_level = 3;
+ for (int i = 0; i < maxlevel - min_lod_level; i++) {
+ float bias = (i == 0) ? 0.0f : 1.0f;
+ pinfo->texel_size = 1.0f / mipsize;
+ pinfo->padding_size = powf(2.0f, (float)(maxlevel - min_lod_level - 1 - i));
+ /* XXX : WHY THE HECK DO WE NEED THIS ??? */
+ /* padding is incorrect without this! float precision issue? */
+ if (pinfo->padding_size > 32) {
+ pinfo->padding_size += 5;
+ }
+ if (pinfo->padding_size > 16) {
+ pinfo->padding_size += 4;
+ }
+ else if (pinfo->padding_size > 8) {
+ pinfo->padding_size += 2;
+ }
+ else if (pinfo->padding_size > 4) {
+ pinfo->padding_size += 1;
+ }
+ pinfo->layer = 0;
+ pinfo->roughness = (float)i / ((float)maxlevel - 4.0f);
+ pinfo->roughness *= pinfo->roughness; /* Disney Roughness */
+ pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */
+ CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */
+
+#if 1 /* Variable Sample count (fast) */
+ switch (i) {
+ case 0: pinfo->samples_ct = 1.0f; break;
+ case 1: pinfo->samples_ct = 16.0f; break;
+ case 2: pinfo->samples_ct = 32.0f; break;
+ case 3: pinfo->samples_ct = 64.0f; break;
+ default: pinfo->samples_ct = 128.0f; break;
+ }
+#else /* Constant Sample count (slow) */
+ pinfo->samples_ct = 1024.0f;
+#endif
+
+ pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
+ pinfo->lodfactor = bias + 0.5f * log((float)(PROBE_CUBE_SIZE * PROBE_CUBE_SIZE) * pinfo->invsamples_ct) / log(2);
+ pinfo->lodmax = floorf(log2f(PROBE_CUBE_SIZE)) - 2.0f;
+
+ DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, i);
+ DRW_framebuffer_viewport_size(sldata->probe_filter_fb, mipsize, mipsize);
+ DRW_draw_pass(psl->probe_prefilter);
+ DRW_framebuffer_texture_detach(sldata->probe_pool);
+
+ mipsize /= 2;
+ CLAMP_MIN(mipsize, 1);
+ }
+ /* For shading, save max level of the octahedron map */
+ pinfo->lodmax = (float)(maxlevel - min_lod_level) - 1.0f;
+ /* reattach to have a valid framebuffer. */
+ DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
+
+ /* 4 - Compute spherical harmonics */
+ /* Tweaking parameters to balance perf. vs precision */
+ pinfo->shres = 16; /* Less texture fetches & reduce branches */
+ pinfo->lodfactor = 4.0f; /* Improve cache reuse */
+ DRW_framebuffer_bind(sldata->probe_sh_fb);
+ DRW_draw_pass(psl->probe_sh_compute);
+ DRW_framebuffer_read_data(0, 0, 9, 1, 3, 0, (float *)pinfo->shcoefs);
+}
+
+void EEVEE_probes_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.probe_filter_sh);
+ DRW_SHADER_FREE_SAFE(e_data.probe_spherical_harmonic_sh);
+ DRW_TEXTURE_FREE_SAFE(e_data.hammersley);
+}
+
+void EEVEE_scene_layer_probes_free(EEVEE_SceneLayerData *sldata)
+{
+ MEM_SAFE_FREE(sldata->probes);
+ DRW_UBO_FREE_SAFE(sldata->probe_ubo);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_fb);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_filter_fb);
+ DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_sh_fb);
+ DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
+ DRW_TEXTURE_FREE_SAFE(sldata->probe_depth_rt);
+ DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
+ DRW_TEXTURE_FREE_SAFE(sldata->probe_sh);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/background_vert.glsl b/source/blender/draw/engines/eevee/shaders/background_vert.glsl
new file mode 100644
index 00000000000..9b43d563d7c
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/background_vert.glsl
@@ -0,0 +1,17 @@
+
+in vec2 pos;
+
+out vec3 varposition;
+out vec3 varnormal;
+out vec3 viewPosition;
+
+/* necessary for compilation*/
+out vec3 worldPosition;
+out vec3 worldNormal;
+
+void main()
+{
+ gl_Position = vec4(pos, 1.0, 1.0);
+ varposition = viewPosition = vec3(pos, -1.0);
+ varnormal = normalize(-varposition);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
new file mode 100644
index 00000000000..a9be6ca5478
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -0,0 +1,274 @@
+
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_1_PI 0.318309886183790671538 /* 1/pi */
+#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
+#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
+
+#define LUT_SIZE 64
+
+/* ------- Structures -------- */
+
+struct LightData {
+ vec4 position_influence; /* w : InfluenceRadius */
+ vec4 color_spec; /* w : Spec Intensity */
+ vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
+ vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
+ vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
+ vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Lamp Type */
+};
+
+/* convenience aliases */
+#define l_color color_spec.rgb
+#define l_spec color_spec.a
+#define l_position position_influence.xyz
+#define l_influence position_influence.w
+#define l_sizex rightvec_sizex.w
+#define l_sizey upvec_sizey.w
+#define l_right rightvec_sizex.xyz
+#define l_up upvec_sizey.xyz
+#define l_forward forwardvec_type.xyz
+#define l_type forwardvec_type.w
+#define l_spot_size spotdata_radius_shadow.x
+#define l_spot_blend spotdata_radius_shadow.y
+#define l_radius spotdata_radius_shadow.z
+#define l_shadowid spotdata_radius_shadow.w
+
+
+struct ShadowCubeData {
+ vec4 near_far_bias;
+};
+
+/* convenience aliases */
+#define sh_cube_near near_far_bias.x
+#define sh_cube_far near_far_bias.y
+#define sh_cube_bias near_far_bias.z
+
+
+struct ShadowMapData {
+ mat4 shadowmat;
+ vec4 near_far_bias;
+};
+
+/* convenience aliases */
+#define sh_map_near near_far_bias.x
+#define sh_map_far near_far_bias.y
+#define sh_map_bias near_far_bias.z
+
+#ifndef MAX_CASCADE_NUM
+#define MAX_CASCADE_NUM 4
+#endif
+
+struct ShadowCascadeData {
+ mat4 shadowmat[MAX_CASCADE_NUM];
+ /* arrays of float are not aligned so use vec4 */
+ vec4 split_distances;
+ vec4 bias;
+};
+
+struct ShadingData {
+ vec3 V; /* View vector */
+ vec3 N; /* World Normal of the fragment */
+ vec3 W; /* World Position of the fragment */
+ vec3 l_vector; /* Current Light vector */
+};
+
+/* ------- Convenience functions --------- */
+
+vec3 mul(mat3 m, vec3 v) { return m * v; }
+mat3 mul(mat3 m1, mat3 m2) { return m1 * m2; }
+
+float saturate(float a) { return clamp(a, 0.0, 1.0); }
+vec2 saturate(vec2 a) { return clamp(a, 0.0, 1.0); }
+vec3 saturate(vec3 a) { return clamp(a, 0.0, 1.0); }
+vec4 saturate(vec4 a) { return clamp(a, 0.0, 1.0); }
+
+float distance_squared(vec2 a, vec2 b) { a -= b; return dot(a, a); }
+float distance_squared(vec3 a, vec3 b) { a -= b; return dot(a, a); }
+
+float inverse_distance(vec3 V) { return max( 1 / length(V), 1e-8); }
+
+float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
+{
+ return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
+}
+
+vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
+{
+ float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
+ return lineorigin + linedirection * dist;
+}
+
+float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+{
+ /* aligned plane normal */
+ vec3 L = planeorigin - lineorigin;
+ float diskdist = length(L);
+ vec3 planenormal = -normalize(L);
+ return -diskdist / dot(planenormal, linedirection);
+}
+
+vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+{
+ float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
+ if (dist < 0) {
+ /* if intersection is behind we fake the intersection to be
+ * really far and (hopefully) not inside the radius of interest */
+ dist = 1e16;
+ }
+ return lineorigin + linedirection * dist;
+}
+
+/* Return texture coordinates to sample Surface LUT */
+vec2 lut_coords(float cosTheta, float roughness)
+{
+ float theta = acos(cosTheta);
+ vec2 coords = vec2(roughness, theta / M_PI_2);
+
+ /* scale and bias coordinates, for correct filtered lookup */
+ return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
+}
+
+/* -- Tangent Space conversion -- */
+vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return T * vector.x + B * vector.y + N * vector.z;
+}
+
+vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return vec3( dot(T, vector), dot(B, vector), dot(N, vector));
+}
+
+void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
+{
+ vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0);
+ T = normalize( cross(UpVector, N) );
+ B = cross(N, T);
+}
+
+/* ---- Opengl Depth conversion ---- */
+float linear_depth(bool is_persp, float z, float zf, float zn)
+{
+ if (is_persp) {
+ return (zn * zf) / (z * (zn - zf) + zf);
+ }
+ else {
+ return (z * 2.0 - 1.0) * zf;
+ }
+}
+
+float buffer_depth(bool is_persp, float z, float zf, float zn)
+{
+ if (is_persp) {
+ return (zf * (zn - z)) / (z * (zn - zf));
+ }
+ else {
+ return (z / (zf * 2.0)) + 0.5;
+ }
+}
+
+#define spherical_harmonics spherical_harmonics_L2
+
+/* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */
+vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[9])
+{
+ vec3 sh = vec3(0.0);
+
+ sh += 0.282095 * shcoefs[0];
+
+ sh += -0.488603 * N.z * shcoefs[1];
+ sh += 0.488603 * N.y * shcoefs[2];
+ sh += -0.488603 * N.x * shcoefs[3];
+
+ return sh;
+}
+
+vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9])
+{
+ vec3 sh = vec3(0.0);
+
+ sh += 0.282095 * shcoefs[0];
+
+ sh += -0.488603 * N.z * shcoefs[1];
+ sh += 0.488603 * N.y * shcoefs[2];
+ sh += -0.488603 * N.x * shcoefs[3];
+
+ sh += 1.092548 * N.x * N.z * shcoefs[4];
+ sh += -1.092548 * N.z * N.y * shcoefs[5];
+ sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6];
+ sh += -1.092548 * N.x * N.y * shcoefs[7];
+ sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8];
+
+ return sh;
+}
+
+vec3 get_specular_dominant_dir(vec3 N, vec3 R, float roughness)
+{
+ float smoothness = 1.0 - roughness;
+ float fac = smoothness * (sqrt(smoothness) + roughness);
+ return normalize(mix(N, R, fac));
+}
+
+/* Fresnel */
+vec3 F_schlick(vec3 f0, float cos_theta)
+{
+ float fac = pow(1.0 - cos_theta, 5);
+
+ /* Unreal specular matching : if specular color is below 2% intensity,
+ * (using green channel for intensity) treat as shadowning */
+ return saturate(50.0 * f0.g) * fac + (1.0 - fac) * f0;
+}
+
+/* Fresnel approximation for LTC area lights (not MRP) */
+vec3 F_area(vec3 f0, vec2 lut)
+{
+ vec2 fac = normalize(lut.xy);
+
+ /* Unreal specular matching : if specular color is below 2% intensity,
+ * (using green channel for intensity) treat as shadowning */
+ return saturate(50.0 * f0.g) * fac.y + fac.x * f0;
+}
+
+/* Fresnel approximation for LTC area lights (not MRP) */
+vec3 F_ibl(vec3 f0, vec2 lut)
+{
+ /* Unreal specular matching : if specular color is below 2% intensity,
+ * (using green channel for intensity) treat as shadowning */
+ return saturate(50.0 * f0.g) * lut.y + lut.x * f0;
+}
+
+/* GGX */
+float D_ggx_opti(float NH, float a2)
+{
+ float tmp = (NH * a2 - NH) * NH + 1.0;
+ return M_PI * tmp*tmp; /* Doing RCP and mul a2 at the end */
+}
+
+float G1_Smith_GGX(float NX, float a2)
+{
+ /* Using Brian Karis approach and refactoring by NX/NX
+ * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV
+ * Rcp is done on the whole G later
+ * Note that this is not convenient for the transmition formula */
+ return NX + sqrt(NX * (NX - NX * a2) + a2);
+ /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */
+}
+
+float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness)
+{
+ float a = roughness;
+ float a2 = a * a;
+
+ vec3 H = normalize(L + V);
+ float NH = max(dot(N, H), 1e-8);
+ float NL = max(dot(N, L), 1e-8);
+ float NV = max(dot(N, V), 1e-8);
+
+ float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */
+ float D = D_ggx_opti(NH, a2);
+
+ /* Denominator is canceled by G1_Smith */
+ /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */
+ return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */
+}
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
new file mode 100644
index 00000000000..e91c4a4411b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
@@ -0,0 +1,180 @@
+/* Bsdf direct light function */
+/* in other word, how materials react to scene lamps */
+
+/* Naming convention
+ * V View vector (normalized)
+ * N World Normal (normalized)
+ * L Outgoing Light Vector (Surface to Light in World Space) (normalized)
+ * Ldist Distance from surface to the light
+ * W World Pos
+ */
+
+/* ------------ Diffuse ------------- */
+
+float direct_diffuse_point(LightData ld, ShadingData sd)
+{
+ float dist = length(sd.l_vector);
+ vec3 L = sd.l_vector / dist;
+ float bsdf = max(0.0, dot(sd.N, L));
+ bsdf /= dist * dist;
+ return bsdf;
+}
+
+/* infinitly far away point source, no decay */
+float direct_diffuse_sun(LightData ld, ShadingData sd)
+{
+ float bsdf = max(0.0, dot(sd.N, -ld.l_forward));
+ bsdf *= M_1_PI; /* Normalize */
+ return bsdf;
+}
+
+/* From Frostbite PBR Course
+ * Analitical irradiance from a sphere with correct horizon handling
+ * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
+float direct_diffuse_sphere(LightData ld, ShadingData sd)
+{
+ float dist = length(sd.l_vector);
+ vec3 L = sd.l_vector / dist;
+ float radius = max(ld.l_sizex, 0.0001);
+ float costheta = clamp(dot(sd.N, L), -0.999, 0.999);
+ float h = min(ld.l_radius / dist , 0.9999);
+ float h2 = h*h;
+ float costheta2 = costheta * costheta;
+ float bsdf;
+
+ if (costheta2 > h2) {
+ bsdf = M_PI * h2 * clamp(costheta, 0.0, 1.0);
+ }
+ else {
+ float sintheta = sqrt(1.0 - costheta2);
+ float x = sqrt(1.0 / h2 - 1.0);
+ float y = -x * (costheta / sintheta);
+ float sinthetasqrty = sintheta * sqrt(1.0 - y * y);
+ bsdf = (costheta * acos(y) - x * sinthetasqrty) * h2 + atan(sinthetasqrty / x);
+ }
+
+ bsdf = max(bsdf, 0.0);
+ bsdf *= M_1_PI2;
+
+ return bsdf;
+}
+
+/* From Frostbite PBR Course
+ * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
+float direct_diffuse_rectangle(LightData ld, ShadingData sd)
+{
+ vec3 corners[4];
+ corners[0] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey;
+ corners[1] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
+ corners[2] = sd.l_vector + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
+ corners[3] = sd.l_vector + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
+
+ float bsdf = ltc_evaluate(sd.N, sd.V, mat3(1.0), corners);
+ bsdf *= M_1_2PI;
+ return bsdf;
+}
+
+
+#if 0
+float direct_diffuse_unit_disc(vec3 N, vec3 L)
+{
+
+}
+#endif
+
+/* ----------- GGx ------------ */
+vec3 direct_ggx_point(ShadingData sd, float roughness, vec3 f0)
+{
+ float dist = length(sd.l_vector);
+ vec3 L = sd.l_vector / dist;
+ float bsdf = bsdf_ggx(sd.N, L, sd.V, roughness);
+ bsdf /= dist * dist;
+
+ /* Fresnel */
+ float VH = max(dot(sd.V, normalize(sd.V + L)), 0.0);
+ return F_schlick(f0, VH) * bsdf;
+}
+
+vec3 direct_ggx_sun(LightData ld, ShadingData sd, float roughness, vec3 f0)
+{
+ float bsdf = bsdf_ggx(sd.N, -ld.l_forward, sd.V, roughness);
+ float VH = max(dot(sd.V, normalize(sd.V - ld.l_forward)), 0.0);
+ return F_schlick(f0, VH) * bsdf;
+}
+
+vec3 direct_ggx_sphere(LightData ld, ShadingData sd, float roughness, vec3 f0)
+{
+ vec3 L = normalize(sd.l_vector);
+ vec3 spec_dir = get_specular_dominant_dir(sd.N, reflect(-sd.V, sd.N), roughness);
+ vec3 P = line_aligned_plane_intersect(vec3(0.0), spec_dir, sd.l_vector);
+
+ vec3 Px = normalize(P - sd.l_vector) * ld.l_radius;
+ vec3 Py = cross(Px, L);
+
+ vec2 uv = lut_coords(dot(sd.N, sd.V), sqrt(roughness));
+ vec3 brdf_lut = texture(brdfLut, uv).rgb;
+ vec4 ltc_lut = texture(ltcMat, uv).rgba;
+ mat3 ltc_mat = ltc_matrix(ltc_lut);
+
+// #define HIGHEST_QUALITY
+#ifdef HIGHEST_QUALITY
+ vec3 Pxy1 = normalize( Px + Py) * ld.l_radius;
+ vec3 Pxy2 = normalize(-Px + Py) * ld.l_radius;
+
+ /* counter clockwise */
+ vec3 points[8];
+ points[0] = sd.l_vector + Px;
+ points[1] = sd.l_vector - Pxy2;
+ points[2] = sd.l_vector - Py;
+ points[3] = sd.l_vector - Pxy1;
+ points[4] = sd.l_vector - Px;
+ points[5] = sd.l_vector + Pxy2;
+ points[6] = sd.l_vector + Py;
+ points[7] = sd.l_vector + Pxy1;
+ float bsdf = ltc_evaluate_circle(sd.N, sd.V, ltc_mat, points);
+#else
+ vec3 points[4];
+ points[0] = sd.l_vector + Px;
+ points[1] = sd.l_vector - Py;
+ points[2] = sd.l_vector - Px;
+ points[3] = sd.l_vector + Py;
+ float bsdf = ltc_evaluate(sd.N, sd.V, ltc_mat, points);
+ /* sqrt(pi/2) difference between square and disk area */
+ bsdf *= 1.25331413731;
+#endif
+
+ bsdf *= brdf_lut.b; /* Bsdf intensity */
+ bsdf *= M_1_2PI * M_1_PI;
+
+ vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
+
+ return spec;
+}
+
+vec3 direct_ggx_rectangle(LightData ld, ShadingData sd, float roughness, vec3 f0)
+{
+ vec3 corners[4];
+ corners[0] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey;
+ corners[1] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
+ corners[2] = sd.l_vector + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
+ corners[3] = sd.l_vector + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
+
+ vec2 uv = lut_coords(dot(sd.N, sd.V), sqrt(roughness));
+ vec3 brdf_lut = texture(brdfLut, uv).rgb;
+ vec4 ltc_lut = texture(ltcMat, uv).rgba;
+ mat3 ltc_mat = ltc_matrix(ltc_lut);
+ float bsdf = ltc_evaluate(sd.N, sd.V, ltc_mat, corners);
+ bsdf *= brdf_lut.b; /* Bsdf intensity */
+ bsdf *= M_1_2PI;
+
+ vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
+
+ return spec;
+}
+
+#if 0
+float direct_ggx_disc(vec3 N, vec3 L)
+{
+
+}
+#endif \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
new file mode 100644
index 00000000000..b8fac61519e
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
@@ -0,0 +1,46 @@
+
+out vec4 FragColor;
+
+void main() {
+ vec3 N, T, B, V;
+
+ float NV = ( 1.0 - (clamp(gl_FragCoord.y / BRDF_LUT_SIZE, 1e-4, 0.9999)));
+ float sqrtRoughness = clamp(gl_FragCoord.x / BRDF_LUT_SIZE, 1e-4, 0.9999);
+ float a = sqrtRoughness * sqrtRoughness;
+ float a2 = a * a;
+
+ N = vec3(0.0, 0.0, 1.0);
+ T = vec3(1.0, 0.0, 0.0);
+ B = vec3(0.0, 1.0, 0.0);
+ V = vec3(sqrt(1.0 - NV * NV), 0.0, NV);
+
+ setup_noise();
+
+ /* Integrating BRDF */
+ float brdf_accum = 0.0;
+ float fresnel_accum = 0.0;
+ for (float i = 0; i < sampleCount; i++) {
+ vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
+ vec3 L = -reflect(V, H);
+ float NL = L.z;
+
+ if (NL > 0.0) {
+ float NH = max(H.z, 0.0);
+ float VH = max(dot(V, H), 0.0);
+
+ float G1_v = G1_Smith_GGX(NV, a2);
+ float G1_l = G1_Smith_GGX(NL, a2);
+ float G_smith = 4.0 * NV * NL / (G1_v * G1_l); /* See G1_Smith_GGX for explanations. */
+
+ float brdf = (G_smith * VH) / (NH * NV);
+ float Fc = pow(1.0 - VH, 5.0);
+
+ brdf_accum += (1.0 - Fc) * brdf;
+ fresnel_accum += Fc * brdf;
+ }
+ }
+ brdf_accum /= sampleCount;
+ fresnel_accum /= sampleCount;
+
+ FragColor = vec4(brdf_accum, fresnel_accum, 0.0, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
new file mode 100644
index 00000000000..898c7bfc578
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
@@ -0,0 +1,54 @@
+
+uniform sampler1D texHammersley;
+uniform sampler2D texJitter;
+uniform float sampleCount;
+uniform float invSampleCount;
+
+vec2 jitternoise = vec2(0.0);
+
+void setup_noise(void)
+{
+ jitternoise = texture(texJitter, gl_FragCoord.xy / NOISE_SIZE).rg; /* Global variable */
+}
+
+vec3 hammersley_3d(float i, float invsamplenbr)
+{
+ vec3 Xi; /* Theta, cos(Phi), sin(Phi) */
+
+ Xi.x = i * invsamplenbr; /* i/samples */
+ Xi.x = fract(Xi.x + jitternoise.x);
+
+ int u = int(mod(i + jitternoise.y * HAMMERSLEY_SIZE, HAMMERSLEY_SIZE));
+
+ Xi.yz = texelFetch(texHammersley, u, 0).rg;
+
+ return Xi;
+}
+
+vec3 hammersley_3d(float i)
+{
+ return hammersley_3d(i, invSampleCount);
+}
+
+/* -------------- BSDFS -------------- */
+
+float pdf_ggx_reflect(float NH, float a2)
+{
+ return NH * a2 / D_ggx_opti(NH, a2);
+}
+
+vec3 sample_ggx(float nsample, float a2, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ /* Theta is the aperture angle of the cone */
+ float z = sqrt( (1.0 - Xi.x) / ( 1.0 + a2 * Xi.x - Xi.x ) ); /* cos theta */
+ float r = sqrt( 1.0 - z * z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ /* Microfacet Normal */
+ vec3 Ht = vec3(x, y, z);
+
+ return tangent_to_world(Ht, N, T, B);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
new file mode 100644
index 00000000000..a212536011b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -0,0 +1,15 @@
+
+uniform vec3 basecol;
+uniform float metallic;
+uniform float specular;
+uniform float roughness;
+
+out vec4 FragColor;
+
+void main()
+{
+ vec3 dielectric = vec3(0.034) * specular * 2.0;
+ vec3 diffuse = mix(basecol, vec3(0.0), metallic);
+ vec3 f0 = mix(dielectric, basecol, metallic);
+ FragColor = vec4(eevee_surface_lit(worldNormal, diffuse, f0, roughness, 1.0), 1.0);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
new file mode 100644
index 00000000000..075ee22dc6f
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
@@ -0,0 +1,8 @@
+
+uniform vec3 color;
+
+out vec4 FragColor;
+
+void main() {
+ FragColor = vec4(color, 1.0);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
new file mode 100644
index 00000000000..52b1cc406d2
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
@@ -0,0 +1,207 @@
+/* Original implementation by Keijiro Takahashi
+ * Blender integration by Clément Foucault
+ *
+ * Original License :
+ *
+ * Kino/Bloom v2 - Bloom filter for Unity
+ *
+ * Copyright (C) 2015, 2016 Keijiro Takahashi
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+uniform sampler2D sourceBuffer; /* Buffer to filter */
+uniform vec2 sourceBufferTexelSize;
+
+/* Step Blit */
+uniform vec4 curveThreshold;
+
+/* Step Upsample */
+uniform sampler2D baseBuffer; /* Previous accumulation buffer */
+uniform vec2 baseBufferTexelSize;
+uniform float sampleScale;
+
+/* Step Resolve */
+uniform float bloomIntensity;
+
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+/* -------------- Utils ------------- */
+
+float brightness(vec3 c)
+{
+ return max(max(c.r, c.g), c.b);
+}
+
+/* 3-tap median filter */
+vec3 median(vec3 a, vec3 b, vec3 c)
+{
+ return a + b + c - min(min(a, b), c) - max(max(a, b), c);
+}
+
+/* ------------- Filters ------------ */
+
+vec3 downsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize)
+{
+ /* Downsample with a 4x4 box filter + anti-flicker filter */
+ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1);
+
+ vec3 s1 = texture(tex, uv + d.xy).rgb;
+ vec3 s2 = texture(tex, uv + d.zy).rgb;
+ vec3 s3 = texture(tex, uv + d.xw).rgb;
+ vec3 s4 = texture(tex, uv + d.zw).rgb;
+
+ /* Karis's luma weighted average (using brightness instead of luma) */
+ float s1w = 1.0 / (brightness(s1) + 1.0);
+ float s2w = 1.0 / (brightness(s2) + 1.0);
+ float s3w = 1.0 / (brightness(s3) + 1.0);
+ float s4w = 1.0 / (brightness(s4) + 1.0);
+ float one_div_wsum = 1.0 / (s1w + s2w + s3w + s4w);
+
+ return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div_wsum;
+}
+
+vec3 downsample_filter(sampler2D tex, vec2 uv, vec2 texelSize)
+{
+ /* Downsample with a 4x4 box filter */
+ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1);
+
+ vec3 s;
+ s = texture(tex, uv + d.xy).rgb;
+ s += texture(tex, uv + d.zy).rgb;
+ s += texture(tex, uv + d.xw).rgb;
+ s += texture(tex, uv + d.zw).rgb;
+
+ return s * (1.0 / 4);
+}
+
+vec3 upsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize)
+{
+ /* 9-tap bilinear upsampler (tent filter) */
+ vec4 d = texelSize.xyxy * vec4(1, 1, -1, 0) * sampleScale;
+
+ vec3 s;
+ s = texture(tex, uv - d.xy).rgb;
+ s += texture(tex, uv - d.wy).rgb * 2;
+ s += texture(tex, uv - d.zy).rgb;
+
+ s += texture(tex, uv + d.zw).rgb * 2;
+ s += texture(tex, uv ).rgb * 4;
+ s += texture(tex, uv + d.xw).rgb * 2;
+
+ s += texture(tex, uv + d.zy).rgb;
+ s += texture(tex, uv + d.wy).rgb * 2;
+ s += texture(tex, uv + d.xy).rgb;
+
+ return s * (1.0 / 16.0);
+}
+
+vec3 upsample_filter(sampler2D tex, vec2 uv, vec2 texelSize)
+{
+ /* 4-tap bilinear upsampler */
+ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1) * (sampleScale * 0.5);
+
+ vec3 s;
+ s = texture(tex, uv + d.xy).rgb;
+ s += texture(tex, uv + d.zy).rgb;
+ s += texture(tex, uv + d.xw).rgb;
+ s += texture(tex, uv + d.zw).rgb;
+
+ return s * (1.0 / 4.0);
+}
+
+/* ----------- Steps ----------- */
+
+vec4 step_blit(void)
+{
+ vec2 uv = uvcoordsvar.xy + sourceBufferTexelSize.xy * 0.5;
+
+#ifdef HIGH_QUALITY /* Anti flicker */
+ vec3 d = sourceBufferTexelSize.xyx * vec3(1, 1, 0);
+ vec3 s0 = texture(sourceBuffer, uvcoordsvar.xy).rgb;
+ vec3 s1 = texture(sourceBuffer, uvcoordsvar.xy - d.xz).rgb;
+ vec3 s2 = texture(sourceBuffer, uvcoordsvar.xy + d.xz).rgb;
+ vec3 s3 = texture(sourceBuffer, uvcoordsvar.xy - d.zy).rgb;
+ vec3 s4 = texture(sourceBuffer, uvcoordsvar.xy + d.zy).rgb;
+ vec3 m = median(median(s0.rgb, s1, s2), s3, s4);
+#else
+ vec3 s0 = texture(sourceBuffer, uvcoordsvar.xy).rgb;
+ vec3 m = s0.rgb;
+#endif
+
+ /* Pixel brightness */
+ float br = brightness(m);
+
+ /* Under-threshold part: quadratic curve */
+ float rq = clamp(br - curveThreshold.x, 0, curveThreshold.y);
+ rq = curveThreshold.z * rq * rq;
+
+ /* Combine and apply the brightness response curve. */
+ m *= max(rq, br - curveThreshold.w) / max(br, 1e-5);
+
+ return vec4(m, 1.0);
+}
+
+vec4 step_downsample(void)
+{
+#ifdef HIGH_QUALITY /* Anti flicker */
+ vec3 sample = downsample_filter_high(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
+#else
+ vec3 sample = downsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
+#endif
+ return vec4(sample, 1.0);
+}
+
+vec4 step_upsample(void)
+{
+#ifdef HIGH_QUALITY
+ vec3 blur = upsample_filter_high(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
+#else
+ vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
+#endif
+ vec3 base = texture(baseBuffer, uvcoordsvar.xy).rgb;
+ return vec4(base + blur, 1.0);
+}
+
+vec4 step_resolve(void)
+{
+#ifdef HIGH_QUALITY
+ vec3 blur = upsample_filter_high(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
+#else
+ vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
+#endif
+ vec4 base = texture(baseBuffer, uvcoordsvar.xy);
+ vec3 cout = base.rgb + blur * bloomIntensity;
+ return vec4(cout, base.a);
+}
+
+void main(void)
+{
+#if defined(STEP_BLIT)
+ FragColor = step_blit();
+#elif defined(STEP_DOWNSAMPLE)
+ FragColor = step_downsample();
+#elif defined(STEP_UPSAMPLE)
+ FragColor = step_upsample();
+#elif defined(STEP_RESOLVE)
+ FragColor = step_resolve();
+#endif
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
new file mode 100644
index 00000000000..2f5143390ce
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -0,0 +1,261 @@
+
+uniform mat4 ProjectionMatrix;
+
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
+
+uniform vec3 dofParams;
+
+#define dof_aperturesize dofParams.x
+#define dof_distance dofParams.y
+#define dof_invsensorsize dofParams.z
+
+uniform vec4 bokehParams;
+
+#define bokeh_sides bokehParams.x /* Polygon Bokeh shape number of sides */
+#define bokeh_rotation bokehParams.y
+#define bokeh_ratio bokehParams.z
+#define bokeh_maxsize bokehParams.w
+
+uniform vec2 nearFar; /* Near & far view depths values */
+
+/* initial uv coordinate */
+in vec2 uvcoord;
+
+layout(location = 0) out vec4 fragData0;
+layout(location = 1) out vec4 fragData1;
+layout(location = 2) out vec4 fragData2;
+
+#define M_PI 3.1415926535897932384626433832795
+#define M_2PI 6.2831853071795864769252868
+
+/* -------------- Utils ------------- */
+
+/* calculate 4 samples at once */
+float calculate_coc(in float zdepth)
+{
+ float coc = dof_aperturesize * (dof_distance / zdepth - 1.0);
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_invsensorsize;
+}
+
+vec4 calculate_coc(in vec4 zdepth)
+{
+ vec4 coc = dof_aperturesize * (vec4(dof_distance) / zdepth - vec4(1.0));
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_invsensorsize;
+}
+
+float max4(vec4 x)
+{
+ return max(max(x.x, x.y), max(x.z, x.w));
+}
+
+float linear_depth(float z)
+{
+ /* if persp */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ return (nearFar.x * nearFar.y) / (z * (nearFar.x - nearFar.y) + nearFar.y);
+ }
+ else {
+ return (z * 2.0 - 1.0) * nearFar.y;
+ }
+}
+
+vec4 linear_depth(vec4 z)
+{
+ /* if persp */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ return (nearFar.xxxx * nearFar.yyyy) / (z * (nearFar.xxxx - nearFar.yyyy) + nearFar.yyyy);
+ }
+ else {
+ return (z * 2.0 - 1.0) * nearFar.yyyy;
+ }
+}
+
+#define THRESHOLD 0.0
+
+/* ----------- Steps ----------- */
+
+/* Downsample the color buffer to half resolution.
+ * Weight color samples by
+ * Compute maximum CoC for near and far blur. */
+void step_downsample(void)
+{
+ ivec4 uvs = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1);
+
+ /* custom downsampling */
+ vec4 color1 = texelFetch(colorBuffer, uvs.xy, 0);
+ vec4 color2 = texelFetch(colorBuffer, uvs.zw, 0);
+ vec4 color3 = texelFetch(colorBuffer, uvs.zy, 0);
+ vec4 color4 = texelFetch(colorBuffer, uvs.xw, 0);
+
+ /* Leverage SIMD by combining 4 depth samples into a vec4 */
+ vec4 depth;
+ depth.r = texelFetch(depthBuffer, uvs.xy, 0).r;
+ depth.g = texelFetch(depthBuffer, uvs.zw, 0).r;
+ depth.b = texelFetch(depthBuffer, uvs.zy, 0).r;
+ depth.a = texelFetch(depthBuffer, uvs.xw, 0).r;
+
+ vec4 zdepth = linear_depth(depth);
+
+ /* Compute signed CoC for each depth samples */
+ vec4 coc_near = calculate_coc(zdepth);
+ vec4 coc_far = -coc_near;
+
+ /* now we need to write the near-far fields premultiplied by the coc */
+ vec4 near_weights = step(THRESHOLD, coc_near);
+ vec4 far_weights = step(THRESHOLD, coc_far);
+
+ /* now write output to weighted buffers. */
+ fragData0 = color1 * near_weights.x +
+ color2 * near_weights.y +
+ color3 * near_weights.z +
+ color4 * near_weights.w;
+
+ fragData1 = color1 * far_weights.x +
+ color2 * far_weights.y +
+ color3 * far_weights.z +
+ color4 * far_weights.w;
+
+ float norm_near = dot(near_weights, near_weights);
+ float norm_far = dot(far_weights, far_weights);
+
+ if (norm_near > 0.0) {
+ fragData0 /= norm_near;
+ }
+
+ if (norm_far > 0.0) {
+ fragData1 /= norm_far;
+ }
+
+ float max_near_coc = max(max4(coc_near), 0.0);
+ float max_far_coc = max(max4(coc_far), 0.0);
+
+ fragData2 = vec4(max_near_coc, max_far_coc, 0.0, 1.0);
+}
+
+/* coordinate used for calculating radius et al set in geometry shader */
+in vec2 particlecoord;
+flat in vec4 color;
+
+/* accumulate color in the near/far blur buffers */
+void step_scatter(void)
+{
+ /* Early out */
+ float dist_sqrd = dot(particlecoord, particlecoord);
+
+ /* Circle Dof */
+ if (dist_sqrd > 1.0) {
+ discard;
+ }
+
+ /* Regular Polygon Dof */
+ if (bokeh_sides > 0.0) {
+ /* Circle parametrization */
+ float theta = atan(particlecoord.y, particlecoord.x) + bokeh_rotation;
+ float r;
+
+ r = cos(M_PI / bokeh_sides) /
+ (cos(theta - (M_2PI / bokeh_sides) * floor((bokeh_sides * theta + M_PI) / M_2PI)));
+
+ if (dist_sqrd > r * r) {
+ discard;
+ }
+ }
+
+ fragData0 = color;
+}
+
+#define MERGE_THRESHOLD 4.0
+
+uniform sampler2D farBuffer;
+uniform sampler2D nearBuffer;
+
+vec4 upsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize)
+{
+ /* 9-tap bilinear upsampler (tent filter) */
+ vec4 d = texelSize.xyxy * vec4(1, 1, -1, 0);
+
+ vec4 s;
+ s = texture(tex, uv - d.xy);
+ s += texture(tex, uv - d.wy) * 2;
+ s += texture(tex, uv - d.zy);
+
+ s += texture(tex, uv + d.zw) * 2;
+ s += texture(tex, uv ) * 4;
+ s += texture(tex, uv + d.xw) * 2;
+
+ s += texture(tex, uv + d.zy);
+ s += texture(tex, uv + d.wy) * 2;
+ s += texture(tex, uv + d.xy);
+
+ return s * (1.0 / 16.0);
+}
+
+vec4 upsample_filter(sampler2D tex, vec2 uv, vec2 texelSize)
+{
+ /* 4-tap bilinear upsampler */
+ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1) * 0.5;
+
+ vec4 s;
+ s = texture(tex, uv + d.xy);
+ s += texture(tex, uv + d.zy);
+ s += texture(tex, uv + d.xw);
+ s += texture(tex, uv + d.zw);
+
+ return s * (1.0 / 4.0);
+}
+
+/* Combine the Far and Near color buffers */
+void step_resolve(void)
+{
+ /* Recompute Near / Far CoC */
+ float depth = texture(depthBuffer, uvcoord).r;
+ float zdepth = linear_depth(depth);
+ float coc_signed = calculate_coc(zdepth);
+ float coc_far = max(-coc_signed, 0.0);
+ float coc_near = max(coc_signed, 0.0);
+
+ /* Recompute Near / Far CoC */
+ vec2 texelSize = 1.0 / vec2(textureSize(farBuffer, 0));
+ vec4 srccolor = texture(colorBuffer, uvcoord);
+ vec4 farcolor = upsample_filter_high(farBuffer, uvcoord, texelSize);
+ vec4 nearcolor = upsample_filter_high(nearBuffer, uvcoord, texelSize);
+
+ float farweight = farcolor.a;
+ if (farweight > 0.0)
+ farcolor /= farweight;
+
+ float mixfac = smoothstep(1.0, MERGE_THRESHOLD, coc_far);
+
+ farweight = mix(1.0, farweight, mixfac);
+
+ float nearweight = nearcolor.a;
+ if (nearweight > 0.0) {
+ nearcolor /= nearweight;
+ }
+
+ if (coc_near > 1.0) {
+ mixfac = smoothstep(1.0, MERGE_THRESHOLD, coc_near);
+ fragData0 = mix(srccolor, nearcolor, mixfac);
+ }
+ else {
+ float totalweight = nearweight + farweight;
+ vec4 finalcolor = mix(srccolor, farcolor, mixfac);
+ fragData0 = mix(finalcolor, nearcolor, nearweight / totalweight);
+ }
+}
+
+void main()
+{
+#ifdef STEP_DOWNSAMPLE
+ step_downsample();
+#elif defined(STEP_SCATTER)
+ step_scatter();
+#elif defined(STEP_RESOLVE)
+ step_resolve();
+#endif
+}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_geom.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_geom.glsl
new file mode 100644
index 00000000000..1c774885a32
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_geom.glsl
@@ -0,0 +1,55 @@
+uniform ivec2 targetBufferSize;
+
+uniform vec2 layerSelection;
+
+uniform sampler2D colorBuffer;
+uniform sampler2D cocBuffer;
+
+layout(points) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+#define POS gl_in[0].gl_Position
+
+in vec2 uvcoord[];
+out vec2 particlecoord;
+flat out vec4 color;
+
+#define M_PI 3.1415926535897932384626433832795
+
+void main()
+{
+ vec4 coc = textureLod(cocBuffer, uvcoord[0], 0.0);
+
+ float offset_val = dot(coc.rg, layerSelection);
+ if (offset_val < 1.0)
+ return;
+
+ vec4 colortex = textureLod(colorBuffer, uvcoord[0], 0.0);
+
+ /* find the area the pixel will cover and divide the color by it */
+ float alpha = 1.0 / (offset_val * offset_val * M_PI);
+ colortex *= alpha;
+ colortex.a = alpha;
+
+ vec2 offset_far = vec2(offset_val * 0.5) / vec2(targetBufferSize.x, targetBufferSize.y);
+
+ color = colortex;
+
+ gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
+ particlecoord = vec2(-1.0, -1.0);
+ EmitVertex();
+
+ gl_Position = POS + vec4(-offset_far.x, offset_far.y, 0.0, 0.0);
+ particlecoord = vec2(-1.0, 1.0);
+ EmitVertex();
+
+ gl_Position = POS + vec4(offset_far.x, -offset_far.y, 0.0, 0.0);
+ particlecoord = vec2(1.0, -1.0);
+ EmitVertex();
+
+ gl_Position = POS + vec4(offset_far.x, offset_far.y, 0.0, 0.0);
+ particlecoord = vec2(1.0, 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
new file mode 100644
index 00000000000..0f5c5e5b16b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
@@ -0,0 +1,99 @@
+
+in vec2 pos;
+in vec2 uvs;
+
+uniform vec2 layerSelection;
+
+uniform vec4 bokehParams;
+
+#define bokeh_sides bokehParams.x /* Polygon Bokeh shape number of sides */
+#define bokeh_rotation bokehParams.y
+#define bokeh_ratio bokehParams.z
+#define bokeh_maxsize bokehParams.w
+
+uniform sampler2D colorBuffer;
+uniform sampler2D cocBuffer;
+
+flat out vec4 color;
+out vec2 particlecoord;
+
+#define M_PI 3.1415926535897932384626433832795
+
+/* geometry shading pass, calculate a texture coordinate based on the indexed id */
+void step_scatter()
+{
+ ivec2 tex_size = textureSize(cocBuffer, 0);
+ vec2 texel_size = 1.0 / vec2(tex_size);
+
+ int t_id = gl_VertexID / 3; /* Triangle Id */
+
+ ivec2 texelco = ivec2(0);
+ /* some math to get the target pixel */
+ texelco.x = t_id % tex_size.x;
+ texelco.y = t_id / tex_size.x;
+
+ float coc = dot(layerSelection, texelFetch(cocBuffer, texelco, 0).rg);
+
+ /* Clamp to max size for performance */
+ coc = min(coc, bokeh_maxsize);
+
+ if (coc >= 1.0) {
+ color = texelFetch(colorBuffer, texelco, 0);
+ /* find the area the pixel will cover and divide the color by it */
+ float alpha = 1.0 / (coc * coc * M_PI);
+ color *= alpha;
+ color.a = alpha;
+ }
+ else {
+ color = vec4(0.0);
+ }
+
+ /* Generate Triangle : less memory fetches from a VBO */
+ int v_id = gl_VertexID % 3; /* Vertex Id */
+
+ /* Extend to cover at least the unit circle */
+ const float extend = (cos(M_PI / 4.0) + 1.0) * 2.0;
+ /* Crappy diagram
+ * ex 1
+ * | \
+ * | \
+ * 1 | \
+ * | \
+ * | \
+ * 0 | x \
+ * | Circle \
+ * | Origin \
+ * -1 0 --------------- 2
+ * -1 0 1 ex
+ **/
+ gl_Position.x = float(v_id / 2) * extend - 1.0; /* int divisor round down */
+ gl_Position.y = float(v_id % 2) * extend - 1.0;
+ gl_Position.z = 0.0;
+ gl_Position.w = 1.0;
+
+ /* Generate Triangle */
+ particlecoord = gl_Position.xy;
+
+ gl_Position.xy *= coc * texel_size * vec2(bokeh_ratio, 1.0);
+ gl_Position.xy -= 1.0 - 0.5 * texel_size; /* NDC Bottom left */
+ gl_Position.xy += (0.5 + vec2(texelco) * 2.0) * texel_size;
+}
+
+out vec2 uvcoord;
+
+void passthrough()
+{
+ uvcoord = uvs;
+ gl_Position = vec4(pos, 0.0, 1.0);
+}
+
+void main()
+{
+#if defined(STEP_DOWNSAMPLE)
+ passthrough();
+#elif defined(STEP_SCATTER)
+ step_scatter();
+#elif defined(STEP_RESOLVE)
+ passthrough();
+#endif
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
new file mode 100644
index 00000000000..8960b339a61
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
@@ -0,0 +1,63 @@
+
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
+
+
+/* current frame */
+uniform mat4 currInvViewProjMatrix;
+
+/* past frame frame */
+uniform mat4 pastViewProjMatrix;
+
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+#define MAX_SAMPLE 64
+
+uniform int samples;
+
+float wang_hash_noise(uint s)
+{
+ uint seed = (uint(gl_FragCoord.x) * 1664525u + uint(gl_FragCoord.y)) + s;
+
+ seed = (seed ^ 61u) ^ (seed >> 16u);
+ seed *= 9u;
+ seed = seed ^ (seed >> 4u);
+ seed *= 0x27d4eb2du;
+ seed = seed ^ (seed >> 15u);
+
+ float value = float(seed);
+ value *= 1.0 / 4294967296.0;
+ return fract(value);
+}
+
+void main()
+{
+ vec3 ndc_pos;
+ ndc_pos.xy = uvcoordsvar.xy;
+ ndc_pos.z = texture(depthBuffer, uvcoordsvar.xy).x;
+
+ float inv_samples = 1.0 / float(samples);
+ float noise = 2.0 * wang_hash_noise(0u) * inv_samples;
+
+ /* Normalize Device Coordinates are [-1, +1]. */
+ ndc_pos = ndc_pos * 2.0 - 1.0;
+
+ vec4 p = currInvViewProjMatrix * vec4(ndc_pos, 1.0);
+ vec3 world_pos = p.xyz / p.w; /* Perspective divide */
+
+ /* Now find where was this pixel position
+ * inside the past camera viewport */
+ vec4 old_ndc = pastViewProjMatrix * vec4(world_pos, 1.0);
+ old_ndc.xyz /= old_ndc.w; /* Perspective divide */
+
+ vec2 motion = (ndc_pos.xy - old_ndc.xy) * 0.25; /* 0.25 fit cycles ref */
+
+ float inc = 2.0 * inv_samples;
+ float i = -1.0 + noise;
+ for (int j = 0; j < samples && j < MAX_SAMPLE; j++) {
+ FragColor += texture(colorBuffer, uvcoordsvar.xy + motion * i) * inv_samples;
+ i += inc;
+ }
+}
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
new file mode 100644
index 00000000000..92069dc37e4
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -0,0 +1,228 @@
+
+uniform int light_count;
+uniform vec3 cameraPos;
+uniform vec3 eye;
+uniform mat4 ProjectionMatrix;
+
+uniform sampler2D probeFiltered;
+uniform float lodMax;
+uniform vec3 shCoefs[9];
+
+#ifndef USE_LTC
+uniform sampler2D brdfLut;
+#endif
+uniform sampler2DArray shadowCubes;
+uniform sampler2DArrayShadow shadowCascades;
+
+layout(std140) uniform light_block {
+ LightData lights_data[MAX_LIGHT];
+};
+
+layout(std140) uniform shadow_block {
+ ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE];
+ ShadowMapData shadows_map_data[MAX_SHADOW_MAP];
+ ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE];
+};
+
+in vec3 worldPosition;
+in vec3 viewPosition;
+
+#ifdef USE_FLAT_NORMAL
+flat in vec3 worldNormal;
+flat in vec3 viewNormal;
+#else
+in vec3 worldNormal;
+in vec3 viewNormal;
+#endif
+
+/* type */
+#define POINT 0.0
+#define SUN 1.0
+#define SPOT 2.0
+#define HEMI 3.0
+#define AREA 4.0
+
+vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size)
+{
+ /* projection onto octahedron */
+ cubevec /= dot( vec3(1), abs(cubevec) );
+
+ /* out-folding of the downward faces */
+ if ( cubevec.z < 0.0 ) {
+ cubevec.xy = (1.0 - abs(cubevec.yx)) * sign(cubevec.xy);
+ }
+
+ /* mapping to [0;1]ˆ2 texture space */
+ vec2 uvs = cubevec.xy * (0.5) + 0.5;
+
+ /* edge filtering fix */
+ uvs *= 1.0 - 2.0 * texel_size;
+ uvs += texel_size;
+
+ return uvs;
+}
+
+vec4 textureLod_octahedron(sampler2D tex, vec3 cubevec, float lod)
+{
+ vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lodMax)));
+
+ vec2 uvs = mapping_octahedron(cubevec, texelSize);
+
+ return textureLod(tex, uvs, lod);
+}
+
+vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec)
+{
+ vec2 texelSize = 1.0 / vec2(textureSize(tex, 0));
+
+ vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize);
+
+ return texture(tex, vec3(uvs, cubevec.w));
+}
+
+void light_shade(
+ LightData ld, ShadingData sd, vec3 albedo, float roughness, vec3 f0,
+ out vec3 diffuse, out vec3 specular)
+{
+#ifdef USE_LTC
+ if (ld.l_type == SUN) {
+ /* TODO disk area light */
+ diffuse = direct_diffuse_sun(ld, sd) * albedo;
+ specular = direct_ggx_sun(ld, sd, roughness, f0);
+ }
+ else if (ld.l_type == AREA) {
+ diffuse = direct_diffuse_rectangle(ld, sd) * albedo;
+ specular = direct_ggx_rectangle(ld, sd, roughness, f0);
+ }
+ else {
+ diffuse = direct_diffuse_sphere(ld, sd) * albedo;
+ specular = direct_ggx_sphere(ld, sd, roughness, f0);
+ }
+#else
+ if (ld.l_type == SUN) {
+ diffuse = direct_diffuse_sun(ld, sd) * albedo;
+ specular = direct_ggx_sun(ld, sd, roughness, f0);
+ }
+ else {
+ diffuse = direct_diffuse_point(ld, sd) * albedo;
+ specular = direct_ggx_point(sd, roughness, f0);
+ }
+#endif
+}
+
+void light_visibility(LightData ld, ShadingData sd, out float vis)
+{
+ vis = 1.0;
+
+ if (ld.l_type == SPOT) {
+ float z = dot(ld.l_forward, sd.l_vector);
+ vec3 lL = sd.l_vector / z;
+ float x = dot(ld.l_right, lL) / ld.l_sizex;
+ float y = dot(ld.l_up, lL) / ld.l_sizey;
+
+ float ellipse = 1.0 / sqrt(1.0 + x * x + y * y);
+
+ float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend);
+
+ vis *= spotmask;
+ vis *= step(0.0, -dot(sd.l_vector, ld.l_forward));
+ }
+ else if (ld.l_type == AREA) {
+ vis *= step(0.0, -dot(sd.l_vector, ld.l_forward));
+ }
+
+ /* shadowing */
+ if (ld.l_shadowid >= (MAX_SHADOW_MAP + MAX_SHADOW_CUBE)) {
+ /* Shadow Cascade */
+ float shid = ld.l_shadowid - (MAX_SHADOW_CUBE + MAX_SHADOW_MAP);
+ ShadowCascadeData smd = shadows_cascade_data[int(shid)];
+
+ /* Finding Cascade index */
+ vec4 z = vec4(-dot(cameraPos - worldPosition, normalize(eye)));
+ vec4 comp = step(z, smd.split_distances);
+ float cascade = dot(comp, comp);
+ mat4 shadowmat;
+ float bias;
+
+ /* Manual Unrolling of a loop for better performance.
+ * Doing fetch directly with cascade index leads to
+ * major performance impact. (0.27ms -> 10.0ms for 1 light) */
+ if (cascade == 0.0) {
+ shadowmat = smd.shadowmat[0];
+ bias = smd.bias[0];
+ }
+ else if (cascade == 1.0) {
+ shadowmat = smd.shadowmat[1];
+ bias = smd.bias[1];
+ }
+ else if (cascade == 2.0) {
+ shadowmat = smd.shadowmat[2];
+ bias = smd.bias[2];
+ }
+ else {
+ shadowmat = smd.shadowmat[3];
+ bias = smd.bias[3];
+ }
+
+ vec4 shpos = shadowmat * vec4(sd.W, 1.0);
+ shpos.z -= bias * shpos.w;
+ shpos.xyz /= shpos.w;
+
+ vis *= texture(shadowCascades, vec4(shpos.xy, shid * float(MAX_CASCADE_NUM) + cascade, shpos.z));
+ }
+ else if (ld.l_shadowid >= 0.0) {
+ /* Shadow Cube */
+ float shid = ld.l_shadowid;
+ ShadowCubeData scd = shadows_cube_data[int(shid)];
+
+ vec3 cubevec = sd.W - ld.l_position;
+ float dist = length(cubevec);
+
+ float z = texture_octahedron(shadowCubes, vec4(cubevec, shid)).r;
+
+ float esm_test = min(1.0, exp(-5.0 * dist) * z);
+ float sh_test = step(0, z - dist);
+
+ vis *= esm_test;
+ }
+}
+
+vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, float ao)
+{
+ float roughnessSquared = roughness * roughness;
+
+ ShadingData sd;
+ sd.N = normalize(world_normal);
+ sd.V = (ProjectionMatrix[3][3] == 0.0) /* if perspective */
+ ? normalize(cameraPos - worldPosition)
+ : normalize(eye);
+ sd.W = worldPosition;
+
+ vec3 radiance = vec3(0.0);
+ vec3 indirect_radiance = vec3(0.0);
+
+ /* Analitic Lights */
+ for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
+ LightData ld = lights_data[i];
+ vec3 diff, spec;
+ float vis;
+
+ sd.l_vector = ld.l_position - worldPosition;
+
+ light_visibility(ld, sd, vis);
+ light_shade(ld, sd, albedo, roughnessSquared, f0, diff, spec);
+
+ radiance += vis * (diff + spec) * ld.l_color;
+ }
+
+ vec3 spec_dir = get_specular_dominant_dir(sd.N, reflect(-sd.V, sd.N), roughnessSquared);
+
+ /* Envmaps */
+ vec2 uv = lut_coords(dot(sd.N, sd.V), roughness);
+ vec3 brdf_lut = texture(brdfLut, uv).rgb;
+ vec3 Li = textureLod_octahedron(probeFiltered, spec_dir, roughness * lodMax).rgb;
+ indirect_radiance += Li * F_ibl(f0, brdf_lut.rg);
+ indirect_radiance += spherical_harmonics(sd.N, shCoefs) * albedo;
+
+ return radiance + indirect_radiance * ao;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
new file mode 100644
index 00000000000..cf5c8a311f1
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
@@ -0,0 +1,34 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
+uniform mat4 ModelViewMatrix;
+uniform mat3 WorldNormalMatrix;
+#ifndef ATTRIB
+uniform mat3 NormalMatrix;
+#endif
+
+in vec3 pos;
+in vec3 nor;
+
+out vec3 worldPosition;
+out vec3 viewPosition;
+
+#ifdef USE_FLAT_NORMAL
+flat out vec3 worldNormal;
+flat out vec3 viewNormal;
+#else
+out vec3 worldNormal;
+out vec3 viewNormal;
+#endif
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ viewPosition = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
+ worldPosition = (ModelMatrix * vec4(pos, 1.0)).xyz;
+ viewNormal = normalize(NormalMatrix * nor);
+ worldNormal = normalize(WorldNormalMatrix * nor);
+
+#ifdef ATTRIB
+ pass_attrib(pos);
+#endif
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
new file mode 100644
index 00000000000..4b02e8c222f
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
@@ -0,0 +1,232 @@
+/* Mainly From https://eheitzresearch.wordpress.com/415-2/ */
+
+#define USE_LTC
+
+uniform sampler2D ltcMat;
+uniform sampler2D brdfLut;
+
+/* from Real-Time Area Lighting: a Journey from Research to Production
+ * Stephen Hill and Eric Heitz */
+float edge_integral(vec3 p1, vec3 p2)
+{
+#if 0
+ /* more accurate replacement of acos */
+ float x = dot(p1, p2);
+ float y = abs(x);
+
+ float a = 5.42031 + (3.12829 + 0.0902326 * y) * y;
+ float b = 3.45068 + (4.18814 + y) * y;
+ float theta_sintheta = a / b;
+
+ if (x < 0.0) {
+ theta_sintheta = (M_PI / sqrt(1.0 - x * x)) - theta_sintheta;
+ }
+ vec3 u = cross(p1, p2);
+ return theta_sintheta * dot(u, N);
+#endif
+ float cos_theta = dot(p1, p2);
+ cos_theta = clamp(cos_theta, -0.9999, 0.9999);
+
+ float theta = acos(cos_theta);
+ vec3 u = normalize(cross(p1, p2));
+ return theta * cross(p1, p2).z / sin(theta);
+}
+
+int clip_quad_to_horizon(inout vec3 L[5])
+{
+ /* detect clipping config */
+ int config = 0;
+ if (L[0].z > 0.0) config += 1;
+ if (L[1].z > 0.0) config += 2;
+ if (L[2].z > 0.0) config += 4;
+ if (L[3].z > 0.0) config += 8;
+
+ /* clip */
+ int n = 0;
+
+ if (config == 0)
+ {
+ /* clip all */
+ }
+ else if (config == 1) /* V1 clip V2 V3 V4 */
+ {
+ n = 3;
+ L[1] = -L[1].z * L[0] + L[0].z * L[1];
+ L[2] = -L[3].z * L[0] + L[0].z * L[3];
+ }
+ else if (config == 2) /* V2 clip V1 V3 V4 */
+ {
+ n = 3;
+ L[0] = -L[0].z * L[1] + L[1].z * L[0];
+ L[2] = -L[2].z * L[1] + L[1].z * L[2];
+ }
+ else if (config == 3) /* V1 V2 clip V3 V4 */
+ {
+ n = 4;
+ L[2] = -L[2].z * L[1] + L[1].z * L[2];
+ L[3] = -L[3].z * L[0] + L[0].z * L[3];
+ }
+ else if (config == 4) /* V3 clip V1 V2 V4 */
+ {
+ n = 3;
+ L[0] = -L[3].z * L[2] + L[2].z * L[3];
+ L[1] = -L[1].z * L[2] + L[2].z * L[1];
+ }
+ else if (config == 5) /* V1 V3 clip V2 V4) impossible */
+ {
+ n = 0;
+ }
+ else if (config == 6) /* V2 V3 clip V1 V4 */
+ {
+ n = 4;
+ L[0] = -L[0].z * L[1] + L[1].z * L[0];
+ L[3] = -L[3].z * L[2] + L[2].z * L[3];
+ }
+ else if (config == 7) /* V1 V2 V3 clip V4 */
+ {
+ n = 5;
+ L[4] = -L[3].z * L[0] + L[0].z * L[3];
+ L[3] = -L[3].z * L[2] + L[2].z * L[3];
+ }
+ else if (config == 8) /* V4 clip V1 V2 V3 */
+ {
+ n = 3;
+ L[0] = -L[0].z * L[3] + L[3].z * L[0];
+ L[1] = -L[2].z * L[3] + L[3].z * L[2];
+ L[2] = L[3];
+ }
+ else if (config == 9) /* V1 V4 clip V2 V3 */
+ {
+ n = 4;
+ L[1] = -L[1].z * L[0] + L[0].z * L[1];
+ L[2] = -L[2].z * L[3] + L[3].z * L[2];
+ }
+ else if (config == 10) /* V2 V4 clip V1 V3) impossible */
+ {
+ n = 0;
+ }
+ else if (config == 11) /* V1 V2 V4 clip V3 */
+ {
+ n = 5;
+ L[4] = L[3];
+ L[3] = -L[2].z * L[3] + L[3].z * L[2];
+ L[2] = -L[2].z * L[1] + L[1].z * L[2];
+ }
+ else if (config == 12) /* V3 V4 clip V1 V2 */
+ {
+ n = 4;
+ L[1] = -L[1].z * L[2] + L[2].z * L[1];
+ L[0] = -L[0].z * L[3] + L[3].z * L[0];
+ }
+ else if (config == 13) /* V1 V3 V4 clip V2 */
+ {
+ n = 5;
+ L[4] = L[3];
+ L[3] = L[2];
+ L[2] = -L[1].z * L[2] + L[2].z * L[1];
+ L[1] = -L[1].z * L[0] + L[0].z * L[1];
+ }
+ else if (config == 14) /* V2 V3 V4 clip V1 */
+ {
+ n = 5;
+ L[4] = -L[0].z * L[3] + L[3].z * L[0];
+ L[0] = -L[0].z * L[1] + L[1].z * L[0];
+ }
+ else if (config == 15) /* V1 V2 V3 V4 */
+ {
+ n = 4;
+ }
+
+ if (n == 3)
+ L[3] = L[0];
+ if (n == 4)
+ L[4] = L[0];
+
+ return n;
+}
+
+mat3 ltc_matrix(vec4 lut)
+{
+ /* load inverse matrix */
+ mat3 Minv = mat3(
+ vec3( 1, 0, lut.y),
+ vec3( 0, lut.z, 0),
+ vec3(lut.w, 0, lut.x)
+ );
+
+ return Minv;
+}
+
+float ltc_evaluate(vec3 N, vec3 V, mat3 Minv, vec3 corners[4])
+{
+ /* construct orthonormal basis around N */
+ vec3 T1, T2;
+ T1 = normalize(V - N*dot(V, N));
+ T2 = cross(N, T1);
+
+ /* rotate area light in (T1, T2, R) basis */
+ Minv = Minv * transpose(mat3(T1, T2, N));
+
+ /* polygon (allocate 5 vertices for clipping) */
+ vec3 L[5];
+ L[0] = Minv * corners[0];
+ L[1] = Minv * corners[1];
+ L[2] = Minv * corners[2];
+ L[3] = Minv * corners[3];
+
+ int n = clip_quad_to_horizon(L);
+
+ if (n == 0)
+ return 0.0;
+
+ /* project onto sphere */
+ L[0] = normalize(L[0]);
+ L[1] = normalize(L[1]);
+ L[2] = normalize(L[2]);
+ L[3] = normalize(L[3]);
+ L[4] = normalize(L[4]);
+
+ /* integrate */
+ float sum = 0.0;
+
+ sum += edge_integral(L[0], L[1]);
+ sum += edge_integral(L[1], L[2]);
+ sum += edge_integral(L[2], L[3]);
+ if (n >= 4)
+ sum += edge_integral(L[3], L[4]);
+ if (n == 5)
+ sum += edge_integral(L[4], L[0]);
+
+ return abs(sum);
+}
+
+/* Aproximate circle with an octogone */
+#define LTC_CIRCLE_RES 8
+float ltc_evaluate_circle(vec3 N, vec3 V, mat3 Minv, vec3 p[LTC_CIRCLE_RES])
+{
+ /* construct orthonormal basis around N */
+ vec3 T1, T2;
+ T1 = normalize(V - N*dot(V, N));
+ T2 = cross(N, T1);
+
+ /* rotate area light in (T1, T2, R) basis */
+ Minv = Minv * transpose(mat3(T1, T2, N));
+
+ for (int i = 0; i < LTC_CIRCLE_RES; ++i) {
+ p[i] = Minv * p[i];
+ /* clip to horizon */
+ p[i].z = max(0.0, p[i].z);
+ /* project onto sphere */
+ p[i] = normalize(p[i]);
+ }
+
+ /* integrate */
+ float sum = 0.0;
+ for (int i = 0; i < LTC_CIRCLE_RES - 1; ++i) {
+ sum += edge_integral(p[i], p[i + 1]);
+ }
+ sum += edge_integral(p[LTC_CIRCLE_RES - 1], p[0]);
+
+ return max(0.0, sum);
+}
+
diff --git a/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl b/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl
new file mode 100644
index 00000000000..33714c5293c
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl
@@ -0,0 +1,86 @@
+
+uniform samplerCube probeHdr;
+uniform float roughnessSquared;
+uniform float texelSize;
+uniform float lodFactor;
+uniform float lodMax;
+uniform float paddingSize;
+
+in vec3 worldPosition;
+
+out vec4 FragColor;
+
+vec3 octahedral_to_cubemap_proj(vec2 co)
+{
+ co = co * 2.0 - 1.0;
+
+ vec2 abs_co = abs(co);
+ vec3 v = vec3(co, 1.0 - (abs_co.x + abs_co.y));
+
+ if ( abs_co.x + abs_co.y > 1.0 ) {
+ v.xy = (abs(co.yx) - 1.0) * -sign(co.xy);
+ }
+
+ return v;
+}
+
+void main() {
+ vec2 uvs = gl_FragCoord.xy * texelSize;
+
+ /* Add a N pixel border to ensure filtering is correct
+ * for N mipmap levels. */
+ uvs += uvs * texelSize * paddingSize * 2.0;
+ uvs -= texelSize * paddingSize;
+
+ /* edge mirroring : only mirror if directly adjacent
+ * (not diagonally adjacent) */
+ vec2 m = abs(uvs - 0.5) + 0.5;
+ vec2 f = floor(m);
+ if (f.x - f.y != 0.0) {
+ uvs = 1.0 - uvs;
+ }
+
+ /* clamp to [0-1] */
+ uvs = fract(uvs);
+
+ /* get cubemap vector */
+ vec3 cubevec = octahedral_to_cubemap_proj(uvs);
+
+ vec3 N, T, B, V;
+
+ vec3 R = normalize(cubevec);
+
+ /* Isotropic assumption */
+ N = V = R;
+
+ make_orthonormal_basis(N, T, B); /* Generate tangent space */
+
+ /* Noise to dither the samples */
+ /* Note : ghosting is better looking than noise. */
+ // setup_noise();
+
+ /* Integrating Envmap */
+ float weight = 0.0;
+ vec3 out_radiance = vec3(0.0);
+ for (float i = 0; i < sampleCount; i++) {
+ vec3 H = sample_ggx(i, roughnessSquared, N, T, B); /* Microfacet normal */
+ vec3 L = -reflect(V, H);
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ float NH = max(1e-8, dot(N, H)); /* cosTheta */
+
+ /* Coarse Approximation of the mapping distortion
+ * Unit Sphere -> Cubemap Face */
+ const float dist = 4.0 * M_PI / 6.0;
+ float pdf = pdf_ggx_reflect(NH, roughnessSquared);
+ /* http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html : Equation 13 */
+ float lod = clamp(lodFactor - 0.5 * log2(pdf * dist), 0.0, lodMax) ;
+
+ out_radiance += textureLod(probeHdr, L, lod).rgb * NL;
+ weight += NL;
+ }
+ }
+
+ FragColor = vec4(out_radiance / weight, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/probe_geom.glsl b/source/blender/draw/engines/eevee/shaders/probe_geom.glsl
new file mode 100644
index 00000000000..c7250e1212e
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/probe_geom.glsl
@@ -0,0 +1,28 @@
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+uniform int Layer;
+
+in vec4 vPos[];
+flat in int face[];
+
+out vec3 worldPosition;
+out vec3 worldNormal; /* Required. otherwise generate linking error on AMD. */
+
+const vec3 maj_axes[6] = vec3[6](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3( 0.0, 0.0, 1.0), vec3( 0.0, 0.0, -1.0));
+const vec3 x_axis[6] = vec3[6](vec3(0.0, 0.0, -1.0), vec3( 0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec3( 1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0));
+const vec3 y_axis[6] = vec3[6](vec3(0.0, -1.0, 0.0), vec3( 0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0), vec3( 0.0, -1.0, 0.0), vec3( 0.0, -1.0, 0.0));
+
+void main() {
+ int f = face[0];
+ gl_Layer = Layer + f;
+
+ for (int v = 0; v < 3; ++v) {
+ gl_Position = vPos[v];
+ worldPosition = x_axis[f] * vPos[v].x + y_axis[f] * vPos[v].y + maj_axes[f];
+ EmitVertex();
+ }
+
+ EndPrimitive();
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/probe_sh_frag.glsl b/source/blender/draw/engines/eevee/shaders/probe_sh_frag.glsl
new file mode 100644
index 00000000000..1bb14b76f42
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/probe_sh_frag.glsl
@@ -0,0 +1,107 @@
+
+uniform samplerCube probeHdr;
+uniform int probeSize;
+uniform float lodBias;
+
+in vec3 worldPosition;
+
+out vec4 FragColor;
+
+#define M_4PI 12.5663706143591729
+
+const mat3 CUBE_ROTATIONS[6] = mat3[](
+ mat3(vec3( 0.0, 0.0, -1.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3(-1.0, 0.0, 0.0)),
+ mat3(vec3( 0.0, 0.0, 1.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3( 1.0, 0.0, 0.0)),
+ mat3(vec3( 1.0, 0.0, 0.0),
+ vec3( 0.0, 0.0, 1.0),
+ vec3( 0.0, -1.0, 0.0)),
+ mat3(vec3( 1.0, 0.0, 0.0),
+ vec3( 0.0, 0.0, -1.0),
+ vec3( 0.0, 1.0, 0.0)),
+ mat3(vec3( 1.0, 0.0, 0.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3( 0.0, 0.0, -1.0)),
+ mat3(vec3(-1.0, 0.0, 0.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3( 0.0, 0.0, 1.0)));
+
+vec3 get_cubemap_vector(vec2 co, int face)
+{
+ return normalize(CUBE_ROTATIONS[face] * vec3(co * 2.0 - 1.0, 1.0));
+}
+
+float area_element(float x, float y)
+{
+ return atan(x * y, sqrt(x * x + y * y + 1));
+}
+
+float texel_solid_angle(vec2 co, float halfpix)
+{
+ vec2 v1 = (co - vec2(halfpix)) * 2.0 - 1.0;
+ vec2 v2 = (co + vec2(halfpix)) * 2.0 - 1.0;
+
+ return area_element(v1.x, v1.y) - area_element(v1.x, v2.y) - area_element(v2.x, v1.y) + area_element(v2.x, v2.y);
+}
+
+void main()
+{
+ float pixstep = 1.0 / probeSize;
+ float halfpix = pixstep / 2.0;
+
+ float weight_accum = 0.0;
+ vec3 sh = vec3(0.0);
+
+ int shnbr = int(floor(gl_FragCoord.x));
+
+ for (int face = 0; face < 6; ++face) {
+ for (float x = halfpix; x < 1.0; x += pixstep) {
+ for (float y = halfpix; y < 1.0; y += pixstep) {
+ float shcoef;
+
+ vec2 facecoord = vec2(x,y);
+ vec3 cubevec = get_cubemap_vector(facecoord, face);
+ float weight = texel_solid_angle(facecoord, halfpix);
+
+ if (shnbr == 0) {
+ shcoef = 0.282095;
+ }
+ else if (shnbr == 1) {
+ shcoef = -0.488603 * cubevec.z * 2.0 / 3.0;
+ }
+ else if (shnbr == 2) {
+ shcoef = 0.488603 * cubevec.y * 2.0 / 3.0;
+ }
+ else if (shnbr == 3) {
+ shcoef = -0.488603 * cubevec.x * 2.0 / 3.0;
+ }
+ else if (shnbr == 4) {
+ shcoef = 1.092548 * cubevec.x * cubevec.z * 1.0 / 4.0;
+ }
+ else if (shnbr == 5) {
+ shcoef = -1.092548 * cubevec.z * cubevec.y * 1.0 / 4.0;
+ }
+ else if (shnbr == 6) {
+ shcoef = 0.315392 * (3.0 * cubevec.y * cubevec.y - 1.0) * 1.0 / 4.0;
+ }
+ else if (shnbr == 7) {
+ shcoef = 1.092548 * cubevec.x * cubevec.y * 1.0 / 4.0;
+ }
+ else { /* (shnbr == 8) */
+ shcoef = 0.546274 * (cubevec.x * cubevec.x - cubevec.z * cubevec.z) * 1.0 / 4.0;
+ }
+
+ vec4 sample = textureLod(probeHdr, cubevec, lodBias);
+ sh += sample.rgb * shcoef * weight;
+ weight_accum += weight;
+ }
+ }
+ }
+
+ sh *= M_4PI / weight_accum;
+
+ FragColor = vec4(sh, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/probe_vert.glsl b/source/blender/draw/engines/eevee/shaders/probe_vert.glsl
new file mode 100644
index 00000000000..f5077d52845
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/probe_vert.glsl
@@ -0,0 +1,10 @@
+
+in vec3 pos;
+
+out vec4 vPos;
+flat out int face;
+
+void main() {
+ vPos = vec4(pos, 1.0);
+ face = gl_InstanceID;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
new file mode 100644
index 00000000000..7a8b06e3430
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
@@ -0,0 +1,15 @@
+
+layout(std140) uniform shadow_render_block {
+ mat4 ShadowMatrix[6];
+ vec4 lampPosition;
+ int layer;
+};
+
+in vec3 worldPosition;
+
+out vec4 FragColor;
+
+void main() {
+ float dist = distance(lampPosition.xyz, worldPosition.xyz);
+ FragColor = vec4(exp(5.0 * dist), 0.0, 0.0, 1.0);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
new file mode 100644
index 00000000000..4bd2999787b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
@@ -0,0 +1,27 @@
+
+layout(std140) uniform shadow_render_block {
+ mat4 ShadowMatrix[6];
+ vec4 lampPosition;
+ int layer;
+};
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+in vec4 vPos[];
+flat in int face[];
+
+out vec3 worldPosition;
+
+void main() {
+ int f = face[0];
+ gl_Layer = f;
+
+ for (int v = 0; v < 3; ++v) {
+ gl_Position = ShadowMatrix[f] * vPos[v];
+ worldPosition = vPos[v].xyz;
+ EmitVertex();
+ }
+
+ EndPrimitive();
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
new file mode 100644
index 00000000000..67bee97fade
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -0,0 +1,64 @@
+
+uniform samplerCube shadowCube;
+
+out vec4 FragColor;
+
+vec3 octahedral_to_cubemap_proj(vec2 co)
+{
+ co = co * 2.0 - 1.0;
+
+ vec2 abs_co = abs(co);
+ vec3 v = vec3(co, 1.0 - (abs_co.x + abs_co.y));
+
+ if ( abs_co.x + abs_co.y > 1.0 ) {
+ v.xy = (abs(co.yx) - 1.0) * -sign(co.xy);
+ }
+
+ return v;
+}
+
+void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
+{
+ vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0);
+ T = normalize( cross(UpVector, N) );
+ B = cross(N, T);
+}
+
+void main() {
+ const vec2 texelSize = vec2(1.0 / 512.0);
+
+ vec2 uvs = gl_FragCoord.xy * texelSize;
+
+ /* add a 2 pixel border to ensure filtering is correct */
+ uvs.xy *= 1.0 + texelSize * 2.0;
+ uvs.xy -= texelSize;
+
+ float pattern = 1.0;
+
+ /* edge mirroring : only mirror if directly adjacent
+ * (not diagonally adjacent) */
+ vec2 m = abs(uvs - 0.5) + 0.5;
+ vec2 f = floor(m);
+ if (f.x - f.y != 0.0) {
+ uvs.xy = 1.0 - uvs.xy;
+ }
+
+ /* clamp to [0-1] */
+ uvs.xy = fract(uvs.xy);
+
+ /* get cubemap vector */
+ vec3 cubevec = octahedral_to_cubemap_proj(uvs.xy);
+
+ vec3 T, B;
+ make_orthonormal_basis(cubevec, T, B);
+
+ vec2 offsetvec = texelSize.xy * vec2(-1.0, 1.0); /* Totally arbitrary */
+
+ /* get cubemap shadow value */
+ FragColor = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.x * B).rrrr;
+ FragColor += texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).rrrr;
+ FragColor += texture(shadowCube, cubevec + offsetvec.y * T + offsetvec.x * B).rrrr;
+ FragColor += texture(shadowCube, cubevec + offsetvec.y * T + offsetvec.y * B).rrrr;
+
+ FragColor /= 4.0;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
new file mode 100644
index 00000000000..f14354ad4cd
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
@@ -0,0 +1,22 @@
+
+layout(std140) uniform shadow_render_block {
+ mat4 ShadowMatrix[6];
+ vec4 lampPosition;
+ int layer;
+};
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+in vec4 vPos[];
+
+void main() {
+ gl_Layer = layer;
+
+ for (int v = 0; v < 3; ++v) {
+ gl_Position = vPos[v];
+ EmitVertex();
+ }
+
+ EndPrimitive();
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
new file mode 100644
index 00000000000..dee020f19b4
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
@@ -0,0 +1,8 @@
+
+in vec3 pos;
+
+out vec4 vPos;
+
+void main() {
+ vPos = vec4(pos, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
new file mode 100644
index 00000000000..288098ba771
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ShadowModelMatrix;
+
+in vec3 pos;
+
+out vec4 vPos;
+
+flat out int face;
+
+void main() {
+ vPos = ShadowModelMatrix * vec4(pos, 1.0);
+ face = gl_InstanceID;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
new file mode 100644
index 00000000000..c48518ef5e7
--- /dev/null
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2017, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file external_engine.h
+ * \ingroup draw_engine
+ *
+ * Base engine for external render engines.
+ * We use it for depth and non-mesh objects.
+ */
+
+#include "DRW_render.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_icons.h"
+#include "BKE_idprop.h"
+#include "BKE_main.h"
+
+#include "ED_view3d.h"
+#include "ED_screen.h"
+
+#include "GPU_glew.h"
+#include "GPU_matrix.h"
+#include "GPU_shader.h"
+#include "GPU_viewport.h"
+
+#include "external_engine.h"
+/* Shaders */
+
+#define EXTERNAL_ENGINE "BLENDER_EXTERNAL"
+
+/* *********** LISTS *********** */
+
+/* GPUViewport.storage
+ * Is freed everytime the viewport engine changes */
+typedef struct EXTERNAL_Storage {
+ int dummy;
+} EXTERNAL_Storage;
+
+typedef struct EXTERNAL_StorageList {
+ struct EXTERNAL_Storage *storage;
+ struct EXTERNAL_PrivateData *g_data;
+} EXTERNAL_StorageList;
+
+typedef struct EXTERNAL_FramebufferList {
+ struct GPUFrameBuffer *default_fb;
+} EXTERNAL_FramebufferList;
+
+typedef struct EXTERNAL_TextureList {
+ /* default */
+ struct GPUTexture *depth;
+} EXTERNAL_TextureList;
+
+typedef struct EXTERNAL_PassList {
+ struct DRWPass *depth_pass;
+} EXTERNAL_PassList;
+
+typedef struct EXTERNAL_Data {
+ void *engine_type;
+ EXTERNAL_FramebufferList *fbl;
+ EXTERNAL_TextureList *txl;
+ EXTERNAL_PassList *psl;
+ EXTERNAL_StorageList *stl;
+ char info[GPU_INFO_SIZE];
+} EXTERNAL_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Depth Pre Pass */
+ struct GPUShader *depth_sh;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EXTERNAL_PrivateData {
+ DRWShadingGroup *depth_shgrp;
+} EXTERNAL_PrivateData; /* Transient data */
+
+/* Functions */
+
+static void EXTERNAL_engine_init(void *UNUSED(vedata))
+{
+ /* Depth prepass */
+ if (!e_data.depth_sh) {
+ e_data.depth_sh = DRW_shader_create_3D_depth_only();
+ }
+}
+
+static void EXTERNAL_cache_init(void *vedata)
+{
+ EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
+ EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ /* Depth Pass */
+ {
+ psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
+ }
+}
+
+static void EXTERNAL_cache_populate(void *vedata, Object *ob)
+{
+ EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+
+ if (!DRW_object_is_renderable(ob))
+ return;
+
+ struct Batch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ /* Depth Prepass */
+ DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
+ }
+}
+
+static void EXTERNAL_cache_finish(void *UNUSED(vedata))
+{
+}
+
+static void external_draw_scene(void *vedata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ ARegion *ar = draw_ctx->ar;
+ RenderEngineType *type;
+
+ DRW_state_reset_ex(DRW_STATE_DEFAULT & ~DRW_STATE_DEPTH_LESS);
+
+ /* Create render engine. */
+ if (!rv3d->render_engine) {
+ RenderEngine *engine;
+ type = RE_engines_find(scene->r.engine);
+
+ if (!(type->view_update && type->render_to_view)) {
+ return;
+ }
+
+ engine = RE_engine_create_ex(type, true);
+ engine->tile_x = scene->r.tilex;
+ engine->tile_y = scene->r.tiley;
+ type->view_update(engine, draw_ctx->evil_C);
+ rv3d->render_engine = engine;
+ }
+
+ /* Rendered draw. */
+ gpuPushProjectionMatrix();
+ ED_region_pixelspace(ar);
+
+ /* Render result draw. */
+ type = rv3d->render_engine->type;
+ type->render_to_view(rv3d->render_engine, draw_ctx->evil_C);
+
+ gpuPopProjectionMatrix();
+
+ /* Set render info. */
+ EXTERNAL_Data *data = vedata;
+ if (rv3d->render_engine->text[0] != '\0') {
+ BLI_strncpy(data->info, rv3d->render_engine->text, sizeof(data->info));
+ }
+ else {
+ data->info[0] = '\0';
+ }
+}
+
+static void EXTERNAL_draw_scene(void *vedata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
+
+ /* Will be NULL during OpenGL render.
+ * OpenGL render is used for quick preview (thumbnails or sequencer preview)
+ * where using the rendering engine to preview doesn't make so much sense. */
+ if (draw_ctx->evil_C) {
+ external_draw_scene(vedata);
+ }
+ DRW_draw_pass(psl->depth_pass);
+}
+
+static void EXTERNAL_engine_free(void)
+{
+ /* All shaders are builtin. */
+}
+
+static const DrawEngineDataSize EXTERNAL_data_size = DRW_VIEWPORT_DATA_SIZE(EXTERNAL_Data);
+
+DrawEngineType draw_engine_external_type = {
+ NULL, NULL,
+ N_("External"),
+ &EXTERNAL_data_size,
+ &EXTERNAL_engine_init,
+ &EXTERNAL_engine_free,
+ &EXTERNAL_cache_init,
+ &EXTERNAL_cache_populate,
+ &EXTERNAL_cache_finish,
+ NULL,
+ &EXTERNAL_draw_scene
+};
+
+/* Note: currently unused, we should not register unless we want to see this when debugging the view. */
+
+RenderEngineType DRW_engine_viewport_external_type = {
+ NULL, NULL,
+ EXTERNAL_ENGINE, N_("External"), RE_INTERNAL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &draw_engine_external_type,
+ {NULL, NULL, NULL}
+};
+
+#undef EXTERNAL_ENGINE
diff --git a/source/blender/draw/engines/external/external_engine.h b/source/blender/draw/engines/external/external_engine.h
new file mode 100644
index 00000000000..1789fb67efe
--- /dev/null
+++ b/source/blender/draw/engines/external/external_engine.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file external_engine.h
+ * \ingroup draw_engine
+ */
+
+#ifndef __EXTERNAL_ENGINE_H__
+#define __EXTERNAL_ENGINE_H__
+
+extern RenderEngineType DRW_engine_viewport_external_type;
+
+#endif /* __EXTERNAL_ENGINE_H__ */
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
new file mode 100644
index 00000000000..12cdf04a826
--- /dev/null
+++ b/source/blender/draw/intern/DRW_render.h
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file DRW_render.h
+ * \ingroup draw
+ */
+
+/* This is the Render Functions used by Realtime engines to draw with OpenGL */
+
+#ifndef __DRW_RENDER_H__
+#define __DRW_RENDER_H__
+
+#include "BKE_context.h"
+#include "BKE_layer.h"
+#include "BKE_material.h"
+#include "BKE_scene.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math_matrix.h"
+#include "BLI_math_vector.h"
+#include "BLI_string.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_scene_types.h"
+
+#include "draw_common.h"
+#include "draw_cache.h"
+#include "draw_view.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RE_engine.h"
+
+struct bContext;
+struct GPUFrameBuffer;
+struct GPUShader;
+struct GPUMaterial;
+struct GPUTexture;
+struct GPUUniformBuffer;
+struct Object;
+struct Batch;
+struct DefaultFramebufferList;
+struct DefaultTextureList;
+struct DRWTextStore;
+struct LampEngineData;
+struct RenderEngineType;
+struct ViewportEngineData;
+struct ViewportEngineData_Info;
+
+typedef struct DRWUniform DRWUniform;
+typedef struct DRWInterface DRWInterface;
+typedef struct DRWPass DRWPass;
+typedef struct DRWShadingGroup DRWShadingGroup;
+
+/* declare members as empty (unused) */
+typedef char DRWViewportEmptyList;
+
+#define DRW_VIEWPORT_LIST_SIZE(list) \
+ (sizeof(list) == sizeof(DRWViewportEmptyList) ? 0 : ((sizeof(list)) / sizeof(void *)))
+
+/* Unused members must be either pass list or 'char *' when not usd. */
+#define DRW_VIEWPORT_DATA_SIZE(ty) { \
+ DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->fbl)), \
+ DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->txl)), \
+ DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->psl)), \
+ DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->stl)) \
+}
+
+typedef struct DrawEngineDataSize {
+ int fbl_len;
+ int txl_len;
+ int psl_len;
+ int stl_len;
+} DrawEngineDataSize;
+
+typedef struct DrawEngineType {
+ struct DrawEngineType *next, *prev;
+
+ char idname[32];
+
+ const DrawEngineDataSize *vedata_size;
+
+ void (*engine_init)(void *vedata);
+ void (*engine_free)(void);
+
+ void (*cache_init)(void *vedata);
+ void (*cache_populate)(void *vedata, struct Object *ob);
+ void (*cache_finish)(void *vedata);
+
+ void (*draw_background)(void *vedata);
+ void (*draw_scene)(void *vedata);
+} DrawEngineType;
+
+#ifndef __DRW_ENGINE_H__
+/* Buffer and textures used by the viewport by default */
+typedef struct DefaultFramebufferList {
+ struct GPUFrameBuffer *default_fb;
+} DefaultFramebufferList;
+
+typedef struct DefaultTextureList {
+ struct GPUTexture *color;
+ struct GPUTexture *depth;
+} DefaultTextureList;
+#endif
+
+/* Textures */
+
+typedef enum {
+ DRW_TEX_RGBA_8,
+ DRW_TEX_RGBA_16,
+ DRW_TEX_RGBA_32,
+ DRW_TEX_RGB_11_11_10,
+ DRW_TEX_RGB_8,
+ DRW_TEX_RGB_16,
+ DRW_TEX_RGB_32,
+ DRW_TEX_RG_8,
+ DRW_TEX_RG_16,
+ DRW_TEX_RG_32,
+ DRW_TEX_R_8,
+ DRW_TEX_R_16,
+ DRW_TEX_R_32,
+ DRW_TEX_DEPTH_16,
+ DRW_TEX_DEPTH_24,
+ DRW_TEX_DEPTH_32,
+} DRWTextureFormat;
+
+typedef enum {
+ DRW_TEX_FILTER = (1 << 0),
+ DRW_TEX_WRAP = (1 << 1),
+ DRW_TEX_COMPARE = (1 << 2),
+ DRW_TEX_MIPMAP = (1 << 3),
+ DRW_TEX_TEMP = (1 << 4),
+} DRWTextureFlag;
+
+struct GPUTexture *DRW_texture_create_1D(
+ int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels);
+struct GPUTexture *DRW_texture_create_2D(
+ int w, int h, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels);
+struct GPUTexture *DRW_texture_create_2D_array(
+ int w, int h, int d, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels);
+struct GPUTexture *DRW_texture_create_cube(
+ int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels);
+void DRW_texture_generate_mipmaps(struct GPUTexture *tex);
+void DRW_texture_free(struct GPUTexture *tex);
+#define DRW_TEXTURE_FREE_SAFE(tex) do { \
+ if (tex != NULL) { \
+ DRW_texture_free(tex); \
+ tex = NULL; \
+ } \
+} while (0)
+
+/* UBOs */
+struct GPUUniformBuffer *DRW_uniformbuffer_create(int size, const void *data);
+void DRW_uniformbuffer_update(struct GPUUniformBuffer *ubo, const void *data);
+void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo);
+#define DRW_UBO_FREE_SAFE(ubo) do { \
+ if (ubo != NULL) { \
+ DRW_uniformbuffer_free(ubo); \
+ ubo = NULL; \
+ } \
+} while (0)
+
+/* Buffers */
+#define MAX_FBO_TEX 5
+
+typedef struct DRWFboTexture {
+ struct GPUTexture **tex;
+ int format;
+ DRWTextureFlag flag;
+} DRWFboTexture;
+
+void DRW_framebuffer_init(
+ struct GPUFrameBuffer **fb, void *engine_type, int width, int height,
+ DRWFboTexture textures[MAX_FBO_TEX], int textures_len);
+void DRW_framebuffer_bind(struct GPUFrameBuffer *fb);
+void DRW_framebuffer_clear(bool color, bool depth, bool stencil, float clear_col[4], float clear_depth);
+void DRW_framebuffer_read_data(int x, int y, int w, int h, int channels, int slot, float *data);
+void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, int mip);
+void DRW_framebuffer_texture_detach(struct GPUTexture *tex);
+void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth);
+void DRW_framebuffer_viewport_size(struct GPUFrameBuffer *UNUSED(fb_read), int w, int h);
+void DRW_framebuffer_free(struct GPUFrameBuffer *fb);
+#define DRW_FRAMEBUFFER_FREE_SAFE(fb) do { \
+ if (fb != NULL) { \
+ DRW_framebuffer_free(fb); \
+ fb = NULL; \
+ } \
+} while (0)
+
+void DRW_transform_to_display(struct GPUTexture *tex);
+
+/* Shaders */
+struct GPUShader *DRW_shader_create(
+ const char *vert, const char *geom, const char *frag, const char *defines);
+struct GPUShader *DRW_shader_create_with_lib(
+ const char *vert, const char *geom, const char *frag, const char *lib, const char *defines);
+struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
+struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
+struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
+struct GPUShader *DRW_shader_create_3D_depth_only(void);
+void DRW_shader_free(struct GPUShader *shader);
+#define DRW_SHADER_FREE_SAFE(shader) do { \
+ if (shader != NULL) { \
+ DRW_shader_free(shader); \
+ shader = NULL; \
+ } \
+} while (0)
+
+/* Batches */
+
+typedef enum {
+ DRW_STATE_WRITE_DEPTH = (1 << 0),
+ DRW_STATE_WRITE_COLOR = (1 << 1),
+ DRW_STATE_DEPTH_LESS = (1 << 2),
+ DRW_STATE_DEPTH_EQUAL = (1 << 3),
+ DRW_STATE_DEPTH_GREATER = (1 << 4),
+ DRW_STATE_CULL_BACK = (1 << 5),
+ DRW_STATE_CULL_FRONT = (1 << 6),
+ DRW_STATE_WIRE = (1 << 7),
+ DRW_STATE_WIRE_LARGE = (1 << 8),
+ DRW_STATE_POINT = (1 << 9),
+ DRW_STATE_STIPPLE_2 = (1 << 10),
+ DRW_STATE_STIPPLE_3 = (1 << 11),
+ DRW_STATE_STIPPLE_4 = (1 << 12),
+ DRW_STATE_BLEND = (1 << 13),
+ DRW_STATE_ADDITIVE = (1 << 14),
+ DRW_STATE_MULTIPLY = (1 << 15),
+
+ DRW_STATE_WRITE_STENCIL_SELECT = (1 << 27),
+ DRW_STATE_WRITE_STENCIL_ACTIVE = (1 << 28),
+ DRW_STATE_TEST_STENCIL_SELECT = (1 << 29),
+ DRW_STATE_TEST_STENCIL_ACTIVE = (1 << 30),
+} DRWState;
+
+#define DRW_STATE_DEFAULT (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS)
+
+
+DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
+DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
+DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, struct Batch *geom);
+DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, struct Batch *geom);
+DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass);
+DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass);
+DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size);
+
+typedef void (DRWCallGenerateFn)(
+ DRWShadingGroup *shgroup,
+ void (*draw_fn)(DRWShadingGroup *shgroup, struct Batch *geom),
+ void *user_data);
+
+void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Batch *instances);
+
+void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
+void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Batch *geom, float (*obmat)[4]);
+void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, struct Batch *geom, struct Object *ob);
+void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, struct Object *ob, float (*obmat)[4]);
+void DRW_shgroup_call_generate_add(
+ DRWShadingGroup *shgroup, DRWCallGenerateFn *geometry_fn, void *user_data, float (*obmat)[4]);
+void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len);
+#define DRW_shgroup_call_dynamic_add(shgroup, ...) do { \
+ const void *array[] = {__VA_ARGS__}; \
+ DRW_shgroup_call_dynamic_add_array(shgroup, array, (sizeof(array) / sizeof(*array))); \
+} while (0)
+#define DRW_shgroup_call_dynamic_add_empty(shgroup) do { \
+ DRW_shgroup_call_dynamic_add_array(shgroup, NULL, 0); \
+} while (0)
+void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count);
+
+void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
+void DRW_shgroup_attrib_int(DRWShadingGroup *shgroup, const char *name, int size);
+void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size);
+
+void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const struct GPUTexture *tex);
+void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const struct GPUUniformBuffer *ubo);
+void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, struct GPUTexture **tex);
+void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize);
+void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
+void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
+void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
+void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
+void DRW_shgroup_uniform_short_to_int(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize);
+void DRW_shgroup_uniform_short_to_float(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize);
+void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize);
+void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize);
+void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize);
+void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value);
+void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value);
+
+/* Passes */
+DRWPass *DRW_pass_create(const char *name, DRWState state);
+void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DRWShadingGroup *shgrp), void *userData);
+
+/* Viewport */
+typedef enum {
+ DRW_MAT_PERS,
+ DRW_MAT_PERSINV,
+ DRW_MAT_VIEW,
+ DRW_MAT_VIEWINV,
+ DRW_MAT_WIN,
+ DRW_MAT_WININV,
+} DRWViewportMatrixType;
+
+void DRW_viewport_init(const bContext *C);
+void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
+const float *DRW_viewport_size_get(void);
+const float *DRW_viewport_screenvecs_get(void);
+const float *DRW_viewport_pixelsize_get(void);
+bool DRW_viewport_is_persp_get(void);
+
+struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void);
+struct DefaultTextureList *DRW_viewport_texture_list_get(void);
+
+/* SceneLayers */
+void **DRW_scene_layer_engine_data_get(DrawEngineType *engine_type, void (*callback)(void *storage));
+
+/* Objects */
+void **DRW_object_engine_data_get(
+ Object *ob, DrawEngineType *engine_type, void (*callback)(void *storage));
+struct LampEngineData *DRW_lamp_engine_data_get(Object *ob, struct RenderEngineType *engine_type);
+void DRW_lamp_engine_data_free(struct LampEngineData *led);
+
+/* Settings */
+bool DRW_object_is_renderable(struct Object *ob);
+bool DRW_object_is_flat_normal(struct Object *ob);
+
+/* Draw commands */
+void DRW_draw_pass(DRWPass *pass);
+
+void DRW_draw_text_cache_queue(struct DRWTextStore *dt);
+
+void DRW_draw_callbacks_pre_scene(void);
+void DRW_draw_callbacks_post_scene(void);
+
+int DRW_draw_region_engine_info_offset(void);
+void DRW_draw_region_engine_info(void);
+
+void DRW_state_reset_ex(DRWState state);
+void DRW_state_reset(void);
+
+/* Selection */
+void DRW_select_load_id(unsigned int id);
+
+/* Draw State */
+void DRW_state_dfdy_factors_get(float dfdyfac[2]);
+bool DRW_state_is_fbo(void);
+bool DRW_state_is_select(void);
+bool DRW_state_is_depth(void);
+bool DRW_state_show_text(void);
+
+struct DRWTextStore *DRW_state_text_cache_get(void);
+
+/* Avoid too many lookups while drawing */
+typedef struct DRWContextState {
+ struct ARegion *ar; /* 'CTX_wm_region(C)' */
+ struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */
+ struct View3D *v3d; /* 'CTX_wm_view3d(C)' */
+
+ struct Scene *scene; /* 'CTX_data_scene(C)' */
+ struct SceneLayer *sl; /* 'CTX_data_scene_layer(C)' */
+
+ /* Use 'scene->obedit' for edit-mode */
+ struct Object *obact; /* 'OBACT_NEW' */
+
+ /* Last resort (some functions take this as an arg so we can't easily avoid).
+ * May be NULL when used for selection or depth buffer. */
+ const struct bContext *evil_C;
+} DRWContextState;
+
+void DRW_context_state_init(const struct bContext *C, DRWContextState *r_draw_ctx);
+const DRWContextState *DRW_context_state_get(void);
+
+#endif /* __DRW_RENDER_H__ */
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
new file mode 100644
index 00000000000..bbb22ad2548
--- /dev/null
+++ b/source/blender/draw/intern/draw_armature.c
@@ -0,0 +1,1442 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_armature.c
+ * \ingroup draw
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_object_types.h"
+
+#include "DRW_render.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_dlrbTree.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "BKE_global.h"
+#include "BKE_modifier.h"
+#include "BKE_nla.h"
+#include "BKE_curve.h"
+
+#include "BIF_gl.h"
+
+#include "ED_armature.h"
+#include "ED_keyframes_draw.h"
+
+#include "GPU_select.h"
+
+#include "UI_resources.h"
+
+#include "draw_common.h"
+#include "draw_manager_text.h"
+
+#define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var))
+#define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag))
+
+/* For now just match 2.7x where possible. */
+// #define USE_SOLID_COLOR
+
+/* Reset for drawing each armature object */
+static struct {
+ /* Current armature object */
+ Object *ob;
+ /* Reset when changing current_armature */
+ DRWShadingGroup *bone_octahedral_solid;
+ DRWShadingGroup *bone_octahedral_wire;
+ DRWShadingGroup *bone_box_solid;
+ DRWShadingGroup *bone_box_wire;
+ DRWShadingGroup *bone_wire_wire;
+ DRWShadingGroup *bone_envelope_solid;
+ DRWShadingGroup *bone_envelope_distance;
+ DRWShadingGroup *bone_envelope_wire;
+ DRWShadingGroup *bone_envelope_head_wire;
+ DRWShadingGroup *bone_point_solid;
+ DRWShadingGroup *bone_point_wire;
+ DRWShadingGroup *bone_axes;
+ DRWShadingGroup *relationship_lines;
+
+ DRWPass *pass_bone_solid;
+ DRWPass *pass_bone_wire;
+ DRWPass *pass_bone_envelope;
+} g_data = {NULL};
+
+/* -------------------------------------------------------------------- */
+
+/** \name Shader Groups (DRW_shgroup)
+ * \{ */
+
+/* Octahedral */
+static void DRW_shgroup_bone_octahedral_solid(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_octahedral_solid == NULL) {
+ struct Batch *geom = DRW_cache_bone_octahedral_get();
+ g_data.bone_octahedral_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_solid, bone_mat, color);
+}
+
+static void DRW_shgroup_bone_octahedral_wire(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_octahedral_wire == NULL) {
+ struct Batch *geom = DRW_cache_bone_octahedral_wire_outline_get();
+ g_data.bone_octahedral_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_wire, bone_mat, color);
+}
+
+/* Box / B-Bone */
+static void DRW_shgroup_bone_box_solid(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_box_solid == NULL) {
+ struct Batch *geom = DRW_cache_bone_box_get();
+ g_data.bone_box_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_box_solid, bone_mat, color);
+}
+
+static void DRW_shgroup_bone_box_wire(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_box_wire == NULL) {
+ struct Batch *geom = DRW_cache_bone_box_wire_outline_get();
+ g_data.bone_box_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_box_wire, bone_mat, color);
+}
+
+/* Wire */
+static void DRW_shgroup_bone_wire_wire(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_wire_wire == NULL) {
+ struct Batch *geom = DRW_cache_bone_wire_wire_outline_get();
+ g_data.bone_wire_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_wire_wire, bone_mat, color);
+}
+
+/* Envelope */
+static void DRW_shgroup_bone_envelope_distance(
+ const float (*bone_mat)[4], const float color[4],
+ const float *radius_head, const float *radius_tail, const float *distance)
+{
+ if (g_data.pass_bone_envelope != NULL) {
+ if (g_data.bone_envelope_distance == NULL) {
+ struct Batch *geom = DRW_cache_bone_envelope_distance_outline_get();
+ /* Note: bone_wire draw pass is not really working, think we need another one here? */
+ g_data.bone_envelope_distance = shgroup_instance_bone_envelope_wire(g_data.pass_bone_envelope, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_envelope_distance, bone_mat, color, radius_head, radius_tail, distance);
+ }
+}
+
+static void DRW_shgroup_bone_envelope_solid(
+ const float (*bone_mat)[4], const float color[4],
+ const float *radius_head, const float *radius_tail)
+{
+ if (g_data.bone_envelope_solid == NULL) {
+ struct Batch *geom = DRW_cache_bone_envelope_solid_get();
+ g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_envelope_solid, bone_mat, color, radius_head, radius_tail);
+}
+
+static void DRW_shgroup_bone_envelope_wire(
+ const float (*bone_mat)[4], const float color[4],
+ const float *radius_head, const float *radius_tail, const float *distance)
+{
+ if (g_data.bone_envelope_wire == NULL) {
+ struct Batch *geom = DRW_cache_bone_envelope_wire_outline_get();
+ g_data.bone_envelope_wire = shgroup_instance_bone_envelope_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_envelope_wire, bone_mat, color, radius_head, radius_tail, distance);
+}
+
+static void DRW_shgroup_bone_envelope_head_wire(
+ const float (*bone_mat)[4], const float color[4],
+ const float *radius_head, const float *radius_tail, const float *distance)
+{
+ if (g_data.bone_envelope_head_wire == NULL) {
+ struct Batch *geom = DRW_cache_bone_envelope_head_wire_outline_get();
+ g_data.bone_envelope_head_wire = shgroup_instance_bone_envelope_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_envelope_head_wire, bone_mat, color, radius_head, radius_tail, distance);
+}
+
+/* Custom (geometry) */
+
+static void DRW_shgroup_bone_custom_solid(const float (*bone_mat)[4], const float color[4], Object *custom)
+{
+ /* grr, not re-using instances! */
+ struct Batch *geom = DRW_cache_object_surface_get(custom);
+ if (geom) {
+ DRWShadingGroup *shgrp_geom_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat);
+ DRW_shgroup_call_dynamic_add(shgrp_geom_solid, bone_mat, color);
+ }
+}
+
+static void DRW_shgroup_bone_custom_wire(const float (*bone_mat)[4], const float color[4], Object *custom)
+{
+ /* grr, not re-using instances! */
+ struct Batch *geom = DRW_cache_object_wire_outline_get(custom);
+ if (geom) {
+ DRWShadingGroup *shgrp_geom_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ DRW_shgroup_call_dynamic_add(shgrp_geom_wire, bone_mat, color);
+ }
+}
+
+/* Head and tail sphere */
+static void DRW_shgroup_bone_point_solid(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_point_solid == NULL) {
+ struct Batch *geom = DRW_cache_bone_point_get();
+ g_data.bone_point_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, bone_mat, color);
+}
+
+static void DRW_shgroup_bone_point_wire(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_point_wire == NULL) {
+ struct Batch *geom = DRW_cache_bone_point_wire_outline_get();
+ g_data.bone_point_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, bone_mat, color);
+}
+
+/* Axes */
+static void DRW_shgroup_bone_axes(const float (*bone_mat)[4], const float color[4])
+{
+ if (g_data.bone_axes == NULL) {
+ struct Batch *geom = DRW_cache_bone_arrows_get();
+ g_data.bone_axes = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(g_data.bone_axes, bone_mat, color);
+}
+
+/* Relationship lines */
+static void UNUSED_FUNCTION(DRW_shgroup_bone_relationship_lines)(const float head[3], const float tail[3])
+{
+ DRW_shgroup_call_dynamic_add(g_data.relationship_lines, head);
+ DRW_shgroup_call_dynamic_add(g_data.relationship_lines, tail);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Drawing Theme Helpers
+ *
+ * Note, this section is duplicate of code in 'drawarmature.c'.
+ *
+ * \{ */
+
+/* global here is reset before drawing each bone */
+struct {
+ const ThemeWireColor *bcolor;
+} g_color;
+
+/* values of colCode for set_pchan_color */
+enum {
+ PCHAN_COLOR_NORMAL = 0, /* normal drawing */
+ PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
+ PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */
+
+ PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */
+ PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */
+ PCHAN_COLOR_LINEBONE /* for the middle of line-bones */
+};
+
+/* This function sets the color-set for coloring a certain bone */
+static void set_pchan_colorset(Object *ob, bPoseChannel *pchan)
+{
+ bPose *pose = (ob) ? ob->pose : NULL;
+ bArmature *arm = (ob) ? ob->data : NULL;
+ bActionGroup *grp = NULL;
+ short color_index = 0;
+
+ /* sanity check */
+ if (ELEM(NULL, ob, arm, pose, pchan)) {
+ g_color.bcolor = NULL;
+ return;
+ }
+
+ /* only try to set custom color if enabled for armature */
+ if (arm->flag & ARM_COL_CUSTOM) {
+ /* currently, a bone can only use a custom color set if it's group (if it has one),
+ * has been set to use one
+ */
+ if (pchan->agrp_index) {
+ grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
+ if (grp)
+ color_index = grp->customCol;
+ }
+ }
+
+ /* bcolor is a pointer to the color set to use. If NULL, then the default
+ * color set (based on the theme colors for 3d-view) is used.
+ */
+ if (color_index > 0) {
+ bTheme *btheme = UI_GetTheme();
+ g_color.bcolor = &btheme->tarm[(color_index - 1)];
+ }
+ else if (color_index == -1) {
+ /* use the group's own custom color set (grp is always != NULL here) */
+ g_color.bcolor = &grp->cs;
+ }
+ else {
+ g_color.bcolor = NULL;
+ }
+}
+
+/* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */
+static void cp_shade_color3ub(unsigned char cp[3], const int offset)
+{
+ int r, g, b;
+
+ r = offset + (int) cp[0];
+ CLAMP(r, 0, 255);
+ g = offset + (int) cp[1];
+ CLAMP(g, 0, 255);
+ b = offset + (int) cp[2];
+ CLAMP(b, 0, 255);
+
+ cp[0] = r;
+ cp[1] = g;
+ cp[2] = b;
+}
+
+/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
+static bool set_pchan_color(short colCode, const int boneflag, const short constflag, float r_color[4])
+{
+ float *fcolor = r_color;
+ const ThemeWireColor *bcolor = g_color.bcolor;
+
+ switch (colCode) {
+ case PCHAN_COLOR_NORMAL:
+ {
+ if (bcolor) {
+ unsigned char cp[4] = {255};
+
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ copy_v3_v3_char((char *)cp, bcolor->active);
+ if (!(boneflag & BONE_SELECTED)) {
+ cp_shade_color3ub(cp, -80);
+ }
+ }
+ else if (boneflag & BONE_SELECTED) {
+ copy_v3_v3_char((char *)cp, bcolor->select);
+ }
+ else {
+ /* a bit darker than solid */
+ copy_v3_v3_char((char *)cp, bcolor->solid);
+ cp_shade_color3ub(cp, -50);
+ }
+
+ rgb_uchar_to_float(fcolor, cp);
+ }
+ else {
+ if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
+ UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor);
+ }
+ else if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_WIRE, fcolor);
+ }
+ }
+
+ return true;
+ }
+ case PCHAN_COLOR_SOLID:
+ {
+ if (bcolor) {
+ rgb_uchar_to_float(fcolor, (unsigned char *)bcolor->solid);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
+
+ return true;
+ }
+ case PCHAN_COLOR_CONSTS:
+ {
+ if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
+ unsigned char cp[4];
+ if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 80);
+ else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 80);
+
+ rgba_uchar_to_float(fcolor, cp);
+
+ return true;
+ }
+ return false;
+ }
+ case PCHAN_COLOR_SPHEREBONE_BASE:
+ {
+ if (bcolor) {
+ unsigned char cp[4] = {255};
+
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ copy_v3_v3_char((char *)cp, bcolor->active);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ copy_v3_v3_char((char *)cp, bcolor->select);
+ }
+ else {
+ copy_v3_v3_char((char *)cp, bcolor->solid);
+ }
+
+ rgb_uchar_to_float(fcolor, cp);
+ }
+ else {
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
+ }
+
+ return true;
+ }
+ case PCHAN_COLOR_SPHEREBONE_END:
+ {
+ if (bcolor) {
+ unsigned char cp[4] = {255};
+
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ copy_v3_v3_char((char *)cp, bcolor->active);
+ cp_shade_color3ub(cp, 10);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ copy_v3_v3_char((char *)cp, bcolor->select);
+ cp_shade_color3ub(cp, -30);
+ }
+ else {
+ copy_v3_v3_char((char *)cp, bcolor->solid);
+ cp_shade_color3ub(cp, -30);
+ }
+
+ rgb_uchar_to_float(fcolor, cp);
+ }
+ else {
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor);
+ }
+ else {
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
+ }
+ }
+ break;
+ }
+ case PCHAN_COLOR_LINEBONE:
+ {
+ /* inner part in background color or constraint */
+ if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) {
+ unsigned char cp[4];
+ if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 255);
+ else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 255);
+ else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 255);
+ else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 255);
+ else if (constflag) UI_GetThemeColor4ubv(TH_BONE_POSE, cp); /* PCHAN_HAS_ACTION */
+
+ rgb_uchar_to_float(fcolor, cp);
+ }
+ else {
+ if (bcolor) {
+ const char *cp = bcolor->solid;
+ rgb_uchar_to_float(fcolor, (unsigned char *)cp);
+ fcolor[3] = 204.f / 255.f;
+ }
+ else {
+ UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor);
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Drawing Color Helpers
+ * \{ */
+
+/**
+ * Follow `TH_*` naming except for mixed colors.
+ */
+static struct {
+ float select_color[4];
+ float edge_select_color[4];
+ float bone_select_color[4]; /* tint */
+ float wire_color[4];
+ float wire_edit_color[4];
+ float bone_solid_color[4];
+ float bone_active_unselect_color[4]; /* mix */
+ float bone_pose_color[4];
+ float bone_pose_active_color[4];
+ float bone_pose_active_unselect_color[4]; /* mix */
+ float text_hi_color[4];
+ float text_color[4];
+ float vertex_select_color[4];
+ float vertex_color[4];
+
+ /* not a theme, this is an override */
+ const float *const_color;
+} g_theme;
+
+/** See: 'set_pchan_color'*/
+static void update_color(const float const_color[4])
+{
+ g_theme.const_color = const_color;
+
+#define NO_ALPHA(c) (((c)[3] = 1.0f), (c))
+
+ UI_GetThemeColor3fv(TH_SELECT, NO_ALPHA(g_theme.select_color));
+ UI_GetThemeColor3fv(TH_EDGE_SELECT, NO_ALPHA(g_theme.edge_select_color));
+ UI_GetThemeColorShade3fv(TH_EDGE_SELECT, -20, NO_ALPHA(g_theme.bone_select_color));
+ UI_GetThemeColor3fv(TH_WIRE, NO_ALPHA(g_theme.wire_color));
+ UI_GetThemeColor3fv(TH_WIRE_EDIT, NO_ALPHA(g_theme.wire_edit_color));
+ UI_GetThemeColor3fv(TH_BONE_SOLID, NO_ALPHA(g_theme.bone_solid_color));
+ UI_GetThemeColorBlendShade3fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, NO_ALPHA(g_theme.bone_active_unselect_color));
+ UI_GetThemeColor3fv(TH_BONE_POSE, NO_ALPHA(g_theme.bone_pose_color));
+ UI_GetThemeColor3fv(TH_BONE_POSE_ACTIVE, NO_ALPHA(g_theme.bone_pose_active_color));
+ UI_GetThemeColorBlendShade3fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, NO_ALPHA(g_theme.bone_pose_active_unselect_color));
+ UI_GetThemeColor3fv(TH_TEXT_HI, NO_ALPHA(g_theme.text_hi_color));
+ UI_GetThemeColor3fv(TH_TEXT, NO_ALPHA(g_theme.text_color));
+ UI_GetThemeColor3fv(TH_VERTEX_SELECT, NO_ALPHA(g_theme.vertex_select_color));
+ UI_GetThemeColor3fv(TH_VERTEX, NO_ALPHA(g_theme.vertex_color));
+
+#undef NO_ALPHA
+}
+
+static const float *get_bone_solid_color(
+ const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm,
+ const int boneflag, const short constflag)
+{
+ if (g_theme.const_color)
+ return g_theme.bone_solid_color;
+
+#ifdef USE_SOLID_COLOR
+ /* Edit Mode */
+ if (eBone) {
+ bool is_active = (arm->act_edbone == eBone);
+ if (eBone->flag & BONE_SELECTED) {
+ if (is_active) {
+ return g_theme.edge_select_color;
+ }
+ else {
+ return g_theme.bone_select_color;
+ }
+ }
+ }
+ else if (arm->flag & ARM_POSEMODE) {
+ bool is_active = (arm->act_bone == pchan->bone);
+ if (pchan->bone->flag & BONE_SELECTED) {
+ if (is_active) {
+ return g_theme.bone_pose_active_color;
+ }
+ else {
+ return g_theme.bone_pose_color;
+ }
+ }
+ }
+#else
+ if (arm->drawtype == ARM_ENVELOPE) {
+ /* Edit Mode */
+ if (eBone) {
+ bool is_active = (arm->act_edbone == eBone);
+ if (eBone->flag & BONE_SELECTED) {
+ if (is_active) {
+ return g_theme.edge_select_color;
+ }
+ else {
+ return g_theme.bone_select_color;
+ }
+ }
+ }
+ else if (arm->flag & ARM_POSEMODE) {
+ bool is_active = (arm->act_bone == pchan->bone);
+ if (pchan->bone->flag & BONE_SELECTED) {
+ if (is_active) {
+ return g_theme.bone_pose_active_color;
+ }
+ else {
+ return g_theme.bone_pose_color;
+ }
+ }
+ }
+ }
+#endif
+
+ if (arm->flag & ARM_POSEMODE) {
+ float *disp_color = pchan->draw_data->solid_color;
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag, disp_color);
+ disp_color[3] = 1.0;
+ return disp_color;
+ }
+
+ return g_theme.bone_solid_color;
+}
+
+static const float *get_bone_wire_color(
+ const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm,
+ const int boneflag, const short constflag)
+{
+ if (g_theme.const_color)
+ return g_theme.const_color;
+
+ if (eBone) {
+ if (boneflag & BONE_SELECTED) {
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ return g_theme.edge_select_color;
+ }
+ else {
+ return g_theme.bone_select_color;
+ }
+ }
+ else {
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ return g_theme.bone_active_unselect_color;
+ }
+ else {
+ return g_theme.wire_edit_color;
+ }
+ }
+ }
+ else if (arm->flag & ARM_POSEMODE) {
+ float *disp_color = pchan->draw_data->wire_color;
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag, disp_color);
+ disp_color[3] = 1.0;
+ return disp_color;
+
+
+#if 0
+ if (boneflag & BONE_SELECTED) {
+ if (is_active) {
+ return g_theme.bone_pose_active_color;
+ }
+ else {
+ return g_theme.bone_pose_color;
+ }
+ }
+ else {
+ if (is_active) {
+ return g_theme.bone_pose_active_unselect_color;
+ }
+ else {
+ return g_theme.wire_color;
+ }
+ }
+#endif
+ }
+
+ return g_theme.vertex_color;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Helper Utils
+ * \{ */
+
+static void pchan_draw_data_init(bPoseChannel *pchan)
+{
+ if (pchan->draw_data != NULL) {
+ if (pchan->draw_data->bbone_matrix_len != pchan->bone->segments) {
+ MEM_SAFE_FREE(pchan->draw_data);
+ }
+ }
+
+ if (pchan->draw_data == NULL) {
+ pchan->draw_data = MEM_mallocN(sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__);
+ pchan->draw_data->bbone_matrix_len = pchan->bone->segments;
+ }
+}
+
+static void draw_bone_update_disp_matrix_default(EditBone *eBone, bPoseChannel *pchan)
+{
+ float s[4][4], ebmat[4][4];
+ float length;
+ float (*bone_mat)[4];
+ float (*disp_mat)[4];
+ float (*disp_tail_mat)[4];
+
+ /* TODO : This should be moved to depsgraph or armature refresh
+ * and not be tight to the draw pass creation.
+ * This would refresh armature without invalidating the draw cache */
+ if (pchan) {
+ length = pchan->bone->length;
+ bone_mat = pchan->pose_mat;
+ disp_mat = pchan->disp_mat;
+ disp_tail_mat = pchan->disp_tail_mat;
+ }
+ else {
+ eBone->length = len_v3v3(eBone->tail, eBone->head);
+ ED_armature_ebone_to_mat4(eBone, ebmat);
+
+ length = eBone->length;
+ bone_mat = ebmat;
+ disp_mat = eBone->disp_mat;
+ disp_tail_mat = eBone->disp_tail_mat;
+ }
+
+ scale_m4_fl(s, length);
+ mul_m4_m4m4(disp_mat, bone_mat, s);
+ copy_m4_m4(disp_tail_mat, disp_mat);
+ translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f);
+}
+
+/* XXX Direct copy from drawarmature.c... This is ugly! */
+/* A partial copy of b_bone_spline_setup(), with just the parts for previewing editmode curve settings
+ *
+ * This assumes that prev/next bones don't have any impact (since they should all still be in the "straight"
+ * position here anyway), and that we can simply apply the bbone settings to get the desired effect...
+ */
+static void ebone_spline_preview(EditBone *ebone, float result_array[MAX_BBONE_SUBDIV][4][4])
+{
+ float h1[3], h2[3], length, hlength1, hlength2, roll1 = 0.0f, roll2 = 0.0f;
+ float mat3[3][3];
+ float data[MAX_BBONE_SUBDIV + 1][4], *fp;
+ int a;
+
+ length = ebone->length;
+
+ hlength1 = ebone->ease1 * length * 0.390464f; /* 0.5f * sqrt(2) * kappa, the handle length for near-perfect circles */
+ hlength2 = ebone->ease2 * length * 0.390464f;
+
+ /* find the handle points, since this is inside bone space, the
+ * first point = (0, 0, 0)
+ * last point = (0, length, 0)
+ *
+ * we also just apply all the "extra effects", since they're the whole reason we're doing this...
+ */
+ h1[0] = ebone->curveInX;
+ h1[1] = hlength1;
+ h1[2] = ebone->curveInY;
+ roll1 = ebone->roll1;
+
+ h2[0] = ebone->curveOutX;
+ h2[1] = -hlength2;
+ h2[2] = ebone->curveOutY;
+ roll2 = ebone->roll2;
+
+ /* make curve */
+ if (ebone->segments > MAX_BBONE_SUBDIV)
+ ebone->segments = MAX_BBONE_SUBDIV;
+
+ BKE_curve_forward_diff_bezier(0.0f, h1[0], h2[0], 0.0f, data[0], MAX_BBONE_SUBDIV, 4 * sizeof(float));
+ BKE_curve_forward_diff_bezier(0.0f, h1[1], length + h2[1], length, data[0] + 1, MAX_BBONE_SUBDIV, 4 * sizeof(float));
+ BKE_curve_forward_diff_bezier(0.0f, h1[2], h2[2], 0.0f, data[0] + 2, MAX_BBONE_SUBDIV, 4 * sizeof(float));
+ BKE_curve_forward_diff_bezier(roll1, roll1 + 0.390464f * (roll2 - roll1), roll2 - 0.390464f * (roll2 - roll1), roll2, data[0] + 3, MAX_BBONE_SUBDIV, 4 * sizeof(float));
+
+ equalize_bbone_bezier(data[0], ebone->segments); /* note: does stride 4! */
+
+ /* make transformation matrices for the segments for drawing */
+ for (a = 0, fp = data[0]; a < ebone->segments; a++, fp += 4) {
+ sub_v3_v3v3(h1, fp + 4, fp);
+ vec_roll_to_mat3(h1, fp[3], mat3); /* fp[3] is roll */
+
+ copy_m4_m3(result_array[a], mat3);
+ copy_v3_v3(result_array[a][3], fp);
+
+ /* "extra" scale facs... */
+ {
+ const int num_segments = ebone->segments;
+
+ const float scaleFactorIn = 1.0f + (ebone->scaleIn - 1.0f) * ((float)(num_segments - a) / (float)num_segments);
+ const float scaleFactorOut = 1.0f + (ebone->scaleOut - 1.0f) * ((float)(a + 1) / (float)num_segments);
+
+ const float scalefac = scaleFactorIn * scaleFactorOut;
+ float bscalemat[4][4], bscale[3];
+
+ bscale[0] = scalefac;
+ bscale[1] = 1.0f;
+ bscale[2] = scalefac;
+
+ size_to_mat4(bscalemat, bscale);
+
+ /* Note: don't multiply by inverse scale mat here, as it causes problems with scaling shearing and breaking segment chains */
+ mul_m4_series(result_array[a], result_array[a], bscalemat);
+ }
+ }
+}
+
+static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pchan)
+{
+ float s[4][4], ebmat[4][4];
+ float length, xwidth, zwidth;
+ float (*bone_mat)[4];
+ short bbone_segments;
+
+ /* TODO : This should be moved to depsgraph or armature refresh
+ * and not be tight to the draw pass creation.
+ * This would refresh armature without invalidating the draw cache */
+ if (pchan) {
+ length = pchan->bone->length;
+ xwidth = pchan->bone->xwidth;
+ zwidth = pchan->bone->zwidth;
+ bone_mat = pchan->pose_mat;
+ bbone_segments = pchan->bone->segments;
+ }
+ else {
+ eBone->length = len_v3v3(eBone->tail, eBone->head);
+ ED_armature_ebone_to_mat4(eBone, ebmat);
+
+ length = eBone->length;
+ xwidth = eBone->xwidth;
+ zwidth = eBone->zwidth;
+ bone_mat = ebmat;
+ bbone_segments = eBone->segments;
+ }
+
+ size_to_mat4(s, (const float[3]){xwidth, length / bbone_segments, zwidth});
+
+ /* Compute BBones segment matrices... */
+ /* Note that we need this even for one-segment bones, because box drawing need specific weirdo matrix for the box,
+ * that we cannot use to draw end points & co. */
+ if (pchan) {
+ Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
+ if (bbone_segments > 1) {
+ b_bone_spline_setup(pchan, 0, bbones_mat);
+
+ for (int i = bbone_segments; i--; bbones_mat++) {
+ mul_m4_m4m4(bbones_mat->mat, bbones_mat->mat, s);
+ mul_m4_m4m4(bbones_mat->mat, bone_mat, bbones_mat->mat);
+ }
+ }
+ else {
+ mul_m4_m4m4(bbones_mat->mat, bone_mat, s);
+ }
+ }
+ else {
+ float (*bbones_mat)[4][4] = eBone->disp_bbone_mat;
+
+ if (bbone_segments > 1) {
+ ebone_spline_preview(eBone, bbones_mat);
+
+ for (int i = bbone_segments; i--; bbones_mat++) {
+ mul_m4_m4m4(*bbones_mat, *bbones_mat, s);
+ mul_m4_m4m4(*bbones_mat, bone_mat, *bbones_mat);
+ }
+ }
+ else {
+ mul_m4_m4m4(*bbones_mat, bone_mat, s);
+ }
+ }
+
+ /* Grrr... We need default display matrix to draw end points, axes, etc. :( */
+ draw_bone_update_disp_matrix_default(eBone, pchan);
+}
+
+static void draw_bone_update_disp_matrix_custom(bPoseChannel *pchan)
+{
+ float s[4][4];
+ float length;
+ float (*bone_mat)[4];
+ float (*disp_mat)[4];
+ float (*disp_tail_mat)[4];
+
+ /* See TODO above */
+ length = PCHAN_CUSTOM_DRAW_SIZE(pchan);
+ bone_mat = pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat;
+ disp_mat = pchan->disp_mat;
+ disp_tail_mat = pchan->disp_tail_mat;
+
+ scale_m4_fl(s, length);
+ mul_m4_m4m4(disp_mat, bone_mat, s);
+ copy_m4_m4(disp_tail_mat, disp_mat);
+ translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f);
+}
+
+static void draw_axes(EditBone *eBone, bPoseChannel *pchan)
+{
+ const float *col = (g_theme.const_color) ? g_theme.const_color :
+ (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? g_theme.text_hi_color : g_theme.text_color;
+
+ DRW_shgroup_bone_axes(BONE_VAR(eBone, pchan, disp_mat), col);
+}
+
+static void draw_points(
+ const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm,
+ const int boneflag, const short constflag,
+ const int select_id)
+{
+ const float *col_solid_root = g_theme.bone_solid_color;
+ const float *col_solid_tail = g_theme.bone_solid_color;
+ const float *col_wire_root = (g_theme.const_color) ? g_theme.const_color : g_theme.vertex_color;
+ const float *col_wire_tail = (g_theme.const_color) ? g_theme.const_color : g_theme.vertex_color;
+
+ const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
+ static const float envelope_ignore = -1.0f;
+
+ /* Edit bone points can be selected */
+ if (eBone) {
+ if (eBone->flag & BONE_ROOTSEL) {
+#ifdef USE_SOLID_COLOR
+ col_solid_root = g_theme.vertex_select_color;
+#else
+ if (is_envelope_draw) {
+ col_solid_root = g_theme.vertex_select_color;
+ }
+#endif
+ col_wire_root = g_theme.vertex_select_color;
+ }
+ if (eBone->flag & BONE_TIPSEL) {
+#ifdef USE_SOLID_COLOR
+ col_solid_tail = g_theme.vertex_select_color;
+#else
+ if (is_envelope_draw) {
+ col_solid_tail = g_theme.vertex_select_color;
+ }
+#endif
+ col_wire_tail = g_theme.vertex_select_color;
+ }
+ }
+ else if (arm->flag & ARM_POSEMODE) {
+ col_solid_root = col_solid_tail = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
+ col_wire_root = col_wire_tail = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+ }
+
+ /* Draw root point if we are not connected and parent are not hidden */
+ if ((BONE_FLAG(eBone, pchan) & BONE_CONNECTED) == 0) {
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_ROOT);
+ }
+
+ if (eBone) {
+ if (!((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent))) {
+ if (is_envelope_draw) {
+ DRW_shgroup_bone_envelope_solid(eBone->disp_mat, col_solid_root,
+ &eBone->rad_head, &envelope_ignore);
+ DRW_shgroup_bone_envelope_head_wire(eBone->disp_mat, col_wire_root,
+ &eBone->rad_head, &envelope_ignore, &envelope_ignore);
+ }
+ else {
+ DRW_shgroup_bone_point_solid(eBone->disp_mat, col_solid_root);
+ DRW_shgroup_bone_point_wire(eBone->disp_mat, col_wire_root);
+ }
+ }
+ }
+ else {
+ Bone *bone = pchan->bone;
+ if (!((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)))) {
+ if (is_envelope_draw) {
+ DRW_shgroup_bone_envelope_solid(pchan->disp_mat, col_solid_root,
+ &bone->rad_head, &envelope_ignore);
+ DRW_shgroup_bone_envelope_head_wire(pchan->disp_mat, col_wire_root,
+ &bone->rad_head, &envelope_ignore, &envelope_ignore);
+ }
+ else {
+ DRW_shgroup_bone_point_solid(pchan->disp_mat, col_solid_root);
+ DRW_shgroup_bone_point_wire(pchan->disp_mat, col_wire_root);
+ }
+ }
+ }
+ }
+
+ /* Draw tip point */
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_TIP);
+ }
+
+ if (is_envelope_draw) {
+ const float *rad_tail = eBone ? &eBone->rad_tail : &pchan->bone->rad_tail;
+ DRW_shgroup_bone_envelope_solid(
+ BONE_VAR(eBone, pchan, disp_mat), col_solid_tail, &envelope_ignore, rad_tail);
+ DRW_shgroup_bone_envelope_head_wire(
+ BONE_VAR(eBone, pchan, disp_mat), col_wire_tail, &envelope_ignore, rad_tail, &envelope_ignore);
+ }
+ else {
+ DRW_shgroup_bone_point_solid(BONE_VAR(eBone, pchan, disp_tail_mat), col_solid_tail);
+ DRW_shgroup_bone_point_wire(BONE_VAR(eBone, pchan, disp_tail_mat), col_wire_tail);
+ }
+
+ if (select_id != -1) {
+ DRW_select_load_id(-1);
+ }
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Draw Bones
+ * \{ */
+
+static void draw_bone_custom_shape(
+ EditBone *eBone, bPoseChannel *pchan, bArmature *arm,
+ const int boneflag, const short constflag,
+ const int select_id)
+{
+ const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
+ const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+ const float (*disp_mat)[4] = pchan->disp_mat;
+
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_BONE);
+ }
+
+ DRW_shgroup_bone_custom_solid(disp_mat, col_solid, pchan->custom);
+ DRW_shgroup_bone_custom_wire(disp_mat, col_wire, pchan->custom);
+
+ if (select_id != -1) {
+ DRW_select_load_id(-1);
+ }
+}
+
+static void draw_bone_envelope(
+ EditBone *eBone, bPoseChannel *pchan, bArmature *arm,
+ const int boneflag, const short constflag,
+ const int select_id)
+{
+ const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
+ const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+
+ static const float col_white[4] = {1.0f, 1.0f, 1.0f, 0.2f};
+
+ float *rad_head, *rad_tail, *distance;
+ if (eBone) {
+ rad_tail = &eBone->rad_tail;
+ distance = &eBone->dist;
+ rad_head = (eBone->parent && (boneflag & BONE_CONNECTED)) ? &eBone->parent->rad_tail : &eBone->rad_head;
+ }
+ else {
+ rad_tail = &pchan->bone->rad_tail;
+ distance = &pchan->bone->dist;
+ rad_head = (pchan->parent && (boneflag & BONE_CONNECTED)) ? &pchan->parent->bone->rad_tail : &pchan->bone->rad_head;
+ }
+
+ if ((boneflag & BONE_NO_DEFORM) == 0 &&
+ ((boneflag & BONE_SELECTED) || (eBone && (boneflag & (BONE_ROOTSEL | BONE_TIPSEL)))))
+ {
+ DRW_shgroup_bone_envelope_distance(BONE_VAR(eBone, pchan, disp_mat), col_white, rad_head, rad_tail, distance);
+ }
+
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_BONE);
+ }
+
+ DRW_shgroup_bone_envelope_solid(BONE_VAR(eBone, pchan, disp_mat), col_solid, rad_head, rad_tail);
+ DRW_shgroup_bone_envelope_wire(BONE_VAR(eBone, pchan, disp_mat), col_wire, rad_head, rad_tail, distance);
+
+ if (select_id != -1) {
+ DRW_select_load_id(-1);
+ }
+
+ draw_points(eBone, pchan, arm, boneflag, constflag, select_id);
+}
+
+static void draw_bone_line(
+ EditBone *UNUSED(eBone), bPoseChannel *UNUSED(pchan), bArmature *UNUSED(arm),
+ const int UNUSED(boneflag), const short UNUSED(constflag),
+ const int UNUSED(select_id))
+{
+ /* work in progress -- fclem */
+}
+
+static void draw_bone_wire(
+ EditBone *eBone, bPoseChannel *pchan, bArmature *arm,
+ const int boneflag, const short constflag,
+ const int select_id)
+{
+ const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_BONE);
+ }
+
+ if (pchan) {
+ Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
+ BLI_assert(bbones_mat != NULL);
+
+ for (int i = pchan->bone->segments; i--; bbones_mat++) {
+ DRW_shgroup_bone_wire_wire(bbones_mat->mat, col_wire);
+ }
+ }
+ else if (eBone) {
+ for (int i = 0; i < eBone->segments; i++) {
+ DRW_shgroup_bone_wire_wire(eBone->disp_bbone_mat[i], col_wire);
+ }
+ }
+
+ if (select_id != -1) {
+ DRW_select_load_id(-1);
+ }
+
+ if (eBone) {
+ draw_points(eBone, pchan, arm, boneflag, constflag, select_id);
+ }
+}
+
+static void draw_bone_box(
+ EditBone *eBone, bPoseChannel *pchan, bArmature *arm,
+ const int boneflag, const short constflag,
+ const int select_id)
+{
+ const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
+ const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_BONE);
+ }
+
+ if (pchan) {
+ Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
+ BLI_assert(bbones_mat != NULL);
+
+ for (int i = pchan->bone->segments; i--; bbones_mat++) {
+ DRW_shgroup_bone_box_solid(bbones_mat->mat, col_solid);
+ DRW_shgroup_bone_box_wire(bbones_mat->mat, col_wire);
+ }
+ }
+ else if (eBone) {
+ for (int i = 0; i < eBone->segments; i++) {
+ DRW_shgroup_bone_box_solid(eBone->disp_bbone_mat[i], col_solid);
+ DRW_shgroup_bone_box_wire(eBone->disp_bbone_mat[i], col_wire);
+ }
+ }
+
+ if (select_id != -1) {
+ DRW_select_load_id(-1);
+ }
+
+ if (eBone) {
+ draw_points(eBone, pchan, arm, boneflag, constflag, select_id);
+ }
+}
+
+static void draw_bone_octahedral(
+ EditBone *eBone, bPoseChannel *pchan, bArmature *arm,
+ const int boneflag, const short constflag,
+ const int select_id)
+{
+ const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
+ const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+
+ if (select_id != -1) {
+ DRW_select_load_id(select_id | BONESEL_BONE);
+ }
+
+ DRW_shgroup_bone_octahedral_solid(BONE_VAR(eBone, pchan, disp_mat), col_solid);
+ DRW_shgroup_bone_octahedral_wire(BONE_VAR(eBone, pchan, disp_mat), col_wire);
+
+ if (select_id != -1) {
+ DRW_select_load_id(-1);
+ }
+
+ draw_points(eBone, pchan, arm, boneflag, constflag, select_id);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Main Draw Loops
+ * \{ */
+
+static void draw_armature_edit(Object *ob)
+{
+ EditBone *eBone;
+ bArmature *arm = ob->data;
+ int index;
+ const bool is_select = DRW_state_is_select();
+
+ update_color(NULL);
+
+ const bool show_text = DRW_state_show_text();
+
+ for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) {
+ if (eBone->layer & arm->layer) {
+ if ((eBone->flag & BONE_HIDDEN_A) == 0) {
+ const int select_id = is_select ? index : (unsigned int)-1;
+
+ const short constflag = 0;
+
+ /* catch exception for bone with hidden parent */
+ int boneflag = eBone->flag;
+ if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) {
+ boneflag &= ~BONE_CONNECTED;
+ }
+
+ /* set temporary flag for drawing bone as active, but only if selected */
+ if (eBone == arm->act_edbone) {
+ boneflag |= BONE_DRAW_ACTIVE;
+ }
+
+ if (arm->drawtype == ARM_ENVELOPE) {
+ draw_bone_update_disp_matrix_default(eBone, NULL);
+ draw_bone_envelope(eBone, NULL, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_LINE) {
+ draw_bone_update_disp_matrix_default(eBone, NULL);
+ draw_bone_line(eBone, NULL, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_WIRE) {
+ draw_bone_update_disp_matrix_bbone(eBone, NULL);
+ draw_bone_wire(eBone, NULL, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_B_BONE) {
+ draw_bone_update_disp_matrix_bbone(eBone, NULL);
+ draw_bone_box(eBone, NULL, arm, boneflag, constflag, select_id);
+ }
+ else {
+ draw_bone_update_disp_matrix_default(eBone, NULL);
+ draw_bone_octahedral(eBone, NULL, arm, boneflag, constflag, select_id);
+ }
+
+ /* Draw names of bone */
+ if (show_text && (arm->flag & ARM_DRAWNAMES)) {
+ unsigned char color[4];
+ UI_GetThemeColor4ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, color);
+
+ float vec[3];
+ mid_v3_v3v3(vec, eBone->head, eBone->tail);
+ mul_m4_v3(ob->obmat, vec);
+
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRW_text_cache_add(
+ dt, vec, eBone->name, strlen(eBone->name),
+ 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
+ }
+
+ /* Draw additional axes */
+ if (arm->flag & ARM_DRAWAXES) {
+ draw_axes(eBone, NULL);
+ }
+ }
+ }
+ }
+}
+
+/* if const_color is NULL do pose mode coloring */
+static void draw_armature_pose(Object *ob, const float const_color[4])
+{
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan;
+ int index = -1;
+ Bone *bone;
+
+ update_color(const_color);
+
+ /* We can't safely draw non-updated pose, might contain NULL bone pointers... */
+ if (ob->pose->flag & POSE_RECALC) {
+ BKE_pose_rebuild(ob, arm);
+ }
+
+ // if (!(base->flag & OB_FROMDUPLI)) // TODO
+ {
+ if (ob->mode & OB_MODE_POSE) {
+ arm->flag |= ARM_POSEMODE;
+ }
+
+ if (arm->flag & ARM_POSEMODE) {
+ index = ob->base_selection_color;
+ }
+ }
+
+ const bool is_pose_select = (arm->flag & ARM_POSEMODE) && DRW_state_is_select();
+ const bool show_text = DRW_state_show_text();
+
+ /* being set below */
+ arm->layer_used = 0;
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ bone = pchan->bone;
+ arm->layer_used |= bone->layer;
+
+ /* bone must be visible */
+ if ((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) {
+ if (bone->layer & arm->layer) {
+ const int select_id = is_pose_select ? index : (unsigned int)-1;
+
+ const short constflag = pchan->constflag;
+
+ pchan_draw_data_init(pchan);
+
+ if (const_color) {
+ /* keep color */
+ }
+ else {
+ /* set color-set to use */
+ set_pchan_colorset(ob, pchan);
+ }
+
+ int boneflag = bone->flag;
+ /* catch exception for bone with hidden parent */
+ boneflag = bone->flag;
+ if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
+ boneflag &= ~BONE_CONNECTED;
+ }
+
+ /* set temporary flag for drawing bone as active, but only if selected */
+ if (bone == arm->act_bone)
+ boneflag |= BONE_DRAW_ACTIVE;
+
+
+ if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
+ draw_bone_update_disp_matrix_custom(pchan);
+ draw_bone_custom_shape(NULL, pchan, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_ENVELOPE) {
+ draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_envelope(NULL, pchan, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_LINE) {
+ draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_line(NULL, pchan, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_WIRE) {
+ draw_bone_update_disp_matrix_bbone(NULL, pchan);
+ draw_bone_wire(NULL, pchan, arm, boneflag, constflag, select_id);
+ }
+ else if (arm->drawtype == ARM_B_BONE) {
+ draw_bone_update_disp_matrix_bbone(NULL, pchan);
+ draw_bone_box(NULL, pchan, arm, boneflag, constflag, select_id);
+ }
+ else {
+ draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_octahedral(NULL, pchan, arm, boneflag, constflag, select_id);
+ }
+
+ /* Draw names of bone */
+ if (show_text && (arm->flag & ARM_DRAWNAMES)) {
+ unsigned char color[4];
+ UI_GetThemeColor4ubv((arm->flag & ARM_POSEMODE) &&
+ (bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, color);
+ float vec[3];
+ mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail);
+ mul_m4_v3(ob->obmat, vec);
+
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRW_text_cache_add(
+ dt, vec, pchan->name, strlen(pchan->name),
+ 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
+ }
+
+ /* Draw additional axes */
+ if (arm->flag & ARM_DRAWAXES) {
+ draw_axes(NULL, pchan);
+ }
+ }
+ }
+ if (is_pose_select) {
+ index += 0x10000;
+ }
+ }
+
+ arm->flag &= ~ARM_POSEMODE;
+}
+
+/**
+ * This function set the object space to use for all subsequent `DRW_shgroup_bone_*` calls.
+ */
+static void DRW_shgroup_armature(
+ Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWPass *pass_bone_envelope,
+ DRWShadingGroup *shgrp_relationship_lines)
+{
+ memset(&g_data, 0x0, sizeof(g_data));
+ g_data.ob = ob;
+
+ g_data.pass_bone_solid = pass_bone_solid;
+ g_data.pass_bone_wire = pass_bone_wire;
+ g_data.pass_bone_envelope = pass_bone_envelope;
+ g_data.relationship_lines = shgrp_relationship_lines;
+
+ memset(&g_color, 0x0, sizeof(g_color));
+}
+
+void DRW_shgroup_armature_object(
+ Object *ob, SceneLayer *sl, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWPass *UNUSED(pass_bone_envelope),
+ DRWShadingGroup *shgrp_relationship_lines)
+{
+ float *color;
+ DRW_object_wire_theme_get(ob, sl, &color);
+
+ DRW_shgroup_armature(ob, pass_bone_solid, pass_bone_wire, NULL, shgrp_relationship_lines);
+ draw_armature_pose(ob, color);
+}
+
+void DRW_shgroup_armature_pose(
+ Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWPass *pass_bone_envelope,
+ DRWShadingGroup *shgrp_relationship_lines)
+{
+ DRW_shgroup_armature(ob, pass_bone_solid, pass_bone_wire, pass_bone_envelope, shgrp_relationship_lines);
+ draw_armature_pose(ob, NULL);
+}
+
+void DRW_shgroup_armature_edit(
+ Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWPass *pass_bone_envelope,
+ DRWShadingGroup *shgrp_relationship_lines)
+{
+ DRW_shgroup_armature(ob, pass_bone_solid, pass_bone_wire, pass_bone_envelope, shgrp_relationship_lines);
+ draw_armature_edit(ob);
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
new file mode 100644
index 00000000000..06ec0f746e0
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache.c
@@ -0,0 +1,2415 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_cache.c
+ * \ingroup draw
+ */
+
+
+#include "DNA_scene_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "GPU_batch.h"
+
+#include "draw_cache.h"
+#include "draw_cache_impl.h"
+
+static struct DRWShapeCache {
+ Batch *drw_single_vertice;
+ Batch *drw_fullscreen_quad;
+ Batch *drw_screenspace_circle;
+ Batch *drw_plain_axes;
+ Batch *drw_single_arrow;
+ Batch *drw_cube;
+ Batch *drw_circle;
+ Batch *drw_square;
+ Batch *drw_line;
+ Batch *drw_line_endpoints;
+ Batch *drw_empty_sphere;
+ Batch *drw_empty_cone;
+ Batch *drw_arrows;
+ Batch *drw_axis_names;
+ Batch *drw_image_plane;
+ Batch *drw_image_plane_wire;
+ Batch *drw_field_wind;
+ Batch *drw_field_force;
+ Batch *drw_field_vortex;
+ Batch *drw_field_tube_limit;
+ Batch *drw_field_cone_limit;
+ Batch *drw_lamp;
+ Batch *drw_lamp_sunrays;
+ Batch *drw_lamp_area;
+ Batch *drw_lamp_hemi;
+ Batch *drw_lamp_spot;
+ Batch *drw_lamp_spot_square;
+ Batch *drw_speaker;
+ Batch *drw_bone_octahedral;
+ Batch *drw_bone_octahedral_wire;
+ Batch *drw_bone_box;
+ Batch *drw_bone_box_wire;
+ Batch *drw_bone_wire_wire;
+ Batch *drw_bone_envelope;
+ Batch *drw_bone_envelope_distance;
+ Batch *drw_bone_envelope_wire;
+ Batch *drw_bone_envelope_head_wire;
+ Batch *drw_bone_point;
+ Batch *drw_bone_point_wire;
+ Batch *drw_bone_arrows;
+ Batch *drw_camera;
+ Batch *drw_camera_tria;
+ Batch *drw_camera_focus;
+ Batch *drw_particle_cross;
+ Batch *drw_particle_circle;
+ Batch *drw_particle_axis;
+} SHC = {NULL};
+
+void DRW_shape_cache_free(void)
+{
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_single_vertice);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_fullscreen_quad);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_plain_axes);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_single_arrow);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_cube);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_circle);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_square);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_line);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_line_endpoints);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_empty_sphere);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_empty_cone);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_arrows);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_axis_names);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_image_plane);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_image_plane_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_field_wind);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_field_force);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_field_vortex);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_field_tube_limit);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_field_cone_limit);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_sunrays);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_area);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_hemi);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_spot);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_spot_square);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_speaker);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_octahedral);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_octahedral_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_box);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_box_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_wire_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_distance);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_head_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_point);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_point_wire);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_arrows);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_camera);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_camera_tria);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_camera_focus);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_particle_cross);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_particle_circle);
+ BATCH_DISCARD_ALL_SAFE(SHC.drw_particle_axis);
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Helper functions
+ * \{ */
+
+static void add_fancy_edge(
+ VertexBuffer *vbo, unsigned int pos_id, unsigned int n1_id, unsigned int n2_id,
+ unsigned int *v_idx, const float co1[3], const float co2[3],
+const float n1[3], const float n2[3])
+{
+ VertexBuffer_set_attrib(vbo, n1_id, *v_idx, n1);
+ VertexBuffer_set_attrib(vbo, n2_id, *v_idx, n2);
+ VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++, co1);
+
+ VertexBuffer_set_attrib(vbo, n1_id, *v_idx, n1);
+ VertexBuffer_set_attrib(vbo, n2_id, *v_idx, n2);
+ VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++, co2);
+}
+
+static void add_lat_lon_vert(
+ VertexBuffer *vbo, unsigned int pos_id, unsigned int nor_id,
+ unsigned int *v_idx, const float rad, const float lat, const float lon)
+{
+ float pos[3], nor[3];
+ nor[0] = sinf(lat) * cosf(lon);
+ nor[1] = cosf(lat);
+ nor[2] = sinf(lat) * sinf(lon);
+ mul_v3_v3fl(pos, nor, rad);
+
+ VertexBuffer_set_attrib(vbo, nor_id, *v_idx, nor);
+ VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++, pos);
+}
+
+static VertexBuffer *fill_arrows_vbo(const float scale)
+{
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Line */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 6 * 3);
+
+ float v1[3] = {0.0, 0.0, 0.0};
+ float v2[3] = {0.0, 0.0, 0.0};
+ float vtmp1[3], vtmp2[3];
+
+ for (int axis = 0; axis < 3; axis++) {
+ const int arrow_axis = (axis == 0) ? 1 : 0;
+
+ v2[axis] = 1.0f;
+ mul_v3_v3fl(vtmp1, v1, scale);
+ mul_v3_v3fl(vtmp2, v2, scale);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 6 + 0, vtmp1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 6 + 1, vtmp2);
+
+ v1[axis] = 0.85f;
+ v1[arrow_axis] = -0.08f;
+ mul_v3_v3fl(vtmp1, v1, scale);
+ mul_v3_v3fl(vtmp2, v2, scale);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 6 + 2, vtmp1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 6 + 3, vtmp2);
+
+ v1[arrow_axis] = 0.08f;
+ mul_v3_v3fl(vtmp1, v1, scale);
+ mul_v3_v3fl(vtmp2, v2, scale);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 6 + 4, vtmp1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 6 + 5, vtmp2);
+
+ /* reset v1 & v2 to zero */
+ v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
+ }
+
+ return vbo;
+}
+
+static VertexBuffer *sphere_wire_vbo(const float rad)
+{
+#define NSEGMENTS 16
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, NSEGMENTS * 2 * 3);
+
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = rad * cosf(angle);
+ p[i][1] = rad * sinf(angle);
+ }
+
+ for (int axis = 0; axis < 3; ++axis) {
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ float cv[2], v[3];
+
+ cv[0] = p[(i + j) % NSEGMENTS][0];
+ cv[1] = p[(i + j) % NSEGMENTS][1];
+
+ if (axis == 0)
+ v[0] = cv[0], v[1] = cv[1], v[2] = 0.0f;
+ else if (axis == 1)
+ v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
+ else
+ v[0] = 0.0f, v[1] = cv[0], v[2] = cv[1];
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 2 + j + (NSEGMENTS * 2 * axis), v);
+ }
+ }
+ }
+
+ return vbo;
+#undef NSEGMENTS
+}
+
+/* Quads */
+Batch *DRW_cache_fullscreen_quad_get(void)
+{
+ if (!SHC.drw_fullscreen_quad) {
+ /* Use a triangle instead of a real quad */
+ /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */
+ float pos[3][2] = {{-1.0f, -1.0f}, { 3.0f, -1.0f}, {-1.0f, 3.0f}};
+ float uvs[3][2] = {{ 0.0f, 0.0f}, { 2.0f, 0.0f}, { 0.0f, 2.0f}};
+
+ /* Position Only 2D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos, uvs; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ attr_id.uvs = VertexFormat_add_attrib(&format, "uvs", COMP_F32, 2, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 3);
+
+ for (int i = 0; i < 3; ++i) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i, pos[i]);
+ VertexBuffer_set_attrib(vbo, attr_id.uvs, i, uvs[i]);
+ }
+
+ SHC.drw_fullscreen_quad = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_fullscreen_quad;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Common
+ * \{ */
+
+Batch *DRW_cache_cube_get(void)
+{
+ if (!SHC.drw_cube) {
+ const GLfloat verts[8][3] = {
+ {-1.0f, -1.0f, -1.0f},
+ {-1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f},
+ {-1.0f, 1.0f, 1.0f},
+ { 1.0f, -1.0f, -1.0f},
+ { 1.0f, -1.0f, 1.0f},
+ { 1.0f, 1.0f, -1.0f},
+ { 1.0f, 1.0f, 1.0f}
+ };
+
+ const GLubyte indices[24] = {0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 24);
+
+ for (int i = 0; i < 24; ++i) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i, verts[indices[i]]);
+ }
+
+ SHC.drw_cube = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_cube;
+}
+
+Batch *DRW_cache_circle_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_circle) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2);
+
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[2] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a * 2, v);
+
+ v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[2] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[1] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a * 2 + 1, v);
+ }
+
+ SHC.drw_circle = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_circle;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_square_get(void)
+{
+ if (!SHC.drw_square) {
+ float p[4][3] = {{ 1.0f, 0.0f, 1.0f},
+ { 1.0f, 0.0f, -1.0f},
+ {-1.0f, 0.0f, -1.0f},
+ {-1.0f, 0.0f, 1.0f}};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 8);
+
+ for (int i = 0; i < 4; i++) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 2, p[i % 4]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 2 + 1, p[(i+1) % 4]);
+ }
+
+ SHC.drw_square = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_square;
+}
+
+Batch *DRW_cache_single_line_get(void)
+{
+ /* Z axis line */
+ if (!SHC.drw_line) {
+ float v1[3] = {0.0f, 0.0f, 0.0f};
+ float v2[3] = {0.0f, 0.0f, 1.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 2);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 0, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 1, v2);
+
+ SHC.drw_line = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_line;
+}
+
+Batch *DRW_cache_single_line_endpoints_get(void)
+{
+ /* Z axis line */
+ if (!SHC.drw_line_endpoints) {
+ float v1[3] = {0.0f, 0.0f, 0.0f};
+ float v2[3] = {0.0f, 0.0f, 1.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 2);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 0, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 1, v2);
+
+ SHC.drw_line_endpoints = Batch_create(PRIM_POINTS, vbo, NULL);
+ }
+ return SHC.drw_line_endpoints;
+}
+
+Batch *DRW_cache_screenspace_circle_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_screenspace_circle) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL + 1);
+
+ for (int a = 0; a <= CIRCLE_RESOL; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a, v);
+ }
+
+ SHC.drw_screenspace_circle = Batch_create(PRIM_LINE_STRIP, vbo, NULL);
+ }
+ return SHC.drw_screenspace_circle;
+#undef CIRCLE_RESOL
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Common Object API
+ * \{ */
+
+Batch *DRW_cache_object_wire_outline_get(Object *ob)
+{
+ switch (ob->type) {
+ case OB_MESH:
+ return DRW_cache_mesh_wire_outline_get(ob);
+
+ /* TODO, should match 'DRW_cache_object_surface_get' */
+ default:
+ return NULL;
+ }
+}
+
+Batch *DRW_cache_object_surface_get(Object *ob)
+{
+ switch (ob->type) {
+ case OB_MESH:
+ return DRW_cache_mesh_surface_get(ob);
+ case OB_CURVE:
+ return DRW_cache_curve_surface_get(ob);
+ case OB_SURF:
+ return DRW_cache_surf_surface_get(ob);
+ case OB_FONT:
+ return DRW_cache_text_surface_get(ob);
+ default:
+ return NULL;
+ }
+}
+
+Batch **DRW_cache_object_surface_material_get(struct Object *ob)
+{
+ switch (ob->type) {
+ case OB_MESH:
+ return DRW_cache_mesh_surface_shaded_get(ob);
+ default:
+ return NULL;
+ }
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Empties
+ * \{ */
+
+Batch *DRW_cache_plain_axes_get(void)
+{
+ if (!SHC.drw_plain_axes) {
+ int axis;
+ float v1[3] = {0.0f, 0.0f, 0.0f};
+ float v2[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 6);
+
+ for (axis = 0; axis < 3; axis++) {
+ v1[axis] = 1.0f;
+ v2[axis] = -1.0f;
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 2, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, axis * 2 + 1, v2);
+
+ /* reset v1 & v2 to zero for next axis */
+ v1[axis] = v2[axis] = 0.0f;
+ }
+
+ SHC.drw_plain_axes = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_plain_axes;
+}
+
+Batch *DRW_cache_single_arrow_get(void)
+{
+ if (!SHC.drw_single_arrow) {
+ float v1[3] = {0.0f, 0.0f, 1.0f}, v2[3], v3[3];
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Square Pyramid */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 12);
+
+ v2[0] = 0.035f; v2[1] = 0.035f;
+ v3[0] = -0.035f; v3[1] = 0.035f;
+ v2[2] = v3[2] = 0.75f;
+
+ for (int sides = 0; sides < 4; sides++) {
+ if (sides % 2 == 1) {
+ v2[0] = -v2[0];
+ v3[1] = -v3[1];
+ }
+ else {
+ v2[1] = -v2[1];
+ v3[0] = -v3[0];
+ }
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, sides * 3 + 0, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, sides * 3 + 1, v2);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, sides * 3 + 2, v3);
+ }
+
+ SHC.drw_single_arrow = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_single_arrow;
+}
+
+Batch *DRW_cache_empty_sphere_get(void)
+{
+ if (!SHC.drw_empty_sphere) {
+ VertexBuffer *vbo = sphere_wire_vbo(1.0f);
+ SHC.drw_empty_sphere = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_empty_sphere;
+}
+
+Batch *DRW_cache_empty_cone_get(void)
+{
+#define NSEGMENTS 8
+ if (!SHC.drw_empty_cone) {
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = cosf(angle);
+ p[i][1] = sinf(angle);
+ }
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, NSEGMENTS * 4);
+
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float cv[2], v[3];
+ cv[0] = p[(i) % NSEGMENTS][0];
+ cv[1] = p[(i) % NSEGMENTS][1];
+
+ /* cone sides */
+ v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4, v);
+ v[0] = 0.0f, v[1] = 2.0f, v[2] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4 + 1, v);
+
+ /* end ring */
+ v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4 + 2, v);
+ cv[0] = p[(i + 1) % NSEGMENTS][0];
+ cv[1] = p[(i + 1) % NSEGMENTS][1];
+ v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4 + 3, v);
+ }
+
+ SHC.drw_empty_cone = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_empty_cone;
+#undef NSEGMENTS
+}
+
+Batch *DRW_cache_arrows_get(void)
+{
+ if (!SHC.drw_arrows) {
+ VertexBuffer *vbo = fill_arrows_vbo(1.0f);
+
+ SHC.drw_arrows = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_arrows;
+}
+
+Batch *DRW_cache_axis_names_get(void)
+{
+ if (!SHC.drw_axis_names) {
+ const float size = 0.1f;
+ float v1[3], v2[3];
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* Using 3rd component as axis indicator */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Line */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 14);
+
+ /* X */
+ copy_v3_fl3(v1, -size, size, 0.0f);
+ copy_v3_fl3(v2, size, -size, 0.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 0, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 1, v2);
+
+ copy_v3_fl3(v1, size, size, 0.0f);
+ copy_v3_fl3(v2, -size, -size, 0.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 2, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 3, v2);
+
+ /* Y */
+ copy_v3_fl3(v1, -size + 0.25f * size, size, 1.0f);
+ copy_v3_fl3(v2, 0.0f, 0.0f, 1.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 4, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 5, v2);
+
+ copy_v3_fl3(v1, size - 0.25f * size, size, 1.0f);
+ copy_v3_fl3(v2, -size + 0.25f * size, -size, 1.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 6, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 7, v2);
+
+ /* Z */
+ copy_v3_fl3(v1, -size, size, 2.0f);
+ copy_v3_fl3(v2, size, size, 2.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 8, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 9, v2);
+
+ copy_v3_fl3(v1, size, size, 2.0f);
+ copy_v3_fl3(v2, -size, -size, 2.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 10, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 11, v2);
+
+ copy_v3_fl3(v1, -size, -size, 2.0f);
+ copy_v3_fl3(v2, size, -size, 2.0f);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 12, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 13, v2);
+
+ SHC.drw_axis_names = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_axis_names;
+}
+
+Batch *DRW_cache_image_plane_get(void)
+{
+ if (!SHC.drw_image_plane) {
+ const float quad[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+ static VertexFormat format = { 0 };
+ static struct { uint pos, texCoords; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ attr_id.texCoords = VertexFormat_add_attrib(&format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 4);
+ for (uint j = 0; j < 4; j++) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, j, quad[j]);
+ VertexBuffer_set_attrib(vbo, attr_id.texCoords, j, quad[j]);
+ }
+ SHC.drw_image_plane = Batch_create(PRIM_TRIANGLE_FAN, vbo, NULL);
+ }
+ return SHC.drw_image_plane;
+}
+
+Batch *DRW_cache_image_plane_wire_get(void)
+{
+ if (!SHC.drw_image_plane_wire) {
+ const float quad[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 4);
+ for (uint j = 0; j < 4; j++) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, j, quad[j]);
+ }
+ SHC.drw_image_plane_wire = Batch_create(PRIM_LINE_LOOP, vbo, NULL);
+ }
+ return SHC.drw_image_plane_wire;
+}
+
+/* Force Field */
+Batch *DRW_cache_field_wind_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_field_wind) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 4);
+
+ for (int i = 0; i < 4; i++) {
+ float z = 0.05f * (float)i;
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2, v);
+
+ v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2 + 1, v);
+ }
+ }
+
+ SHC.drw_field_wind = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_field_wind;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_field_force_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_field_force) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 3);
+
+ for (int i = 0; i < 3; i++) {
+ float radius = 1.0f + 0.5f * (float)i;
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[2] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2, v);
+
+ v[0] = radius * sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[1] = radius * cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[2] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2 + 1, v);
+ }
+ }
+
+ SHC.drw_field_force = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_field_force;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_field_vortex_get(void)
+{
+#define SPIRAL_RESOL 32
+ if (!SHC.drw_field_vortex) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+ unsigned int v_idx = 0;
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, SPIRAL_RESOL * 2 + 1);
+
+ for (int a = SPIRAL_RESOL; a > -1; a--) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+ v[1] = cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+ }
+
+ for (int a = 1; a <= SPIRAL_RESOL; a++) {
+ v[0] = -sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+ v[1] = -cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+ }
+
+ SHC.drw_field_vortex = Batch_create(PRIM_LINE_STRIP, vbo, NULL);
+ }
+ return SHC.drw_field_vortex;
+#undef SPIRAL_RESOL
+}
+
+Batch *DRW_cache_field_tube_limit_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_field_tube_limit) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+ unsigned int v_idx = 0;
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 + 8);
+
+ /* Caps */
+ for (int i = 0; i < 2; i++) {
+ float z = (float)i * 2.0f - 1.0f;
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+
+ v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+ }
+ }
+ /* Side Edges */
+ for (int a = 0; a < 4; a++) {
+ for (int i = 0; i < 2; i++) {
+ float z = (float)i * 2.0f - 1.0f;
+ v[0] = sinf((2.0f * M_PI * a) / 4.0f);
+ v[1] = cosf((2.0f * M_PI * a) / 4.0f);
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+ }
+ }
+
+ SHC.drw_field_tube_limit = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_field_tube_limit;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_field_cone_limit_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_field_cone_limit) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+ unsigned int v_idx = 0;
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 + 8);
+
+ /* Caps */
+ for (int i = 0; i < 2; i++) {
+ float z = (float)i * 2.0f - 1.0f;
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+
+ v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+ }
+ }
+ /* Side Edges */
+ for (int a = 0; a < 4; a++) {
+ for (int i = 0; i < 2; i++) {
+ float z = (float)i * 2.0f - 1.0f;
+ v[0] = z * sinf((2.0f * M_PI * a) / 4.0f);
+ v[1] = z * cosf((2.0f * M_PI * a) / 4.0f);
+ v[2] = z;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, v);
+ }
+ }
+
+ SHC.drw_field_cone_limit = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_field_cone_limit;
+#undef CIRCLE_RESOL
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Lamps
+ * \{ */
+
+Batch *DRW_cache_lamp_get(void)
+{
+#define NSEGMENTS 8
+ if (!SHC.drw_lamp) {
+ float v[2];
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, NSEGMENTS * 2);
+
+ for (int a = 0; a < NSEGMENTS; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)NSEGMENTS));
+ v[1] = cosf((2.0f * M_PI * a) / ((float)NSEGMENTS));
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a * 2, v);
+
+ v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS));
+ v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS));
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a * 2 + 1, v);
+ }
+
+ SHC.drw_lamp = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_lamp;
+#undef NSEGMENTS
+}
+
+Batch *DRW_cache_lamp_sunrays_get(void)
+{
+ if (!SHC.drw_lamp_sunrays) {
+ float v[2], v1[2], v2[2];
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 16);
+
+ for (int a = 0; a < 8; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / 8.0f);
+ v[1] = cosf((2.0f * M_PI * a) / 8.0f);
+
+ mul_v2_v2fl(v1, v, 1.2f);
+ mul_v2_v2fl(v2, v, 2.5f);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a * 2, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, a * 2 + 1, v2);
+ }
+
+ SHC.drw_lamp_sunrays = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_lamp_sunrays;
+}
+
+Batch *DRW_cache_lamp_area_get(void)
+{
+ if (!SHC.drw_lamp_area) {
+ float v1[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 8);
+
+ v1[0] = v1[1] = 0.5f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 0, v1);
+ v1[0] = -0.5f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 1, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 2, v1);
+ v1[1] = -0.5f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 3, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 4, v1);
+ v1[0] = 0.5f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 5, v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 6, v1);
+ v1[1] = 0.5f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 7, v1);
+
+ SHC.drw_lamp_area = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_lamp_area;
+}
+
+Batch *DRW_cache_lamp_hemi_get(void)
+{
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_lamp_hemi) {
+ float v[3];
+ int vidx = 0;
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 - 6 * 2 * 2);
+
+ /* XZ plane */
+ for (int a = 3; a < CIRCLE_RESOL / 2 - 3; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL) - M_PI / 2);
+ v[2] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL) - M_PI / 2) - 1.0f;
+ v[1] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+
+ v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL) - M_PI / 2);
+ v[2] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL) - M_PI / 2) - 1.0f;
+ v[1] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ }
+
+ /* XY plane */
+ for (int a = 3; a < CIRCLE_RESOL / 2 - 3; a++) {
+ v[2] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)) - 1.0f;
+ v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[0] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+
+ v[2] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)) - 1.0f;
+ v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[0] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ }
+
+ /* YZ plane full circle */
+ /* lease v[2] as it is */
+ const float rad = cosf((2.0f * M_PI * 3) / ((float)CIRCLE_RESOL));
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[1] = rad * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[0] = rad * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+
+ v[1] = rad * sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ v[0] = rad * cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ }
+
+
+ SHC.drw_lamp_hemi = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_lamp_hemi;
+#undef CIRCLE_RESOL
+}
+
+
+Batch *DRW_cache_lamp_spot_get(void)
+{
+#define NSEGMENTS 32
+ if (!SHC.drw_lamp_spot) {
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ float n[NSEGMENTS][3];
+ float neg[NSEGMENTS][3];
+ float half_angle = 2 * M_PI / ((float)NSEGMENTS * 2);
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = cosf(angle);
+ p[i][1] = sinf(angle);
+
+ n[i][0] = cosf(angle - half_angle);
+ n[i][1] = sinf(angle - half_angle);
+ n[i][2] = cosf(M_PI / 16.0f); /* slope of the cone */
+ normalize_v3(n[i]); /* necessary ? */
+ negate_v3_v3(neg[i], n[i]);
+ }
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos, n1, n2; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n1 = VertexFormat_add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n2 = VertexFormat_add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, NSEGMENTS * 4);
+
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float cv[2], v[3];
+ cv[0] = p[i % NSEGMENTS][0];
+ cv[1] = p[i % NSEGMENTS][1];
+
+ /* cone sides */
+ v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4, v);
+ v[0] = 0.0f, v[1] = 0.0f, v[2] = 0.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4 + 1, v);
+
+ VertexBuffer_set_attrib(vbo, attr_id.n1, i * 4, n[(i) % NSEGMENTS]);
+ VertexBuffer_set_attrib(vbo, attr_id.n1, i * 4 + 1, n[(i) % NSEGMENTS]);
+ VertexBuffer_set_attrib(vbo, attr_id.n2, i * 4, n[(i+1) % NSEGMENTS]);
+ VertexBuffer_set_attrib(vbo, attr_id.n2, i * 4 + 1, n[(i+1) % NSEGMENTS]);
+
+ /* end ring */
+ v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4 + 2, v);
+ cv[0] = p[(i + 1) % NSEGMENTS][0];
+ cv[1] = p[(i + 1) % NSEGMENTS][1];
+ v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i * 4 + 3, v);
+
+ VertexBuffer_set_attrib(vbo, attr_id.n1, i * 4 + 2, n[(i) % NSEGMENTS]);
+ VertexBuffer_set_attrib(vbo, attr_id.n1, i * 4 + 3, n[(i) % NSEGMENTS]);
+ VertexBuffer_set_attrib(vbo, attr_id.n2, i * 4 + 2, neg[(i) % NSEGMENTS]);
+ VertexBuffer_set_attrib(vbo, attr_id.n2, i * 4 + 3, neg[(i) % NSEGMENTS]);
+ }
+
+ SHC.drw_lamp_spot = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_lamp_spot;
+#undef NSEGMENTS
+}
+
+Batch *DRW_cache_lamp_spot_square_get(void)
+{
+ if (!SHC.drw_lamp_spot_square) {
+ float p[5][3] = {{ 0.0f, 0.0f, 0.0f},
+ { 1.0f, 1.0f, -1.0f},
+ { 1.0f, -1.0f, -1.0f},
+ {-1.0f, -1.0f, -1.0f},
+ {-1.0f, 1.0f, -1.0f}};
+
+ unsigned int v_idx = 0;
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 16);
+
+ /* piramid sides */
+ for (int i = 1; i <= 4; ++i) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, p[0]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, p[i]);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, p[(i % 4)+1]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, p[((i+1) % 4)+1]);
+ }
+
+ SHC.drw_lamp_spot_square = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_lamp_spot_square;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Speaker
+ * \{ */
+
+Batch *DRW_cache_speaker_get(void)
+{
+ if (!SHC.drw_speaker) {
+ float v[3];
+ const int segments = 16;
+ int vidx = 0;
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 3 * segments * 2 + 4 * 4);
+
+ for (int j = 0; j < 3; j++) {
+ float z = 0.25f * j - 0.125f;
+ float r = (j == 0 ? 0.5f : 0.25f);
+
+ copy_v3_fl3(v, r, 0.0f, z);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ for (int i = 1; i < segments; i++) {
+ float x = cosf(2.f * (float)M_PI * i / segments) * r;
+ float y = sinf(2.f * (float)M_PI * i / segments) * r;
+ copy_v3_fl3(v, x, y, z);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ }
+ copy_v3_fl3(v, r, 0.0f, z);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ }
+
+ for (int j = 0; j < 4; j++) {
+ float x = (((j + 1) % 2) * (j - 1)) * 0.5f;
+ float y = ((j % 2) * (j - 2)) * 0.5f;
+ for (int i = 0; i < 3; i++) {
+ if (i == 1) {
+ x *= 0.5f;
+ y *= 0.5f;
+ }
+
+ float z = 0.25f * i - 0.125f;
+ copy_v3_fl3(v, x, y, z);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ if (i == 1) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, v);
+ }
+ }
+ }
+
+ SHC.drw_speaker = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_speaker;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Armature Bones
+ * \{ */
+
+static const float bone_octahedral_verts[6][3] = {
+ { 0.0f, 0.0f, 0.0f},
+ { 0.1f, 0.1f, 0.1f},
+ { 0.1f, 0.1f, -0.1f},
+ {-0.1f, 0.1f, -0.1f},
+ {-0.1f, 0.1f, 0.1f},
+ { 0.0f, 1.0f, 0.0f}
+};
+
+static const unsigned int bone_octahedral_wire[24] = {
+ 0, 1, 1, 5, 5, 3, 3, 0,
+ 0, 4, 4, 5, 5, 2, 2, 0,
+ 1, 2, 2, 3, 3, 4, 4, 1,
+};
+
+/* aligned with bone_octahedral_wire
+ * Contains adjacent normal index */
+static const unsigned int bone_octahedral_wire_adjacent_face[24] = {
+ 0, 3, 4, 7, 5, 6, 1, 2,
+ 2, 3, 6, 7, 4, 5, 0, 1,
+ 0, 4, 1, 5, 2, 6, 3, 7,
+};
+
+static const unsigned int bone_octahedral_solid_tris[8][3] = {
+ {2, 1, 0}, /* bottom */
+ {3, 2, 0},
+ {4, 3, 0},
+ {1, 4, 0},
+
+ {5, 1, 2}, /* top */
+ {5, 2, 3},
+ {5, 3, 4},
+ {5, 4, 1}
+};
+
+/* aligned with bone_octahedral_solid_tris */
+static const float bone_octahedral_solid_normals[8][3] = {
+ { M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
+ {-0.00000000f, -M_SQRT1_2, -M_SQRT1_2},
+ {-M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
+ { 0.00000000f, -M_SQRT1_2, M_SQRT1_2},
+ { 0.99388373f, 0.11043154f, -0.00000000f},
+ { 0.00000000f, 0.11043154f, -0.99388373f},
+ {-0.99388373f, 0.11043154f, 0.00000000f},
+ { 0.00000000f, 0.11043154f, 0.99388373f}
+};
+
+Batch *DRW_cache_bone_octahedral_get(void)
+{
+ if (!SHC.drw_bone_octahedral) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.nor = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 24);
+
+ for (int i = 0; i < 8; i++) {
+ VertexBuffer_set_attrib(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][0]]);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][1]]);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]);
+ }
+
+ SHC.drw_bone_octahedral = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_bone_octahedral;
+}
+
+Batch *DRW_cache_bone_octahedral_wire_outline_get(void)
+{
+ if (!SHC.drw_bone_octahedral_wire) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, n1, n2; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n1 = VertexFormat_add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n2 = VertexFormat_add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 12 * 2);
+
+ for (int i = 0; i < 12; i++) {
+ const float *co1 = bone_octahedral_verts[bone_octahedral_wire[i * 2]];
+ const float *co2 = bone_octahedral_verts[bone_octahedral_wire[i * 2 + 1]];
+ const float *n1 = bone_octahedral_solid_normals[bone_octahedral_wire_adjacent_face[i * 2]];
+ const float *n2 = bone_octahedral_solid_normals[bone_octahedral_wire_adjacent_face[i * 2 + 1]];
+ add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n1, n2);
+ }
+
+ SHC.drw_bone_octahedral_wire = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_bone_octahedral_wire;
+}
+
+
+/* XXX TODO move that 1 unit cube to more common/generic place? */
+static const float bone_box_verts[8][3] = {
+ { 1.0f, 0.0f, 1.0f},
+ { 1.0f, 0.0f, -1.0f},
+ {-1.0f, 0.0f, -1.0f},
+ {-1.0f, 0.0f, 1.0f},
+ { 1.0f, 1.0f, 1.0f},
+ { 1.0f, 1.0f, -1.0f},
+ {-1.0f, 1.0f, -1.0f},
+ {-1.0f, 1.0f, 1.0f}
+};
+
+static const unsigned int bone_box_wire[24] = {
+ 0, 1, 1, 2, 2, 3, 3, 0,
+ 4, 5, 5, 6, 6, 7, 7, 4,
+ 0, 4, 1, 5, 2, 6, 3, 7,
+};
+
+/* aligned with bone_octahedral_wire
+ * Contains adjacent normal index */
+static const unsigned int bone_box_wire_adjacent_face[24] = {
+ 0, 2, 0, 4, 1, 6, 1, 8,
+ 3, 10, 5, 10, 7, 11, 9, 11,
+ 3, 8, 2, 5, 4, 7, 6, 9,
+};
+
+static const unsigned int bone_box_solid_tris[12][3] = {
+ {0, 1, 2}, /* bottom */
+ {0, 2, 3},
+
+ {0, 1, 5}, /* sides */
+ {0, 5, 4},
+
+ {1, 2, 6},
+ {1, 6, 5},
+
+ {2, 3, 7},
+ {2, 7, 6},
+
+ {3, 0, 4},
+ {3, 4, 7},
+
+ {4, 5, 6}, /* top */
+ {4, 6, 7},
+};
+
+/* aligned with bone_octahedral_solid_tris */
+static const float bone_box_solid_normals[12][3] = {
+ { 0.0f, -1.0f, 0.0f},
+ { 0.0f, -1.0f, 0.0f},
+
+ { 1.0f, 0.0f, 0.0f},
+ { 1.0f, 0.0f, 0.0f},
+
+ { 0.0f, 0.0f, -1.0f},
+ { 0.0f, 0.0f, -1.0f},
+
+ {-1.0f, 0.0f, 0.0f},
+ {-1.0f, 0.0f, 0.0f},
+
+ { 0.0f, 0.0f, 1.0f},
+ { 0.0f, 0.0f, 1.0f},
+
+ { 0.0f, 1.0f, 0.0f},
+ { 0.0f, 1.0f, 0.0f},
+};
+
+Batch *DRW_cache_bone_box_get(void)
+{
+ if (!SHC.drw_bone_box) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.nor = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 36);
+
+ for (int i = 0; i < 12; i++) {
+ for (int j = 0; j < 3; j++) {
+ VertexBuffer_set_attrib(vbo, attr_id.nor, v_idx, bone_box_solid_normals[i]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, bone_box_verts[bone_box_solid_tris[i][j]]);
+ }
+ }
+
+ SHC.drw_bone_box = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_bone_box;
+}
+
+Batch *DRW_cache_bone_box_wire_outline_get(void)
+{
+ if (!SHC.drw_bone_box_wire) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, n1, n2; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n1 = VertexFormat_add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n2 = VertexFormat_add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 12 * 2);
+
+ for (int i = 0; i < 12; i++) {
+ const float *co1 = bone_box_verts[bone_box_wire[i * 2]];
+ const float *co2 = bone_box_verts[bone_box_wire[i * 2 + 1]];
+ const float *n1 = bone_box_solid_normals[bone_box_wire_adjacent_face[i * 2]];
+ const float *n2 = bone_box_solid_normals[bone_box_wire_adjacent_face[i * 2 + 1]];
+ add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n1, n2);
+ }
+
+ SHC.drw_bone_box_wire = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_bone_box_wire;
+}
+
+
+Batch *DRW_cache_bone_wire_wire_outline_get(void)
+{
+ if (!SHC.drw_bone_wire_wire) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, n1, n2; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n1 = VertexFormat_add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.n2 = VertexFormat_add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 2);
+
+ const float co1[3] = {0.0f, 0.0f, 0.0f};
+ const float co2[3] = {0.0f, 1.0f, 0.0f};
+ const float n[3] = {1.0f, 0.0f, 0.0f};
+ add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n, n);
+
+ SHC.drw_bone_wire_wire = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_bone_wire_wire;
+}
+
+
+/* Helpers for envelope bone's solid sphere-with-hidden-equatorial-cylinder.
+ * Note that here we only encode head/tail in forth component of the vector. */
+static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3])
+{
+ /* Poles are along Y axis. */
+ r_nor[0] = sinf(lat) * cosf(lon);
+ r_nor[1] = cosf(lat);
+ r_nor[2] = sinf(lat) * sinf(lon);
+}
+
+static void benv_add_tri(VertexBuffer *vbo, uint pos_id, uint *v_idx, float *co1, float *co2, float *co3)
+{
+ /* Given tri and its seven other mirrors along X/Y/Z axes. */
+ for (int x = -1; x <= 1; x += 2) {
+ for (int y = -1; y <= 1; y += 2) {
+ const float head_tail = (y == -1) ? 0.0f : 1.0f;
+ for (int z = -1; z <= 1; z += 2) {
+ VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++,
+ (const float[4]){co1[0] * x, co1[1] * y, co1[2] * z, head_tail});
+ VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++,
+ (const float[4]){co2[0] * x, co2[1] * y, co2[2] * z, head_tail});
+ VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++,
+ (const float[4]){co3[0] * x, co3[1] * y, co3[2] * z, head_tail});
+ }
+ }
+ }
+}
+
+Batch *DRW_cache_bone_envelope_solid_get(void)
+{
+#define CIRCLE_RESOL 32 /* Must be multiple of 4 */
+ if (!SHC.drw_bone_envelope) {
+ const int lon_res = CIRCLE_RESOL / 4;
+ const int lat_res = CIRCLE_RESOL / 4;
+ const float lon_inc = M_PI_2 / lon_res;
+ const float lat_inc = M_PI_2 / lat_res;
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 4, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, lat_res * lon_res * 8 * 6);
+
+ float lon = 0.0f;
+ for (int i = 0; i < lon_res; i++, lon += lon_inc) {
+ float lat = 0.0f;
+ float co1[3], co2[3], co3[3], co4[3];
+
+ for (int j = 0; j < lat_res; j++, lat += lat_inc) {
+ benv_lat_lon_to_co(lat , lon , co1);
+ benv_lat_lon_to_co(lat , lon + lon_inc, co2);
+ benv_lat_lon_to_co(lat + lat_inc, lon + lon_inc, co3);
+ benv_lat_lon_to_co(lat + lat_inc, lon , co4);
+
+ if (j != 0) { /* At pole, n1 and n2 are identical. */
+ benv_add_tri(vbo, attr_id.pos, &v_idx, co1, co2, co3);
+ }
+ benv_add_tri(vbo, attr_id.pos, &v_idx, co1, co3, co4);
+ }
+
+ /* lat is at equator (i.e. lat == pi / 2). */
+ /* We need to add 'cylinder' part between the equators (along XZ plane). */
+ for (int x = -1; x <= 1; x += 2) {
+ for (int z = -1; z <= 1; z += 2) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+ (const float[4]){co3[0] * x, co3[1], co3[2] * z, 0.0f});
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+ (const float[4]){co4[0] * x, co4[1], co4[2] * z, 0.0f});
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+ (const float[4]){co4[0] * x, co4[1], co4[2] * z, 1.0f});
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+ (const float[4]){co3[0] * x, co3[1], co3[2] * z, 0.0f});
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+ (const float[4]){co4[0] * x, co4[1], co4[2] * z, 1.0f});
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+ (const float[4]){co3[0] * x, co3[1], co3[2] * z, 1.0f});
+ }
+ }
+ }
+
+ SHC.drw_bone_envelope = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_bone_envelope;
+}
+
+
+Batch *DRW_cache_bone_envelope_distance_outline_get(void)
+{
+#define CIRCLE_RESOL 32 /* Must be multiple of 2 */
+ if (!SHC.drw_bone_envelope_distance) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id;
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 4, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 + 6);
+
+ /* Encoded triangle strip, vertex shader gives them final correct value. */
+ for (int i = 0; i < CIRCLE_RESOL + 1; i++) {
+ const bool is_headtail_transition = ELEM(i, CIRCLE_RESOL / 2, CIRCLE_RESOL);
+ const float head_tail = (i > CIRCLE_RESOL / 2) ? 1.0f : 0.0f;
+ const float alpha = 2.0f * M_PI * i / CIRCLE_RESOL;
+ const float x = cosf(alpha);
+ const float y = -sinf(alpha);
+
+ /* { X, Y, head/tail, inner/outer border } */
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){x, y, head_tail, 0.0f});
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){x, y, head_tail, 1.0f});
+ if (is_headtail_transition) {
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){x, y, 1.0f - head_tail, 0.0f});
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){x, y, 1.0f - head_tail, 1.0f});
+ }
+ }
+
+ SHC.drw_bone_envelope_distance = Batch_create(PRIM_TRIANGLE_STRIP, vbo, NULL);
+ }
+ return SHC.drw_bone_envelope_distance;
+#undef CIRCLE_RESOL
+}
+
+
+/* Bone body. */
+Batch *DRW_cache_bone_envelope_wire_outline_get(void)
+{
+ if (!SHC.drw_bone_envelope_wire) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id;
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 4, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 4);
+
+ /* Two lines between head and tail circles. */
+ /* Encoded lines, vertex shader gives them final correct value. */
+ /* { X, Y, head/tail, inner/outer border } */
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){ 1.0f, 0.0f, 0.0f, 0.0f});
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){ 1.0f, 0.0f, 1.0f, 0.0f});
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){-1.0f, 0.0f, 0.0f, 0.0f});
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){-1.0f, 0.0f, 1.0f, 0.0f});
+
+ SHC.drw_bone_envelope_wire = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_bone_envelope_wire;
+}
+
+
+/* Bone head and tail. */
+Batch *DRW_cache_bone_envelope_head_wire_outline_get(void)
+{
+#define CIRCLE_RESOL 32 /* Must be multiple of 2 */
+ if (!SHC.drw_bone_envelope_head_wire) {
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id;
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 4, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL);
+
+ /* Encoded lines, vertex shader gives them final correct value. */
+ /* Only head circle (tail is drawn in disp_tail_mat space as a head one by draw_armature.c's draw_point()). */
+ for (int i = 0; i < CIRCLE_RESOL; i++) {
+ const float alpha = 2.0f * M_PI * i / CIRCLE_RESOL;
+ const float x = cosf(alpha);
+ const float y = -sinf(alpha);
+
+ /* { X, Y, head/tail, inner/outer border } */
+ VertexBuffer_set_attrib(vbo, pos_id, v_idx++, (const float[4]){ x, y, 0.0f, 0.0f});
+ }
+
+ SHC.drw_bone_envelope_head_wire = Batch_create(PRIM_LINE_LOOP, vbo, NULL);
+ }
+ return SHC.drw_bone_envelope_head_wire;
+#undef CIRCLE_RESOL
+}
+
+
+Batch *DRW_cache_bone_point_get(void)
+{
+ if (!SHC.drw_bone_point) {
+ const int lon_res = 16;
+ const int lat_res = 8;
+ const float rad = 0.05f;
+ const float lon_inc = 2 * M_PI / lon_res;
+ const float lat_inc = M_PI / lat_res;
+ unsigned int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.nor = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, (lat_res - 1) * lon_res * 6);
+
+ float lon = 0.0f;
+ for (int i = 0; i < lon_res; i++, lon += lon_inc) {
+ float lat = 0.0f;
+ for (int j = 0; j < lat_res; j++, lat += lat_inc) {
+ if (j != lat_res - 1) { /* Pole */
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
+ }
+
+ if (j != 0) { /* Pole */
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon + lon_inc);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
+ }
+ }
+ }
+
+ SHC.drw_bone_point = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_bone_point;
+}
+
+Batch *DRW_cache_bone_point_wire_outline_get(void)
+{
+ if (!SHC.drw_bone_point_wire) {
+ VertexBuffer *vbo = sphere_wire_vbo(0.05f);
+ SHC.drw_bone_point_wire = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_bone_point_wire;
+}
+
+Batch *DRW_cache_bone_arrows_get(void)
+{
+ if (!SHC.drw_bone_arrows) {
+ VertexBuffer *vbo = fill_arrows_vbo(0.25f);
+ SHC.drw_bone_arrows = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_bone_arrows;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Camera
+ * \{ */
+
+Batch *DRW_cache_camera_get(void)
+{
+ if (!SHC.drw_camera) {
+ float v0 = 0.0f; /* Center point */
+ float v1 = 1.0f; /* + X + Y */
+ float v2 = 2.0f; /* + X - Y */
+ float v3 = 3.0f; /* - X - Y */
+ float v4 = 4.0f; /* - X + Y */
+ float v5 = 5.0f; /* tria + X */
+ float v6 = 6.0f; /* tria - X */
+ float v7 = 7.0f; /* tria + Y */
+ int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* use x coordinate to identify the vertex
+ * the vertex shader take care to place it
+ * appropriatelly */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 1, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 22);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v0);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v1);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v0);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v2);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v0);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v3);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v0);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v4);
+
+ /* camera frame */
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v1);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v2);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v2);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v3);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v3);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v4);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v4);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v1);
+
+ /* tria */
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v5);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v6);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v6);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v7);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v7);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v5);
+
+ SHC.drw_camera = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+ return SHC.drw_camera;
+}
+
+Batch *DRW_cache_camera_tria_get(void)
+{
+ if (!SHC.drw_camera_tria) {
+ float v5 = 5.0f; /* tria + X */
+ float v6 = 6.0f; /* tria - X */
+ float v7 = 7.0f; /* tria + Y */
+ int v_idx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* use x coordinate to identify the vertex
+ * the vertex shader take care to place it
+ * appropriatelly */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 1, KEEP_FLOAT);
+ }
+
+ /* Vertices */
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 6);
+
+ /* tria */
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v5);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v6);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++, &v7);
+
+ SHC.drw_camera_tria = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return SHC.drw_camera_tria;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Object Mode Helpers
+ * \{ */
+
+/* Object Center */
+Batch *DRW_cache_single_vert_get(void)
+{
+ if (!SHC.drw_single_vertice) {
+ float v1[3] = {0.0f, 0.0f, 0.0f};
+
+ /* Position Only 3D format */
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 1);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 0, v1);
+
+ SHC.drw_single_vertice = Batch_create(PRIM_POINTS, vbo, NULL);
+ }
+ return SHC.drw_single_vertice;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Meshes
+ * \{ */
+
+Batch *DRW_cache_mesh_surface_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_all_triangles(me);
+}
+
+void DRW_cache_mesh_wire_overlay_get(
+ Object *ob,
+ Batch **r_tris, Batch **r_ledges, Batch **r_lverts)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+
+ *r_tris = DRW_mesh_batch_cache_get_overlay_triangles(me);
+ *r_ledges = DRW_mesh_batch_cache_get_overlay_loose_edges(me);
+ *r_lverts = DRW_mesh_batch_cache_get_overlay_loose_verts(me);
+}
+
+void DRW_cache_mesh_normals_overlay_get(
+ Object *ob,
+ Batch **r_tris, Batch **r_ledges, Batch **r_lverts)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+
+ *r_tris = DRW_mesh_batch_cache_get_overlay_triangles_nor(me);
+ *r_ledges = DRW_mesh_batch_cache_get_overlay_loose_edges_nor(me);
+ *r_lverts = DRW_mesh_batch_cache_get_overlay_loose_verts(me);
+}
+
+Batch *DRW_cache_face_centers_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+
+ return DRW_mesh_batch_cache_get_overlay_facedots(me);
+}
+
+Batch *DRW_cache_mesh_wire_outline_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_fancy_edges(me);
+}
+
+Batch *DRW_cache_mesh_surface_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_triangles_with_normals(me);
+}
+
+Batch *DRW_cache_mesh_surface_weights_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(me, ob->actdef - 1);
+}
+
+Batch *DRW_cache_mesh_surface_vert_colors_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(me);
+}
+
+/* Return list of batches */
+Batch **DRW_cache_mesh_surface_shaded_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_surface_shaded(me);
+}
+
+/* Return list of batches */
+Batch **DRW_cache_mesh_surface_texpaint_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_surface_texpaint(me);
+}
+
+Batch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_surface_texpaint_single(me);
+}
+
+Batch *DRW_cache_mesh_surface_verts_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_points_with_normals(me);
+}
+
+Batch *DRW_cache_mesh_edges_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_all_edges(me);
+}
+
+Batch *DRW_cache_mesh_verts_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_all_verts(me);
+}
+
+Batch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, bool use_sel)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_weight_overlay_edges(me, use_wire, use_sel);
+}
+
+Batch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_weight_overlay_faces(me);
+}
+
+Batch *DRW_cache_mesh_verts_weight_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_weight_overlay_verts(me);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Curve
+ * \{ */
+
+Batch *DRW_cache_curve_edge_wire_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_CURVE);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_wire_edge(cu, ob->curve_cache);
+}
+
+Batch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size)
+{
+ BLI_assert(ob->type == OB_CURVE);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_normal_edge(cu, ob->curve_cache, normal_size);
+}
+
+Batch *DRW_cache_curve_edge_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_CURVE);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_overlay_edges(cu);
+}
+
+Batch *DRW_cache_curve_vert_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_CURVE);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_overlay_verts(cu);
+}
+
+Batch *DRW_cache_curve_surface_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_CURVE);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Font
+ * \{ */
+
+Batch *DRW_cache_text_edge_wire_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_FONT);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_wire_edge(cu, ob->curve_cache);
+}
+
+Batch *DRW_cache_text_surface_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_FONT);
+ struct Curve *cu = ob->data;
+ if (cu->editfont && (cu->flag & CU_FAST)) {
+ return NULL;
+ }
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache);
+}
+
+Batch *DRW_cache_text_cursor_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_FONT);
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_overlay_cursor(cu);
+}
+
+Batch *DRW_cache_text_select_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_FONT);
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_overlay_select(cu);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Surface
+ * \{ */
+
+Batch *DRW_cache_surf_surface_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_SURF);
+
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Lattice
+ * \{ */
+
+Batch *DRW_cache_lattice_verts_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_LATTICE);
+
+ struct Lattice *lt = ob->data;
+ return DRW_lattice_batch_cache_get_all_verts(lt);
+}
+
+Batch *DRW_cache_lattice_wire_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_LATTICE);
+
+ struct Lattice *lt = ob->data;
+ return DRW_lattice_batch_cache_get_all_edges(lt);
+}
+
+Batch *DRW_cache_lattice_vert_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_LATTICE);
+
+ struct Lattice *lt = ob->data;
+ return DRW_lattice_batch_cache_get_overlay_verts(lt);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Particles
+ * \{ */
+
+Batch *DRW_cache_particles_get_hair(ParticleSystem *psys)
+{
+ return DRW_particles_batch_cache_get_hair(psys);
+}
+
+Batch *DRW_cache_particles_get_dots(ParticleSystem *psys)
+{
+ return DRW_particles_batch_cache_get_dots(psys);
+}
+
+Batch *DRW_cache_particles_get_prim(int type)
+{
+ switch (type) {
+ case PART_DRAW_CROSS:
+ if (!SHC.drw_particle_cross) {
+ static VertexFormat format = { 0 };
+ static unsigned pos_id, axis_id;
+
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "inst_pos", COMP_F32, 3, KEEP_FLOAT);
+ axis_id = VertexFormat_add_attrib(&format, "axis", COMP_I32, 1, KEEP_INT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 6);
+
+ /* X axis */
+ float co[3] = {-1.0f, 0.0f, 0.0f};
+ int axis = -1;
+ VertexBuffer_set_attrib(vbo, pos_id, 0, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 0, &axis);
+
+ co[0] = 1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 1, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 1, &axis);
+
+ /* Y axis */
+ co[0] = 0.0f;
+ co[1] = -1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 2, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 2, &axis);
+
+ co[1] = 1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 3, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 3, &axis);
+
+ /* Z axis */
+ co[1] = 0.0f;
+ co[2] = -1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 4, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 4, &axis);
+
+ co[2] = 1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 5, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 5, &axis);
+
+ SHC.drw_particle_cross = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+
+ return SHC.drw_particle_cross;
+ case PART_DRAW_AXIS:
+ if (!SHC.drw_particle_axis) {
+ static VertexFormat format = { 0 };
+ static unsigned pos_id, axis_id;
+
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "inst_pos", COMP_F32, 3, KEEP_FLOAT);
+ axis_id = VertexFormat_add_attrib(&format, "axis", COMP_I32, 1, KEEP_INT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 6);
+
+ /* X axis */
+ float co[3] = {0.0f, 0.0f, 0.0f};
+ int axis = 0;
+ VertexBuffer_set_attrib(vbo, pos_id, 0, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 0, &axis);
+
+ co[0] = 1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 1, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 1, &axis);
+
+ /* Y axis */
+ co[0] = 0.0f;
+ axis = 1;
+ VertexBuffer_set_attrib(vbo, pos_id, 2, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 2, &axis);
+
+ co[1] = 1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 3, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 3, &axis);
+
+ /* Z axis */
+ co[1] = 0.0f;
+ axis = 2;
+ VertexBuffer_set_attrib(vbo, pos_id, 4, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 4, &axis);
+
+ co[2] = 1.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, 5, co);
+ VertexBuffer_set_attrib(vbo, axis_id, 5, &axis);
+
+ SHC.drw_particle_axis = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+
+ return SHC.drw_particle_axis;
+ case PART_DRAW_CIRC:
+#define CIRCLE_RESOL 32
+ if (!SHC.drw_particle_circle) {
+ float v[3] = {0.0f, 0.0f, 0.0f};
+ int axis = -1;
+
+ static VertexFormat format = { 0 };
+ static unsigned pos_id, axis_id;
+
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "inst_pos", COMP_F32, 3, KEEP_FLOAT);
+ axis_id = VertexFormat_add_attrib(&format, "axis", COMP_I32, 1, KEEP_INT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, CIRCLE_RESOL);
+
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v[2] = 0.0f;
+ VertexBuffer_set_attrib(vbo, pos_id, a, v);
+ VertexBuffer_set_attrib(vbo, axis_id, a, &axis);
+ }
+
+ SHC.drw_particle_circle = Batch_create(PRIM_LINE_LOOP, vbo, NULL);
+ }
+
+ return SHC.drw_particle_circle;
+#undef CIRCLE_RESOL
+ default:
+ BLI_assert(false);
+ break;
+ }
+
+ return NULL;
+}
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
new file mode 100644
index 00000000000..f2c140923a8
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_cache.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_CACHE_H__
+#define __DRAW_CACHE_H__
+
+struct Batch;
+struct Object;
+
+void DRW_shape_cache_free(void);
+
+/* Common Shapes */
+struct Batch *DRW_cache_fullscreen_quad_get(void);
+struct Batch *DRW_cache_single_vert_get(void);
+struct Batch *DRW_cache_single_line_get(void);
+struct Batch *DRW_cache_single_line_endpoints_get(void);
+struct Batch *DRW_cache_screenspace_circle_get(void);
+
+/* Common Object */
+struct Batch *DRW_cache_object_wire_outline_get(struct Object *ob);
+struct Batch *DRW_cache_object_surface_get(struct Object *ob);
+struct Batch **DRW_cache_object_surface_material_get(struct Object *ob);
+
+/* Empties */
+struct Batch *DRW_cache_plain_axes_get(void);
+struct Batch *DRW_cache_single_arrow_get(void);
+struct Batch *DRW_cache_cube_get(void);
+struct Batch *DRW_cache_circle_get(void);
+struct Batch *DRW_cache_square_get(void);
+struct Batch *DRW_cache_empty_sphere_get(void);
+struct Batch *DRW_cache_empty_cone_get(void);
+struct Batch *DRW_cache_arrows_get(void);
+struct Batch *DRW_cache_axis_names_get(void);
+struct Batch *DRW_cache_image_plane_get(void);
+struct Batch *DRW_cache_image_plane_wire_get(void);
+
+/* Force Field */
+struct Batch *DRW_cache_field_wind_get(void);
+struct Batch *DRW_cache_field_force_get(void);
+struct Batch *DRW_cache_field_vortex_get(void);
+struct Batch *DRW_cache_field_tube_limit_get(void);
+struct Batch *DRW_cache_field_cone_limit_get(void);
+
+/* Lamps */
+struct Batch *DRW_cache_lamp_get(void);
+struct Batch *DRW_cache_lamp_sunrays_get(void);
+struct Batch *DRW_cache_lamp_area_get(void);
+struct Batch *DRW_cache_lamp_hemi_get(void);
+struct Batch *DRW_cache_lamp_spot_get(void);
+struct Batch *DRW_cache_lamp_spot_square_get(void);
+
+/* Camera */
+struct Batch *DRW_cache_camera_get(void);
+struct Batch *DRW_cache_camera_tria_get(void);
+
+/* Speaker */
+struct Batch *DRW_cache_speaker_get(void);
+
+/* Bones */
+struct Batch *DRW_cache_bone_octahedral_get(void);
+struct Batch *DRW_cache_bone_octahedral_wire_outline_get(void);
+struct Batch *DRW_cache_bone_box_get(void);
+struct Batch *DRW_cache_bone_box_wire_outline_get(void);
+struct Batch *DRW_cache_bone_wire_wire_outline_get(void);
+struct Batch *DRW_cache_bone_envelope_solid_get(void);
+struct Batch *DRW_cache_bone_envelope_distance_outline_get(void);
+struct Batch *DRW_cache_bone_envelope_wire_outline_get(void);
+struct Batch *DRW_cache_bone_envelope_head_wire_outline_get(void);
+struct Batch *DRW_cache_bone_point_get(void);
+struct Batch *DRW_cache_bone_point_wire_outline_get(void);
+struct Batch *DRW_cache_bone_arrows_get(void);
+
+/* Meshes */
+struct Batch *DRW_cache_mesh_surface_overlay_get(struct Object *ob);
+void DRW_cache_mesh_wire_overlay_get(
+ struct Object *ob,
+ struct Batch **r_tris, struct Batch **r_ledges, struct Batch **r_lverts);
+void DRW_cache_mesh_normals_overlay_get(
+ struct Object *ob,
+ struct Batch **r_tris, struct Batch **r_ledges, struct Batch **r_lverts);
+struct Batch *DRW_cache_face_centers_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_surface_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_surface_verts_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_edges_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_verts_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use_wire, bool use_sel);
+struct Batch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob);
+struct Batch **DRW_cache_mesh_surface_shaded_get(struct Object *ob);
+struct Batch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
+
+/* Curve */
+struct Batch *DRW_cache_curve_surface_get(struct Object *ob);
+struct Batch *DRW_cache_curve_surface_verts_get(struct Object *ob);
+struct Batch *DRW_cache_curve_edge_wire_get(struct Object *ob);
+/* edit-mode */
+struct Batch *DRW_cache_curve_edge_normal_get(struct Object *ob, float normal_size);
+struct Batch *DRW_cache_curve_edge_overlay_get(struct Object *ob);
+struct Batch *DRW_cache_curve_vert_overlay_get(struct Object *ob);
+
+/* Font */
+struct Batch *DRW_cache_text_edge_wire_get(struct Object *ob);
+struct Batch *DRW_cache_text_surface_get(struct Object *ob);
+/* edit-mode */
+struct Batch *DRW_cache_text_cursor_overlay_get(struct Object *ob);
+struct Batch *DRW_cache_text_select_overlay_get(struct Object *ob);
+
+/* Surface */
+struct Batch *DRW_cache_surf_surface_get(struct Object *ob);
+
+/* Lattice */
+struct Batch *DRW_cache_lattice_verts_get(struct Object *ob);
+struct Batch *DRW_cache_lattice_wire_get(struct Object *ob);
+struct Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob);
+
+/* Particles */
+struct Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys);
+struct Batch *DRW_cache_particles_get_dots(struct ParticleSystem *psys);
+struct Batch *DRW_cache_particles_get_prim(int type);
+
+#endif /* __DRAW_CACHE_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
new file mode 100644
index 00000000000..bfb61199674
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_cache_impl.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_CACHE_IMPL_H__
+#define __DRAW_CACHE_IMPL_H__
+
+struct Batch;
+struct ListBase;
+struct CurveCache;
+struct ParticleSystem;
+
+struct Curve;
+struct Lattice;
+struct Mesh;
+
+/* Expose via BKE callbacks */
+void DRW_curve_batch_cache_dirty(struct Curve *cu, int mode);
+void DRW_curve_batch_cache_free(struct Curve *cu);
+
+void DRW_mesh_batch_cache_dirty(struct Mesh *me, int mode);
+void DRW_mesh_batch_cache_free(struct Mesh *me);
+
+void DRW_lattice_batch_cache_dirty(struct Lattice *lt, int mode);
+void DRW_lattice_batch_cache_free(struct Lattice *lt);
+
+void DRW_particle_batch_cache_dirty(struct ParticleSystem *psys, int mode);
+void DRW_particle_batch_cache_free(struct ParticleSystem *psys);
+
+/* Curve */
+struct Batch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache);
+struct Batch *DRW_curve_batch_cache_get_normal_edge(
+ struct Curve *cu, struct CurveCache *ob_curve_cache, float normal_size);
+struct Batch *DRW_curve_batch_cache_get_overlay_edges(struct Curve *cu);
+struct Batch *DRW_curve_batch_cache_get_overlay_verts(struct Curve *cu);
+
+struct Batch *DRW_curve_batch_cache_get_triangles_with_normals(struct Curve *cu, struct CurveCache *ob_curve_cache);
+
+/* Curve (Font) */
+struct Batch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu);
+struct Batch *DRW_curve_batch_cache_get_overlay_select(struct Curve *cu);
+
+/* DispList */
+struct Batch *BLI_displist_batch_calc_surface(struct ListBase *lb);
+
+/* Lattice */
+struct Batch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt);
+struct Batch *DRW_lattice_batch_cache_get_all_verts(struct Lattice *lt);
+struct Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt);
+
+/* Mesh */
+
+struct Batch **DRW_mesh_batch_cache_get_surface_shaded(struct Mesh *me);
+struct Batch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel);
+struct Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup);
+struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide);
+struct Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_overlay_triangles(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_overlay_triangles_nor(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me);
+
+/* Particles */
+struct Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys);
+struct Batch *DRW_particles_batch_cache_get_dots(struct ParticleSystem *psys);
+
+#endif /* __DRAW_CACHE_IMPL_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
new file mode 100644
index 00000000000..3fbee0d7c2a
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -0,0 +1,1047 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file draw_cache_impl_curve.c
+ * \ingroup draw
+ *
+ * \brief Curve API for render engines
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "DNA_curve_types.h"
+
+#include "BKE_curve.h"
+
+#include "BKE_font.h"
+
+#include "GPU_batch.h"
+
+#include "draw_cache_impl.h" /* own include */
+
+#define SELECT 1
+
+/**
+ * TODO
+ * - Ensure `CurveCache`, `SEQUENCER_DAG_WORKAROUND`.
+ * - Check number of verts/edges to see if cache is valid.
+ * - Check if 'overlay.edges' can use single attribyte per edge, not 2 (for selection drawing).
+ */
+
+static void curve_batch_cache_clear(Curve *cu);
+
+/* ---------------------------------------------------------------------- */
+/* Curve Interface, direct access to basic data. */
+
+static void curve_render_overlay_verts_edges_len_get(
+ ListBase *lb, bool hide_handles,
+ int *r_vert_len, int *r_edge_len)
+{
+ BLI_assert(r_vert_len || r_edge_len);
+ int vert_len = 0;
+ int edge_len = 0;
+ for (Nurb *nu = lb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ vert_len += hide_handles ? nu->pntsu : (nu->pntsu * 3);
+ /* 2x handles per point*/
+ edge_len += 2 * nu->pntsu;
+ }
+ else if (nu->bp) {
+ vert_len += nu->pntsu;
+ /* segments between points */
+ edge_len += nu->pntsu - 1;
+ }
+ }
+ if (r_vert_len) {
+ *r_vert_len = vert_len;
+ }
+ if (r_edge_len) {
+ *r_edge_len = edge_len;
+ }
+}
+
+static void curve_render_wire_verts_edges_len_get(
+ const CurveCache *ob_curve_cache,
+ int *r_vert_len, int *r_edge_len)
+{
+ BLI_assert(r_vert_len || r_edge_len);
+ int vert_len = 0;
+ int edge_len = 0;
+ for (const BevList *bl = ob_curve_cache->bev.first; bl; bl = bl->next) {
+ if (bl->nr > 0) {
+ const bool is_cyclic = bl->poly != -1;
+
+ /* verts */
+ vert_len += bl->nr;
+
+ /* edges */
+ edge_len += bl->nr;
+ if (!is_cyclic) {
+ edge_len -= 1;
+ }
+ }
+ }
+ if (r_vert_len) {
+ *r_vert_len = vert_len;
+ }
+ if (r_edge_len) {
+ *r_edge_len = edge_len;
+ }
+}
+
+static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_curve_cache)
+{
+ int normal_len = 0;
+ const BevList *bl;
+ const Nurb *nu;
+ for (bl = ob_curve_cache->bev.first, nu = lb->first; nu && bl; bl = bl->next, nu = nu->next) {
+ int nr = bl->nr;
+ int skip = nu->resolu / 16;
+#if 0
+ while (nr-- > 0) { /* accounts for empty bevel lists */
+ normal_len += 1;
+ nr -= skip;
+ }
+#else
+ normal_len += max_ii((nr + max_ii(skip - 1, 0)) / (skip + 1), 0);
+#endif
+ }
+ return normal_len;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Curve Interface, indirect, partially cached access to complex data. */
+
+typedef struct CurveRenderData {
+ int types;
+
+ struct {
+ int vert_len;
+ int edge_len;
+ } overlay;
+
+ struct {
+ int vert_len;
+ int edge_len;
+ } wire;
+
+ /* edit mode normal's */
+ struct {
+ /* 'edge_len == len * 2'
+ * 'vert_len == len * 3' */
+ int len;
+ } normal;
+
+ struct {
+ EditFont *edit_font;
+ } text;
+
+ bool hide_handles;
+ bool hide_normals;
+
+ /* borrow from 'Object' */
+ CurveCache *ob_curve_cache;
+
+ /* borrow from 'Curve' */
+ ListBase *nurbs;
+
+ /* edit, index in nurb list */
+ int actnu;
+ /* edit, index in active nurb (BPoint or BezTriple) */
+ int actvert;
+} CurveRenderData;
+
+enum {
+ /* Wire center-line */
+ CU_DATATYPE_WIRE = 1 << 0,
+ /* Edit-mode verts and optionally handles */
+ CU_DATATYPE_OVERLAY = 1 << 1,
+ /* Edit-mode normals */
+ CU_DATATYPE_NORMAL = 1 << 2,
+ /* Geometry */
+ CU_DATATYPE_SURFACE = 1 << 3,
+ /* Text */
+ CU_DATATYPE_TEXT_SELECT = 1 << 4,
+};
+
+/*
+ * ob_curve_cache can be NULL, only needed for CU_DATATYPE_WIRE
+ */
+static CurveRenderData *curve_render_data_create(Curve *cu, CurveCache *ob_curve_cache, const int types)
+{
+ CurveRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
+ rdata->types = types;
+ ListBase *nurbs;
+
+ rdata->hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0;
+ rdata->hide_normals = (cu->drawflag & CU_HIDE_NORMALS) != 0;
+
+ rdata->actnu = cu->actnu;
+ rdata->actvert = cu->actvert;
+
+ rdata->ob_curve_cache = ob_curve_cache;
+
+ if (types & CU_DATATYPE_WIRE) {
+ curve_render_wire_verts_edges_len_get(
+ rdata->ob_curve_cache,
+ &rdata->wire.vert_len, &rdata->wire.edge_len);
+ }
+
+ if (cu->editnurb) {
+ EditNurb *editnurb = cu->editnurb;
+ nurbs = &editnurb->nurbs;
+
+ if (types & CU_DATATYPE_OVERLAY) {
+ curve_render_overlay_verts_edges_len_get(
+ nurbs, rdata->hide_handles,
+ &rdata->overlay.vert_len,
+ rdata->hide_handles ? NULL : &rdata->overlay.edge_len);
+
+ rdata->actnu = cu->actnu;
+ rdata->actvert = cu->actvert;
+ }
+ if (types & CU_DATATYPE_NORMAL) {
+ rdata->normal.len = curve_render_normal_len_get(nurbs, rdata->ob_curve_cache);
+ }
+ }
+ else {
+ nurbs = &cu->nurb;
+ }
+
+ rdata->nurbs = nurbs;
+
+ rdata->text.edit_font = cu->editfont;
+
+ return rdata;
+}
+
+static void curve_render_data_free(CurveRenderData *rdata)
+{
+#if 0
+ if (rdata->loose_verts) {
+ MEM_freeN(rdata->loose_verts);
+ }
+#endif
+ MEM_freeN(rdata);
+}
+
+static int curve_render_data_overlay_verts_len_get(const CurveRenderData *rdata)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_OVERLAY);
+ return rdata->overlay.vert_len;
+}
+
+static int curve_render_data_overlay_edges_len_get(const CurveRenderData *rdata)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_OVERLAY);
+ return rdata->overlay.edge_len;
+}
+
+static int curve_render_data_wire_verts_len_get(const CurveRenderData *rdata)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_WIRE);
+ return rdata->wire.vert_len;
+}
+
+static int curve_render_data_wire_edges_len_get(const CurveRenderData *rdata)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_WIRE);
+ return rdata->wire.edge_len;
+}
+
+static int curve_render_data_normal_len_get(const CurveRenderData *rdata)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_NORMAL);
+ return rdata->normal.len;
+}
+
+enum {
+ VFLAG_VERTEX_SELECTED = 1 << 0,
+ VFLAG_VERTEX_ACTIVE = 1 << 1,
+};
+
+/* ---------------------------------------------------------------------- */
+/* Curve Batch Cache */
+
+typedef struct CurveBatchCache {
+ /* center-line */
+ struct {
+ VertexBuffer *verts;
+ VertexBuffer *edges;
+ Batch *batch;
+ ElementList *elem;
+ } wire;
+
+ /* normals */
+ struct {
+ VertexBuffer *verts;
+ VertexBuffer *edges;
+ Batch *batch;
+ ElementList *elem;
+ } normal;
+
+ /* control handles and vertices */
+ struct {
+ Batch *edges;
+ Batch *verts;
+ } overlay;
+
+ struct {
+ Batch *batch;
+ } surface;
+
+ /* 3d text */
+ struct {
+ Batch *select;
+ Batch *cursor;
+ } text;
+
+ /* settings to determine if cache is invalid */
+ bool is_dirty;
+
+ bool hide_handles;
+ bool hide_normals;
+
+ float normal_size;
+
+ bool is_editmode;
+} CurveBatchCache;
+
+/* Batch cache management. */
+
+static bool curve_batch_cache_valid(Curve *cu)
+{
+ CurveBatchCache *cache = cu->batch_cache;
+
+ if (cache == NULL) {
+ return false;
+ }
+
+ if (cache->is_editmode != ((cu->editnurb != NULL) || (cu->editfont != NULL))) {
+ return false;
+ }
+
+ if (cache->is_editmode) {
+ if (cu->editnurb) {
+ if ((cache->hide_handles != ((cu->drawflag & CU_HIDE_HANDLES) != 0))) {
+ return false;
+ }
+ else if ((cache->hide_normals != ((cu->drawflag & CU_HIDE_NORMALS) != 0))) {
+ return false;
+ }
+ }
+ else if (cu->editfont) {
+ /* TODO */
+ }
+ }
+
+ if (cache->is_dirty == false) {
+ return true;
+ }
+ else {
+ /* TODO: check number of vertices/edges? */
+ if (cache->is_editmode) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void curve_batch_cache_init(Curve *cu)
+{
+ CurveBatchCache *cache = cu->batch_cache;
+
+ if (!cache) {
+ cache = cu->batch_cache = MEM_callocN(sizeof(*cache), __func__);
+ }
+ else {
+ memset(cache, 0, sizeof(*cache));
+ }
+
+ cache->hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0;
+ cache->hide_normals = (cu->drawflag & CU_HIDE_NORMALS) != 0;
+
+#if 0
+ ListBase *nurbs;
+ if (cu->editnurb) {
+ EditNurb *editnurb = cu->editnurb;
+ nurbs = &editnurb->nurbs;
+ }
+ else {
+ nurbs = &cu->nurb;
+ }
+#endif
+
+ cache->is_editmode = (cu->editnurb != NULL) || (cu->editfont != NULL);
+
+ cache->is_dirty = false;
+}
+
+static CurveBatchCache *curve_batch_cache_get(Curve *cu)
+{
+ if (!curve_batch_cache_valid(cu)) {
+ curve_batch_cache_clear(cu);
+ curve_batch_cache_init(cu);
+ }
+ return cu->batch_cache;
+}
+
+void DRW_curve_batch_cache_dirty(Curve *cu, int mode)
+{
+ CurveBatchCache *cache = cu->batch_cache;
+ if (cache == NULL) {
+ return;
+ }
+ switch (mode) {
+ case BKE_CURVE_BATCH_DIRTY_ALL:
+ cache->is_dirty = true;
+ break;
+ case BKE_CURVE_BATCH_DIRTY_SELECT:
+ /* editnurb */
+ BATCH_DISCARD_ALL_SAFE(cache->overlay.verts);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay.edges);
+
+ /* editfont */
+ BATCH_DISCARD_ALL_SAFE(cache->text.select);
+ BATCH_DISCARD_ALL_SAFE(cache->text.cursor);
+ break;
+ default:
+ BLI_assert(0);
+ }
+}
+
+static void curve_batch_cache_clear(Curve *cu)
+{
+ CurveBatchCache *cache = cu->batch_cache;
+ if (!cache) {
+ return;
+ }
+
+ BATCH_DISCARD_ALL_SAFE(cache->overlay.verts);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay.edges);
+
+ BATCH_DISCARD_ALL_SAFE(cache->surface.batch);
+
+ if (cache->wire.batch) {
+ BATCH_DISCARD_ALL_SAFE(cache->wire.batch);
+ cache->wire.verts = NULL;
+ cache->wire.edges = NULL;
+ cache->wire.elem = NULL;
+ }
+ else {
+ VERTEXBUFFER_DISCARD_SAFE(cache->wire.verts);
+ VERTEXBUFFER_DISCARD_SAFE(cache->wire.edges);
+ ELEMENTLIST_DISCARD_SAFE(cache->wire.elem);
+ }
+
+ if (cache->normal.batch) {
+ BATCH_DISCARD_ALL_SAFE(cache->normal.batch);
+ cache->normal.verts = NULL;
+ cache->normal.edges = NULL;
+ cache->normal.elem = NULL;
+ }
+ else {
+ VERTEXBUFFER_DISCARD_SAFE(cache->normal.verts);
+ VERTEXBUFFER_DISCARD_SAFE(cache->normal.edges);
+ ELEMENTLIST_DISCARD_SAFE(cache->normal.elem);
+ }
+
+ /* 3d text */
+ BATCH_DISCARD_ALL_SAFE(cache->text.cursor);
+ BATCH_DISCARD_ALL_SAFE(cache->text.select);
+}
+
+void DRW_curve_batch_cache_free(Curve *cu)
+{
+ curve_batch_cache_clear(cu);
+ MEM_SAFE_FREE(cu->batch_cache);
+}
+
+/* -------------------------------------------------------------------- */
+
+/** \name Private Curve Cache API
+ * \{ */
+
+/* Batch cache usage. */
+static VertexBuffer *curve_batch_cache_get_wire_verts(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_WIRE);
+ BLI_assert(rdata->ob_curve_cache != NULL);
+
+ if (cache->wire.verts == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int vert_len = curve_render_data_wire_verts_len_get(rdata);
+
+ VertexBuffer *vbo = cache->wire.verts = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, vert_len);
+ int vbo_len_used = 0;
+ for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) {
+ if (bl->nr > 0) {
+ const int i_end = vbo_len_used + bl->nr;
+ for (const BevPoint *bevp = bl->bevpoints; vbo_len_used < i_end; vbo_len_used++, bevp++) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bevp->vec);
+ }
+ }
+ }
+ BLI_assert(vbo_len_used == vert_len);
+ }
+
+ return cache->wire.verts;
+}
+
+static ElementList *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_WIRE);
+ BLI_assert(rdata->ob_curve_cache != NULL);
+
+ if (cache->wire.edges == NULL) {
+ const int vert_len = curve_render_data_wire_verts_len_get(rdata);
+ const int edge_len = curve_render_data_wire_edges_len_get(rdata);
+ int edge_len_used = 0;
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len);
+
+ int i = 0;
+ for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) {
+ if (bl->nr > 0) {
+ const bool is_cyclic = bl->poly != -1;
+ const int i_end = i + (bl->nr);
+ int i_prev;
+ if (is_cyclic) {
+ i_prev = i + (bl->nr - 1);
+ }
+ else {
+ i_prev = i;
+ i += 1;
+ }
+ for (; i < i_end; i_prev = i++) {
+ add_line_vertices(&elb, i_prev, i);
+ edge_len_used += 1;
+ }
+ }
+ }
+
+ if (rdata->hide_handles) {
+ BLI_assert(edge_len_used <= edge_len);
+ }
+ else {
+ BLI_assert(edge_len_used == edge_len);
+ }
+
+ cache->wire.elem = ElementList_build(&elb);
+ }
+
+ return cache->wire.elem;
+}
+
+static VertexBuffer *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_NORMAL);
+ BLI_assert(rdata->ob_curve_cache != NULL);
+
+ if (cache->normal.verts == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int normal_len = curve_render_data_normal_len_get(rdata);
+ const int vert_len = normal_len * 3;
+
+ VertexBuffer *vbo = cache->normal.verts = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, vert_len);
+ int vbo_len_used = 0;
+
+ const BevList *bl;
+ const Nurb *nu;
+
+ for (bl = rdata->ob_curve_cache->bev.first, nu = rdata->nurbs->first;
+ nu && bl;
+ bl = bl->next, nu = nu->next)
+ {
+ const BevPoint *bevp = bl->bevpoints;
+ int nr = bl->nr;
+ int skip = nu->resolu / 16;
+
+ while (nr-- > 0) { /* accounts for empty bevel lists */
+ const float fac = bevp->radius * cache->normal_size;
+ float vec_a[3]; /* Offset perpendicular to the curve */
+ float vec_b[3]; /* Delta along the curve */
+
+ vec_a[0] = fac;
+ vec_a[1] = 0.0f;
+ vec_a[2] = 0.0f;
+
+ mul_qt_v3(bevp->quat, vec_a);
+ madd_v3_v3fl(vec_a, bevp->dir, -fac);
+
+ reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
+ negate_v3(vec_b);
+
+ add_v3_v3(vec_a, bevp->vec);
+ add_v3_v3(vec_b, bevp->vec);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, vec_a);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, bevp->vec);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, vec_b);
+
+ bevp += skip + 1;
+ nr -= skip;
+ }
+ }
+ BLI_assert(vbo_len_used == vert_len);
+ }
+
+ return cache->normal.verts;
+}
+
+static ElementList *curve_batch_cache_get_normal_edges(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_NORMAL);
+ BLI_assert(rdata->ob_curve_cache != NULL);
+
+ if (cache->normal.edges == NULL) {
+ const int normal_len = curve_render_data_normal_len_get(rdata);
+ const int vert_len = normal_len * 3;
+ const int edge_len = normal_len * 2;
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len);
+
+ int vbo_len_used = 0;
+ for (int i = 0; i < normal_len; i++) {
+ add_line_vertices(&elb, vbo_len_used + 0, vbo_len_used + 1);
+ add_line_vertices(&elb, vbo_len_used + 1, vbo_len_used + 2);
+ vbo_len_used += 3;
+ }
+
+ BLI_assert(vbo_len_used == vert_len);
+
+ cache->normal.elem = ElementList_build(&elb);
+ }
+
+ return cache->normal.elem;
+}
+
+static void curve_batch_cache_create_overlay_batches(Curve *cu)
+{
+ /* Since CU_DATATYPE_OVERLAY is slow to generate, generate them all at once */
+ int options = CU_DATATYPE_OVERLAY;
+
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+ CurveRenderData *rdata = curve_render_data_create(cu, NULL, options);
+
+ if (cache->overlay.verts == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.data = VertexFormat_add_attrib(&format, "data", COMP_U8, 1, KEEP_INT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ const int vbo_len_capacity = curve_render_data_overlay_verts_len_get(rdata);
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+ int i = 0;
+ for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ int a = 0;
+ for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
+ if (bezt->hide == false) {
+ const bool is_active = (i == rdata->actvert);
+ char vflag;
+
+ if (rdata->hide_handles) {
+ vflag = (bezt->f2 & SELECT) ?
+ (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+ }
+ else {
+ for (int j = 0; j < 3; j++) {
+ vflag = ((&bezt->f1)[j] & SELECT) ?
+ (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bezt->vec[j]);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+ }
+ }
+ }
+ i += 1;
+ }
+ }
+ else if (nu->bp) {
+ int a = 0;
+ for (const BPoint *bp = nu->bp; a < nu->pntsu; a++, bp++) {
+ if (bp->hide == false) {
+ const bool is_active = (i == rdata->actvert);
+ char vflag;
+ vflag = (bp->f1 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bp->vec);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+ }
+ i += 1;
+ }
+ }
+ i += nu->pntsu;
+ }
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+
+ cache->overlay.verts = Batch_create(PRIM_POINTS, vbo, NULL);
+ }
+
+
+ if ((cache->overlay.edges == NULL) && (rdata->hide_handles == false)) {
+ /* Note: we could reference indices to vertices (above) */
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.data = VertexFormat_add_attrib(&format, "data", COMP_U8, 1, KEEP_INT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ const int edge_len = curve_render_data_overlay_edges_len_get(rdata);
+ const int vbo_len_capacity = edge_len * 2;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+ int i = 0;
+ for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ int a = 0;
+ for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
+ if (bezt->hide == false) {
+ const bool is_active = (i == rdata->actvert);
+ char vflag;
+
+ vflag = (bezt->f1 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bezt->vec[0]);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+
+ /* same vertex twice, only check different selection */
+ for (int j = 0; j < 2; j++) {
+ vflag = ((j ? bezt->f3 : bezt->f1) & SELECT) ?
+ (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+ }
+
+ vflag = (bezt->f3 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bezt->vec[2]);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+ }
+ i += 1;
+ }
+ }
+ else if (nu->bp) {
+ int a = 1;
+ for (const BPoint *bp_prev = nu->bp, *bp_curr = &nu->bp[1]; a < nu->pntsu; a++, bp_prev = bp_curr++) {
+ if ((bp_prev->hide == false) && (bp_curr->hide == false)) {
+ char vflag;
+ vflag = ((bp_prev->f1 & SELECT) && (bp_curr->f1 & SELECT)) ? VFLAG_VERTEX_SELECTED : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bp_prev->vec);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, bp_curr->vec);
+ VertexBuffer_set_attrib(vbo, attr_id.data, vbo_len_used, &vflag);
+ vbo_len_used += 1;
+
+ }
+ }
+ }
+ }
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+
+ cache->overlay.edges = Batch_create(PRIM_LINES, vbo, NULL);
+ }
+
+ curve_render_data_free(rdata);
+}
+
+static Batch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_SURFACE);
+ if (cache->surface.batch == NULL) {
+ cache->surface.batch = BLI_displist_batch_calc_surface(&rdata->ob_curve_cache->disp);
+ }
+ return cache->surface.batch;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Private Object/Font Cache API
+ * \{ */
+
+
+static Batch *curve_batch_cache_get_overlay_select(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT);
+ if (cache->text.select == NULL) {
+ EditFont *ef = rdata->text.edit_font;
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ const int vbo_len_capacity = ef->selboxes_len * 6;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ float box[4][3];
+
+ /* fill in xy below */
+ box[0][2] = box[1][2] = box[2][2] = box[3][2] = 0.001;
+
+ for (int i = 0; i < ef->selboxes_len; i++) {
+ EditFontSelBox *sb = &ef->selboxes[i];
+
+ float selboxw;
+ if (i + 1 != ef->selboxes_len) {
+ if (ef->selboxes[i + 1].y == sb->y)
+ selboxw = ef->selboxes[i + 1].x - sb->x;
+ else
+ selboxw = sb->w;
+ }
+ else {
+ selboxw = sb->w;
+ }
+
+ if (sb->rot == 0.0f) {
+ copy_v2_fl2(box[0], sb->x, sb->y);
+ copy_v2_fl2(box[1], sb->x + selboxw, sb->y);
+ copy_v2_fl2(box[2], sb->x + selboxw, sb->y + sb->h);
+ copy_v2_fl2(box[3], sb->x, sb->y + sb->h);
+ }
+ else {
+ float mat[2][2];
+
+ angle_to_mat2(mat, sb->rot);
+
+ copy_v2_fl2(box[0], sb->x, sb->y);
+
+ copy_v2_fl2(box[1], selboxw, 0.0f);
+ mul_m2v2(mat, box[1]);
+ add_v2_v2(box[1], &sb->x);
+
+ copy_v2_fl2(box[2], selboxw, sb->h);
+ mul_m2v2(mat, box[2]);
+ add_v2_v2(box[2], &sb->x);
+
+ copy_v2_fl2(box[3], 0.0f, sb->h);
+ mul_m2v2(mat, box[3]);
+ add_v2_v2(box[3], &sb->x);
+ }
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, box[0]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, box[1]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, box[2]);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, box[0]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, box[2]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used++, box[3]);
+ }
+ BLI_assert(vbo_len_used == vbo_len_capacity);
+ cache->text.select = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+ }
+ return cache->text.select;
+}
+
+static Batch *curve_batch_cache_get_overlay_cursor(CurveRenderData *rdata, CurveBatchCache *cache)
+{
+ BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT);
+ if (cache->text.cursor == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ const int vbo_len_capacity = 4;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+ for (int i = 0; i < 4; i++) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i, rdata->text.edit_font->textcurs[i]);
+ }
+ cache->text.cursor = Batch_create(PRIM_TRIANGLE_FAN, vbo, NULL);
+ }
+ return cache->text.cursor;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Public Object/Curve API
+ * \{ */
+
+Batch *DRW_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_cache)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->wire.batch == NULL) {
+ /* create batch from Curve */
+ CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_WIRE);
+
+ cache->wire.batch = Batch_create(
+ PRIM_LINES,
+ curve_batch_cache_get_wire_verts(rdata, cache),
+ curve_batch_cache_get_wire_edges(rdata, cache));
+
+ curve_render_data_free(rdata);
+ }
+ return cache->wire.batch;
+}
+
+Batch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve_cache, float normal_size)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->normal.batch != NULL) {
+ cache->normal_size = normal_size;
+ if (cache->normal_size != normal_size) {
+ BATCH_DISCARD_ALL_SAFE(cache->normal.batch);
+ }
+ }
+ cache->normal_size = normal_size;
+
+ if (cache->normal.batch == NULL) {
+ /* create batch from Curve */
+ CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_NORMAL);
+
+ cache->normal.batch = Batch_create(
+ PRIM_LINES,
+ curve_batch_cache_get_normal_verts(rdata, cache),
+ curve_batch_cache_get_normal_edges(rdata, cache));
+
+ curve_render_data_free(rdata);
+ cache->normal_size = normal_size;
+ }
+ return cache->normal.batch;
+}
+
+Batch *DRW_curve_batch_cache_get_overlay_edges(Curve *cu)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->overlay.edges == NULL) {
+ curve_batch_cache_create_overlay_batches(cu);
+ }
+
+ return cache->overlay.edges;
+}
+
+Batch *DRW_curve_batch_cache_get_overlay_verts(Curve *cu)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->overlay.verts == NULL) {
+ curve_batch_cache_create_overlay_batches(cu);
+ }
+
+ return cache->overlay.verts;
+}
+
+Batch *DRW_curve_batch_cache_get_triangles_with_normals(
+ struct Curve *cu, struct CurveCache *ob_curve_cache)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->surface.batch == NULL) {
+ CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE);
+
+ curve_batch_cache_get_pos_and_normals(rdata, cache);
+
+ curve_render_data_free(rdata);
+ }
+
+ return cache->surface.batch;
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Public Object/Font API
+ * \{ */
+
+Batch *DRW_curve_batch_cache_get_overlay_select(Curve *cu)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->text.select == NULL) {
+ CurveRenderData *rdata = curve_render_data_create(cu, NULL, CU_DATATYPE_TEXT_SELECT);
+
+ curve_batch_cache_get_overlay_select(rdata, cache);
+
+ curve_render_data_free(rdata);
+ }
+
+ return cache->text.select;
+}
+
+Batch *DRW_curve_batch_cache_get_overlay_cursor(Curve *cu)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+
+ if (cache->text.cursor == NULL) {
+ CurveRenderData *rdata = curve_render_data_create(cu, NULL, CU_DATATYPE_TEXT_SELECT);
+
+ curve_batch_cache_get_overlay_cursor(rdata, cache);
+
+ curve_render_data_free(rdata);
+ }
+
+ return cache->text.cursor;
+}
+
+/** \} */ \ No newline at end of file
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
new file mode 100644
index 00000000000..9e93409c24d
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -0,0 +1,168 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file draw_cache_impl_displist.c
+ * \ingroup draw
+ *
+ * \brief DispList API for render engines
+ *
+ * \note DispList may be removed soon! This is a utility for object types that use render.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "DNA_curve_types.h"
+
+#include "BKE_displist.h"
+
+#include "GPU_batch.h"
+
+#include "draw_cache_impl.h" /* own include */
+
+static int dl_vert_len(const DispList *dl)
+{
+ switch (dl->type) {
+ case DL_INDEX3:
+ case DL_INDEX4:
+ return dl->nr;
+ case DL_SURF:
+ return dl->parts * dl->nr;
+ }
+ return 0;
+}
+
+static int dl_tri_len(const DispList *dl)
+{
+ switch (dl->type) {
+ case DL_INDEX3:
+ return dl->parts;
+ case DL_INDEX4:
+ return dl->parts * 2;
+ case DL_SURF:
+ return dl->totindex * 2;
+ }
+ return 0;
+}
+
+/* see: displist_get_allverts */
+static int curve_render_surface_vert_len_get(const ListBase *lb)
+{
+ int vert_len = 0;
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ vert_len += dl_vert_len(dl);
+ }
+ return vert_len;
+}
+
+static int curve_render_surface_tri_len_get(const ListBase *lb)
+{
+ int tri_len = 0;
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ tri_len += dl_tri_len(dl);
+ }
+ return tri_len;
+}
+
+Batch *BLI_displist_batch_calc_surface(ListBase *lb)
+{
+ const int tri_len = curve_render_surface_tri_len_get(lb);
+ if (tri_len == 0) {
+ return NULL;
+ }
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.nor = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int vert_len = curve_render_surface_vert_len_get(lb);
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ {
+ const int vbo_len_capacity = vert_len;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ BKE_displist_normals_add(lb);
+
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ const bool ndata_is_single = dl->type == DL_INDEX3;
+ if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
+ const float *fp_co = dl->verts;
+ const float *fp_no = dl->nors;
+ const int vbo_end = vbo_len_used + dl_vert_len(dl);
+ while (vbo_len_used < vbo_end) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vbo_len_used, fp_co);
+ if (fp_no) {
+ VertexBuffer_set_attrib(vbo, attr_id.nor, vbo_len_used, fp_no);
+ if (ndata_is_single == false) {
+ fp_no += 3;
+ }
+ }
+ fp_co += 3;
+ vbo_len_used += 1;
+ }
+ }
+ }
+ }
+
+ {
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, tri_len, vert_len);
+
+ int ofs = 0;
+ int tri_len_used = 0;
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
+ if (dl->type == DL_INDEX3) {
+ const int *idx = dl->index;
+ const int i_end = dl->parts;
+ for (int i = 0; i < i_end; i++) {
+ add_triangle_vertices(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
+ tri_len_used += 1;
+ idx += 3;
+ }
+ }
+ else if (ELEM(dl->type, DL_INDEX4, DL_SURF)) {
+ const int *idx = dl->index;
+ const int i_end = dl->totindex;
+ for (int i = 0; i < i_end; i++) {
+ add_triangle_vertices(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
+ tri_len_used += 1;
+ add_triangle_vertices(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
+ tri_len_used += 1;
+ idx += 4;
+ }
+ }
+ ofs += dl_vert_len(dl);
+ }
+ }
+
+ return Batch_create(PRIM_TRIANGLES, vbo, ElementList_build(&elb));
+ }
+}
diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c
new file mode 100644
index 00000000000..e5d8a6c9301
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl_lattice.c
@@ -0,0 +1,510 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file draw_cache_impl_lattice.c
+ * \ingroup draw
+ *
+ * \brief Lattice API for render engines
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_lattice_types.h"
+
+#include "BKE_lattice.h"
+
+#include "GPU_batch.h"
+
+#include "draw_cache_impl.h" /* own include */
+
+#define SELECT 1
+
+/**
+ * TODO
+ * - 'DispList' is currently not used
+ * (we could avoid using since it will be removed)
+ */
+
+static void lattice_batch_cache_clear(Lattice *lt);
+
+/* ---------------------------------------------------------------------- */
+/* Lattice Interface, direct access to basic data. */
+
+static int vert_len_calc(int u, int v, int w)
+{
+ if (u <= 0 || v <= 0 || w <= 0) {
+ return 0;
+ }
+ return u * v * w;
+}
+
+static int edge_len_calc(int u, int v, int w)
+{
+ if (u <= 0 || v <= 0 || w <= 0) {
+ return 0;
+ }
+ return (((((u - 1) * v) +
+ ((v - 1) * u)) * w) +
+ ((w - 1) * (u * v)));
+}
+
+static int lattice_render_verts_len_get(Lattice *lt)
+{
+ if (lt->editlatt) {
+ lt = lt->editlatt->latt;
+ }
+
+ const int u = lt->pntsu;
+ const int v = lt->pntsv;
+ const int w = lt->pntsw;
+
+ if ((lt->flag & LT_OUTSIDE) == 0) {
+ return vert_len_calc(u, v, w);
+ }
+ else {
+ /* TODO remove internal coords */
+ return vert_len_calc(u, v, w);
+ }
+}
+
+static int lattice_render_edges_len_get(Lattice *lt)
+{
+ if (lt->editlatt) {
+ lt = lt->editlatt->latt;
+ }
+
+ const int u = lt->pntsu;
+ const int v = lt->pntsv;
+ const int w = lt->pntsw;
+
+ if ((lt->flag & LT_OUTSIDE) == 0) {
+ return edge_len_calc(u, v, w);
+ }
+ else {
+ /* TODO remove internal coords */
+ return edge_len_calc(u, v, w);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/* Lattice Interface, indirect, partially cached access to complex data. */
+
+typedef struct LatticeRenderData {
+ int types;
+
+ int vert_len;
+ int edge_len;
+
+ struct {
+ int u_len, v_len, w_len;
+ } dims;
+ bool show_only_outside;
+
+ struct EditLatt *edit_latt;
+ BPoint *bp;
+
+ int actbp;
+} LatticeRenderData;
+
+enum {
+ LR_DATATYPE_VERT = 1 << 0,
+ LR_DATATYPE_EDGE = 1 << 1,
+ LR_DATATYPE_OVERLAY = 1 << 2,
+};
+
+static LatticeRenderData *lattice_render_data_create(Lattice *lt, const int types)
+{
+ LatticeRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
+ rdata->types = types;
+
+ if (lt->editlatt) {
+ EditLatt *editlatt = lt->editlatt;
+ lt = editlatt->latt;
+
+ rdata->edit_latt = editlatt;
+
+ if (types & (LR_DATATYPE_VERT)) {
+ rdata->vert_len = lattice_render_verts_len_get(lt);
+ }
+ if (types & (LR_DATATYPE_EDGE)) {
+ rdata->edge_len = lattice_render_edges_len_get(lt);
+ }
+ if (types & LR_DATATYPE_OVERLAY) {
+ rdata->actbp = lt->actbp;
+ }
+ }
+ else {
+ if (types & (LR_DATATYPE_VERT)) {
+ rdata->vert_len = lattice_render_verts_len_get(lt);
+ }
+ if (types & (LR_DATATYPE_EDGE)) {
+ rdata->edge_len = lattice_render_edges_len_get(lt);
+ /*no edge data */
+ }
+ }
+
+ rdata->bp = lt->def;
+
+ rdata->dims.u_len = lt->pntsu;
+ rdata->dims.v_len = lt->pntsv;
+ rdata->dims.w_len = lt->pntsw;
+
+ rdata->show_only_outside = (lt->flag & LT_OUTSIDE) != 0;
+ rdata->actbp = lt->actbp;
+
+ return rdata;
+}
+
+static void lattice_render_data_free(LatticeRenderData *rdata)
+{
+#if 0
+ if (rdata->loose_verts) {
+ MEM_freeN(rdata->loose_verts);
+ }
+#endif
+ MEM_freeN(rdata);
+}
+
+static int lattice_render_data_verts_len_get(const LatticeRenderData *rdata)
+{
+ BLI_assert(rdata->types & LR_DATATYPE_VERT);
+ return rdata->vert_len;
+}
+
+static int lattice_render_data_edges_len_get(const LatticeRenderData *rdata)
+{
+ BLI_assert(rdata->types & LR_DATATYPE_EDGE);
+ return rdata->edge_len;
+}
+
+static const BPoint *lattice_render_data_vert_bpoint(const LatticeRenderData *rdata, const int vert_idx)
+{
+ BLI_assert(rdata->types & LR_DATATYPE_VERT);
+ return &rdata->bp[vert_idx];
+}
+
+enum {
+ VFLAG_VERTEX_SELECTED = 1 << 0,
+ VFLAG_VERTEX_ACTIVE = 1 << 1,
+};
+
+/* ---------------------------------------------------------------------- */
+/* Lattice Batch Cache */
+
+typedef struct LatticeBatchCache {
+ VertexBuffer *pos;
+ ElementList *edges;
+
+ Batch *all_verts;
+ Batch *all_edges;
+
+ Batch *overlay_verts;
+
+ /* settings to determine if cache is invalid */
+ bool is_dirty;
+
+ struct {
+ int u_len, v_len, w_len;
+ } dims;
+ bool show_only_outside;
+
+ bool is_editmode;
+} LatticeBatchCache;
+
+/* Batch cache management. */
+
+static bool lattice_batch_cache_valid(Lattice *lt)
+{
+ LatticeBatchCache *cache = lt->batch_cache;
+
+ if (cache == NULL) {
+ return false;
+ }
+
+ if (cache->is_editmode != (lt->editlatt != NULL)) {
+ return false;
+ }
+
+ if (cache->is_dirty == false) {
+ return true;
+ }
+ else {
+ if (cache->is_editmode) {
+ return false;
+ }
+ else if ((cache->dims.u_len != lt->pntsu) ||
+ (cache->dims.v_len != lt->pntsv) ||
+ (cache->dims.w_len != lt->pntsw) ||
+ ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0))))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void lattice_batch_cache_init(Lattice *lt)
+{
+ LatticeBatchCache *cache = lt->batch_cache;
+
+ if (!cache) {
+ cache = lt->batch_cache = MEM_callocN(sizeof(*cache), __func__);
+ }
+ else {
+ memset(cache, 0, sizeof(*cache));
+ }
+
+ cache->dims.u_len = lt->pntsu;
+ cache->dims.v_len = lt->pntsv;
+ cache->dims.w_len = lt->pntsw;
+ cache->show_only_outside = (lt->flag & LT_OUTSIDE) != 0;
+
+ cache->is_editmode = lt->editlatt != NULL;
+
+ cache->is_dirty = false;
+}
+
+static LatticeBatchCache *lattice_batch_cache_get(Lattice *lt)
+{
+ if (!lattice_batch_cache_valid(lt)) {
+ lattice_batch_cache_clear(lt);
+ lattice_batch_cache_init(lt);
+ }
+ return lt->batch_cache;
+}
+
+void DRW_lattice_batch_cache_dirty(Lattice *lt, int mode)
+{
+ LatticeBatchCache *cache = lt->batch_cache;
+ if (cache == NULL) {
+ return;
+ }
+ switch (mode) {
+ case BKE_LATTICE_BATCH_DIRTY_ALL:
+ cache->is_dirty = true;
+ break;
+ case BKE_LATTICE_BATCH_DIRTY_SELECT:
+ /* TODO Separate Flag vbo */
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_verts);
+ break;
+ default:
+ BLI_assert(0);
+ }
+}
+
+static void lattice_batch_cache_clear(Lattice *lt)
+{
+ LatticeBatchCache *cache = lt->batch_cache;
+ if (!cache) {
+ return;
+ }
+
+ BATCH_DISCARD_SAFE(cache->all_verts);
+ BATCH_DISCARD_SAFE(cache->all_edges);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_verts);
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos);
+ ELEMENTLIST_DISCARD_SAFE(cache->edges);
+}
+
+void DRW_lattice_batch_cache_free(Lattice *lt)
+{
+ lattice_batch_cache_clear(lt);
+ MEM_SAFE_FREE(lt->batch_cache);
+}
+
+/* Batch cache usage. */
+static VertexBuffer *lattice_batch_cache_get_pos(LatticeRenderData *rdata, LatticeBatchCache *cache)
+{
+ BLI_assert(rdata->types & LR_DATATYPE_VERT);
+
+ if (cache->pos == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int vert_len = lattice_render_data_verts_len_get(rdata);
+
+ cache->pos = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(cache->pos, vert_len);
+ for (int i = 0; i < vert_len; ++i) {
+ const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i);
+ VertexBuffer_set_attrib(cache->pos, attr_id.pos, i, bp->vec);
+ }
+ }
+
+ return cache->pos;
+}
+
+static ElementList *lattice_batch_cache_get_edges(LatticeRenderData *rdata, LatticeBatchCache *cache)
+{
+ BLI_assert(rdata->types & (LR_DATATYPE_VERT | LR_DATATYPE_EDGE));
+
+ if (cache->edges == NULL) {
+ const int vert_len = lattice_render_data_verts_len_get(rdata);
+ const int edge_len = lattice_render_data_edges_len_get(rdata);
+ int edge_len_real = 0;
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len);
+
+#define LATT_INDEX(u, v, w) \
+ ((((w) * rdata->dims.v_len + (v)) * rdata->dims.u_len) + (u))
+
+ for (int w = 0; w < rdata->dims.w_len; w++) {
+ int wxt = (w == 0 || w == rdata->dims.w_len - 1);
+ for (int v = 0; v < rdata->dims.v_len; v++) {
+ int vxt = (v == 0 || v == rdata->dims.v_len - 1);
+ for (int u = 0; u < rdata->dims.u_len; u++) {
+ int uxt = (u == 0 || u == rdata->dims.u_len - 1);
+
+ if (w && ((uxt || vxt) || !rdata->show_only_outside)) {
+ add_line_vertices(&elb, LATT_INDEX(u, v, w - 1), LATT_INDEX(u, v, w));
+ BLI_assert(edge_len_real <= edge_len);
+ edge_len_real++;
+ }
+ if (v && ((uxt || wxt) || !rdata->show_only_outside)) {
+ add_line_vertices(&elb, LATT_INDEX(u, v - 1, w), LATT_INDEX(u, v, w));
+ BLI_assert(edge_len_real <= edge_len);
+ edge_len_real++;
+ }
+ if (u && ((vxt || wxt) || !rdata->show_only_outside)) {
+ add_line_vertices(&elb, LATT_INDEX(u - 1, v, w), LATT_INDEX(u, v, w));
+ BLI_assert(edge_len_real <= edge_len);
+ edge_len_real++;
+ }
+ }
+ }
+ }
+
+#undef LATT_INDEX
+
+ if (rdata->show_only_outside) {
+ BLI_assert(edge_len_real <= edge_len);
+ }
+ else {
+ BLI_assert(edge_len_real == edge_len);
+ }
+
+ cache->edges = ElementList_build(&elb);
+ }
+
+ return cache->edges;
+}
+
+static void lattice_batch_cache_create_overlay_batches(Lattice *lt)
+{
+ /* Since LR_DATATYPE_OVERLAY is slow to generate, generate them all at once */
+ int options = LR_DATATYPE_VERT | LR_DATATYPE_OVERLAY;
+
+ LatticeBatchCache *cache = lattice_batch_cache_get(lt);
+ LatticeRenderData *rdata = lattice_render_data_create(lt, options);
+
+ if (cache->overlay_verts == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.data = VertexFormat_add_attrib(&format, "data", COMP_U8, 1, KEEP_INT);
+ }
+
+ const int vert_len = lattice_render_data_verts_len_get(rdata);
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, vert_len);
+ for (int i = 0; i < vert_len; ++i) {
+ const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i);
+
+ char vflag = 0;
+ if (bp->f1 & SELECT) {
+ if (i == rdata->actbp) {
+ vflag |= VFLAG_VERTEX_ACTIVE;
+ }
+ else {
+ vflag |= VFLAG_VERTEX_SELECTED;
+ }
+ }
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i, bp->vec);
+ VertexBuffer_set_attrib(vbo, attr_id.data, i, &vflag);
+ }
+
+ cache->overlay_verts = Batch_create(PRIM_POINTS, vbo, NULL);
+ }
+
+ lattice_render_data_free(rdata);
+}
+
+Batch *DRW_lattice_batch_cache_get_all_edges(Lattice *lt)
+{
+ LatticeBatchCache *cache = lattice_batch_cache_get(lt);
+
+ if (cache->all_edges == NULL) {
+ /* create batch from Lattice */
+ LatticeRenderData *rdata = lattice_render_data_create(lt, LR_DATATYPE_VERT | LR_DATATYPE_EDGE);
+
+ cache->all_edges = Batch_create(PRIM_LINES, lattice_batch_cache_get_pos(rdata, cache),
+ lattice_batch_cache_get_edges(rdata, cache));
+
+ lattice_render_data_free(rdata);
+ }
+
+ return cache->all_edges;
+}
+
+Batch *DRW_lattice_batch_cache_get_all_verts(Lattice *lt)
+{
+ LatticeBatchCache *cache = lattice_batch_cache_get(lt);
+
+ if (cache->all_verts == NULL) {
+ LatticeRenderData *rdata = lattice_render_data_create(lt, LR_DATATYPE_VERT);
+
+ cache->all_verts = Batch_create(PRIM_POINTS, lattice_batch_cache_get_pos(rdata, cache), NULL);
+
+ lattice_render_data_free(rdata);
+ }
+
+ return cache->all_verts;
+}
+
+Batch *DRW_lattice_batch_cache_get_overlay_verts(Lattice *lt)
+{
+ LatticeBatchCache *cache = lattice_batch_cache_get(lt);
+
+ if (cache->overlay_verts == NULL) {
+ lattice_batch_cache_create_overlay_batches(lt);
+ }
+
+ return cache->overlay_verts;
+}
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
new file mode 100644
index 00000000000..aebebc92ec2
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -0,0 +1,3235 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file draw_cache_impl_mesh.c
+ * \ingroup draw
+ *
+ * \brief Mesh API for render engines
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+#include "BLI_string.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_editmesh.h"
+#include "BKE_editmesh_tangent.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_tangent.h"
+#include "BKE_texture.h"
+
+#include "bmesh.h"
+
+#include "GPU_batch.h"
+#include "GPU_draw.h"
+
+#include "draw_cache_impl.h" /* own include */
+
+static void mesh_batch_cache_clear(Mesh *me);
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Mesh/BMesh Interface (direct access to basic data).
+ * \{ */
+
+static int mesh_render_verts_len_get(Mesh *me)
+{
+ return me->edit_btmesh ? me->edit_btmesh->bm->totvert : me->totvert;
+}
+
+static int mesh_render_edges_len_get(Mesh *me)
+{
+ return me->edit_btmesh ? me->edit_btmesh->bm->totedge : me->totedge;
+}
+
+static int mesh_render_looptri_len_get(Mesh *me)
+{
+ return me->edit_btmesh ? me->edit_btmesh->tottri : poly_to_tri_count(me->totpoly, me->totloop);
+}
+
+static int mesh_render_polys_len_get(Mesh *me)
+{
+ return me->edit_btmesh ? me->edit_btmesh->bm->totface : me->totpoly;
+}
+
+static int mesh_render_mat_len_get(Mesh *me)
+{
+ return MAX2(1, me->totcol);
+}
+
+static int UNUSED_FUNCTION(mesh_render_loops_len_get)(Mesh *me)
+{
+ return me->edit_btmesh ? me->edit_btmesh->bm->totloop : me->totloop;
+}
+
+/** \} */
+
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Mesh/BMesh Interface (indirect, partially cached access to complex data).
+ * \{ */
+
+typedef struct EdgeAdjacentPolys {
+ int count;
+ int face_index[2];
+} EdgeAdjacentPolys;
+
+typedef struct EdgeDrawAttr {
+ unsigned char v_flag;
+ unsigned char e_flag;
+ unsigned char crease;
+ unsigned char bweight;
+} EdgeDrawAttr;
+
+typedef struct MeshRenderData {
+ int types;
+
+ int vert_len;
+ int edge_len;
+ int tri_len;
+ int loop_len;
+ int poly_len;
+ int mat_len;
+ int loose_vert_len;
+ int loose_edge_len;
+
+ BMEditMesh *edit_bmesh;
+ MVert *mvert;
+ MEdge *medge;
+ MLoop *mloop;
+ MPoly *mpoly;
+ float (*orco)[3];
+ MDeformVert *dvert;
+ MLoopUV *mloopuv;
+ MLoopCol *mloopcol;
+
+ /* CustomData 'cd' cache for efficient access. */
+ struct {
+ struct {
+ MLoopUV **uv;
+ int uv_len;
+ int uv_active;
+
+ MLoopCol **vcol;
+ int vcol_len;
+ int vcol_active;
+
+ float (**tangent)[4];
+ int tangent_active;
+
+ bool *auto_vcol;
+ } layers;
+
+ /* Custom-data offsets (only needed for BMesh access) */
+ struct {
+ int crease;
+ int bweight;
+ int *uv;
+ int *vcol;
+ } offset;
+
+ struct {
+ char (*auto_mix)[32];
+ char (*uv)[32];
+ char (*vcol)[32];
+ char (*tangent)[32];
+ } uuid;
+
+ /* for certain cases we need an output loop-data storage (bmesh tangents) */
+ struct {
+ CustomData ldata;
+ /* grr, special case variable (use in place of 'dm->tangent_mask') */
+ char tangent_mask;
+ } output;
+ } cd;
+
+ BMVert *eve_act;
+ BMEdge *eed_act;
+ BMFace *efa_act;
+
+ /* Data created on-demand (usually not for bmesh-based data). */
+ EdgeAdjacentPolys *edges_adjacent_polys;
+ MLoopTri *mlooptri;
+ int *loose_edges;
+ int *loose_verts;
+
+ float (*poly_normals)[3];
+ float (*vert_weight_color)[3];
+ char (*vert_color)[3];
+ short (*poly_normals_short)[3];
+ short (*vert_normals_short)[3];
+ bool *edge_select_bool;
+} MeshRenderData;
+
+enum {
+ MR_DATATYPE_VERT = 1 << 0,
+ MR_DATATYPE_EDGE = 1 << 1,
+ MR_DATATYPE_LOOPTRI = 1 << 2,
+ MR_DATATYPE_LOOP = 1 << 3,
+ MR_DATATYPE_POLY = 1 << 4,
+ MR_DATATYPE_OVERLAY = 1 << 5,
+ MR_DATATYPE_SHADING = 1 << 6,
+ MR_DATATYPE_DVERT = 1 << 7,
+ MR_DATATYPE_LOOPCOL = 1 << 8,
+ MR_DATATYPE_LOOPUV = 1 << 9,
+};
+
+/**
+ * These functions look like they would be slow but they will typically return true on the first iteration.
+ * Only false when all attached elements are hidden.
+ */
+static bool bm_vert_has_visible_edge(const BMVert *v)
+{
+ const BMEdge *e_iter, *e_first;
+
+ e_iter = e_first = v->e;
+ do {
+ if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
+ return false;
+}
+
+static bool bm_edge_has_visible_face(const BMEdge *e)
+{
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ return false;
+}
+
+
+static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
+{
+ MeshRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
+ rdata->types = types;
+ rdata->mat_len = mesh_render_mat_len_get(me);
+
+ CustomData_reset(&rdata->cd.output.ldata);
+
+ if (me->edit_btmesh) {
+ BMEditMesh *embm = me->edit_btmesh;
+ BMesh *bm = embm->bm;
+
+ rdata->edit_bmesh = embm;
+
+ int bm_ensure_types = 0;
+ if (types & (MR_DATATYPE_VERT)) {
+ rdata->vert_len = bm->totvert;
+ bm_ensure_types |= BM_VERT;
+ }
+ if (types & (MR_DATATYPE_EDGE)) {
+ rdata->edge_len = bm->totedge;
+ bm_ensure_types |= BM_EDGE;
+ }
+ if (types & MR_DATATYPE_LOOPTRI) {
+ BKE_editmesh_tessface_calc(embm);
+ rdata->tri_len = embm->tottri;
+ }
+ if (types & MR_DATATYPE_LOOP) {
+ rdata->loop_len = bm->totloop;
+ bm_ensure_types |= BM_LOOP;
+ }
+ if (types & MR_DATATYPE_POLY) {
+ rdata->poly_len = bm->totface;
+ bm_ensure_types |= BM_FACE;
+ }
+ if (types & MR_DATATYPE_OVERLAY) {
+ rdata->efa_act = BM_mesh_active_face_get(bm, false, true);
+ rdata->eed_act = BM_mesh_active_edge_get(bm);
+ rdata->eve_act = BM_mesh_active_vert_get(bm);
+ rdata->cd.offset.crease = CustomData_get_offset(&bm->edata, CD_CREASE);
+ rdata->cd.offset.bweight = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ }
+ if (types & (MR_DATATYPE_DVERT)) {
+ bm_ensure_types |= BM_VERT;
+ }
+
+ BM_mesh_elem_index_ensure(bm, bm_ensure_types);
+ BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP);
+ if (types & MR_DATATYPE_OVERLAY) {
+ rdata->loose_vert_len = rdata->loose_edge_len = 0;
+
+ int *lverts = rdata->loose_verts = MEM_mallocN(rdata->vert_len * sizeof(int), "Loose Vert");
+ int *ledges = rdata->loose_edges = MEM_mallocN(rdata->edge_len * sizeof(int), "Loose Edges");
+
+ {
+ BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
+ BMVert **vtable = bm->vtable;
+ for (int i = 0; i < bm->totvert; i++) {
+ const BMVert *eve = vtable[i];
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ /* Loose vert */
+ if (eve->e == NULL || !bm_vert_has_visible_edge(eve)) {
+ lverts[rdata->loose_vert_len++] = i;
+ }
+ }
+ }
+ }
+
+ {
+ BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
+ BMEdge **etable = bm->etable;
+ for (int i = 0; i < bm->totedge; i++) {
+ const BMEdge *eed = etable[i];
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ /* Loose edge */
+ if (eed->l == NULL || !bm_edge_has_visible_face(eed)) {
+ ledges[rdata->loose_edge_len++] = i;
+ }
+ }
+ }
+ }
+
+ rdata->loose_verts = MEM_reallocN(rdata->loose_verts, rdata->loose_vert_len * sizeof(int));
+ rdata->loose_edges = MEM_reallocN(rdata->loose_edges, rdata->loose_edge_len * sizeof(int));
+ }
+ }
+ else {
+ if (types & (MR_DATATYPE_VERT)) {
+ rdata->vert_len = me->totvert;
+ rdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
+ }
+ if (types & (MR_DATATYPE_EDGE)) {
+ rdata->edge_len = me->totedge;
+ rdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
+ }
+ if (types & MR_DATATYPE_LOOPTRI) {
+ const int tri_len = rdata->tri_len = poly_to_tri_count(me->totpoly, me->totloop);
+ rdata->mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * tri_len, __func__);
+ BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, rdata->mlooptri);
+ }
+ if (types & MR_DATATYPE_LOOP) {
+ rdata->loop_len = me->totloop;
+ rdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
+ }
+ if (types & MR_DATATYPE_POLY) {
+ rdata->poly_len = me->totpoly;
+ rdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
+ }
+ if (types & MR_DATATYPE_DVERT) {
+ rdata->vert_len = me->totvert;
+ rdata->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
+ }
+ if (types & MR_DATATYPE_LOOPCOL) {
+ rdata->loop_len = me->totloop;
+ rdata->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
+ }
+ if (types & MR_DATATYPE_LOOPUV) {
+ rdata->loop_len = me->totloop;
+ rdata->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
+ }
+ }
+
+ if (types & MR_DATATYPE_SHADING) {
+ CustomData *cd_vdata, *cd_ldata;
+
+ if (me->edit_btmesh) {
+ BMesh *bm = me->edit_btmesh->bm;
+ cd_vdata = &bm->vdata;
+ cd_ldata = &bm->ldata;
+ }
+ else {
+ cd_vdata = &me->vdata;
+ cd_ldata = &me->ldata;
+ }
+
+ rdata->orco = CustomData_get_layer(cd_vdata, CD_ORCO);
+ /* If orco is not available compute it ourselves */
+ if (!rdata->orco) {
+ if (me->edit_btmesh) {
+ BMesh *bm = me->edit_btmesh->bm;
+ rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
+ BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
+ BMVert **vtable = bm->vtable;
+ for (int i = 0; i < bm->totvert; i++) {
+ copy_v3_v3(rdata->orco[i], vtable[i]->co);
+ }
+ BKE_mesh_orco_verts_transform(me, rdata->orco, rdata->vert_len, 0);
+ }
+ else {
+ rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
+ MVert *mvert = rdata->mvert;
+ for (int a = 0; a < rdata->vert_len; a++, mvert++) {
+ copy_v3_v3(rdata->orco[a], mvert->co);
+ }
+ BKE_mesh_orco_verts_transform(me, rdata->orco, rdata->vert_len, 0);
+ }
+ }
+
+ const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
+
+ /* don't access mesh directly, instead use vars taken from BMesh or Mesh */
+#define me DONT_USE_THIS
+#ifdef me /* quiet warning */
+#endif
+
+ rdata->cd.layers.uv_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPUV);
+ rdata->cd.layers.vcol_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPCOL);
+
+ rdata->cd.layers.uv = MEM_mallocN(sizeof(*rdata->cd.layers.uv) * rdata->cd.layers.uv_len, __func__);
+ rdata->cd.layers.vcol = MEM_mallocN(sizeof(*rdata->cd.layers.vcol) * rdata->cd.layers.vcol_len, __func__);
+ rdata->cd.layers.tangent = MEM_mallocN(sizeof(*rdata->cd.layers.tangent) * rdata->cd.layers.uv_len, __func__);
+
+ rdata->cd.uuid.uv = MEM_mallocN(sizeof(*rdata->cd.uuid.uv) * rdata->cd.layers.uv_len, __func__);
+ rdata->cd.uuid.vcol = MEM_mallocN(sizeof(*rdata->cd.uuid.vcol) * rdata->cd.layers.vcol_len, __func__);
+ rdata->cd.uuid.tangent = MEM_mallocN(sizeof(*rdata->cd.uuid.tangent) * rdata->cd.layers.uv_len, __func__);
+
+ rdata->cd.offset.uv = MEM_mallocN(sizeof(*rdata->cd.offset.uv) * rdata->cd.layers.uv_len, __func__);
+ rdata->cd.offset.vcol = MEM_mallocN(sizeof(*rdata->cd.offset.vcol) * rdata->cd.layers.vcol_len, __func__);
+
+ /* Allocate max */
+ rdata->cd.layers.auto_vcol = MEM_callocN(
+ sizeof(*rdata->cd.layers.auto_vcol) * rdata->cd.layers.vcol_len, __func__);
+ rdata->cd.uuid.auto_mix = MEM_mallocN(
+ sizeof(*rdata->cd.uuid.auto_mix) * (rdata->cd.layers.vcol_len + rdata->cd.layers.uv_len), __func__);
+
+ /* XXX FIXME XXX */
+ /* We use a hash to identify each data layer based on its name.
+ * Gawain then search for this name in the current shader and bind if it exists.
+ * NOTE : This is prone to hash collision.
+ * One solution to hash collision would be to format the cd layer name
+ * to a safe glsl var name, but without name clash.
+ * NOTE 2 : Replicate changes to code_generate_vertex_new() in gpu_codegen.c */
+ for (int i = 0; i < rdata->cd.layers.vcol_len; ++i) {
+ const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i);
+ unsigned int hash = BLI_ghashutil_strhash_p(name);
+ BLI_snprintf(rdata->cd.uuid.vcol[i], sizeof(*rdata->cd.uuid.vcol), "c%u", hash);
+ rdata->cd.layers.vcol[i] = CustomData_get_layer_n(cd_ldata, CD_MLOOPCOL, i);
+ if (rdata->edit_bmesh) {
+ rdata->cd.offset.vcol[i] = CustomData_get_n_offset(&rdata->edit_bmesh->bm->ldata, CD_MLOOPCOL, i);
+ }
+
+ /* Gather number of auto layers. */
+ /* We only do vcols that are not overridden by uvs */
+ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) {
+ BLI_snprintf(
+ rdata->cd.uuid.auto_mix[rdata->cd.layers.uv_len + i],
+ sizeof(*rdata->cd.uuid.auto_mix), "a%u", hash);
+ rdata->cd.layers.auto_vcol[i] = true;
+ }
+ }
+
+ /* Start Fresh */
+ CustomData_free_layers(cd_ldata, CD_MLOOPTANGENT, rdata->loop_len);
+ for (int i = 0; i < rdata->cd.layers.uv_len; ++i) {
+ const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i);
+ unsigned int hash = BLI_ghashutil_strhash_p(name);
+
+ {
+ /* UVs */
+ BLI_snprintf(rdata->cd.uuid.uv[i], sizeof(*rdata->cd.uuid.uv), "u%u", hash);
+ rdata->cd.layers.uv[i] = CustomData_get_layer_n(cd_ldata, CD_MLOOPUV, i);
+ if (rdata->edit_bmesh) {
+ rdata->cd.offset.uv[i] = CustomData_get_n_offset(&rdata->edit_bmesh->bm->ldata, CD_MLOOPUV, i);
+ }
+ BLI_snprintf(rdata->cd.uuid.auto_mix[i], sizeof(*rdata->cd.uuid.auto_mix), "a%u", hash);
+ }
+
+ {
+ /* Tangents*/
+ BLI_snprintf(rdata->cd.uuid.tangent[i], sizeof(*rdata->cd.uuid.tangent), "t%u", hash);
+
+ if (!CustomData_has_layer(&rdata->cd.output.ldata, CD_MLOOPTANGENT)) {
+
+ /* Tangent Names */
+ char tangent_names[MAX_MTFACE][MAX_NAME];
+ int tangent_names_len = 0;
+ for (tangent_names_len = 0; tangent_names_len < rdata->cd.layers.uv_len; tangent_names_len++) {
+ BLI_strncpy(
+ tangent_names[tangent_names_len],
+ CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, tangent_names_len), MAX_NAME);
+ }
+
+ if (rdata->edit_bmesh) {
+ BMEditMesh *em = rdata->edit_bmesh;
+ BMesh *bm = em->bm;
+
+ if (is_auto_smooth) {
+ /* TODO: split normals, see below */
+ }
+
+ bool calc_active_tangent = false;
+ float (*poly_normals)[3] = rdata->poly_normals;
+ float (*loop_normals)[3] = CustomData_get_layer(cd_ldata, CD_NORMAL);
+
+ BKE_editmesh_loop_tangent_calc(
+ em, calc_active_tangent,
+ tangent_names, tangent_names_len,
+ poly_normals, loop_normals,
+ rdata->orco,
+ &rdata->cd.output.ldata, bm->totloop,
+ &rdata->cd.output.tangent_mask);
+ }
+ else {
+#undef me
+
+ if (is_auto_smooth) {
+ if (!CustomData_has_layer(cd_ldata, CD_NORMAL)) {
+ BKE_mesh_calc_normals_split(me);
+ }
+ }
+
+ bool calc_active_tangent = false;
+ const float (*poly_normals)[3] = rdata->poly_normals;
+ const float (*loop_normals)[3] = CustomData_get_layer(cd_ldata, CD_NORMAL);
+
+ BKE_mesh_calc_loop_tangent_ex(
+ me->mvert,
+ me->mpoly, me->totpoly,
+ me->mloop,
+ rdata->mlooptri, rdata->tri_len,
+ cd_ldata,
+ calc_active_tangent,
+ tangent_names, tangent_names_len,
+ poly_normals, loop_normals,
+ rdata->orco,
+ &rdata->cd.output.ldata, me->totloop,
+ &rdata->cd.output.tangent_mask);
+
+ /* If we store tangents in the mesh, set temporary. */
+#if 0
+ CustomData_set_layer_flag(cd_ldata, CD_MLOOPTANGENT, CD_FLAG_TEMPORARY);
+#endif
+
+#define me DONT_USE_THIS
+#ifdef me /* quiet warning */
+#endif
+ }
+ }
+ /* Done adding tangents. */
+
+ /* note: BKE_editmesh_loop_tangent_calc calculates 'CD_TANGENT',
+ * not 'CD_MLOOPTANGENT' (as done below). It's OK, they're compatible. */
+ rdata->cd.layers.tangent[i] = CustomData_get_layer_n(&rdata->cd.output.ldata, CD_TANGENT, i);
+ BLI_assert(rdata->cd.layers.tangent[i] != NULL);
+ }
+ }
+
+ rdata->cd.layers.uv_active = CustomData_get_active_layer_index(
+ cd_ldata, CD_MLOOPUV) - CustomData_get_layer_index(cd_ldata, CD_MLOOPUV);
+ rdata->cd.layers.vcol_active = CustomData_get_active_layer_index(
+ cd_ldata, CD_MLOOPCOL) - CustomData_get_layer_index(cd_ldata, CD_MLOOPCOL);
+ rdata->cd.layers.tangent_active = CustomData_get_active_layer_index(
+ cd_ldata, CD_MLOOPTANGENT) - CustomData_get_layer_index(cd_ldata, CD_MLOOPTANGENT);
+
+#undef me
+ }
+
+ return rdata;
+}
+
+static void mesh_render_data_free(MeshRenderData *rdata)
+{
+ MEM_SAFE_FREE(rdata->orco);
+ MEM_SAFE_FREE(rdata->cd.offset.uv);
+ MEM_SAFE_FREE(rdata->cd.offset.vcol);
+ MEM_SAFE_FREE(rdata->cd.uuid.auto_mix);
+ MEM_SAFE_FREE(rdata->cd.uuid.uv);
+ MEM_SAFE_FREE(rdata->cd.uuid.vcol);
+ MEM_SAFE_FREE(rdata->cd.uuid.tangent);
+ MEM_SAFE_FREE(rdata->cd.layers.uv);
+ MEM_SAFE_FREE(rdata->cd.layers.vcol);
+ MEM_SAFE_FREE(rdata->cd.layers.tangent);
+ MEM_SAFE_FREE(rdata->cd.layers.auto_vcol);
+ MEM_SAFE_FREE(rdata->loose_verts);
+ MEM_SAFE_FREE(rdata->loose_edges);
+ MEM_SAFE_FREE(rdata->edges_adjacent_polys);
+ MEM_SAFE_FREE(rdata->mlooptri);
+ MEM_SAFE_FREE(rdata->poly_normals);
+ MEM_SAFE_FREE(rdata->poly_normals_short);
+ MEM_SAFE_FREE(rdata->vert_normals_short);
+ MEM_SAFE_FREE(rdata->vert_weight_color);
+ MEM_SAFE_FREE(rdata->edge_select_bool);
+ MEM_SAFE_FREE(rdata->vert_color);
+
+ CustomData_free(&rdata->cd.output.ldata, rdata->loop_len);
+
+ MEM_freeN(rdata);
+}
+
+/** \} */
+
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Accessor Functions
+ * \{ */
+
+static const char *mesh_render_data_uv_auto_layer_uuid_get(const MeshRenderData *rdata, int layer)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_SHADING);
+ return rdata->cd.uuid.auto_mix[layer];
+}
+
+static const char *mesh_render_data_vcol_auto_layer_uuid_get(const MeshRenderData *rdata, int layer)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_SHADING);
+ return rdata->cd.uuid.auto_mix[rdata->cd.layers.uv_len + layer];
+}
+
+static const char *mesh_render_data_uv_layer_uuid_get(const MeshRenderData *rdata, int layer)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_SHADING);
+ return rdata->cd.uuid.uv[layer];
+}
+
+static const char *mesh_render_data_vcol_layer_uuid_get(const MeshRenderData *rdata, int layer)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_SHADING);
+ return rdata->cd.uuid.vcol[layer];
+}
+
+static const char *mesh_render_data_tangent_layer_uuid_get(const MeshRenderData *rdata, int layer)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_SHADING);
+ return rdata->cd.uuid.tangent[layer];
+}
+
+static int mesh_render_data_verts_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+ return rdata->vert_len;
+}
+
+static int mesh_render_data_loose_verts_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_OVERLAY);
+ return rdata->loose_vert_len;
+}
+
+static int mesh_render_data_edges_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_EDGE);
+ return rdata->edge_len;
+}
+
+static int mesh_render_data_loose_edges_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_OVERLAY);
+ return rdata->loose_edge_len;
+}
+
+static int mesh_render_data_looptri_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
+ return rdata->tri_len;
+}
+
+static int mesh_render_data_mat_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_POLY);
+ return rdata->mat_len;
+}
+
+static int UNUSED_FUNCTION(mesh_render_data_loops_len_get)(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_LOOP);
+ return rdata->loop_len;
+}
+
+static int mesh_render_data_polys_len_get(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_POLY);
+ return rdata->poly_len;
+}
+
+/** \} */
+
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Internal Cache (Lazy Initialization)
+ * \{ */
+
+/** Ensure #MeshRenderData.poly_normals_short */
+static void mesh_render_data_ensure_poly_normals_short(MeshRenderData *rdata)
+{
+ short (*pnors_short)[3] = rdata->poly_normals_short;
+ if (pnors_short == NULL) {
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter fiter;
+ BMFace *efa;
+ int i;
+
+ pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__);
+ BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) {
+ normal_float_to_short_v3(pnors_short[i], efa->no);
+ }
+ }
+ else {
+ float (*pnors)[3] = rdata->poly_normals;
+
+ if (!pnors) {
+ pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * rdata->poly_len, __func__);
+ BKE_mesh_calc_normals_poly(
+ rdata->mvert, NULL, rdata->vert_len,
+ rdata->mloop, rdata->mpoly, rdata->loop_len, rdata->poly_len, pnors, true);
+ }
+
+ pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__);
+ for (int i = 0; i < rdata->poly_len; i++) {
+ normal_float_to_short_v3(pnors_short[i], pnors[i]);
+ }
+ }
+ }
+}
+
+/** Ensure #MeshRenderData.vert_normals_short */
+static void mesh_render_data_ensure_vert_normals_short(MeshRenderData *rdata)
+{
+ short (*vnors_short)[3] = rdata->vert_normals_short;
+ if (vnors_short == NULL) {
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter viter;
+ BMVert *eve;
+ int i;
+
+ vnors_short = rdata->vert_normals_short = MEM_mallocN(sizeof(*vnors_short) * rdata->vert_len, __func__);
+ BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
+ normal_float_to_short_v3(vnors_short[i], eve->no);
+ }
+ }
+ else {
+ /* data from mesh used directly */
+ BLI_assert(0);
+ }
+ }
+}
+
+
+/** Ensure #MeshRenderData.vert_color */
+static void mesh_render_data_ensure_vert_color(MeshRenderData *rdata)
+{
+ char (*vcol)[3] = rdata->vert_color;
+ if (vcol == NULL) {
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
+ if (cd_loop_color_offset == -1) {
+ goto fallback;
+ }
+
+ vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
+
+ BMIter fiter;
+ BMFace *efa;
+ int i = 0;
+
+ BM_ITER_MESH(efa, &fiter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ const MLoopCol *lcol = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_color_offset);
+ vcol[i][0] = lcol->r;
+ vcol[i][1] = lcol->g;
+ vcol[i][2] = lcol->b;
+ i += 1;
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ BLI_assert(i == rdata->loop_len);
+ }
+ else {
+ if (rdata->mloopcol == NULL) {
+ goto fallback;
+ }
+
+ vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
+
+ for (int i = 0; i < rdata->loop_len; i++) {
+ vcol[i][0] = rdata->mloopcol[i].r;
+ vcol[i][1] = rdata->mloopcol[i].g;
+ vcol[i][2] = rdata->mloopcol[i].b;
+ }
+ }
+ }
+ return;
+
+fallback:
+ vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
+
+ for (int i = 0; i < rdata->loop_len; i++) {
+ vcol[i][0] = 255;
+ vcol[i][1] = 255;
+ vcol[i][2] = 255;
+ }
+}
+
+/* TODO, move into shader? */
+static void rgb_from_weight(float r_rgb[3], const float weight)
+{
+ const float blend = ((weight / 2.0f) + 0.5f);
+
+ if (weight <= 0.25f) { /* blue->cyan */
+ r_rgb[0] = 0.0f;
+ r_rgb[1] = blend * weight * 4.0f;
+ r_rgb[2] = blend;
+ }
+ else if (weight <= 0.50f) { /* cyan->green */
+ r_rgb[0] = 0.0f;
+ r_rgb[1] = blend;
+ r_rgb[2] = blend * (1.0f - ((weight - 0.25f) * 4.0f));
+ }
+ else if (weight <= 0.75f) { /* green->yellow */
+ r_rgb[0] = blend * ((weight - 0.50f) * 4.0f);
+ r_rgb[1] = blend;
+ r_rgb[2] = 0.0f;
+ }
+ else if (weight <= 1.0f) { /* yellow->red */
+ r_rgb[0] = blend;
+ r_rgb[1] = blend * (1.0f - ((weight - 0.75f) * 4.0f));
+ r_rgb[2] = 0.0f;
+ }
+ else {
+ /* exceptional value, unclamped or nan,
+ * avoid uninitialized memory use */
+ r_rgb[0] = 1.0f;
+ r_rgb[1] = 0.0f;
+ r_rgb[2] = 1.0f;
+ }
+}
+
+
+/** Ensure #MeshRenderData.vert_weight_color */
+static void mesh_render_data_ensure_vert_weight_color(MeshRenderData *rdata, const int defgroup)
+{
+ float (*vweight)[3] = rdata->vert_weight_color;
+ if (vweight == NULL) {
+ if (defgroup == -1) {
+ goto fallback;
+ }
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
+ if (cd_dvert_offset == -1) {
+ goto fallback;
+ }
+
+ BMIter viter;
+ BMVert *eve;
+ int i;
+
+ vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
+ BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
+ const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ float weight = defvert_find_weight(dvert, defgroup);
+ if (U.flag & USER_CUSTOM_RANGE) {
+ do_colorband(&U.coba_weight, weight, vweight[i]);
+ }
+ else {
+ rgb_from_weight(vweight[i], weight);
+ }
+ }
+ }
+ else {
+ if (rdata->dvert == NULL) {
+ goto fallback;
+ }
+
+ vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
+ for (int i = 0; i < rdata->vert_len; i++) {
+ float weight = defvert_find_weight(&rdata->dvert[i], defgroup);
+ if (U.flag & USER_CUSTOM_RANGE) {
+ do_colorband(&U.coba_weight, weight, vweight[i]);
+ }
+ else {
+ rgb_from_weight(vweight[i], weight);
+ }
+ }
+ }
+ }
+ return;
+
+fallback:
+ vweight = rdata->vert_weight_color = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__);
+
+ for (int i = 0; i < rdata->vert_len; i++) {
+ vweight[i][2] = 0.5f;
+ }
+}
+
+/** Ensure #MeshRenderData.edge_select_bool */
+static void mesh_render_data_ensure_edge_select_bool(MeshRenderData *rdata, bool use_wire)
+{
+ bool *edge_select_bool = rdata->edge_select_bool;
+ if (edge_select_bool == NULL) {
+ edge_select_bool = rdata->edge_select_bool =
+ MEM_callocN(sizeof(*edge_select_bool) * rdata->edge_len, __func__);
+
+ for (int i = 0; i < rdata->poly_len; i++) {
+ MPoly *poly = &rdata->mpoly[i];
+
+ if (poly->flag & ME_FACE_SEL) {
+ for (int j = 0; j < poly->totloop; j++) {
+ MLoop *loop = &rdata->mloop[poly->loopstart + j];
+ if (use_wire) {
+ edge_select_bool[loop->e] = true;
+ }
+ else {
+ /* Not totally correct, will cause problems for edges with 3x faces. */
+ edge_select_bool[loop->e] = !edge_select_bool[loop->e];
+ }
+ }
+ }
+ }
+ }
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Internal Cache Generation
+ * \{ */
+
+static bool mesh_render_data_pnors_pcenter_select_get(
+ MeshRenderData *rdata, const int poly,
+ float r_pnors[3], float r_center[3], bool *r_selected)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ if (rdata->edit_bmesh) {
+ const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, poly);
+ if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+ BM_face_calc_center_mean(efa, r_center);
+ BM_face_calc_normal(efa, r_pnors);
+ *r_selected = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? true : false;
+ }
+ else {
+ MVert *mvert = rdata->mvert;
+ const MPoly *mpoly = rdata->mpoly + poly;
+ const MLoop *mloop = rdata->mloop + mpoly->loopstart;
+
+ BKE_mesh_calc_poly_center(mpoly, mloop, mvert, r_center);
+ BKE_mesh_calc_poly_normal(mpoly, mloop, mvert, r_pnors);
+
+ *r_selected = false; /* No selection if not in edit mode */
+ }
+
+ return true;
+}
+
+static bool mesh_render_data_edge_vcos_manifold_pnors(
+ MeshRenderData *rdata, const int edge_index,
+ float **r_vco1, float **r_vco2, float **r_pnor1, float **r_pnor2, bool *r_is_manifold)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMEdge *eed = BM_edge_at_index(bm, edge_index);
+ if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+ *r_vco1 = eed->v1->co;
+ *r_vco2 = eed->v2->co;
+ if (BM_edge_is_manifold(eed)) {
+ *r_pnor1 = eed->l->f->no;
+ *r_pnor2 = eed->l->radial_next->f->no;
+ *r_is_manifold = true;
+ }
+ else {
+ *r_is_manifold = false;
+ }
+ }
+ else {
+ MVert *mvert = rdata->mvert;
+ MEdge *medge = rdata->medge;
+ EdgeAdjacentPolys *eap = rdata->edges_adjacent_polys;
+ float (*pnors)[3] = rdata->poly_normals;
+
+ if (!eap) {
+ const MLoop *mloop = rdata->mloop;
+ const MPoly *mpoly = rdata->mpoly;
+ const int poly_len = rdata->poly_len;
+ const bool do_pnors = (pnors == NULL);
+
+ eap = rdata->edges_adjacent_polys = MEM_callocN(sizeof(*eap) * rdata->edge_len, __func__);
+ if (do_pnors) {
+ pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * poly_len, __func__);
+ }
+
+ for (int i = 0; i < poly_len; i++, mpoly++) {
+ if (do_pnors) {
+ BKE_mesh_calc_poly_normal(mpoly, mloop + mpoly->loopstart, mvert, pnors[i]);
+ }
+
+ const int loopend = mpoly->loopstart + mpoly->totloop;
+ for (int j = mpoly->loopstart; j < loopend; j++) {
+ const int edge_idx = mloop[j].e;
+ if (eap[edge_idx].count < 2) {
+ eap[edge_idx].face_index[eap[edge_idx].count] = i;
+ }
+ eap[edge_idx].count++;
+ }
+ }
+ }
+ BLI_assert(eap && pnors);
+
+ *r_vco1 = mvert[medge[edge_index].v1].co;
+ *r_vco2 = mvert[medge[edge_index].v2].co;
+ if (eap[edge_index].count == 2) {
+ *r_pnor1 = pnors[eap[edge_index].face_index[0]];
+ *r_pnor2 = pnors[eap[edge_index].face_index[1]];
+ *r_is_manifold = true;
+ }
+ else {
+ *r_is_manifold = false;
+ }
+ }
+
+ return true;
+}
+
+static void mesh_render_data_looptri_uvs_get(
+ MeshRenderData *rdata, const int tri_idx, const int uv_layer,
+ float *(*r_vert_uvs)[3])
+{
+ if (rdata->edit_bmesh) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
+ (*r_vert_uvs)[0] = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(bm_looptri[0], rdata->cd.offset.uv[uv_layer]))->uv;
+ (*r_vert_uvs)[1] = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(bm_looptri[1], rdata->cd.offset.uv[uv_layer]))->uv;
+ (*r_vert_uvs)[2] = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(bm_looptri[2], rdata->cd.offset.uv[uv_layer]))->uv;
+ }
+ else {
+ const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
+ (*r_vert_uvs)[0] = rdata->cd.layers.uv[uv_layer][mlt->tri[0]].uv;
+ (*r_vert_uvs)[1] = rdata->cd.layers.uv[uv_layer][mlt->tri[1]].uv;
+ (*r_vert_uvs)[2] = rdata->cd.layers.uv[uv_layer][mlt->tri[2]].uv;
+ }
+}
+
+static void mesh_render_data_looptri_cols_get(
+ MeshRenderData *rdata, const int tri_idx, const int vcol_layer,
+ unsigned char *(*r_vert_cols)[3])
+{
+ if (rdata->edit_bmesh) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
+ (*r_vert_cols)[0] = &((MLoopCol *)BM_ELEM_CD_GET_VOID_P(bm_looptri[0], rdata->cd.offset.vcol[vcol_layer]))->r;
+ (*r_vert_cols)[1] = &((MLoopCol *)BM_ELEM_CD_GET_VOID_P(bm_looptri[1], rdata->cd.offset.vcol[vcol_layer]))->r;
+ (*r_vert_cols)[2] = &((MLoopCol *)BM_ELEM_CD_GET_VOID_P(bm_looptri[2], rdata->cd.offset.vcol[vcol_layer]))->r;
+ }
+ else {
+ const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
+ (*r_vert_cols)[0] = &rdata->cd.layers.vcol[vcol_layer][mlt->tri[0]].r;
+ (*r_vert_cols)[1] = &rdata->cd.layers.vcol[vcol_layer][mlt->tri[1]].r;
+ (*r_vert_cols)[2] = &rdata->cd.layers.vcol[vcol_layer][mlt->tri[2]].r;
+ }
+}
+
+static void mesh_render_data_looptri_tans_get(
+ MeshRenderData *rdata, const int tri_idx, const int tangent_layer,
+ float *(*r_vert_tans)[3])
+{
+ if (rdata->edit_bmesh) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
+ (*r_vert_tans)[0] = rdata->cd.layers.tangent[tangent_layer][BM_elem_index_get(bm_looptri[0])];
+ (*r_vert_tans)[1] = rdata->cd.layers.tangent[tangent_layer][BM_elem_index_get(bm_looptri[1])];
+ (*r_vert_tans)[2] = rdata->cd.layers.tangent[tangent_layer][BM_elem_index_get(bm_looptri[2])];
+ }
+ else {
+ const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
+ (*r_vert_tans)[0] = rdata->cd.layers.tangent[tangent_layer][mlt->tri[0]];
+ (*r_vert_tans)[1] = rdata->cd.layers.tangent[tangent_layer][mlt->tri[1]];
+ (*r_vert_tans)[2] = rdata->cd.layers.tangent[tangent_layer][mlt->tri[2]];
+ }
+}
+
+static bool mesh_render_data_looptri_cos_nors_smooth_get(
+ MeshRenderData *rdata, const int tri_idx, const bool use_hide,
+ float *(*r_vert_cos)[3], short **r_tri_nor, short *(*r_vert_nors)[3], bool *r_is_smooth)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+ BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
+ BLI_assert(rdata->types & MR_DATATYPE_LOOP);
+ BLI_assert(rdata->types & MR_DATATYPE_POLY);
+
+ if (rdata->edit_bmesh) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
+
+ /* Assume 'use_hide' */
+ if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+
+ mesh_render_data_ensure_poly_normals_short(rdata);
+ mesh_render_data_ensure_vert_normals_short(rdata);
+
+ short (*pnors_short)[3] = rdata->poly_normals_short;
+ short (*vnors_short)[3] = rdata->vert_normals_short;
+
+ (*r_vert_cos)[0] = bm_looptri[0]->v->co;
+ (*r_vert_cos)[1] = bm_looptri[1]->v->co;
+ (*r_vert_cos)[2] = bm_looptri[2]->v->co;
+ *r_tri_nor = pnors_short[BM_elem_index_get(bm_looptri[0]->f)];
+ (*r_vert_nors)[0] = vnors_short[BM_elem_index_get(bm_looptri[0]->v)];
+ (*r_vert_nors)[1] = vnors_short[BM_elem_index_get(bm_looptri[1]->v)];
+ (*r_vert_nors)[2] = vnors_short[BM_elem_index_get(bm_looptri[2]->v)];
+
+ *r_is_smooth = BM_elem_flag_test_bool(bm_looptri[0]->f, BM_ELEM_SMOOTH);
+ }
+ else {
+ const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
+
+ if (use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE)) {
+ return false;
+ }
+
+ mesh_render_data_ensure_poly_normals_short(rdata);
+
+ short (*pnors_short)[3] = rdata->poly_normals_short;
+
+ (*r_vert_cos)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].co;
+ (*r_vert_cos)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].co;
+ (*r_vert_cos)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].co;
+ *r_tri_nor = pnors_short[mlt->poly];
+ (*r_vert_nors)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].no;
+ (*r_vert_nors)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].no;
+ (*r_vert_nors)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].no;
+
+ *r_is_smooth = (rdata->mpoly[mlt->poly].flag & ME_SMOOTH) != 0;
+ }
+ return true;
+}
+
+/* First 2 bytes are bit flags
+ * 3rd is for sharp edges
+ * 4rd is for creased edges */
+enum {
+ VFLAG_VERTEX_ACTIVE = 1 << 0,
+ VFLAG_VERTEX_SELECTED = 1 << 1,
+ VFLAG_FACE_ACTIVE = 1 << 2,
+ VFLAG_FACE_SELECTED = 1 << 3,
+};
+
+enum {
+ VFLAG_EDGE_EXISTS = 1 << 0,
+ VFLAG_EDGE_ACTIVE = 1 << 1,
+ VFLAG_EDGE_SELECTED = 1 << 2,
+ VFLAG_EDGE_SEAM = 1 << 3,
+ VFLAG_EDGE_SHARP = 1 << 4,
+ /* Beware to not go over 1 << 7
+ * (see gpu_shader_edit_mesh_overlay_geom.glsl) */
+};
+
+static unsigned char mesh_render_data_looptri_flag(MeshRenderData *rdata, const BMFace *efa)
+{
+ unsigned char fflag = 0;
+
+ if (efa == rdata->efa_act)
+ fflag |= VFLAG_FACE_ACTIVE;
+
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
+ fflag |= VFLAG_FACE_SELECTED;
+
+ return fflag;
+}
+
+static void mesh_render_data_edge_flag(
+ const MeshRenderData *rdata, const BMEdge *eed,
+ EdgeDrawAttr *eattr)
+{
+ eattr->e_flag |= VFLAG_EDGE_EXISTS;
+
+ if (eed == rdata->eed_act)
+ eattr->e_flag |= VFLAG_EDGE_ACTIVE;
+
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
+ eattr->e_flag |= VFLAG_EDGE_SELECTED;
+
+ if (BM_elem_flag_test(eed, BM_ELEM_SEAM))
+ eattr->e_flag |= VFLAG_EDGE_SEAM;
+
+ if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
+ eattr->e_flag |= VFLAG_EDGE_SHARP;
+
+ /* Use a byte for value range */
+ if (rdata->cd.offset.crease != -1) {
+ float crease = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.crease);
+ if (crease > 0) {
+ eattr->crease = (char)(crease * 255.0f);
+ }
+ }
+
+ /* Use a byte for value range */
+ if (rdata->cd.offset.bweight != -1) {
+ float bweight = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.bweight);
+ if (bweight > 0) {
+ eattr->bweight = (char)(bweight * 255.0f);
+ }
+ }
+}
+
+static unsigned char mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *eve)
+{
+
+ unsigned char vflag = 0;
+
+ /* Current vertex */
+ if (eve == rdata->eve_act)
+ vflag |= VFLAG_VERTEX_ACTIVE;
+
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
+ vflag |= VFLAG_VERTEX_SELECTED;
+
+ return vflag;
+}
+
+static void add_overlay_tri(
+ MeshRenderData *rdata, VertexBuffer *vbo_pos, VertexBuffer *vbo_nor, VertexBuffer *vbo_data,
+ const unsigned int pos_id, const unsigned int vnor_id, const unsigned int lnor_id, const unsigned int data_id,
+ const BMLoop **bm_looptri, const int base_vert_idx)
+{
+ unsigned char fflag;
+ unsigned char vflag;
+
+ if (vbo_pos) {
+ for (uint i = 0; i < 3; i++) {
+ const float *pos = bm_looptri[i]->v->co;
+ VertexBuffer_set_attrib(vbo_pos, pos_id, base_vert_idx + i, pos);
+ }
+ }
+
+ if (vbo_nor) {
+ /* TODO real loop normal */
+ PackedNormal lnor = convert_i10_v3(bm_looptri[0]->f->no);
+ for (uint i = 0; i < 3; i++) {
+ PackedNormal vnor = convert_i10_v3(bm_looptri[i]->v->no);
+ VertexBuffer_set_attrib(vbo_nor, vnor_id, base_vert_idx + i, &vnor);
+ VertexBuffer_set_attrib(vbo_nor, lnor_id, base_vert_idx + i, &lnor);
+ }
+ }
+
+ if (vbo_data) {
+ fflag = mesh_render_data_looptri_flag(rdata, bm_looptri[0]->f);
+ uint i_prev = 1, i = 2;
+ for (uint i_next = 0; i_next < 3; i_next++) {
+ vflag = mesh_render_data_vertex_flag(rdata, bm_looptri[i]->v);
+ EdgeDrawAttr eattr = {0};
+ if (bm_looptri[i_next] == bm_looptri[i_prev]->prev) {
+ mesh_render_data_edge_flag(rdata, bm_looptri[i_next]->e, &eattr);
+ }
+ eattr.v_flag = fflag | vflag;
+ VertexBuffer_set_attrib(vbo_data, data_id, base_vert_idx + i, &eattr);
+
+ i_prev = i;
+ i = i_next;
+ }
+ }
+}
+
+static void add_overlay_loose_edge(
+ MeshRenderData *rdata, VertexBuffer *vbo_pos, VertexBuffer *vbo_nor, VertexBuffer *vbo_data,
+ const unsigned int pos_id, const unsigned int vnor_id, const unsigned int data_id,
+ const BMEdge *eed, const int base_vert_idx)
+{
+ if (vbo_pos) {
+ for (int i = 0; i < 2; ++i) {
+ const float *pos = (&eed->v1)[i]->co;
+ VertexBuffer_set_attrib(vbo_pos, pos_id, base_vert_idx + i, pos);
+ }
+ }
+
+ if (vbo_nor) {
+ for (int i = 0; i < 2; ++i) {
+ PackedNormal vnor = convert_i10_v3((&eed->v1)[i]->no);
+ VertexBuffer_set_attrib(vbo_nor, vnor_id, base_vert_idx + i, &vnor);
+ }
+ }
+
+ if (vbo_data) {
+ EdgeDrawAttr eattr = {0};
+ mesh_render_data_edge_flag(rdata, eed, &eattr);
+ for (int i = 0; i < 2; ++i) {
+ eattr.v_flag = mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]);
+ VertexBuffer_set_attrib(vbo_data, data_id, base_vert_idx + i, &eattr);
+ }
+ }
+}
+
+static void add_overlay_loose_vert(
+ MeshRenderData *rdata, VertexBuffer *vbo_pos, VertexBuffer *vbo_nor, VertexBuffer *vbo_data,
+ const unsigned int pos_id, const unsigned int vnor_id, const unsigned int data_id,
+ const BMVert *eve, const int base_vert_idx)
+{
+ if (vbo_pos) {
+ const float *pos = eve->co;
+ VertexBuffer_set_attrib(vbo_pos, pos_id, base_vert_idx, pos);
+ }
+
+ if (vbo_nor) {
+ PackedNormal vnor = convert_i10_v3(eve->no);
+ VertexBuffer_set_attrib(vbo_nor, vnor_id, base_vert_idx, &vnor);
+ }
+
+ if (vbo_data) {
+ unsigned char vflag[4] = {0, 0, 0, 0};
+ vflag[0] = mesh_render_data_vertex_flag(rdata, eve);
+ VertexBuffer_set_attrib(vbo_data, data_id, base_vert_idx, vflag);
+ }
+}
+
+/** \} */
+
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Mesh Batch Cache
+ * \{ */
+
+typedef struct MeshBatchCache {
+ VertexBuffer *pos_in_order;
+ VertexBuffer *nor_in_order;
+ ElementList *edges_in_order;
+ ElementList *triangles_in_order;
+ ElementList *overlay_triangles_vpaint;
+
+ Batch *all_verts;
+ Batch *all_edges;
+ Batch *all_triangles;
+
+ VertexBuffer *pos_with_normals;
+ VertexBuffer *pos_with_normals_visible_only; /* for paint modes with vert/face hide support. */
+ VertexBuffer *tri_aligned_weights;
+ VertexBuffer *tri_aligned_vert_colors;
+ VertexBuffer *tri_aligned_select_id;
+ VertexBuffer *tri_aligned_uv; /* Active UV layer (mloopuv) */
+ VertexBuffer *edge_pos_with_select_bool;
+ VertexBuffer *pos_with_select_bool;
+ Batch *triangles_with_normals;
+
+ /* Skip hidden (depending on paint select mode),
+ * 'pos_with_normals' or 'pos_with_normals_visible_only'. */
+ Batch *triangles_with_weights;
+ Batch *triangles_with_vert_colors;
+ /* Always skip hidden */
+ Batch *triangles_with_select_id;
+
+ Batch *points_with_normals;
+ Batch *fancy_edges; /* owns its vertex buffer (not shared) */
+
+ /* Maybe have shaded_triangles_data split into pos_nor and uv_tangent
+ * to minimise data transfer for skinned mesh. */
+ VertexFormat shaded_triangles_format;
+ VertexBuffer *shaded_triangles_data;
+ ElementList **shaded_triangles_in_order;
+ Batch **shaded_triangles;
+
+ /* Texture Paint.*/
+ /* per-texture batch */
+ Batch **texpaint_triangles;
+ Batch *texpaint_triangles_single;
+
+ /* Edit Cage Mesh buffers */
+ VertexBuffer *ed_tri_pos;
+ VertexBuffer *ed_tri_nor; /* LoopNor, VertNor */
+ VertexBuffer *ed_tri_data;
+
+ VertexBuffer *ed_ledge_pos;
+ VertexBuffer *ed_ledge_nor; /* VertNor */
+ VertexBuffer *ed_ledge_data;
+
+ VertexBuffer *ed_lvert_pos;
+ VertexBuffer *ed_lvert_nor; /* VertNor */
+ VertexBuffer *ed_lvert_data;
+
+ VertexBuffer *ed_fcenter_pos;
+ VertexBuffer *ed_fcenter_nor;
+
+ Batch *overlay_triangles;
+ Batch *overlay_triangles_nor; /* PRIM_POINTS */
+ Batch *overlay_loose_edges;
+ Batch *overlay_loose_edges_nor; /* PRIM_POINTS */
+ Batch *overlay_loose_verts;
+ Batch *overlay_facedots;
+
+ Batch *overlay_weight_faces;
+ Batch *overlay_weight_verts;
+ Batch *overlay_paint_edges;
+
+ /* settings to determine if cache is invalid */
+ bool is_dirty;
+ bool is_paint_dirty;
+ int edge_len;
+ int tri_len;
+ int poly_len;
+ int vert_len;
+ int mat_len;
+ bool is_editmode;
+} MeshBatchCache;
+
+/* Batch cache management. */
+
+static bool mesh_batch_cache_valid(Mesh *me)
+{
+ MeshBatchCache *cache = me->batch_cache;
+
+ if (cache == NULL) {
+ return false;
+ }
+
+ /* XXX find another place for this */
+ if (cache->mat_len != mesh_render_mat_len_get(me)) {
+ cache->is_dirty = true;
+ }
+
+ if (cache->is_editmode != (me->edit_btmesh != NULL)) {
+ return false;
+ }
+
+ if (cache->is_paint_dirty) {
+ return false;
+ }
+
+ if (cache->is_dirty == false) {
+ return true;
+ }
+ else {
+ if (cache->is_editmode) {
+ return false;
+ }
+ else if ((cache->vert_len != mesh_render_verts_len_get(me)) ||
+ (cache->edge_len != mesh_render_edges_len_get(me)) ||
+ (cache->tri_len != mesh_render_looptri_len_get(me)) ||
+ (cache->poly_len != mesh_render_polys_len_get(me)) ||
+ (cache->mat_len != mesh_render_mat_len_get(me)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void mesh_batch_cache_init(Mesh *me)
+{
+ MeshBatchCache *cache = me->batch_cache;
+
+ if (!cache) {
+ cache = me->batch_cache = MEM_callocN(sizeof(*cache), __func__);
+ }
+ else {
+ memset(cache, 0, sizeof(*cache));
+ }
+
+ cache->is_editmode = me->edit_btmesh != NULL;
+
+ if (cache->is_editmode == false) {
+ cache->edge_len = mesh_render_edges_len_get(me);
+ cache->tri_len = mesh_render_looptri_len_get(me);
+ cache->poly_len = mesh_render_polys_len_get(me);
+ cache->vert_len = mesh_render_verts_len_get(me);
+ }
+
+ cache->mat_len = mesh_render_mat_len_get(me);
+
+ cache->is_dirty = false;
+ cache->is_paint_dirty = false;
+}
+
+static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
+{
+ if (!mesh_batch_cache_valid(me)) {
+ mesh_batch_cache_clear(me);
+ mesh_batch_cache_init(me);
+ }
+ return me->batch_cache;
+}
+
+void DRW_mesh_batch_cache_dirty(Mesh *me, int mode)
+{
+ MeshBatchCache *cache = me->batch_cache;
+ if (cache == NULL) {
+ return;
+ }
+ switch (mode) {
+ case BKE_MESH_BATCH_DIRTY_ALL:
+ cache->is_dirty = true;
+ break;
+ case BKE_MESH_BATCH_DIRTY_SELECT:
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_tri_data);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_ledge_data);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_lvert_data);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_fcenter_nor); /* Contains select flag */
+ BATCH_DISCARD_SAFE(cache->overlay_triangles);
+ BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
+ BATCH_DISCARD_SAFE(cache->overlay_loose_edges);
+
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
+ break;
+ case BKE_MESH_BATCH_DIRTY_PAINT:
+ cache->is_paint_dirty = true;
+ break;
+ default:
+ BLI_assert(0);
+ }
+}
+
+static void mesh_batch_cache_clear(Mesh *me)
+{
+ MeshBatchCache *cache = me->batch_cache;
+ if (!cache) {
+ return;
+ }
+
+ BATCH_DISCARD_SAFE(cache->all_verts);
+ BATCH_DISCARD_SAFE(cache->all_edges);
+ BATCH_DISCARD_SAFE(cache->all_triangles);
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos_in_order);
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_select_bool);
+ ELEMENTLIST_DISCARD_SAFE(cache->edges_in_order);
+ ELEMENTLIST_DISCARD_SAFE(cache->triangles_in_order);
+ ELEMENTLIST_DISCARD_SAFE(cache->overlay_triangles_vpaint);
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_tri_pos);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_tri_nor);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_tri_data);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_ledge_pos);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_ledge_nor);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_ledge_data);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_lvert_pos);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_lvert_nor);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_lvert_data);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_fcenter_pos);
+ VERTEXBUFFER_DISCARD_SAFE(cache->ed_fcenter_nor);
+ BATCH_DISCARD_SAFE(cache->overlay_triangles);
+ BATCH_DISCARD_SAFE(cache->overlay_triangles_nor);
+ BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
+ BATCH_DISCARD_SAFE(cache->overlay_loose_edges);
+ BATCH_DISCARD_SAFE(cache->overlay_loose_edges_nor);
+
+ BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
+ BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_paint_edges);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
+
+ BATCH_DISCARD_SAFE(cache->triangles_with_normals);
+ BATCH_DISCARD_SAFE(cache->points_with_normals);
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_normals);
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_normals_visible_only);
+ VERTEXBUFFER_DISCARD_SAFE(cache->tri_aligned_vert_colors);
+ VERTEXBUFFER_DISCARD_SAFE(cache->tri_aligned_weights);
+ BATCH_DISCARD_SAFE(cache->triangles_with_weights);
+ BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
+ VERTEXBUFFER_DISCARD_SAFE(cache->tri_aligned_select_id);
+ VERTEXBUFFER_DISCARD_SAFE(cache->tri_aligned_uv);
+ BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
+
+ BATCH_DISCARD_ALL_SAFE(cache->fancy_edges);
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->shaded_triangles_data);
+ if (cache->shaded_triangles_in_order) {
+ for (int i = 0; i < cache->mat_len; ++i) {
+ ELEMENTLIST_DISCARD_SAFE(cache->shaded_triangles_in_order[i]);
+ }
+ }
+ if (cache->shaded_triangles) {
+ for (int i = 0; i < cache->mat_len; ++i) {
+ BATCH_DISCARD_SAFE(cache->shaded_triangles[i]);
+ }
+ }
+
+ MEM_SAFE_FREE(cache->shaded_triangles_in_order);
+ MEM_SAFE_FREE(cache->shaded_triangles);
+
+ if (cache->texpaint_triangles) {
+ for (int i = 0; i < cache->mat_len; ++i) {
+ BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]);
+ }
+ }
+ MEM_SAFE_FREE(cache->texpaint_triangles);
+
+ BATCH_DISCARD_SAFE(cache->texpaint_triangles_single);
+
+}
+
+void DRW_mesh_batch_cache_free(Mesh *me)
+{
+ mesh_batch_cache_clear(me);
+ MEM_SAFE_FREE(me->batch_cache);
+}
+
+/* Batch cache usage. */
+
+static VertexBuffer *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+#define USE_COMP_MESH_DATA
+
+ if (cache->shaded_triangles_data == NULL) {
+ unsigned int vidx = 0;
+ const char *attrib_name;
+
+ if (rdata->cd.layers.uv_len + rdata->cd.layers.vcol_len == 0) {
+ return NULL;
+ }
+
+ VertexFormat *format = &cache->shaded_triangles_format;
+
+ VertexFormat_clear(format);
+
+ /* initialize vertex format */
+ unsigned int *uv_id = MEM_mallocN(sizeof(*uv_id) * rdata->cd.layers.uv_len, "UV attrib format");
+ unsigned int *vcol_id = MEM_mallocN(sizeof(*vcol_id) * rdata->cd.layers.vcol_len, "Vcol attrib format");
+ unsigned int *tangent_id = MEM_mallocN(sizeof(*tangent_id) * rdata->cd.layers.uv_len, "Tangent attrib format");
+
+ for (int i = 0; i < rdata->cd.layers.uv_len; i++) {
+ /* UV */
+ attrib_name = mesh_render_data_uv_layer_uuid_get(rdata, i);
+#if defined(USE_COMP_MESH_DATA) && 0 /* these are clamped. Maybe use them as an option in the future */
+ uv_id[i] = VertexFormat_add_attrib(format, attrib_name, COMP_I16, 2, NORMALIZE_INT_TO_FLOAT);
+#else
+ uv_id[i] = VertexFormat_add_attrib(format, attrib_name, COMP_F32, 2, KEEP_FLOAT);
+#endif
+
+ /* Auto Name */
+ attrib_name = mesh_render_data_uv_auto_layer_uuid_get(rdata, i);
+ VertexFormat_add_alias(format, attrib_name);
+
+ if (i == rdata->cd.layers.uv_active) {
+ VertexFormat_add_alias(format, "u");
+ }
+
+ /* Tangent */
+ attrib_name = mesh_render_data_tangent_layer_uuid_get(rdata, i);
+ /* WATCH IT : only specifying 3 component instead of 4 (4th is sign).
+ * That may cause some problem but I could not make it to fail (fclem) */
+#ifdef USE_COMP_MESH_DATA
+ /* Tangents need more precision than 10_10_10 */
+ tangent_id[i] = VertexFormat_add_attrib(format, attrib_name, COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
+#else
+ tangent_id[i] = VertexFormat_add_attrib(format, attrib_name, COMP_F32, 3, KEEP_FLOAT);
+#endif
+
+ if (i == rdata->cd.layers.uv_active) {
+ VertexFormat_add_alias(format, "t");
+ }
+ }
+
+ for (int i = 0; i < rdata->cd.layers.vcol_len; i++) {
+ attrib_name = mesh_render_data_vcol_layer_uuid_get(rdata, i);
+ vcol_id[i] = VertexFormat_add_attrib(format, attrib_name, COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ /* Auto layer */
+ if (rdata->cd.layers.auto_vcol[i]) {
+ attrib_name = mesh_render_data_vcol_auto_layer_uuid_get(rdata, i);
+ VertexFormat_add_alias(format, attrib_name);
+ }
+
+ if (i == rdata->cd.layers.vcol_active) {
+ VertexFormat_add_alias(format, "c");
+ }
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->shaded_triangles_data = VertexBuffer_create_with_format(format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ /* TODO deduplicate all verts and make use of ElementList in
+ * mesh_batch_cache_get_triangles_in_order_split_by_material. */
+ for (int i = 0; i < tri_len; i++) {
+ float *tri_uvs[3], *tri_tans[3];
+ unsigned char *tri_cols[3];
+
+ if (rdata->edit_bmesh == NULL ||
+ BM_elem_flag_test((rdata->edit_bmesh->looptris[i])[0]->f, BM_ELEM_HIDDEN) == 0)
+ {
+ /* UVs & TANGENTs */
+ for (int j = 0; j < rdata->cd.layers.uv_len; j++) {
+ /* UVs */
+ mesh_render_data_looptri_uvs_get(rdata, i, j, &tri_uvs);
+#if defined(USE_COMP_MESH_DATA) && 0 /* these are clamped. Maybe use them as an option in the future */
+ short s_uvs[3][2];
+ normal_float_to_short_v2(s_uvs[0], tri_uvs[0]);
+ normal_float_to_short_v2(s_uvs[1], tri_uvs[1]);
+ normal_float_to_short_v2(s_uvs[2], tri_uvs[2]);
+#else
+ float **s_uvs = tri_uvs;
+#endif
+ VertexBuffer_set_attrib(vbo, uv_id[j], vidx + 0, s_uvs[0]);
+ VertexBuffer_set_attrib(vbo, uv_id[j], vidx + 1, s_uvs[1]);
+ VertexBuffer_set_attrib(vbo, uv_id[j], vidx + 2, s_uvs[2]);
+
+ /* Tangent */
+ mesh_render_data_looptri_tans_get(rdata, i, j, &tri_tans);
+#ifdef USE_COMP_MESH_DATA
+ /* Tangents need more precision than 10_10_10 */
+ short s_tan[3][3];
+ normal_float_to_short_v3(s_tan[0], tri_tans[0]);
+ normal_float_to_short_v3(s_tan[1], tri_tans[1]);
+ normal_float_to_short_v3(s_tan[2], tri_tans[2]);
+#else
+ float **s_tan = tri_tans;
+#endif
+ VertexBuffer_set_attrib(vbo, tangent_id[j], vidx + 0, s_tan[0]);
+ VertexBuffer_set_attrib(vbo, tangent_id[j], vidx + 1, s_tan[1]);
+ VertexBuffer_set_attrib(vbo, tangent_id[j], vidx + 2, s_tan[2]);
+ }
+
+ /* VCOLs */
+ for (int j = 0; j < rdata->cd.layers.vcol_len; j++) {
+ mesh_render_data_looptri_cols_get(rdata, i, j, &tri_cols);
+ VertexBuffer_set_attrib(vbo, vcol_id[j], vidx + 0, tri_cols[0]);
+ VertexBuffer_set_attrib(vbo, vcol_id[j], vidx + 1, tri_cols[1]);
+ VertexBuffer_set_attrib(vbo, vcol_id[j], vidx + 2, tri_cols[2]);
+ }
+
+ vidx += 3;
+ }
+ }
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+
+ MEM_freeN(uv_id);
+ MEM_freeN(vcol_id);
+ MEM_freeN(tangent_id);
+ }
+
+#undef USE_COMP_MESH_DATA
+
+ return cache->shaded_triangles_data;
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_uv_active(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPUV));
+ BLI_assert(rdata->edit_bmesh == NULL);
+
+ if (cache->tri_aligned_uv == NULL) {
+ unsigned int vidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint uv; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.uv = VertexFormat_add_attrib(&format, "uv", COMP_F32, 2, KEEP_FLOAT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->tri_aligned_uv = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ const MLoopUV *mloopuv = rdata->mloopuv;
+
+ for (int i = 0; i < tri_len; i++) {
+ const MLoopTri *mlt = &rdata->mlooptri[i];
+ VertexBuffer_set_attrib(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[0]].uv);
+ VertexBuffer_set_attrib(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[1]].uv);
+ VertexBuffer_set_attrib(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[2]].uv);
+ }
+ vbo_len_used = vidx;
+
+ BLI_assert(vbo_len_capacity == vbo_len_used);
+ }
+
+ return cache->tri_aligned_uv;
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_pos_and_normals_ex(
+ MeshRenderData *rdata, const bool use_hide,
+ VertexBuffer **r_vbo)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ if (*r_vbo == NULL) {
+ unsigned int vidx = 0, nidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.nor = VertexFormat_add_attrib(&format, "nor", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = *r_vbo = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ for (int i = 0; i < tri_len; i++) {
+ float *tri_vert_cos[3];
+ short *tri_nor, *tri_vert_nors[3];
+ bool is_smooth;
+
+ if (mesh_render_data_looptri_cos_nors_smooth_get(
+ rdata, i, use_hide, &tri_vert_cos, &tri_nor, &tri_vert_nors, &is_smooth))
+ {
+ if (is_smooth) {
+ PackedNormal snor_pack[3] = {
+ convert_i10_s3(tri_vert_nors[0]),
+ convert_i10_s3(tri_vert_nors[1]),
+ convert_i10_s3(tri_vert_nors[2])
+ };
+ PackedNormal *snor[3] = { &snor_pack[0], &snor_pack[1], &snor_pack[2] };
+
+ VertexBuffer_set_attrib(vbo, attr_id.nor, nidx++, snor[0]);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, nidx++, snor[1]);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, nidx++, snor[2]);
+ }
+ else {
+ PackedNormal snor_pack = convert_i10_s3(tri_nor);
+ PackedNormal *snor = &snor_pack;
+
+ VertexBuffer_set_attrib(vbo, attr_id.nor, nidx++, snor);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, nidx++, snor);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, nidx++, snor);
+ }
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, tri_vert_cos[0]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, tri_vert_cos[1]);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, tri_vert_cos[2]);
+ }
+ }
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+ return *r_vbo;
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_pos_and_normals(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ return mesh_batch_cache_get_tri_pos_and_normals_ex(
+ rdata, false,
+ &cache->pos_with_normals);
+}
+static VertexBuffer *mesh_batch_cache_get_tri_pos_and_normals_visible_only(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ return mesh_batch_cache_get_tri_pos_and_normals_ex(
+ rdata, true,
+ &cache->pos_with_normals_visible_only);
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_weights(
+ MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide, int defgroup)
+{
+ BLI_assert(
+ rdata->types &
+ (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT));
+
+ if (cache->tri_aligned_weights == NULL) {
+ unsigned int cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = VertexFormat_add_attrib(&format, "color", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->tri_aligned_weights = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ mesh_render_data_ensure_vert_weight_color(rdata, defgroup);
+ const float (*vert_weight_color)[3] = rdata->vert_weight_color;
+
+ if (rdata->edit_bmesh) {
+ for (int i = 0; i < tri_len; i++) {
+ const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ /* Assume 'use_hide' */
+ if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ const int v_index = BM_elem_index_get(ltri[tri_corner]->v);
+ VertexBuffer_set_attrib(vbo, attr_id.col, cidx++, vert_weight_color[v_index]);
+ }
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < tri_len; i++) {
+ const MLoopTri *mlt = &rdata->mlooptri[i];
+ if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) {
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ const uint v_index = rdata->mloop[mlt->tri[tri_corner]].v;
+ VertexBuffer_set_attrib(vbo, attr_id.col, cidx++, vert_weight_color[v_index]);
+ }
+ }
+ }
+ }
+ vbo_len_used = cidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->tri_aligned_weights;
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_vert_colors(
+ MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
+{
+ BLI_assert(
+ rdata->types &
+ (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL));
+
+ if (cache->tri_aligned_vert_colors == NULL) {
+ unsigned int cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = VertexFormat_add_attrib(&format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->tri_aligned_vert_colors = VertexBuffer_create_with_format(&format);
+
+ const uint vbo_len_capacity = tri_len * 3;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ mesh_render_data_ensure_vert_color(rdata);
+ const char (*vert_color)[3] = rdata->vert_color;
+
+ if (rdata->edit_bmesh) {
+ for (int i = 0; i < tri_len; i++) {
+ const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ /* Assume 'use_hide' */
+ if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ const int l_index = BM_elem_index_get(ltri[tri_corner]);
+ VertexBuffer_set_attrib(vbo, attr_id.col, cidx++, vert_color[l_index]);
+ }
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < tri_len; i++) {
+ const MLoopTri *mlt = &rdata->mlooptri[i];
+ if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) {
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ const uint l_index = mlt->tri[tri_corner];
+ VertexBuffer_set_attrib(vbo, attr_id.col, cidx++, vert_color[l_index]);
+ }
+ }
+ }
+ }
+ const uint vbo_len_used = cidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->tri_aligned_vert_colors;
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_select_id(
+ MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
+{
+ BLI_assert(
+ rdata->types &
+ (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ if (cache->tri_aligned_select_id == NULL) {
+ unsigned int cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = VertexFormat_add_attrib(&format, "color", COMP_I32, 1, KEEP_INT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->tri_aligned_select_id = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ if (rdata->edit_bmesh) {
+ for (int i = 0; i < tri_len; i++) {
+ const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ /* Assume 'use_hide' */
+ if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
+ const int poly_index = BM_elem_index_get(ltri[0]->f);
+ int select_id;
+ GPU_select_index_get(poly_index + 1, &select_id);
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ VertexBuffer_set_attrib(vbo, attr_id.col, cidx++, &select_id);
+ }
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < tri_len; i++) {
+ const MLoopTri *mlt = &rdata->mlooptri[i];
+ const int poly_index = mlt->poly;
+ if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) {
+ int select_id;
+ GPU_select_index_get(poly_index + 1, &select_id);
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ VertexBuffer_set_attrib(vbo, attr_id.col, cidx++, &select_id);
+ }
+ }
+ }
+ }
+ vbo_len_used = cidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->tri_aligned_select_id;
+}
+
+static VertexBuffer *mesh_batch_cache_get_vert_pos_and_nor_in_order(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->pos_in_order == NULL) {
+ static VertexFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.nor = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+
+ VertexBuffer *vbo = cache->pos_in_order = VertexBuffer_create_with_format(&format);
+ const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMVert *eve;
+ uint i;
+
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ static short no_short[3];
+ normal_float_to_short_v3(no_short, eve->no);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i, eve->co);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, i, no_short);
+ }
+ BLI_assert(i == vbo_len_capacity);
+ }
+ else {
+ for (int i = 0; i < vbo_len_capacity; ++i) {
+ VertexBuffer_set_attrib(vbo, attr_id.pos, i, rdata->mvert[i].co);
+ VertexBuffer_set_attrib(vbo, attr_id.nor, i, rdata->mvert[i].no);
+ }
+ }
+ }
+
+ return cache->pos_in_order;
+}
+
+static VertexFormat *edit_mesh_overlay_pos_format(unsigned int *r_pos_id)
+{
+ static VertexFormat format_pos = { 0 };
+ static unsigned pos_id;
+ if (format_pos.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format_pos, "pos", COMP_F32, 3, KEEP_FLOAT);
+ }
+ *r_pos_id = pos_id;
+ return &format_pos;
+}
+
+static VertexFormat *edit_mesh_overlay_nor_format(unsigned int *r_vnor_id, unsigned int *r_lnor_id)
+{
+ static VertexFormat format_nor = { 0 };
+ static VertexFormat format_nor_loop = { 0 };
+ static unsigned vnor_id, vnor_loop_id, lnor_id;
+ if (format_nor.attrib_ct == 0) {
+ vnor_id = VertexFormat_add_attrib(&format_nor, "vnor", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ vnor_loop_id = VertexFormat_add_attrib(&format_nor_loop, "vnor", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ lnor_id = VertexFormat_add_attrib(&format_nor_loop, "lnor", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+ if (r_lnor_id) {
+ *r_vnor_id = vnor_loop_id;
+ *r_lnor_id = lnor_id;
+ return &format_nor_loop;
+ }
+ else {
+ *r_vnor_id = vnor_id;
+ return &format_nor;
+ }
+}
+
+static VertexFormat *edit_mesh_overlay_data_format(unsigned int *r_data_id)
+{
+ static VertexFormat format_flag = { 0 };
+ static unsigned data_id;
+ if (format_flag.attrib_ct == 0) {
+ data_id = VertexFormat_add_attrib(&format_flag, "data", COMP_U8, 4, KEEP_INT);
+ }
+ *r_data_id = data_id;
+ return &format_flag;
+}
+
+static void mesh_batch_cache_create_overlay_tri_buffers(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+
+ /* Positions */
+ VertexBuffer *vbo_pos = NULL;
+ static struct { uint pos, vnor, lnor, data; } attr_id;
+ if (cache->ed_tri_pos == NULL) {
+ vbo_pos = cache->ed_tri_pos =
+ VertexBuffer_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos));
+ VertexBuffer_allocate_data(vbo_pos, vbo_len_capacity);
+ }
+
+ /* Normals */
+ VertexBuffer *vbo_nor = NULL;
+ if (cache->ed_tri_nor == NULL) {
+ vbo_nor = cache->ed_tri_nor =
+ VertexBuffer_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, &attr_id.lnor));
+ VertexBuffer_allocate_data(vbo_nor, vbo_len_capacity);
+ }
+
+ /* Data */
+ VertexBuffer *vbo_data = NULL;
+ if (cache->ed_tri_data == NULL) {
+ vbo_data = cache->ed_tri_data =
+ VertexBuffer_create_with_format(edit_mesh_overlay_data_format(&attr_id.data));
+ VertexBuffer_allocate_data(vbo_data, vbo_len_capacity);
+ }
+
+ for (int i = 0; i < tri_len; i++) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ if (!BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
+ add_overlay_tri(
+ rdata, vbo_pos, vbo_nor, vbo_data,
+ attr_id.pos, attr_id.vnor, attr_id.lnor, attr_id.data,
+ bm_looptri, vbo_len_used);
+
+ vbo_len_used += 3;
+ }
+ }
+
+ /* Finish */
+ if (vbo_len_used != vbo_len_capacity) {
+ if (vbo_pos != NULL) {
+ VertexBuffer_resize_data(vbo_pos, vbo_len_used);
+ }
+ if (vbo_nor != NULL) {
+ VertexBuffer_resize_data(vbo_nor, vbo_len_used);
+ }
+ if (vbo_data != NULL) {
+ VertexBuffer_resize_data(vbo_data, vbo_len_used);
+ }
+ }
+}
+
+static void mesh_batch_cache_create_overlay_ledge_buffers(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
+
+ const int ledge_len = mesh_render_data_loose_edges_len_get(rdata);
+
+ const int vbo_len_capacity = ledge_len * 2;
+ int vbo_len_used = 0;
+
+ /* Positions */
+ VertexBuffer *vbo_pos = NULL;
+ static struct { uint pos, vnor, data; } attr_id;
+ if (cache->ed_ledge_pos == NULL) {
+ vbo_pos = cache->ed_ledge_pos =
+ VertexBuffer_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos));
+ VertexBuffer_allocate_data(vbo_pos, vbo_len_capacity);
+ }
+
+ /* Normals */
+ VertexBuffer *vbo_nor = NULL;
+ if (cache->ed_ledge_nor == NULL) {
+ vbo_nor = cache->ed_ledge_nor =
+ VertexBuffer_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, NULL));
+ VertexBuffer_allocate_data(vbo_nor, vbo_len_capacity);
+ }
+
+ /* Data */
+ VertexBuffer *vbo_data = NULL;
+ if (cache->ed_ledge_data == NULL) {
+ vbo_data = cache->ed_ledge_data =
+ VertexBuffer_create_with_format(edit_mesh_overlay_data_format(&attr_id.data));
+ VertexBuffer_allocate_data(vbo_data, vbo_len_capacity);
+ }
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ for (uint i = 0; i < ledge_len; i++) {
+ const BMEdge *eed = BM_edge_at_index(bm, rdata->loose_edges[i]);
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ add_overlay_loose_edge(
+ rdata, vbo_pos, vbo_nor, vbo_data,
+ attr_id.pos, attr_id.vnor, attr_id.data,
+ eed, vbo_len_used);
+ vbo_len_used += 2;
+ }
+ }
+ }
+
+ /* Finish */
+ if (vbo_len_used != vbo_len_capacity) {
+ if (vbo_pos != NULL) {
+ VertexBuffer_resize_data(vbo_pos, vbo_len_used);
+ }
+ if (vbo_nor != NULL) {
+ VertexBuffer_resize_data(vbo_nor, vbo_len_used);
+ }
+ if (vbo_data != NULL) {
+ VertexBuffer_resize_data(vbo_data, vbo_len_used);
+ }
+ }
+}
+
+static void mesh_batch_cache_create_overlay_lvert_buffers(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
+
+ BMesh *bm = rdata->edit_bmesh->bm;
+ const int lvert_len = mesh_render_data_loose_verts_len_get(rdata);
+
+ const int vbo_len_capacity = lvert_len;
+ int vbo_len_used = 0;
+
+ static struct { uint pos, vnor, data; } attr_id;
+
+ /* Positions */
+ VertexBuffer *vbo_pos = NULL;
+ if (cache->ed_lvert_pos == NULL) {
+ vbo_pos = cache->ed_lvert_pos =
+ VertexBuffer_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos));
+ VertexBuffer_allocate_data(vbo_pos, vbo_len_capacity);
+ }
+
+ /* Normals */
+ VertexBuffer *vbo_nor = NULL;
+ if (cache->ed_lvert_nor == NULL) {
+ vbo_nor = cache->ed_lvert_nor =
+ VertexBuffer_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, NULL));
+ VertexBuffer_allocate_data(vbo_nor, vbo_len_capacity);
+ }
+
+ /* Data */
+ VertexBuffer *vbo_data = NULL;
+ if (cache->ed_lvert_data == NULL) {
+ vbo_data = cache->ed_lvert_data =
+ VertexBuffer_create_with_format(edit_mesh_overlay_data_format(&attr_id.data));
+ VertexBuffer_allocate_data(vbo_data, vbo_len_capacity);
+ }
+
+ for (uint i = 0; i < lvert_len; i++) {
+ BMVert *eve = BM_vert_at_index(bm, rdata->loose_verts[i]);
+ add_overlay_loose_vert(
+ rdata, vbo_pos, vbo_nor, vbo_data,
+ attr_id.pos, attr_id.vnor, attr_id.data,
+ eve, vbo_len_used);
+ vbo_len_used += 1;
+ }
+
+ /* Finish */
+ if (vbo_len_used != vbo_len_capacity) {
+ if (vbo_pos != NULL) {
+ VertexBuffer_resize_data(vbo_pos, vbo_len_used);
+ }
+ if (vbo_nor != NULL) {
+ VertexBuffer_resize_data(vbo_nor, vbo_len_used);
+ }
+ if (vbo_data != NULL) {
+ VertexBuffer_resize_data(vbo_data, vbo_len_used);
+ }
+ }
+}
+
+/* Position */
+static VertexBuffer *mesh_batch_cache_get_edit_tri_pos(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_tri_pos == NULL) {
+ mesh_batch_cache_create_overlay_tri_buffers(rdata, cache);
+ }
+
+ return cache->ed_tri_pos;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edit_ledge_pos(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_ledge_pos == NULL) {
+ mesh_batch_cache_create_overlay_ledge_buffers(rdata, cache);
+ }
+
+ return cache->ed_ledge_pos;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edit_lvert_pos(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_lvert_pos == NULL) {
+ mesh_batch_cache_create_overlay_lvert_buffers(rdata, cache);
+ }
+
+ return cache->ed_lvert_pos;
+}
+
+/* Normal */
+static VertexBuffer *mesh_batch_cache_get_edit_tri_nor(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_tri_nor == NULL) {
+ mesh_batch_cache_create_overlay_tri_buffers(rdata, cache);
+ }
+
+ return cache->ed_tri_nor;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edit_ledge_nor(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_ledge_nor == NULL) {
+ mesh_batch_cache_create_overlay_ledge_buffers(rdata, cache);
+ }
+
+ return cache->ed_ledge_nor;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edit_lvert_nor(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_lvert_nor == NULL) {
+ mesh_batch_cache_create_overlay_lvert_buffers(rdata, cache);
+ }
+
+ return cache->ed_lvert_nor;
+}
+
+/* Data */
+static VertexBuffer *mesh_batch_cache_get_edit_tri_data(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_tri_data == NULL) {
+ mesh_batch_cache_create_overlay_tri_buffers(rdata, cache);
+ }
+
+ return cache->ed_tri_data;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edit_ledge_data(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_ledge_data == NULL) {
+ mesh_batch_cache_create_overlay_ledge_buffers(rdata, cache);
+ }
+
+ return cache->ed_ledge_data;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edit_lvert_data(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_lvert_data == NULL) {
+ mesh_batch_cache_create_overlay_lvert_buffers(rdata, cache);
+ }
+
+ return cache->ed_lvert_data;
+}
+
+static ElementList *mesh_batch_cache_get_edges_in_order(MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
+
+ if (cache->edges_in_order == NULL) {
+ const int vert_len = mesh_render_data_verts_len_get(rdata);
+ const int edge_len = mesh_render_data_edges_len_get(rdata);
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len);
+
+ BLI_assert(rdata->types & MR_DATATYPE_EDGE);
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter eiter;
+ BMEdge *eed;
+ BM_ITER_MESH(eed, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ add_line_vertices(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2));
+ }
+ }
+ }
+ else {
+ const MEdge *ed = rdata->medge;
+ for (int i = 0; i < edge_len; i++, ed++) {
+ add_line_vertices(&elb, ed->v1, ed->v2);
+ }
+ }
+ cache->edges_in_order = ElementList_build(&elb);
+ }
+
+ return cache->edges_in_order;
+}
+
+static ElementList *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
+
+ if (cache->triangles_in_order == NULL) {
+ const int vert_len = mesh_render_data_verts_len_get(rdata);
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, tri_len, vert_len);
+
+ if (rdata->edit_bmesh) {
+ for (int i = 0; i < tri_len; ++i) {
+ const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ add_generic_vertex(&elb, BM_elem_index_get(ltri[tri_corner]->v));
+ }
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < tri_len; ++i) {
+ const MLoopTri *mlt = &rdata->mlooptri[i];
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ add_generic_vertex(&elb, mlt->tri[tri_corner]);
+ }
+ }
+ }
+ cache->triangles_in_order = ElementList_build(&elb);
+ }
+
+ return cache->triangles_in_order;
+}
+
+static ElementList **mesh_batch_cache_get_triangles_in_order_split_by_material(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_POLY));
+
+ if (cache->shaded_triangles_in_order == NULL) {
+ const int poly_len = mesh_render_data_polys_len_get(rdata);
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+ const int mat_len = mesh_render_data_mat_len_get(rdata);
+
+ int *mat_tri_len = MEM_callocN(sizeof(*mat_tri_len) * mat_len, __func__);
+ cache->shaded_triangles_in_order = MEM_callocN(sizeof(*cache->shaded_triangles) * mat_len, __func__);
+ ElementListBuilder *elb = MEM_callocN(sizeof(*elb) * mat_len, __func__);
+
+ /* Note that polygons (not triangles) are used here.
+ * This OK because result is _guaranteed_ to be the same. */
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter fiter;
+ BMFace *efa;
+
+ BM_ITER_MESH(efa, &fiter, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ const short ma_id = efa->mat_nr < mat_len ? efa->mat_nr : 0;
+ mat_tri_len[ma_id] += (efa->len - 2);
+ }
+ }
+ }
+ else {
+ for (uint i = 0; i < poly_len; i++) {
+ const MPoly *mp = &rdata->mpoly[i]; ;
+ const short ma_id = mp->mat_nr < mat_len ? mp->mat_nr : 0;
+ mat_tri_len[ma_id] += (mp->totloop - 2);
+ }
+ }
+
+ /* Init ELBs. */
+ for (int i = 0; i < mat_len; ++i) {
+ ElementListBuilder_init(&elb[i], PRIM_TRIANGLES, mat_tri_len[i], tri_len * 3);
+ }
+
+ /* Populate ELBs. */
+ uint nidx = 0;
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter fiter;
+ BMFace *efa;
+
+ BM_ITER_MESH(efa, &fiter, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ const short ma_id = efa->mat_nr < mat_len ? efa->mat_nr : 0;
+ for (int j = 2; j < efa->len; j++) {
+ add_triangle_vertices(&elb[ma_id], nidx + 0, nidx + 1, nidx + 2);
+ nidx += 3;
+ }
+ }
+ }
+ }
+ else {
+ for (uint i = 0; i < poly_len; i++) {
+ const MPoly *mp = &rdata->mpoly[i]; ;
+ const short ma_id = mp->mat_nr < mat_len ? mp->mat_nr : 0;
+ for (int j = 2; j < mp->totloop; j++) {
+ add_triangle_vertices(&elb[ma_id], nidx + 0, nidx + 1, nidx + 2);
+ nidx += 3;
+ }
+ }
+ }
+
+ /* Build ELBs. */
+ for (int i = 0; i < mat_len; ++i) {
+ cache->shaded_triangles_in_order[i] = ElementList_build(&elb[i]);
+ }
+
+ MEM_freeN(mat_tri_len);
+ MEM_freeN(elb);
+ }
+
+ return cache->shaded_triangles_in_order;
+}
+
+static VertexBuffer *mesh_batch_cache_get_edge_pos_with_sel(
+ MeshRenderData *rdata, MeshBatchCache *cache, bool use_wire, bool use_select_bool)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
+ BLI_assert(rdata->edit_bmesh == NULL);
+
+ if (!cache->edge_pos_with_select_bool) {
+ unsigned int vidx = 0, cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, sel; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.sel = VertexFormat_add_attrib(&format, "select", COMP_U8, 1, KEEP_INT);
+ }
+
+ const int edge_len = mesh_render_data_edges_len_get(rdata);
+
+ VertexBuffer *vbo = cache->edge_pos_with_select_bool = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = edge_len * 2;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ if (use_select_bool) {
+ mesh_render_data_ensure_edge_select_bool(rdata, use_wire);
+ }
+ bool *edge_select_bool = use_select_bool ? rdata->edge_select_bool : NULL;
+
+ for (int i = 0; i < edge_len; i++) {
+ const MEdge *ed = &rdata->medge[i];
+
+ uchar edge_vert_sel;
+ if (use_select_bool && edge_select_bool[i]) {
+ edge_vert_sel = true;
+ }
+ else if (use_wire) {
+ edge_vert_sel = false;
+ }
+ else {
+ continue;
+ }
+
+ VertexBuffer_set_attrib(vbo, attr_id.sel, cidx++, &edge_vert_sel);
+ VertexBuffer_set_attrib(vbo, attr_id.sel, cidx++, &edge_vert_sel);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v1].co);
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v2].co);
+ }
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->edge_pos_with_select_bool;
+}
+
+static ElementList *mesh_batch_cache_get_tri_overlay_weight_faces(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
+
+ if (cache->overlay_triangles_vpaint == NULL) {
+ const int vert_len = mesh_render_data_verts_len_get(rdata);
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, tri_len, vert_len);
+
+ for (int i = 0; i < tri_len; ++i) {
+ const MLoopTri *mlt = &rdata->mlooptri[i];
+ if (!(rdata->mpoly[mlt->poly].flag & (ME_FACE_SEL | ME_HIDE))) {
+ for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
+ add_generic_vertex(&elb, rdata->mloop[mlt->tri[tri_corner]].v);
+ }
+ }
+ }
+ cache->overlay_triangles_vpaint = ElementList_build(&elb);
+ }
+
+ return cache->overlay_triangles_vpaint;
+}
+
+/**
+ * Non-edit mode vertices (only used for weight-paint mode).
+ */
+static VertexBuffer *mesh_batch_cache_get_vert_pos_with_overlay_data(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT));
+ BLI_assert(rdata->edit_bmesh == NULL);
+
+ if (cache->pos_with_select_bool == NULL) {
+ unsigned int cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static struct { uint data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.data = VertexFormat_add_attrib(&format, "data", COMP_I8, 1, KEEP_INT);
+ }
+
+ const int vert_len = mesh_render_data_verts_len_get(rdata);
+
+ VertexBuffer *vbo = cache->pos_with_select_bool = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = vert_len;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ for (int i = 0; i < vert_len; i++) {
+ const MVert *mv = &rdata->mvert[i];
+ const char data = mv->flag & (SELECT | ME_HIDE);
+ VertexBuffer_set_attrib(vbo, attr_id.data, cidx++, &data);
+ }
+ vbo_len_used = cidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->pos_with_select_bool;
+}
+
+/** \} */
+
+
+/* ---------------------------------------------------------------------- */
+
+/** \name Public API
+ * \{ */
+
+Batch *DRW_mesh_batch_cache_get_all_edges(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->all_edges == NULL) {
+ /* create batch from Mesh */
+ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->all_edges = Batch_create(
+ PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
+ mesh_batch_cache_get_edges_in_order(rdata, cache));
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->all_edges;
+}
+
+Batch *DRW_mesh_batch_cache_get_all_triangles(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->all_triangles == NULL) {
+ /* create batch from DM */
+ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->all_triangles = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
+ mesh_batch_cache_get_triangles_in_order(rdata, cache));
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->all_triangles;
+}
+
+Batch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->triangles_with_normals == NULL) {
+ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->triangles_with_normals = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_normals;
+}
+
+Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, int defgroup)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->triangles_with_weights == NULL) {
+ const bool use_hide = (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) != 0;
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->triangles_with_weights = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_tri_weights(rdata, cache, use_hide, defgroup), NULL);
+
+ VertexBuffer *vbo_tris = use_hide ?
+ mesh_batch_cache_get_tri_pos_and_normals_visible_only(rdata, cache) :
+ mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+
+ Batch_add_VertexBuffer(cache->triangles_with_weights, vbo_tris);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_weights;
+}
+
+Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->triangles_with_vert_colors == NULL) {
+ const bool use_hide = (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) != 0;
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->triangles_with_vert_colors = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_tri_vert_colors(rdata, cache, use_hide), NULL);
+
+ VertexBuffer *vbo_tris = use_hide ?
+ mesh_batch_cache_get_tri_pos_and_normals_visible_only(rdata, cache) :
+ mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+ Batch_add_VertexBuffer(cache->triangles_with_vert_colors, vbo_tris);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_vert_colors;
+}
+
+
+struct Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->triangles_with_select_id == NULL) {
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->triangles_with_select_id = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_tri_select_id(rdata, cache, use_hide), NULL);
+
+ VertexBuffer *vbo_tris = use_hide ?
+ mesh_batch_cache_get_tri_pos_and_normals_visible_only(rdata, cache) :
+ mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+ Batch_add_VertexBuffer(cache->triangles_with_select_id, vbo_tris);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_select_id;
+}
+
+Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->points_with_normals == NULL) {
+ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->points_with_normals = Batch_create(
+ PRIM_POINTS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->points_with_normals;
+}
+
+Batch *DRW_mesh_batch_cache_get_all_verts(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->all_verts == NULL) {
+ /* create batch from DM */
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
+
+ cache->all_verts = Batch_create(
+ PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->all_verts;
+}
+
+Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->fancy_edges == NULL) {
+ /* create batch from DM */
+ static VertexFormat format = { 0 };
+ static struct { uint pos, n1, n2; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ attr_id.n1 = VertexFormat_add_attrib(&format, "N1", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ attr_id.n2 = VertexFormat_add_attrib(&format, "N2", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+
+ MeshRenderData *rdata = mesh_render_data_create(
+ me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
+
+ const int edge_len = mesh_render_data_edges_len_get(rdata);
+
+ const int vbo_len_capacity = edge_len * 2; /* these are PRIM_LINE verts, not mesh verts */
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+ for (int i = 0; i < edge_len; ++i) {
+ float *vcos1, *vcos2;
+ float *pnor1 = NULL, *pnor2 = NULL;
+ bool is_manifold;
+
+ if (mesh_render_data_edge_vcos_manifold_pnors(rdata, i, &vcos1, &vcos2, &pnor1, &pnor2, &is_manifold)) {
+
+ PackedNormal n1value = { .x = 0, .y = 0, .z = +511 };
+ PackedNormal n2value = { .x = 0, .y = 0, .z = -511 };
+
+ if (is_manifold) {
+ n1value = convert_i10_v3(pnor1);
+ n2value = convert_i10_v3(pnor2);
+ }
+
+ const PackedNormal *n1 = &n1value;
+ const PackedNormal *n2 = &n2value;
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 2 * i, vcos1);
+ VertexBuffer_set_attrib(vbo, attr_id.n1, 2 * i, n1);
+ VertexBuffer_set_attrib(vbo, attr_id.n2, 2 * i, n2);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, 2 * i + 1, vcos2);
+ VertexBuffer_set_attrib(vbo, attr_id.n1, 2 * i + 1, n1);
+ VertexBuffer_set_attrib(vbo, attr_id.n2, 2 * i + 1, n2);
+
+ vbo_len_used += 2;
+ }
+ }
+ if (vbo_len_used != vbo_len_capacity) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+
+ cache->fancy_edges = Batch_create(PRIM_LINES, vbo, NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->fancy_edges;
+}
+
+static void mesh_batch_cache_create_overlay_batches(Mesh *me)
+{
+ BLI_assert(me->edit_btmesh != NULL);
+
+ /* Since MR_DATATYPE_OVERLAY is slow to generate, generate them all at once */
+ const int options =
+ MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY |
+ MR_DATATYPE_LOOPTRI | MR_DATATYPE_OVERLAY;
+
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+ MeshRenderData *rdata = mesh_render_data_create(me, options);
+
+ if (cache->overlay_triangles == NULL) {
+ cache->overlay_triangles = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL);
+ Batch_add_VertexBuffer(cache->overlay_triangles, mesh_batch_cache_get_edit_tri_nor(rdata, cache));
+ Batch_add_VertexBuffer(cache->overlay_triangles, mesh_batch_cache_get_edit_tri_data(rdata, cache));
+ }
+
+ if (cache->overlay_loose_edges == NULL) {
+ cache->overlay_loose_edges = Batch_create(
+ PRIM_LINES, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL);
+ Batch_add_VertexBuffer(cache->overlay_loose_edges, mesh_batch_cache_get_edit_ledge_nor(rdata, cache));
+ Batch_add_VertexBuffer(cache->overlay_loose_edges, mesh_batch_cache_get_edit_ledge_data(rdata, cache));
+ }
+
+ if (cache->overlay_loose_verts == NULL) {
+ cache->overlay_loose_verts = Batch_create(
+ PRIM_POINTS, mesh_batch_cache_get_edit_lvert_pos(rdata, cache), NULL);
+ Batch_add_VertexBuffer(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_nor(rdata, cache));
+ Batch_add_VertexBuffer(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_data(rdata, cache));
+ }
+
+ if (cache->overlay_triangles_nor == NULL) {
+ cache->overlay_triangles_nor = Batch_create(
+ PRIM_POINTS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL);
+ Batch_add_VertexBuffer(cache->overlay_triangles_nor, mesh_batch_cache_get_edit_tri_nor(rdata, cache));
+ }
+
+ if (cache->overlay_loose_edges_nor == NULL) {
+ cache->overlay_loose_edges_nor = Batch_create(
+ PRIM_POINTS, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL);
+ Batch_add_VertexBuffer(cache->overlay_loose_edges_nor, mesh_batch_cache_get_edit_ledge_nor(rdata, cache));
+ }
+
+ mesh_render_data_free(rdata);
+}
+
+Batch *DRW_mesh_batch_cache_get_overlay_triangles(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_triangles == NULL) {
+ mesh_batch_cache_create_overlay_batches(me);
+ }
+
+ return cache->overlay_triangles;
+}
+
+Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_loose_edges == NULL) {
+ mesh_batch_cache_create_overlay_batches(me);
+ }
+
+ return cache->overlay_loose_edges;
+}
+
+Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_loose_verts == NULL) {
+ mesh_batch_cache_create_overlay_batches(me);
+ }
+
+ return cache->overlay_loose_verts;
+}
+
+Batch *DRW_mesh_batch_cache_get_overlay_triangles_nor(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_triangles_nor == NULL) {
+ mesh_batch_cache_create_overlay_batches(me);
+ }
+
+ return cache->overlay_triangles_nor;
+}
+
+Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_loose_edges_nor == NULL) {
+ mesh_batch_cache_create_overlay_batches(me);
+ }
+
+ return cache->overlay_loose_edges_nor;
+}
+
+Batch *DRW_mesh_batch_cache_get_overlay_facedots(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_facedots == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.data = VertexFormat_add_attrib(&format, "norAndFlag", COMP_I10, 4, NORMALIZE_INT_TO_FLOAT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
+ int vidx = 0;
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+ for (int i = 0; i < vbo_len_capacity; ++i) {
+ float pcenter[3], pnor[3];
+ bool selected = false;
+
+ if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) {
+
+ PackedNormal nor = { .x = 0, .y = 0, .z = -511 };
+ nor = convert_i10_v3(pnor);
+ nor.w = selected ? 1 : 0;
+ VertexBuffer_set_attrib(vbo, attr_id.data, vidx, &nor);
+
+ VertexBuffer_set_attrib(vbo, attr_id.pos, vidx, pcenter);
+
+ vidx += 1;
+
+ }
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+
+ cache->overlay_facedots = Batch_create(PRIM_POINTS, vbo, NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_facedots;
+}
+
+Batch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->shaded_triangles == NULL) {
+ /* create batch from DM */
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI |
+ MR_DATATYPE_POLY | MR_DATATYPE_SHADING;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ const int mat_len = mesh_render_data_mat_len_get(rdata);
+
+ cache->shaded_triangles = MEM_callocN(sizeof(*cache->shaded_triangles) * mat_len, __func__);
+
+ ElementList **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache);
+
+ VertexBuffer *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+ for (int i = 0; i < mat_len; ++i) {
+ cache->shaded_triangles[i] = Batch_create(
+ PRIM_TRIANGLES, vbo, el[i]);
+ VertexBuffer *vbo_shading = mesh_batch_cache_get_tri_shading_data(rdata, cache);
+ if (vbo_shading) {
+ Batch_add_VertexBuffer(cache->shaded_triangles[i], vbo_shading);
+ }
+ }
+
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->shaded_triangles;
+}
+
+Batch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->texpaint_triangles == NULL) {
+ /* create batch from DM */
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOPUV;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ const int mat_len = mesh_render_data_mat_len_get(rdata);
+
+ cache->texpaint_triangles = MEM_callocN(sizeof(*cache->texpaint_triangles) * mat_len, __func__);
+
+ ElementList **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache);
+
+ VertexBuffer *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+ for (int i = 0; i < mat_len; ++i) {
+ cache->texpaint_triangles[i] = Batch_create(
+ PRIM_TRIANGLES, vbo, el[i]);
+ VertexBuffer *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache);
+ if (vbo_uv) {
+ Batch_add_VertexBuffer(cache->texpaint_triangles[i], vbo_uv);
+ }
+ }
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->texpaint_triangles;
+}
+
+Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->texpaint_triangles_single == NULL) {
+ /* create batch from DM */
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOPUV;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ VertexBuffer *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+
+ cache->texpaint_triangles_single = Batch_create(
+ PRIM_TRIANGLES, vbo, NULL);
+ VertexBuffer *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache);
+ if (vbo_uv) {
+ Batch_add_VertexBuffer(cache->texpaint_triangles_single, vbo_uv);
+ }
+ mesh_render_data_free(rdata);
+ }
+ return cache->texpaint_triangles_single;
+}
+
+Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_paint_edges == NULL) {
+ /* create batch from Mesh */
+ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->overlay_paint_edges = Batch_create(
+ PRIM_LINES, mesh_batch_cache_get_edge_pos_with_sel(rdata, cache, use_wire, use_sel), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_paint_edges;
+}
+
+Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_weight_faces == NULL) {
+ /* create batch from Mesh */
+ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ cache->overlay_weight_faces = Batch_create(
+ PRIM_TRIANGLES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
+ mesh_batch_cache_get_tri_overlay_weight_faces(rdata, cache));
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_weight_faces;
+}
+
+Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_weight_verts == NULL) {
+ /* create batch from Mesh */
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
+
+ cache->overlay_weight_verts = Batch_create(
+ PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL);
+
+ Batch_add_VertexBuffer(
+ cache->overlay_weight_verts,
+ mesh_batch_cache_get_vert_pos_with_overlay_data(rdata, cache));
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_weight_verts;
+}
+
+/** \} */
+
+#undef MESH_RENDER_FUNCTION
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
new file mode 100644
index 00000000000..f4b16f1873a
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -0,0 +1,348 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file draw_cache_impl_particles.c
+ * \ingroup draw
+ *
+ * \brief Particle API for render engines
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "DNA_particle_types.h"
+
+#include "BKE_particle.h"
+
+#include "GPU_batch.h"
+
+#include "draw_cache_impl.h" /* own include */
+
+static void particle_batch_cache_clear(ParticleSystem *psys);
+
+/* ---------------------------------------------------------------------- */
+/* Particle Batch Cache */
+
+typedef struct ParticleBatchCache {
+ VertexBuffer *pos;
+ ElementList *segments;
+
+ Batch *hairs;
+
+ int segment_count;
+ int point_count;
+
+ /* settings to determine if cache is invalid */
+ bool is_dirty;
+} ParticleBatchCache;
+
+/* Batch cache management. */
+
+static bool particle_batch_cache_valid(ParticleSystem *psys)
+{
+ ParticleBatchCache *cache = psys->batch_cache;
+
+ if (cache == NULL) {
+ return false;
+ }
+
+ if (cache->is_dirty == false) {
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ return true;
+}
+
+static void particle_batch_cache_init(ParticleSystem *psys)
+{
+ ParticleBatchCache *cache = psys->batch_cache;
+
+ if (!cache) {
+ cache = psys->batch_cache = MEM_callocN(sizeof(*cache), __func__);
+ }
+ else {
+ memset(cache, 0, sizeof(*cache));
+ }
+
+ cache->is_dirty = false;
+}
+
+static ParticleBatchCache *particle_batch_cache_get(ParticleSystem *psys)
+{
+ if (!particle_batch_cache_valid(psys)) {
+ particle_batch_cache_clear(psys);
+ particle_batch_cache_init(psys);
+ }
+ return psys->batch_cache;
+}
+
+void DRW_particle_batch_cache_dirty(ParticleSystem *psys, int mode)
+{
+ ParticleBatchCache *cache = psys->batch_cache;
+ if (cache == NULL) {
+ return;
+ }
+ switch (mode) {
+ case BKE_PARTICLE_BATCH_DIRTY_ALL:
+ cache->is_dirty = true;
+ break;
+ default:
+ BLI_assert(0);
+ }
+}
+
+static void particle_batch_cache_clear(ParticleSystem *psys)
+{
+ ParticleBatchCache *cache = psys->batch_cache;
+ if (!cache) {
+ return;
+ }
+
+ BATCH_DISCARD_SAFE(cache->hairs);
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos);
+ ELEMENTLIST_DISCARD_SAFE(cache->segments);
+}
+
+void DRW_particle_batch_cache_free(ParticleSystem *psys)
+{
+ particle_batch_cache_clear(psys);
+ MEM_SAFE_FREE(psys->batch_cache);
+}
+
+static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache)
+{
+ if (cache->pos == NULL || cache->segments == NULL) {
+ cache->segment_count = 0;
+ cache->point_count = 0;
+
+ if (psys->pathcache && (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
+ for (int i = 0; i < psys->totpart; i++) {
+ ParticleCacheKey *path = psys->pathcache[i];
+
+ if (path->segments > 0) {
+ cache->segment_count += path->segments;
+ cache->point_count += path->segments + 1;
+ }
+ }
+ }
+
+ if (psys->childcache) {
+ int child_count = psys->totchild * psys->part->disp / 100;
+
+ for (int i = 0; i < child_count; i++) {
+ ParticleCacheKey *path = psys->childcache[i];
+
+ if (path->segments > 0) {
+ cache->segment_count += path->segments;
+ cache->point_count += path->segments + 1;
+ }
+ }
+ }
+ }
+}
+
+/* Batch cache usage. */
+static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, ParticleBatchCache *cache)
+{
+ if (cache->pos == NULL || cache->segments == NULL) {
+ int curr_point = 0;
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos);
+ ELEMENTLIST_DISCARD_SAFE(cache->segments);
+
+ static VertexFormat format = { 0 };
+ static struct { uint pos, tan, ind; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.tan = VertexFormat_add_attrib(&format, "tang", COMP_F32, 3, KEEP_FLOAT);
+ attr_id.ind = VertexFormat_add_attrib(&format, "ind", COMP_I32, 1, KEEP_INT);
+ }
+
+ cache->pos = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(cache->pos, cache->point_count);
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_LINES, cache->segment_count, cache->point_count);
+
+ if (psys->pathcache && (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
+ for (int i = 0; i < psys->totpart; i++) {
+ ParticleCacheKey *path = psys->pathcache[i];
+
+ if (path->segments > 0) {
+ float tangent[3];
+
+ for (int j = 0; j < path->segments; j++) {
+ if (j == 0) {
+ sub_v3_v3v3(tangent, path[j + 1].co, path[j].co);
+ }
+ else {
+ sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co);
+ }
+
+ VertexBuffer_set_attrib(cache->pos, attr_id.pos, curr_point, path[j].co);
+ VertexBuffer_set_attrib(cache->pos, attr_id.tan, curr_point, tangent);
+ VertexBuffer_set_attrib(cache->pos, attr_id.ind, curr_point, &i);
+
+ add_line_vertices(&elb, curr_point, curr_point + 1);
+
+ curr_point++;
+ }
+
+ sub_v3_v3v3(tangent, path[path->segments].co, path[path->segments - 1].co);
+
+ VertexBuffer_set_attrib(cache->pos, attr_id.pos, curr_point, path[path->segments].co);
+ VertexBuffer_set_attrib(cache->pos, attr_id.tan, curr_point, tangent);
+ VertexBuffer_set_attrib(cache->pos, attr_id.ind, curr_point, &i);
+
+ curr_point++;
+ }
+ }
+ }
+
+ if (psys->childcache) {
+ int child_count = psys->totchild * psys->part->disp / 100;
+
+ for (int i = 0, x = psys->totpart; i < child_count; i++, x++) {
+ ParticleCacheKey *path = psys->childcache[i];
+ float tangent[3];
+
+ if (path->segments > 0) {
+ for (int j = 0; j < path->segments; j++) {
+ if (j == 0) {
+ sub_v3_v3v3(tangent, path[j + 1].co, path[j].co);
+ }
+ else {
+ sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co);
+ }
+
+ VertexBuffer_set_attrib(cache->pos, attr_id.pos, curr_point, path[j].co);
+ VertexBuffer_set_attrib(cache->pos, attr_id.tan, curr_point, tangent);
+ VertexBuffer_set_attrib(cache->pos, attr_id.ind, curr_point, &x);
+
+ add_line_vertices(&elb, curr_point, curr_point + 1);
+
+ curr_point++;
+ }
+
+ sub_v3_v3v3(tangent, path[path->segments].co, path[path->segments - 1].co);
+
+ VertexBuffer_set_attrib(cache->pos, attr_id.pos, curr_point, path[path->segments].co);
+ VertexBuffer_set_attrib(cache->pos, attr_id.tan, curr_point, tangent);
+ VertexBuffer_set_attrib(cache->pos, attr_id.ind, curr_point, &x);
+
+ curr_point++;
+ }
+ }
+ }
+
+ cache->segments = ElementList_build(&elb);
+ }
+}
+
+static void particle_batch_cache_ensure_pos(ParticleSystem *psys, ParticleBatchCache *cache)
+{
+ if (cache->pos == NULL) {
+ static VertexFormat format = { 0 };
+ static unsigned pos_id, rot_id, val_id;
+ int i, curr_point;
+ ParticleData *pa;
+
+ VERTEXBUFFER_DISCARD_SAFE(cache->pos);
+ ELEMENTLIST_DISCARD_SAFE(cache->segments);
+
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ rot_id = VertexFormat_add_attrib(&format, "rot", COMP_F32, 4, KEEP_FLOAT);
+ val_id = VertexFormat_add_attrib(&format, "val", COMP_F32, 1, KEEP_FLOAT);
+ }
+
+ cache->pos = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(cache->pos, psys->totpart);
+
+ for (curr_point = 0, i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) {
+ if (pa->state.time >= pa->time && pa->state.time < pa->dietime &&
+ !(pa->flag & (PARS_NO_DISP | PARS_UNEXIST)))
+ {
+ float val;
+
+ VertexBuffer_set_attrib(cache->pos, pos_id, curr_point, pa->state.co);
+ VertexBuffer_set_attrib(cache->pos, rot_id, curr_point, pa->state.rot);
+
+ switch (psys->part->draw_col) {
+ case PART_DRAW_COL_VEL:
+ val = len_v3(pa->state.vel) / psys->part->color_vec_max;
+ break;
+ case PART_DRAW_COL_ACC:
+ val = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * psys->part->color_vec_max);
+ break;
+ default:
+ val = -1.0f;
+ break;
+ }
+
+ VertexBuffer_set_attrib(cache->pos, val_id, curr_point, &val);
+
+ curr_point++;
+ }
+ }
+
+ if (curr_point != psys->totpart) {
+ VertexBuffer_resize_data(cache->pos, curr_point);
+ }
+ }
+}
+
+Batch *DRW_particles_batch_cache_get_hair(ParticleSystem *psys)
+{
+ ParticleBatchCache *cache = particle_batch_cache_get(psys);
+
+ if (cache->hairs == NULL) {
+ ensure_seg_pt_count(psys, cache);
+ particle_batch_cache_ensure_pos_and_seg(psys, cache);
+ cache->hairs = Batch_create(PRIM_LINES, cache->pos, cache->segments);
+ }
+
+ return cache->hairs;
+}
+
+Batch *DRW_particles_batch_cache_get_dots(ParticleSystem *psys)
+{
+ ParticleBatchCache *cache = particle_batch_cache_get(psys);
+
+ if (cache->hairs == NULL) {
+ particle_batch_cache_ensure_pos(psys, cache);
+ cache->hairs = Batch_create(PRIM_POINTS, cache->pos, NULL);
+ }
+
+ return cache->hairs;
+}
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
new file mode 100644
index 00000000000..f8040f28f53
--- /dev/null
+++ b/source/blender/draw/intern/draw_common.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/intern/draw_common.c
+ * \ingroup draw
+ */
+
+#include "DRW_render.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "UI_resources.h"
+
+#include "BKE_global.h"
+#include "BKE_texture.h"
+
+#include "draw_common.h"
+
+
+#if 0
+#define UI_COLOR_RGB_FROM_U8(r, g, b, v4) \
+ ARRAY_SET_ITEMS(v4, (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, 1.0)
+#endif
+#define UI_COLOR_RGBA_FROM_U8(r, g, b, a, v4) \
+ ARRAY_SET_ITEMS(v4, (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f)
+
+/* Colors & Constant */
+GlobalsUboStorage ts;
+struct GPUUniformBuffer *globals_ubo = NULL;
+struct GPUTexture *globals_ramp = NULL;
+
+void DRW_globals_update(void)
+{
+ UI_GetThemeColor4fv(TH_WIRE, ts.colorWire);
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, ts.colorWireEdit);
+ UI_GetThemeColor4fv(TH_ACTIVE, ts.colorActive);
+ UI_GetThemeColor4fv(TH_SELECT, ts.colorSelect);
+ UI_GetThemeColor4fv(TH_TRANSFORM, ts.colorTransform);
+ UI_GetThemeColor4fv(TH_GROUP_ACTIVE, ts.colorGroupActive);
+ UI_GetThemeColorShade4fv(TH_GROUP_ACTIVE, -25, ts.colorGroupSelect);
+ UI_GetThemeColor4fv(TH_GROUP, ts.colorGroup);
+ UI_COLOR_RGBA_FROM_U8(0x88, 0xFF, 0xFF, 155, ts.colorLibrarySelect);
+ UI_COLOR_RGBA_FROM_U8(0x55, 0xCC, 0xCC, 155, ts.colorLibrary);
+ UI_GetThemeColor4fv(TH_LAMP, ts.colorLamp);
+ UI_GetThemeColor4fv(TH_SPEAKER, ts.colorSpeaker);
+ UI_GetThemeColor4fv(TH_CAMERA, ts.colorCamera);
+ UI_GetThemeColor4fv(TH_EMPTY, ts.colorEmpty);
+ UI_GetThemeColor4fv(TH_VERTEX, ts.colorVertex);
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, ts.colorVertexSelect);
+ UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, ts.colorEditMeshActive);
+ UI_GetThemeColor4fv(TH_EDGE_SELECT, ts.colorEdgeSelect);
+ UI_GetThemeColor4fv(TH_EDGE_SEAM, ts.colorEdgeSeam);
+ UI_GetThemeColor4fv(TH_EDGE_SHARP, ts.colorEdgeSharp);
+ UI_GetThemeColor4fv(TH_EDGE_CREASE, ts.colorEdgeCrease);
+ UI_GetThemeColor4fv(TH_EDGE_BEVEL, ts.colorEdgeBWeight);
+ UI_GetThemeColor4fv(TH_EDGE_FACESEL, ts.colorEdgeFaceSelect);
+ UI_GetThemeColor4fv(TH_FACE, ts.colorFace);
+ UI_GetThemeColor4fv(TH_FACE_SELECT, ts.colorFaceSelect);
+ UI_GetThemeColor4fv(TH_NORMAL, ts.colorNormal);
+ UI_GetThemeColor4fv(TH_VNORMAL, ts.colorVNormal);
+ UI_GetThemeColor4fv(TH_LNORMAL, ts.colorLNormal);
+ UI_GetThemeColor4fv(TH_FACE_DOT, ts.colorFaceDot);
+ UI_GetThemeColor4fv(TH_BACK, ts.colorBackground);
+
+ /* Grid */
+ UI_GetThemeColorShade4fv(TH_GRID, 10, ts.colorGrid);
+ /* emphasise division lines lighter instead of darker, if background is darker than grid */
+ UI_GetThemeColorShade4fv(TH_GRID,
+ (ts.colorGrid[0] + ts.colorGrid[1] + ts.colorGrid[2] + 0.12 >
+ ts.colorBackground[0] + ts.colorBackground[1] + ts.colorBackground[2])
+ ? 20 : -10, ts.colorGridEmphasise);
+ /* Grid Axis */
+ UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_X, 0.5f, -10, ts.colorGridAxisX);
+ UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_Y, 0.5f, -10, ts.colorGridAxisY);
+ UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_Z, 0.5f, -10, ts.colorGridAxisZ);
+
+ UI_GetThemeColorShadeAlpha4fv(TH_TRANSFORM, 0, -80, ts.colorDeselect);
+ UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, ts.colorOutline);
+ UI_GetThemeColorShadeAlpha4fv(TH_LAMP, 0, 255, ts.colorLampNoAlpha);
+
+ ts.sizeLampCenter = (U.obcenter_dia + 1.5f) * U.pixelsize;
+ ts.sizeLampCircle = U.pixelsize * 9.0f;
+ ts.sizeLampCircleShadow = ts.sizeLampCircle + U.pixelsize * 3.0f;
+
+ /* M_SQRT2 to be at least the same size of the old square */
+ ts.sizeVertex = ceil(UI_GetThemeValuef(TH_VERTEX_SIZE) * M_SQRT2 / 2.0f);
+ ts.sizeFaceDot = ceil(UI_GetThemeValuef(TH_FACEDOT_SIZE) * M_SQRT2);
+ ts.sizeEdge = 1.0f / 2.0f; /* TODO Theme */
+ ts.sizeEdgeFix = 0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * M_SQRT1_2);
+
+ /* TODO Waiting for notifiers to invalidate cache */
+ if (globals_ubo) {
+ DRW_uniformbuffer_free(globals_ubo);
+ }
+
+ globals_ubo = DRW_uniformbuffer_create(sizeof(GlobalsUboStorage), &ts);
+
+ ColorBand ramp = {0};
+ float *colors;
+ int col_size;
+
+ ramp.tot = 3;
+ ramp.data[0].a = 1.0f;
+ ramp.data[0].b = 1.0f;
+ ramp.data[0].pos = 0.0f;
+ ramp.data[1].a = 1.0f;
+ ramp.data[1].g = 1.0f;
+ ramp.data[1].pos = 0.5f;
+ ramp.data[2].a = 1.0f;
+ ramp.data[2].r = 1.0f;
+ ramp.data[2].pos = 1.0f;
+
+ colorband_table_RGBA(&ramp, &colors, &col_size);
+
+ if (globals_ramp) {
+ GPU_texture_free(globals_ramp);
+ }
+ globals_ramp = GPU_texture_create_1D(col_size, colors, NULL);
+
+ MEM_freeN(colors);
+}
+
+/* ********************************* SHGROUP ************************************* */
+
+DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_line_batch_create(sh, pass);
+ DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float color[4], float *size)
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+
+ DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+ DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+ DRW_shgroup_uniform_float(grp, "size", size, 1);
+ DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, float color[4])
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE);
+
+ DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+ DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4])
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT);
+
+ DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+ DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+ DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Batch *geom, float *size)
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "world_pos", 3);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_uniform_float(grp, "size", size, 1);
+ DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
+ DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
+ DRW_shgroup_state_enable(grp, DRW_STATE_STIPPLE_3);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_objspace_solid(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
+{
+ static float light[3] = {0.0f, 0.0f, 1.0f};
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_attrib_float(grp, "color", 4);
+ DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat);
+ DRW_shgroup_uniform_vec3(grp, "light", light, 1);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_objspace_wire(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_attrib_float(grp, "color", 4);
+ DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "size", 1);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "size", 1);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "size", 3);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "size", 1);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "corners", 8);
+ DRW_shgroup_attrib_float(grp, "depth", 1);
+ DRW_shgroup_attrib_float(grp, "tria", 4);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES);
+ static float point_size = 4.0f;
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "start", 1);
+ DRW_shgroup_attrib_float(grp, "end", 1);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Batch *geom)
+{
+ GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR);
+ static bool True = true;
+ static bool False = false;
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
+ DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
+ DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_bone_envelope_wire(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
+{
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_attrib_float(grp, "color", 4);
+ DRW_shgroup_attrib_float(grp, "radius_head", 1);
+ DRW_shgroup_attrib_float(grp, "radius_tail", 1);
+ DRW_shgroup_attrib_float(grp, "distance", 1);
+ DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat);
+
+ return grp;
+}
+
+DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
+{
+ static float light[3] = {0.0f, 0.0f, 1.0f};
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID);
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_attrib_float(grp, "color", 4);
+ DRW_shgroup_attrib_float(grp, "radius_head", 1);
+ DRW_shgroup_attrib_float(grp, "radius_tail", 1);
+ DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat);
+ DRW_shgroup_uniform_vec3(grp, "light", light, 1);
+
+ return grp;
+}
+
+
+/* ******************************************** COLOR UTILS *********************************************** */
+
+/* TODO FINISH */
+/**
+ * Get the wire color theme_id of an object based on it's state
+ * \a r_color is a way to get a pointer to the static color var associated
+ */
+int DRW_object_wire_theme_get(Object *ob, SceneLayer *sl, float **r_color)
+{
+ const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0;
+ const bool active = (sl->basact && sl->basact->object == ob);
+ /* confusing logic here, there are 2 methods of setting the color
+ * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
+ *
+ * note: no theme yet for 'colindex' */
+ int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
+
+ if (//(scene->obedit == NULL) &&
+ ((G.moving & G_TRANSFORM_OBJ) != 0) &&
+ ((ob->base_flag & BASE_SELECTED) != 0))
+ {
+ theme_id = TH_TRANSFORM;
+ }
+ else {
+ /* Sets the 'theme_id' or fallback to wire */
+ if ((ob->flag & OB_FROMGROUP) != 0) {
+ if ((ob->base_flag & BASE_SELECTED) != 0) {
+ theme_id = TH_GROUP_ACTIVE;
+ }
+ else {
+ theme_id = TH_GROUP;
+ }
+ }
+ else {
+ if ((ob->base_flag & BASE_SELECTED) != 0) {
+ theme_id = (active) ? TH_ACTIVE : TH_SELECT;
+ }
+ else {
+ if (ob->type == OB_LAMP) theme_id = TH_LAMP;
+ else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
+ else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
+ else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
+ /* fallback to TH_WIRE */
+ }
+ }
+ }
+
+ if (r_color != NULL) {
+ switch (theme_id) {
+ case TH_WIRE_EDIT: *r_color = ts.colorTransform; break;
+ case TH_ACTIVE: *r_color = ts.colorActive; break;
+ case TH_SELECT: *r_color = ts.colorSelect; break;
+ case TH_GROUP: *r_color = ts.colorGroup; break;
+ case TH_GROUP_ACTIVE: *r_color = ts.colorGroupActive; break;
+ case TH_TRANSFORM: *r_color = ts.colorTransform; break;
+ case OB_SPEAKER: *r_color = ts.colorSpeaker; break;
+ case OB_CAMERA: *r_color = ts.colorCamera; break;
+ case OB_EMPTY: *r_color = ts.colorEmpty; break;
+ case OB_LAMP: *r_color = ts.colorLamp; break;
+ default: *r_color = ts.colorWire; break;
+ }
+
+ /* uses darker active color for non-active + selected */
+ if ((theme_id == TH_GROUP_ACTIVE) && !active) {
+ *r_color = ts.colorGroupSelect;
+ }
+ }
+
+ return theme_id;
+}
+
+/* XXX This is utter shit, better find something more general */
+float *DRW_color_background_blend_get(int theme_id)
+{
+ static float colors[11][4];
+ float *ret;
+
+ switch (theme_id) {
+ case TH_WIRE_EDIT: ret = colors[0]; break;
+ case TH_ACTIVE: ret = colors[1]; break;
+ case TH_SELECT: ret = colors[2]; break;
+ case TH_GROUP: ret = colors[3]; break;
+ case TH_GROUP_ACTIVE: ret = colors[4]; break;
+ case TH_TRANSFORM: ret = colors[5]; break;
+ case OB_SPEAKER: ret = colors[6]; break;
+ case OB_CAMERA: ret = colors[7]; break;
+ case OB_EMPTY: ret = colors[8]; break;
+ case OB_LAMP: ret = colors[9]; break;
+ default: ret = colors[10]; break;
+ }
+
+ UI_GetThemeColorBlendShade4fv(theme_id, TH_BACK, 0.5, 0, ret);
+
+ return ret;
+}
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
new file mode 100644
index 00000000000..2c597a175ff
--- /dev/null
+++ b/source/blender/draw/intern/draw_common.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_common.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_COMMON_H__
+#define __DRAW_COMMON_H__
+
+struct DRWPass;
+struct DRWShadingGroup;
+struct Batch;
+struct Object;
+struct SceneLayer;
+
+/* Used as ubo but colors can be directly referenced as well */
+/* Keep in sync with: common_globals_lib.glsl (globalsBlock) */
+typedef struct GlobalsUboStorage {
+ /* UBOs data needs to be 16 byte aligned (size of vec4) */
+ float colorWire[4];
+ float colorWireEdit[4];
+ float colorActive[4];
+ float colorSelect[4];
+ float colorTransform[4];
+ float colorGroupActive[4];
+ float colorGroupSelect[4];
+ float colorGroup[4];
+ float colorLibrarySelect[4];
+ float colorLibrary[4];
+ float colorLamp[4];
+ float colorSpeaker[4];
+ float colorCamera[4];
+ float colorEmpty[4];
+ float colorVertex[4];
+ float colorVertexSelect[4];
+ float colorEditMeshActive[4];
+ float colorEdgeSelect[4];
+ float colorEdgeSeam[4];
+ float colorEdgeSharp[4];
+ float colorEdgeCrease[4];
+ float colorEdgeBWeight[4];
+ float colorEdgeFaceSelect[4];
+ float colorFace[4];
+ float colorFaceSelect[4];
+ float colorNormal[4];
+ float colorVNormal[4];
+ float colorLNormal[4];
+ float colorFaceDot[4];
+
+ float colorDeselect[4];
+ float colorOutline[4];
+ float colorLampNoAlpha[4];
+
+ float colorBackground[4];
+
+ float colorGrid[4];
+ float colorGridEmphasise[4];
+ float colorGridAxisX[4];
+ float colorGridAxisY[4];
+ float colorGridAxisZ[4];
+
+ /* Pack individual float at the end of the buffer to avoid alignement errors */
+ float sizeLampCenter, sizeLampCircle, sizeLampCircleShadow;
+ float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot;
+ float gridDistance, gridResolution, gridSubdivisions, gridScale;
+} GlobalsUboStorage;
+/* Keep in sync with globalsBlock in shaders */
+
+void DRW_globals_update(void);
+
+struct DRWShadingGroup *shgroup_dynlines_uniform_color(struct DRWPass *pass, float color[4]);
+struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, float color[4], float *size);
+struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, float color[4]);
+struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, float color[4]);
+struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct Batch *geom, float *size);
+struct DRWShadingGroup *shgroup_instance_objspace_solid(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+struct DRWShadingGroup *shgroup_instance_objspace_wire(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance_bone_envelope_wire(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+
+int DRW_object_wire_theme_get(struct Object *ob, struct SceneLayer *sl, float **r_color);
+float *DRW_color_background_blend_get(int theme_id);
+
+/* draw_armature.c */
+void DRW_shgroup_armature_object(
+ struct Object *ob, struct SceneLayer *sl,
+ struct DRWPass *pass_bone_solid, struct DRWPass *pass_bone_wire, struct DRWPass *pass_bone_envelope,
+ struct DRWShadingGroup *shgrp_relationship_lines);
+
+void DRW_shgroup_armature_pose(
+ struct Object *ob,
+ struct DRWPass *pass_bone_solid, struct DRWPass *pass_bone_wire, struct DRWPass *pass_bone_envelope,
+ struct DRWShadingGroup *shgrp_relationship_lines);
+
+void DRW_shgroup_armature_edit(
+ struct Object *ob,
+ struct DRWPass *pass_bone_solid, struct DRWPass *pass_bone_wire, struct DRWPass *pass_bone_envelope,
+ struct DRWShadingGroup *shgrp_relationship_lines);
+
+/* pose_mode.c */
+bool DRW_pose_mode_armature(
+ struct Object *ob, struct Object *active_ob);
+
+#endif /* __DRAW_COMMON_H__ */
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
new file mode 100644
index 00000000000..cf882717f8a
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager.c
@@ -0,0 +1,3309 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/intern/draw_manager.c
+ * \ingroup draw
+ */
+
+#include <stdio.h>
+
+#include "BLI_dynstr.h"
+#include "BLI_listbase.h"
+#include "BLI_rect.h"
+#include "BLI_string.h"
+
+#include "BIF_glutil.h"
+
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_object.h"
+#include "BKE_pbvh.h"
+#include "BKE_paint.h"
+
+#include "BLT_translation.h"
+#include "BLF_api.h"
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "ED_space_api.h"
+#include "ED_screen.h"
+
+#include "intern/gpu_codegen.h"
+#include "GPU_batch.h"
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+#include "GPU_framebuffer.h"
+#include "GPU_immediate.h"
+#include "GPU_lamp.h"
+#include "GPU_material.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+#include "GPU_uniformbuffer.h"
+#include "GPU_viewport.h"
+#include "GPU_matrix.h"
+
+#include "IMB_colormanagement.h"
+
+#include "PIL_time.h"
+
+#include "RE_engine.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "draw_manager_text.h"
+
+/* only for callbacks */
+#include "draw_cache_impl.h"
+
+#include "draw_mode_engines.h"
+
+#include "engines/clay/clay_engine.h"
+#include "engines/eevee/eevee_engine.h"
+#include "engines/basic/basic_engine.h"
+#include "engines/external/external_engine.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#define MAX_ATTRIB_NAME 32
+#define MAX_PASS_NAME 32
+
+/* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
+#define USE_GPU_SELECT
+
+#ifdef USE_GPU_SELECT
+# include "ED_view3d.h"
+# include "ED_armature.h"
+# include "GPU_select.h"
+#endif
+
+extern char datatoc_gpu_shader_2D_vert_glsl[];
+extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
+
+/* Prototypes. */
+static void DRW_engines_enable_external(void);
+
+/* Structures */
+typedef enum {
+ DRW_UNIFORM_BOOL,
+ DRW_UNIFORM_SHORT_TO_INT,
+ DRW_UNIFORM_SHORT_TO_FLOAT,
+ DRW_UNIFORM_INT,
+ DRW_UNIFORM_FLOAT,
+ DRW_UNIFORM_TEXTURE,
+ DRW_UNIFORM_BUFFER,
+ DRW_UNIFORM_MAT3,
+ DRW_UNIFORM_MAT4,
+ DRW_UNIFORM_BLOCK
+} DRWUniformType;
+
+typedef enum {
+ DRW_ATTRIB_INT,
+ DRW_ATTRIB_FLOAT,
+} DRWAttribType;
+
+struct DRWUniform {
+ struct DRWUniform *next, *prev;
+ DRWUniformType type;
+ int location;
+ int length;
+ int arraysize;
+ int bindloc;
+ const void *value;
+};
+
+typedef struct DRWAttrib {
+ struct DRWAttrib *next, *prev;
+ char name[MAX_ATTRIB_NAME];
+ int location;
+ int format_id;
+ int size; /* number of component */
+ int type;
+} DRWAttrib;
+
+struct DRWInterface {
+ ListBase uniforms; /* DRWUniform */
+ ListBase attribs; /* DRWAttrib */
+ int attribs_count;
+ int attribs_stride;
+ int attribs_size[16];
+ int attribs_loc[16];
+ /* matrices locations */
+ int model;
+ int modelinverse;
+ int modelview;
+ int modelviewinverse;
+ int projection;
+ int projectioninverse;
+ int view;
+ int viewinverse;
+ int modelviewprojection;
+ int viewprojection;
+ int viewprojectioninverse;
+ int normal;
+ int worldnormal;
+ int camtexfac;
+ int orcotexfac;
+ int eye;
+ /* Textures */
+ int tex_bind; /* next texture binding point */
+ /* UBO */
+ int ubo_bind; /* next ubo binding point */
+ /* Dynamic batch */
+ Batch *instance_batch; /* contains instances attributes */
+ GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */
+ int instance_count;
+ VertexFormat vbo_format;
+};
+
+struct DRWPass {
+ ListBase shgroups; /* DRWShadingGroup */
+ DRWState state;
+ char name[MAX_PASS_NAME];
+ /* use two query to not stall the cpu waiting for queries to complete */
+ unsigned int timer_queries[2];
+ /* alternate between front and back query */
+ unsigned int front_idx;
+ unsigned int back_idx;
+ bool wasdrawn; /* if it was drawn during this frame */
+};
+
+typedef struct DRWCallHeader {
+ void *next, *prev;
+#ifdef USE_GPU_SELECT
+ int select_id;
+#endif
+ uchar type;
+} DRWCallHeader;
+
+typedef struct DRWCall {
+ DRWCallHeader head;
+
+ float (*obmat)[4];
+ Batch *geometry;
+
+ Object *ob; /* Optionnal */
+} DRWCall;
+
+typedef struct DRWCallGenerate {
+ DRWCallHeader head;
+
+ float (*obmat)[4];
+
+ DRWCallGenerateFn *geometry_fn;
+ void *user_data;
+} DRWCallGenerate;
+
+typedef struct DRWCallDynamic {
+ DRWCallHeader head;
+
+ const void *data[];
+} DRWCallDynamic;
+
+struct DRWShadingGroup {
+ struct DRWShadingGroup *next, *prev;
+
+ GPUShader *shader; /* Shader to bind */
+ DRWInterface *interface; /* Uniforms pointers */
+ ListBase calls; /* DRWCall or DRWCallDynamic depending of type */
+ DRWState state_extra; /* State changes for this batch only (or'd with the pass's state) */
+ int type;
+
+ Batch *instance_geom; /* Geometry to instance */
+ Batch *batch_geom; /* Result of call batching */
+
+#ifdef USE_GPU_SELECT
+ /* backlink to pass we're in */
+ DRWPass *pass_parent;
+#endif
+};
+
+/* Used by DRWShadingGroup.type */
+enum {
+ DRW_SHG_NORMAL,
+ DRW_SHG_POINT_BATCH,
+ DRW_SHG_LINE_BATCH,
+ DRW_SHG_TRIANGLE_BATCH,
+ DRW_SHG_INSTANCE,
+};
+
+/* Used by DRWCall.type */
+enum {
+ /* A single batch */
+ DRW_CALL_SINGLE,
+ /* Uses a callback to draw with any number of batches. */
+ DRW_CALL_GENERATE,
+ /* Arbitrary number of multiple args. */
+ DRW_CALL_DYNAMIC,
+};
+
+/* only 16 bits long */
+enum {
+ STENCIL_SELECT = (1 << 0),
+ STENCIL_ACTIVE = (1 << 1),
+};
+
+/* Render State */
+static struct DRWGlobalState {
+ /* Rendering state */
+ GPUShader *shader;
+ ListBase bound_texs;
+ int tex_bind_id;
+
+ /* Managed by `DRW_state_set`, `DRW_state_reset` */
+ DRWState state;
+
+ /* Per viewport */
+ GPUViewport *viewport;
+ struct GPUFrameBuffer *default_framebuffer;
+ float size[2];
+ float screenvecs[2][3];
+ float pixsize;
+
+ struct {
+ unsigned int is_select : 1;
+ unsigned int is_depth : 1;
+ } options;
+
+ /* Current rendering context */
+ DRWContextState draw_ctx;
+
+ /* Convenience pointer to text_store owned by the viewport */
+ struct DRWTextStore **text_store_p;
+
+ ListBase enabled_engines; /* RenderEngineType */
+} DST = {NULL};
+
+ListBase DRW_engines = {NULL, NULL};
+
+#ifdef USE_GPU_SELECT
+static unsigned int g_DRW_select_id = (unsigned int)-1;
+
+void DRW_select_load_id(unsigned int id)
+{
+ BLI_assert(G.f & G_PICKSEL);
+ g_DRW_select_id = id;
+}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Textures (DRW_texture)
+ * \{ */
+
+static void drw_texture_get_format(DRWTextureFormat format, GPUTextureFormat *data_type, int *channels)
+{
+ switch (format) {
+ case DRW_TEX_RGBA_8: *data_type = GPU_RGBA8; break;
+ case DRW_TEX_RGBA_16: *data_type = GPU_RGBA16F; break;
+ case DRW_TEX_RGB_16: *data_type = GPU_RGB16F; break;
+ case DRW_TEX_RGB_11_11_10: *data_type = GPU_R11F_G11F_B10F; break;
+ case DRW_TEX_RG_16: *data_type = GPU_RG16F; break;
+ case DRW_TEX_RG_32: *data_type = GPU_RG32F; break;
+ case DRW_TEX_R_8: *data_type = GPU_R8; break;
+ case DRW_TEX_R_16: *data_type = GPU_R16F; break;
+ case DRW_TEX_R_32: *data_type = GPU_R32F; break;
+#if 0
+ case DRW_TEX_RGBA_32: *data_type = GPU_RGBA32F; break;
+ case DRW_TEX_RGB_8: *data_type = GPU_RGB8; break;
+ case DRW_TEX_RGB_32: *data_type = GPU_RGB32F; break;
+ case DRW_TEX_RG_8: *data_type = GPU_RG8; break;
+#endif
+ case DRW_TEX_DEPTH_16: *data_type = GPU_DEPTH_COMPONENT16; break;
+ case DRW_TEX_DEPTH_24: *data_type = GPU_DEPTH_COMPONENT24; break;
+ case DRW_TEX_DEPTH_32: *data_type = GPU_DEPTH_COMPONENT32F; break;
+ default :
+ /* file type not supported you must uncomment it from above */
+ BLI_assert(false);
+ break;
+ }
+
+ switch (format) {
+ case DRW_TEX_RGBA_8:
+ case DRW_TEX_RGBA_16:
+ case DRW_TEX_RGBA_32:
+ *channels = 4;
+ break;
+ case DRW_TEX_RGB_8:
+ case DRW_TEX_RGB_16:
+ case DRW_TEX_RGB_32:
+ case DRW_TEX_RGB_11_11_10:
+ *channels = 3;
+ break;
+ case DRW_TEX_RG_8:
+ case DRW_TEX_RG_16:
+ case DRW_TEX_RG_32:
+ *channels = 2;
+ break;
+ default:
+ *channels = 1;
+ break;
+ }
+}
+
+static void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
+{
+ GPU_texture_bind(tex, 0);
+ GPU_texture_filter_mode(tex, flags & DRW_TEX_FILTER);
+ if (flags & DRW_TEX_MIPMAP) {
+ GPU_texture_mipmap_mode(tex, true);
+ DRW_texture_generate_mipmaps(tex);
+ }
+ GPU_texture_wrap_mode(tex, flags & DRW_TEX_WRAP);
+ GPU_texture_compare_mode(tex, flags & DRW_TEX_COMPARE);
+ GPU_texture_unbind(tex);
+}
+
+GPUTexture *DRW_texture_create_1D(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
+{
+ GPUTexture *tex;
+ GPUTextureFormat data_type;
+ int channels;
+
+ drw_texture_get_format(format, &data_type, &channels);
+ tex = GPU_texture_create_1D_custom(w, channels, data_type, fpixels, NULL);
+ drw_texture_set_parameters(tex, flags);
+
+ return tex;
+}
+
+GPUTexture *DRW_texture_create_2D(int w, int h, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
+{
+ GPUTexture *tex;
+ GPUTextureFormat data_type;
+ int channels;
+
+ drw_texture_get_format(format, &data_type, &channels);
+ tex = GPU_texture_create_2D_custom(w, h, channels, data_type, fpixels, NULL);
+ drw_texture_set_parameters(tex, flags);
+
+ return tex;
+}
+
+GPUTexture *DRW_texture_create_2D_array(
+ int w, int h, int d, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
+{
+ GPUTexture *tex;
+ GPUTextureFormat data_type;
+ int channels;
+
+ drw_texture_get_format(format, &data_type, &channels);
+ tex = GPU_texture_create_2D_array_custom(w, h, d, channels, data_type, fpixels, NULL);
+ drw_texture_set_parameters(tex, flags);
+
+ return tex;
+}
+
+GPUTexture *DRW_texture_create_cube(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
+{
+ GPUTexture *tex;
+ GPUTextureFormat data_type;
+ int channels;
+
+ drw_texture_get_format(format, &data_type, &channels);
+ tex = GPU_texture_create_cube_custom(w, channels, data_type, fpixels, NULL);
+ drw_texture_set_parameters(tex, flags);
+
+ return tex;
+}
+
+void DRW_texture_generate_mipmaps(GPUTexture *tex)
+{
+ GPU_texture_bind(tex, 0);
+ GPU_texture_generate_mipmap(tex);
+ GPU_texture_unbind(tex);
+}
+
+void DRW_texture_free(GPUTexture *tex)
+{
+ GPU_texture_free(tex);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Uniform Buffer Object (DRW_uniformbuffer)
+ * \{ */
+
+GPUUniformBuffer *DRW_uniformbuffer_create(int size, const void *data)
+{
+ return GPU_uniformbuffer_create(size, data, NULL);
+}
+
+void DRW_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
+{
+ GPU_uniformbuffer_update(ubo, data);
+}
+
+void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
+{
+ GPU_uniformbuffer_free(ubo);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Shaders (DRW_shader)
+ * \{ */
+
+GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines)
+{
+ return GPU_shader_create(vert, frag, geom, NULL, defines);
+}
+
+GPUShader *DRW_shader_create_with_lib(
+ const char *vert, const char *geom, const char *frag, const char *lib, const char *defines)
+{
+ GPUShader *sh;
+ char *vert_with_lib = NULL;
+ char *frag_with_lib = NULL;
+ char *geom_with_lib = NULL;
+
+ DynStr *ds_vert = BLI_dynstr_new();
+ BLI_dynstr_append(ds_vert, lib);
+ BLI_dynstr_append(ds_vert, vert);
+ vert_with_lib = BLI_dynstr_get_cstring(ds_vert);
+ BLI_dynstr_free(ds_vert);
+
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, lib);
+ BLI_dynstr_append(ds_frag, frag);
+ frag_with_lib = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ if (geom) {
+ DynStr *ds_geom = BLI_dynstr_new();
+ BLI_dynstr_append(ds_geom, lib);
+ BLI_dynstr_append(ds_geom, geom);
+ geom_with_lib = BLI_dynstr_get_cstring(ds_geom);
+ BLI_dynstr_free(ds_geom);
+ }
+
+ sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines);
+
+ MEM_freeN(vert_with_lib);
+ MEM_freeN(frag_with_lib);
+ if (geom) {
+ MEM_freeN(geom_with_lib);
+ }
+
+ return sh;
+}
+
+GPUShader *DRW_shader_create_2D(const char *frag, const char *defines)
+{
+ return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines);
+}
+
+GPUShader *DRW_shader_create_3D(const char *frag, const char *defines)
+{
+ return GPU_shader_create(datatoc_gpu_shader_3D_vert_glsl, frag, NULL, NULL, defines);
+}
+
+GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
+{
+ return GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, frag, NULL, NULL, defines);
+}
+
+GPUShader *DRW_shader_create_3D_depth_only(void)
+{
+ return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
+}
+
+void DRW_shader_free(GPUShader *shader)
+{
+ GPU_shader_free(shader);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Interface (DRW_interface)
+ * \{ */
+
+static DRWInterface *DRW_interface_create(GPUShader *shader)
+{
+ DRWInterface *interface = MEM_mallocN(sizeof(DRWInterface), "DRWInterface");
+
+ interface->model = GPU_shader_get_uniform(shader, "ModelMatrix");
+ interface->modelinverse = GPU_shader_get_uniform(shader, "ModelMatrixInverse");
+ interface->modelview = GPU_shader_get_uniform(shader, "ModelViewMatrix");
+ interface->modelviewinverse = GPU_shader_get_uniform(shader, "ModelViewMatrixInverse");
+ interface->projection = GPU_shader_get_uniform(shader, "ProjectionMatrix");
+ interface->projectioninverse = GPU_shader_get_uniform(shader, "ProjectionMatrixInverse");
+ interface->view = GPU_shader_get_uniform(shader, "ViewMatrix");
+ interface->viewinverse = GPU_shader_get_uniform(shader, "ViewMatrixInverse");
+ interface->viewprojection = GPU_shader_get_uniform(shader, "ViewProjectionMatrix");
+ interface->viewprojectioninverse = GPU_shader_get_uniform(shader, "ViewProjectionMatrixInverse");
+ interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix");
+ interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
+ interface->worldnormal = GPU_shader_get_uniform(shader, "WorldNormalMatrix");
+ interface->camtexfac = GPU_shader_get_uniform(shader, "CameraTexCoFactors");
+ interface->orcotexfac = GPU_shader_get_uniform(shader, "OrcoTexCoFactors[0]");
+ interface->eye = GPU_shader_get_uniform(shader, "eye");
+ interface->instance_count = 0;
+ interface->attribs_count = 0;
+ interface->attribs_stride = 0;
+ interface->instance_vbo = 0;
+ interface->instance_batch = NULL;
+ interface->tex_bind = GPU_max_textures() - 1;
+ interface->ubo_bind = GPU_max_ubo_binds() - 1;
+
+ memset(&interface->vbo_format, 0, sizeof(VertexFormat));
+
+ BLI_listbase_clear(&interface->uniforms);
+ BLI_listbase_clear(&interface->attribs);
+
+ return interface;
+}
+
+#ifdef USE_GPU_SELECT
+static DRWInterface *DRW_interface_duplicate(DRWInterface *interface_src)
+{
+ DRWInterface *interface_dst = MEM_dupallocN(interface_src);
+ BLI_duplicatelist(&interface_dst->uniforms, &interface_src->uniforms);
+ BLI_duplicatelist(&interface_dst->attribs, &interface_src->attribs);
+ return interface_dst;
+}
+#endif
+
+static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
+ DRWUniformType type, const void *value, int length, int arraysize, int bindloc)
+{
+ DRWUniform *uni = MEM_mallocN(sizeof(DRWUniform), "DRWUniform");
+
+ if (type == DRW_UNIFORM_BLOCK) {
+ uni->location = GPU_shader_get_uniform_block(shgroup->shader, name);
+ }
+ else {
+ uni->location = GPU_shader_get_uniform(shgroup->shader, name);
+ }
+
+ BLI_assert(arraysize > 0);
+
+ uni->type = type;
+ uni->value = value;
+ uni->length = length;
+ uni->arraysize = arraysize;
+ uni->bindloc = bindloc; /* for textures */
+
+ if (uni->location == -1) {
+ if (G.debug & G_DEBUG)
+ fprintf(stderr, "Uniform '%s' not found!\n", name);
+ /* Nice to enable eventually, for now eevee uses uniforms that might not exist. */
+ // BLI_assert(0);
+ MEM_freeN(uni);
+ return;
+ }
+
+ BLI_addtail(&shgroup->interface->uniforms, uni);
+}
+
+static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType type, int size, bool dummy)
+{
+ DRWAttrib *attrib = MEM_mallocN(sizeof(DRWAttrib), "DRWAttrib");
+ GLuint program = GPU_shader_get_program(shgroup->shader);
+
+ attrib->location = glGetAttribLocation(program, name);
+ attrib->type = type;
+ attrib->size = size;
+
+/* Adding attribute even if not found for now (to keep memory alignment).
+ * Should ideally take vertex format automatically from batch eventually */
+#if 0
+ if (attrib->location == -1 && !dummy) {
+ if (G.debug & G_DEBUG)
+ fprintf(stderr, "Attribute '%s' not found!\n", name);
+ BLI_assert(0);
+ MEM_freeN(attrib);
+ return;
+ }
+#else
+ UNUSED_VARS(dummy);
+#endif
+
+ BLI_assert(BLI_strnlen(name, 32) < 32);
+ BLI_strncpy(attrib->name, name, 32);
+
+ shgroup->interface->attribs_count += 1;
+
+ BLI_addtail(&shgroup->interface->attribs, attrib);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Shading Group (DRW_shgroup)
+ * \{ */
+
+DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
+{
+ DRWShadingGroup *shgroup = MEM_mallocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
+
+ shgroup->type = DRW_SHG_NORMAL;
+ shgroup->shader = shader;
+ shgroup->interface = DRW_interface_create(shader);
+ shgroup->state_extra = 0;
+ shgroup->batch_geom = NULL;
+ shgroup->instance_geom = NULL;
+
+ BLI_addtail(&pass->shgroups, shgroup);
+ BLI_listbase_clear(&shgroup->calls);
+
+#ifdef USE_GPU_SELECT
+ shgroup->pass_parent = pass;
+#endif
+
+ return shgroup;
+}
+
+DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
+{
+ double time = 0.0; /* TODO make time variable */
+
+ /* TODO : Ideally we should not convert. But since the whole codegen
+ * is relying on GPUPass we keep it as is for now. */
+ GPUPass *gpupass = GPU_material_get_pass(material);
+
+ if (!gpupass) {
+ /* Shader compilation error */
+ return NULL;
+ }
+
+ struct GPUShader *shader = GPU_pass_shader(gpupass);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+
+ /* Converting dynamic GPUInput to DRWUniform */
+ ListBase *inputs = &gpupass->inputs;
+
+ for (GPUInput *input = inputs->first; input; input = input->next) {
+ /* Textures */
+ if (input->ima) {
+ GPUTexture *tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, time, 1);
+
+ if (input->bindtex) {
+ DRW_shgroup_uniform_texture(grp, input->shadername, tex);
+ }
+ }
+ /* Color Ramps */
+ else if (input->tex) {
+ DRW_shgroup_uniform_texture(grp, input->shadername, input->tex);
+ }
+ /* Floats */
+ else {
+ switch (input->type) {
+ case 1:
+ DRW_shgroup_uniform_float(grp, input->shadername, (float *)input->dynamicvec, 1);
+ break;
+ case 2:
+ DRW_shgroup_uniform_vec2(grp, input->shadername, (float *)input->dynamicvec, 1);
+ break;
+ case 3:
+ DRW_shgroup_uniform_vec3(grp, input->shadername, (float *)input->dynamicvec, 1);
+ break;
+ case 4:
+ DRW_shgroup_uniform_vec4(grp, input->shadername, (float *)input->dynamicvec, 1);
+ break;
+ case 9:
+ DRW_shgroup_uniform_mat3(grp, input->shadername, (float *)input->dynamicvec);
+ break;
+ case 16:
+ DRW_shgroup_uniform_mat4(grp, input->shadername, (float *)input->dynamicvec);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return grp;
+}
+
+DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, Batch *geom)
+{
+ DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass);
+
+ if (shgroup) {
+ shgroup->type = DRW_SHG_INSTANCE;
+ shgroup->instance_geom = geom;
+ }
+
+ return shgroup;
+}
+
+DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Batch *geom)
+{
+ DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+
+ shgroup->type = DRW_SHG_INSTANCE;
+ shgroup->instance_geom = geom;
+
+ return shgroup;
+}
+
+DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass)
+{
+ DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+
+ shgroup->type = DRW_SHG_POINT_BATCH;
+ DRW_shgroup_attrib_float(shgroup, "pos", 3);
+
+ return shgroup;
+}
+
+DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass)
+{
+ DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+
+ shgroup->type = DRW_SHG_LINE_BATCH;
+ DRW_shgroup_attrib_float(shgroup, "pos", 3);
+
+ return shgroup;
+}
+
+/* Very special batch. Use this if you position
+ * your vertices with the vertex shader
+ * and dont need any VBO attrib */
+DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size)
+{
+ DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+
+ shgroup->type = DRW_SHG_TRIANGLE_BATCH;
+ shgroup->interface->instance_count = size * 3;
+ DRW_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true);
+
+ return shgroup;
+}
+
+void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
+{
+ BLI_freelistN(&shgroup->calls);
+ BLI_freelistN(&shgroup->interface->uniforms);
+ BLI_freelistN(&shgroup->interface->attribs);
+
+ if (shgroup->interface->instance_vbo &&
+ (shgroup->interface->instance_batch == 0))
+ {
+ glDeleteBuffers(1, &shgroup->interface->instance_vbo);
+ }
+
+ MEM_freeN(shgroup->interface);
+
+ BATCH_DISCARD_ALL_SAFE(shgroup->batch_geom);
+}
+
+void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Batch *instances)
+{
+ BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
+ BLI_assert(shgroup->interface->instance_batch == NULL);
+
+ shgroup->interface->instance_batch = instances;
+}
+
+void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[4])
+{
+ BLI_assert(geom != NULL);
+
+ DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+
+ call->head.type = DRW_CALL_SINGLE;
+#ifdef USE_GPU_SELECT
+ call->head.select_id = g_DRW_select_id;
+#endif
+
+ call->obmat = obmat;
+ call->geometry = geom;
+
+ BLI_addtail(&shgroup->calls, call);
+}
+
+void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Batch *geom, Object *ob)
+{
+ BLI_assert(geom != NULL);
+
+ DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+
+ call->head.type = DRW_CALL_SINGLE;
+#ifdef USE_GPU_SELECT
+ call->head.select_id = g_DRW_select_id;
+#endif
+
+ call->obmat = ob->obmat;
+ call->geometry = geom;
+ call->ob = ob;
+
+ BLI_addtail(&shgroup->calls, call);
+}
+
+void DRW_shgroup_call_generate_add(
+ DRWShadingGroup *shgroup,
+ DRWCallGenerateFn *geometry_fn, void *user_data,
+ float (*obmat)[4])
+{
+ BLI_assert(geometry_fn != NULL);
+
+ DRWCallGenerate *call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate");
+
+ call->head.type = DRW_CALL_GENERATE;
+#ifdef USE_GPU_SELECT
+ call->head.select_id = g_DRW_select_id;
+#endif
+
+ call->obmat = obmat;
+
+ call->geometry_fn = geometry_fn;
+ call->user_data = user_data;
+
+ BLI_addtail(&shgroup->calls, call);
+}
+
+static void sculpt_draw_cb(
+ DRWShadingGroup *shgroup,
+ void (*draw_fn)(DRWShadingGroup *shgroup, Batch *geom),
+ void *user_data)
+{
+ Object *ob = user_data;
+ PBVH *pbvh = ob->sculpt->pbvh;
+
+ if (pbvh) {
+ BKE_pbvh_draw_cb(
+ pbvh, NULL, NULL, false,
+ (void (*)(void *, Batch *))draw_fn, shgroup);
+ }
+}
+
+void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, Object *ob, float (*obmat)[4])
+{
+ DRW_shgroup_call_generate_add(shgroup, sculpt_draw_cb, ob, obmat);
+}
+
+void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len)
+{
+ DRWInterface *interface = shgroup->interface;
+
+#ifdef USE_GPU_SELECT
+ if ((G.f & G_PICKSEL) && (interface->instance_count > 0)) {
+ shgroup = MEM_dupallocN(shgroup);
+ BLI_listbase_clear(&shgroup->calls);
+
+ shgroup->interface = interface = DRW_interface_duplicate(interface);
+ interface->instance_count = 0;
+
+ BLI_addtail(&shgroup->pass_parent->shgroups, shgroup);
+ }
+#endif
+
+ unsigned int data_size = sizeof(void *) * interface->attribs_count;
+ int size = sizeof(DRWCallDynamic) + data_size;
+
+ DRWCallDynamic *call = MEM_callocN(size, "DRWCallDynamic");
+
+ BLI_assert(attr_len == interface->attribs_count);
+ UNUSED_VARS_NDEBUG(attr_len);
+
+ call->head.type = DRW_CALL_DYNAMIC;
+#ifdef USE_GPU_SELECT
+ call->head.select_id = g_DRW_select_id;
+#endif
+
+ if (data_size != 0) {
+ memcpy((void *)call->data, attr, data_size);
+ }
+
+ interface->instance_count += 1;
+
+ BLI_addtail(&shgroup->calls, call);
+}
+
+/* Used for instancing with no attributes */
+void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count)
+{
+ DRWInterface *interface = shgroup->interface;
+
+ BLI_assert(interface->attribs_count == 0);
+
+ interface->instance_count = count;
+}
+
+/**
+ * State is added to #Pass.state while drawing.
+ * Use to temporarily enable draw options.
+ *
+ * Currently there is no way to disable (could add if needed).
+ */
+void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
+{
+ shgroup->state_extra |= state;
+}
+
+void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size)
+{
+ DRW_interface_attrib(shgroup, name, DRW_ATTRIB_FLOAT, size, false);
+}
+
+void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
+{
+ DRWInterface *interface = shgroup->interface;
+
+ if (interface->tex_bind < 0) {
+ /* TODO alert user */
+ printf("Not enough texture slot for %s\n", name);
+ return;
+ }
+
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1, interface->tex_bind--);
+}
+
+void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuffer *ubo)
+{
+ DRWInterface *interface = shgroup->interface;
+
+ /* Be carefull: there is also a limit per shader stage. Usually 1/3 of normal limit. */
+ if (interface->ubo_bind < 0) {
+ /* TODO alert user */
+ printf("Not enough ubo slots for %s\n", name);
+ return;
+ }
+
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1, interface->ubo_bind--);
+}
+
+void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
+{
+ DRWInterface *interface = shgroup->interface;
+
+ if (interface->tex_bind < 0) {
+ /* TODO alert user */
+ printf("Not enough texture slot for %s\n", name);
+ return;
+ }
+
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BUFFER, tex, 0, 1, interface->tex_bind--);
+}
+
+void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 1, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 2, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 3, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_short_to_int(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_INT, value, 1, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_short_to_float(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_FLOAT, value, 1, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 2, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 3, arraysize, 0);
+}
+
+void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT3, value, 9, 1, 0);
+}
+
+void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value)
+{
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1, 0);
+}
+
+/* Creates a VBO containing OGL primitives for all DRWCallDynamic */
+static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
+{
+ DRWInterface *interface = shgroup->interface;
+ int nbr = interface->instance_count;
+
+ PrimitiveType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? PRIM_POINTS :
+ (shgroup->type == DRW_SHG_TRIANGLE_BATCH) ? PRIM_TRIANGLES : PRIM_LINES;
+
+ if (nbr == 0)
+ return;
+
+ /* Upload Data */
+ if (interface->vbo_format.attrib_ct == 0) {
+ for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next) {
+ BLI_assert(attrib->size <= 4); /* matrices have no place here for now */
+ if (attrib->type == DRW_ATTRIB_FLOAT) {
+ attrib->format_id = VertexFormat_add_attrib(
+ &interface->vbo_format, attrib->name, COMP_F32, attrib->size, KEEP_FLOAT);
+ }
+ else if (attrib->type == DRW_ATTRIB_INT) {
+ attrib->format_id = VertexFormat_add_attrib(
+ &interface->vbo_format, attrib->name, COMP_I8, attrib->size, KEEP_INT);
+ }
+ else {
+ BLI_assert(false);
+ }
+ }
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&interface->vbo_format);
+ VertexBuffer_allocate_data(vbo, nbr);
+
+ int j = 0;
+ for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next, j++) {
+ int i = 0;
+ for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
+ VertexBuffer_set_attrib(vbo, attrib->format_id, j, call->data[i]);
+ }
+ }
+
+ /* TODO make the batch dynamic instead of freeing it every times */
+ if (shgroup->batch_geom)
+ Batch_discard_all(shgroup->batch_geom);
+
+ shgroup->batch_geom = Batch_create(type, vbo, NULL);
+}
+
+static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
+{
+ int i = 0;
+ int offset = 0;
+ DRWInterface *interface = shgroup->interface;
+ int buffer_size = 0;
+
+ if (interface->instance_batch != NULL) {
+ return;
+ }
+
+ /* TODO We still need this because gawain does not support Matrix attribs. */
+ if (interface->instance_count == 0) {
+ if (interface->instance_vbo) {
+ glDeleteBuffers(1, &interface->instance_vbo);
+ interface->instance_vbo = 0;
+ }
+ return;
+ }
+
+ /* only once */
+ if (interface->attribs_stride == 0) {
+ for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
+ BLI_assert(attrib->type == DRW_ATTRIB_FLOAT); /* Only float for now */
+ interface->attribs_stride += attrib->size;
+ interface->attribs_size[i] = attrib->size;
+ interface->attribs_loc[i] = attrib->location;
+ }
+ }
+
+ /* Gather Data */
+ buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count;
+ float *data = MEM_mallocN(buffer_size, "Instance VBO data");
+
+ for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next) {
+ for (int j = 0; j < interface->attribs_count; ++j) {
+ memcpy(data + offset, call->data[j], sizeof(float) * interface->attribs_size[j]);
+ offset += interface->attribs_size[j];
+ }
+ }
+
+ /* TODO poke mike to add this to gawain */
+ if (interface->instance_vbo) {
+ glDeleteBuffers(1, &interface->instance_vbo);
+ interface->instance_vbo = 0;
+ }
+
+ glGenBuffers(1, &interface->instance_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo);
+ glBufferData(GL_ARRAY_BUFFER, buffer_size, data, GL_STATIC_DRAW);
+
+ MEM_freeN(data);
+}
+
+static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
+{
+ if ((shgroup->interface->instance_vbo || shgroup->batch_geom) &&
+ (G.debug_value == 667))
+ {
+ return;
+ }
+
+ if (shgroup->type == DRW_SHG_INSTANCE) {
+ shgroup_dynamic_instance(shgroup);
+ }
+ else {
+ shgroup_dynamic_batch(shgroup);
+ }
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Passes (DRW_pass)
+ * \{ */
+
+DRWPass *DRW_pass_create(const char *name, DRWState state)
+{
+ DRWPass *pass = MEM_callocN(sizeof(DRWPass), name);
+ pass->state = state;
+ BLI_strncpy(pass->name, name, MAX_PASS_NAME);
+
+ BLI_listbase_clear(&pass->shgroups);
+
+ return pass;
+}
+
+void DRW_pass_free(DRWPass *pass)
+{
+ for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
+ DRW_shgroup_free(shgroup);
+ }
+
+ glDeleteQueries(2, pass->timer_queries);
+ BLI_freelistN(&pass->shgroups);
+}
+
+void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DRWShadingGroup *shgrp), void *userData)
+{
+ for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
+ callback(userData, shgroup);
+ }
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Draw (DRW_draw)
+ * \{ */
+
+static void DRW_state_set(DRWState state)
+{
+ if (DST.state == state) {
+ return;
+ }
+
+
+#define CHANGED_TO(f) \
+ ((DST.state & (f)) ? \
+ ((state & (f)) ? 0 : -1) : \
+ ((state & (f)) ? 1 : 0))
+
+#define CHANGED_ANY(f) \
+ ((DST.state & (f)) != (state & (f)))
+
+#define CHANGED_ANY_STORE_VAR(f, enabled) \
+ ((DST.state & (f)) != (enabled = (state & (f))))
+
+ /* Depth Write */
+ {
+ int test;
+ if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) {
+ if (test == 1) {
+ glDepthMask(GL_TRUE);
+ }
+ else {
+ glDepthMask(GL_FALSE);
+ }
+ }
+ }
+
+ /* Color Write */
+ {
+ int test;
+ if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) {
+ if (test == 1) {
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }
+ else {
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ }
+ }
+ }
+
+ /* Cull */
+ {
+ DRWState test;
+ if (CHANGED_ANY_STORE_VAR(
+ DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT,
+ test))
+ {
+ if (test) {
+ glEnable(GL_CULL_FACE);
+
+ if ((state & DRW_STATE_CULL_BACK) != 0) {
+ glCullFace(GL_BACK);
+ }
+ else if ((state & DRW_STATE_CULL_FRONT) != 0) {
+ glCullFace(GL_FRONT);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ glDisable(GL_CULL_FACE);
+ }
+ }
+ }
+
+ /* Depth Test */
+ {
+ DRWState test;
+ if (CHANGED_ANY_STORE_VAR(
+ DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER,
+ test))
+ {
+ if (test) {
+ glEnable(GL_DEPTH_TEST);
+
+ if (state & DRW_STATE_DEPTH_LESS) {
+ glDepthFunc(GL_LEQUAL);
+ }
+ else if (state & DRW_STATE_DEPTH_EQUAL) {
+ glDepthFunc(GL_EQUAL);
+ }
+ else if (state & DRW_STATE_DEPTH_GREATER) {
+ glDepthFunc(GL_GREATER);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ glDisable(GL_DEPTH_TEST);
+ }
+ }
+ }
+
+ /* Wire Width */
+ {
+ if (CHANGED_ANY(DRW_STATE_WIRE | DRW_STATE_WIRE_LARGE)) {
+ if ((state & DRW_STATE_WIRE) != 0) {
+ glLineWidth(1.0f);
+ }
+ else if ((state & DRW_STATE_WIRE_LARGE) != 0) {
+ glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
+ }
+ else {
+ /* do nothing */
+ }
+ }
+ }
+
+ /* Points Size */
+ {
+ int test;
+ if ((test = CHANGED_TO(DRW_STATE_POINT))) {
+ if (test == 1) {
+ GPU_enable_program_point_size();
+ glPointSize(5.0f);
+ }
+ else {
+ GPU_disable_program_point_size();
+ }
+ }
+ }
+
+ /* Blending (all buffer) */
+ {
+ int test;
+ if (CHANGED_ANY_STORE_VAR(
+ DRW_STATE_BLEND | DRW_STATE_ADDITIVE | DRW_STATE_MULTIPLY,
+ test))
+ {
+ if (test) {
+ glEnable(GL_BLEND);
+
+ if ((state & DRW_STATE_BLEND) != 0) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else if ((state & DRW_STATE_MULTIPLY) != 0) {
+ glBlendFunc(GL_DST_COLOR, GL_ZERO);
+ }
+ else if ((state & DRW_STATE_ADDITIVE) != 0) {
+ glBlendFunc(GL_ONE, GL_ONE);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ glDisable(GL_BLEND);
+ }
+ }
+ }
+
+ /* Line Stipple */
+ {
+ int test;
+ if (CHANGED_ANY_STORE_VAR(
+ DRW_STATE_STIPPLE_2 | DRW_STATE_STIPPLE_3 | DRW_STATE_STIPPLE_4,
+ test))
+ {
+ if (test) {
+ if ((state & DRW_STATE_STIPPLE_2) != 0) {
+ setlinestyle(2);
+ }
+ else if ((state & DRW_STATE_STIPPLE_3) != 0) {
+ setlinestyle(3);
+ }
+ else if ((state & DRW_STATE_STIPPLE_4) != 0) {
+ setlinestyle(4);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ setlinestyle(0);
+ }
+ }
+ }
+
+ /* Stencil */
+ {
+ DRWState test;
+ if (CHANGED_ANY_STORE_VAR(
+ DRW_STATE_WRITE_STENCIL_SELECT |
+ DRW_STATE_WRITE_STENCIL_ACTIVE |
+ DRW_STATE_TEST_STENCIL_SELECT |
+ DRW_STATE_TEST_STENCIL_ACTIVE,
+ test))
+ {
+ if (test) {
+ glEnable(GL_STENCIL_TEST);
+
+ /* Stencil Write */
+ if ((state & DRW_STATE_WRITE_STENCIL_SELECT) != 0) {
+ glStencilMask(STENCIL_SELECT);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_SELECT);
+ }
+ else if ((state & DRW_STATE_WRITE_STENCIL_ACTIVE) != 0) {
+ glStencilMask(STENCIL_ACTIVE);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_ACTIVE);
+ }
+ /* Stencil Test */
+ else if ((state & DRW_STATE_TEST_STENCIL_SELECT) != 0) {
+ glStencilMask(0x00); /* disable write */
+ glStencilFunc(GL_NOTEQUAL, 0xFF, STENCIL_SELECT);
+ }
+ else if ((state & DRW_STATE_TEST_STENCIL_ACTIVE) != 0) {
+ glStencilMask(0x00); /* disable write */
+ glStencilFunc(GL_NOTEQUAL, 0xFF, STENCIL_ACTIVE);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ /* disable write & test */
+ glStencilMask(0x00);
+ glStencilFunc(GL_ALWAYS, 1, 0xFF);
+ glDisable(GL_STENCIL_TEST);
+ }
+ }
+ }
+
+#undef CHANGED_TO
+#undef CHANGED_ANY
+#undef CHANGED_ANY_STORE_VAR
+
+ DST.state = state;
+}
+
+typedef struct DRWBoundTexture {
+ struct DRWBoundTexture *next, *prev;
+ GPUTexture *tex;
+} DRWBoundTexture;
+
+static void draw_geometry_prepare(
+ DRWShadingGroup *shgroup, const float (*obmat)[4], const float *texcoloc, const float *texcosize)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+ DRWInterface *interface = shgroup->interface;
+
+ float mvp[4][4], mv[4][4], mi[4][4], mvi[4][4], pi[4][4], n[3][3], wn[3][3];
+ float orcofacs[2][3] = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};
+ float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
+
+ bool do_pi = (interface->projectioninverse != -1);
+ bool do_mvp = (interface->modelviewprojection != -1);
+ bool do_mi = (interface->modelinverse != -1);
+ bool do_mv = (interface->modelview != -1);
+ bool do_mvi = (interface->modelviewinverse != -1);
+ bool do_n = (interface->normal != -1);
+ bool do_wn = (interface->worldnormal != -1);
+ bool do_eye = (interface->eye != -1);
+ bool do_orco = (interface->orcotexfac != -1) && (texcoloc != NULL) && (texcosize != NULL);
+
+ if (do_pi) {
+ invert_m4_m4(pi, rv3d->winmat);
+ }
+ if (do_mi) {
+ invert_m4_m4(mi, obmat);
+ }
+ if (do_mvp) {
+ mul_m4_m4m4(mvp, rv3d->persmat, obmat);
+ }
+ if (do_mv || do_mvi || do_n || do_eye) {
+ mul_m4_m4m4(mv, rv3d->viewmat, obmat);
+ }
+ if (do_mvi) {
+ invert_m4_m4(mvi, mv);
+ }
+ if (do_n || do_eye) {
+ copy_m3_m4(n, mv);
+ invert_m3(n);
+ transpose_m3(n);
+ }
+ if (do_wn) {
+ copy_m3_m4(wn, obmat);
+ invert_m3(wn);
+ transpose_m3(wn);
+ }
+ if (do_eye) {
+ /* Used by orthographic wires */
+ float tmp[3][3];
+ invert_m3_m3(tmp, n);
+ /* set eye vector, transformed to object coords */
+ mul_m3_v3(tmp, eye);
+ }
+ if (do_orco) {
+ mul_v3_v3fl(orcofacs[1], texcosize, 2.0f);
+ invert_v3(orcofacs[1]);
+ sub_v3_v3v3(orcofacs[0], texcoloc, texcosize);
+ negate_v3(orcofacs[0]);
+ mul_v3_v3(orcofacs[0], orcofacs[1]); /* result in a nice MADD in the shader */
+ }
+
+ /* Should be really simple */
+ /* step 1 : bind object dependent matrices */
+ if (interface->model != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->model, 16, 1, (float *)obmat);
+ }
+ if (interface->modelinverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->modelinverse, 16, 1, (float *)mi);
+ }
+ if (interface->modelviewprojection != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp);
+ }
+ if (interface->viewinverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->viewinverse, 16, 1, (float *)rv3d->viewinv);
+ }
+ if (interface->viewprojection != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat);
+ }
+ if (interface->viewprojectioninverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->viewprojectioninverse, 16, 1, (float *)rv3d->persinv);
+ }
+ if (interface->projection != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)rv3d->winmat);
+ }
+ if (interface->projectioninverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->projectioninverse, 16, 1, (float *)pi);
+ }
+ if (interface->view != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->view, 16, 1, (float *)rv3d->viewmat);
+ }
+ if (interface->modelview != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->modelview, 16, 1, (float *)mv);
+ }
+ if (interface->modelviewinverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->modelviewinverse, 16, 1, (float *)mvi);
+ }
+ if (interface->normal != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n);
+ }
+ if (interface->worldnormal != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->worldnormal, 9, 1, (float *)wn);
+ }
+ if (interface->camtexfac != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)rv3d->viewcamtexcofac);
+ }
+ if (interface->orcotexfac != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->orcotexfac, 3, 2, (float *)orcofacs);
+ }
+ if (interface->eye != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
+ }
+}
+
+static void draw_geometry_execute(DRWShadingGroup *shgroup, Batch *geom)
+{
+ DRWInterface *interface = shgroup->interface;
+ /* step 2 : bind vertex array & draw */
+ Batch_set_program(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
+ if (interface->instance_batch) {
+ Batch_draw_stupid_instanced_with_batch(geom, interface->instance_batch);
+ }
+ else if (interface->instance_vbo) {
+ Batch_draw_stupid_instanced(geom, interface->instance_vbo, interface->instance_count, interface->attribs_count,
+ interface->attribs_stride, interface->attribs_size, interface->attribs_loc);
+ }
+ else {
+ Batch_draw_stupid(geom);
+ }
+}
+
+static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4], Object *ob)
+{
+ float *texcoloc = NULL;
+ float *texcosize = NULL;
+
+ if (ob != NULL) {
+ BKE_object_obdata_texspace_get(ob, NULL, &texcoloc, &texcosize, NULL);
+ }
+
+ draw_geometry_prepare(shgroup, obmat, texcoloc, texcosize);
+
+ draw_geometry_execute(shgroup, geom);
+}
+
+static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
+{
+ BLI_assert(shgroup->shader);
+ BLI_assert(shgroup->interface);
+
+ DRWInterface *interface = shgroup->interface;
+ GPUTexture *tex;
+ int val;
+ float fval;
+
+ if (DST.shader != shgroup->shader) {
+ if (DST.shader) GPU_shader_unbind();
+ GPU_shader_bind(shgroup->shader);
+ DST.shader = shgroup->shader;
+ }
+
+ const bool is_normal = ELEM(shgroup->type, DRW_SHG_NORMAL);
+
+ if (!is_normal) {
+ shgroup_dynamic_batch_from_calls(shgroup);
+ }
+
+ DRW_state_set(pass_state | shgroup->state_extra);
+
+ /* Binding Uniform */
+ /* Don't check anything, Interface should already contain the least uniform as possible */
+ for (DRWUniform *uni = interface->uniforms.first; uni; uni = uni->next) {
+ DRWBoundTexture *bound_tex;
+
+ switch (uni->type) {
+ case DRW_UNIFORM_SHORT_TO_INT:
+ val = (int)*((short *)uni->value);
+ GPU_shader_uniform_vector_int(
+ shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)&val);
+ break;
+ case DRW_UNIFORM_SHORT_TO_FLOAT:
+ fval = (float)*((short *)uni->value);
+ GPU_shader_uniform_vector(
+ shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)&fval);
+ break;
+ case DRW_UNIFORM_BOOL:
+ case DRW_UNIFORM_INT:
+ GPU_shader_uniform_vector_int(
+ shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)uni->value);
+ break;
+ case DRW_UNIFORM_FLOAT:
+ case DRW_UNIFORM_MAT3:
+ case DRW_UNIFORM_MAT4:
+ GPU_shader_uniform_vector(
+ shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)uni->value);
+ break;
+ case DRW_UNIFORM_TEXTURE:
+ tex = (GPUTexture *)uni->value;
+ GPU_texture_bind(tex, uni->bindloc);
+
+ bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
+ bound_tex->tex = tex;
+ BLI_addtail(&DST.bound_texs, bound_tex);
+
+ GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
+ break;
+ case DRW_UNIFORM_BUFFER:
+ if (!DRW_state_is_fbo()) {
+ break;
+ }
+ tex = *((GPUTexture **)uni->value);
+ GPU_texture_bind(tex, uni->bindloc);
+
+ bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
+ bound_tex->tex = tex;
+ BLI_addtail(&DST.bound_texs, bound_tex);
+
+ GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
+ break;
+ case DRW_UNIFORM_BLOCK:
+ GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
+ GPU_shader_uniform_buffer(shgroup->shader, uni->location, (GPUUniformBuffer *)uni->value);
+ break;
+ }
+ }
+
+#ifdef USE_GPU_SELECT
+ /* use the first item because of selection we only ever add one */
+# define GPU_SELECT_LOAD_IF_PICKSEL(_call) \
+ if ((G.f & G_PICKSEL) && (_call)) { \
+ GPU_select_load_id((_call)->head.select_id); \
+ } ((void)0)
+# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \
+ if ((G.f & G_PICKSEL) && (_call_ls)->first) { \
+ BLI_assert(BLI_listbase_is_single(_call_ls)); \
+ GPU_select_load_id(((DRWCall *)(_call_ls)->first)->head.select_id); \
+ } ((void)0)
+#else
+# define GPU_SELECT_LOAD_IF_PICKSEL(call)
+# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(call)
+#endif
+
+ /* Rendering Calls */
+ if (!is_normal) {
+ /* Replacing multiple calls with only one */
+ float obmat[4][4];
+ unit_m4(obmat);
+
+ if (shgroup->type == DRW_SHG_INSTANCE &&
+ (interface->instance_count > 0 || interface->instance_batch != NULL))
+ {
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls);
+ draw_geometry(shgroup, shgroup->instance_geom, obmat, NULL);
+ }
+ else {
+ /* Some dynamic batch can have no geom (no call to aggregate) */
+ if (shgroup->batch_geom) {
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls);
+ draw_geometry(shgroup, shgroup->batch_geom, obmat, NULL);
+ }
+ }
+ }
+ else {
+ for (DRWCall *call = shgroup->calls.first; call; call = call->head.next) {
+ bool neg_scale = call->obmat && is_negative_m4(call->obmat);
+
+ /* Negative scale objects */
+ if (neg_scale) {
+ glFrontFace(GL_CW);
+ }
+
+ GPU_SELECT_LOAD_IF_PICKSEL(call);
+
+ if (call->head.type == DRW_CALL_SINGLE) {
+ draw_geometry(shgroup, call->geometry, call->obmat, call->ob);
+ }
+ else {
+ BLI_assert(call->head.type == DRW_CALL_GENERATE);
+ DRWCallGenerate *callgen = ((DRWCallGenerate *)call);
+ draw_geometry_prepare(shgroup, callgen->obmat, NULL, NULL);
+ callgen->geometry_fn(shgroup, draw_geometry_execute, callgen->user_data);
+ }
+
+ /* Reset state */
+ if (neg_scale) {
+ glFrontFace(GL_CCW);
+ }
+ }
+ }
+
+ /* TODO: remove, (currently causes alpha issue with sculpt, need to investigate) */
+ DRW_state_reset();
+}
+
+void DRW_draw_pass(DRWPass *pass)
+{
+ /* Start fresh */
+ DST.shader = NULL;
+ DST.tex_bind_id = 0;
+
+ DRW_state_set(pass->state);
+ BLI_listbase_clear(&DST.bound_texs);
+
+ /* Init Timer queries */
+ if (pass->timer_queries[0] == 0) {
+ pass->front_idx = 0;
+ pass->back_idx = 1;
+
+ glGenQueries(2, pass->timer_queries);
+
+ /* dummy query, avoid gl error */
+ glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->front_idx]);
+ glEndQuery(GL_TIME_ELAPSED);
+ }
+ else {
+ /* swap indices */
+ unsigned int tmp = pass->back_idx;
+ pass->back_idx = pass->front_idx;
+ pass->front_idx = tmp;
+ }
+
+ if (!pass->wasdrawn) {
+ /* issue query for the next frame */
+ glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->back_idx]);
+ }
+
+ for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
+ draw_shgroup(shgroup, pass->state);
+ }
+
+ /* Clear Bound textures */
+ for (DRWBoundTexture *bound_tex = DST.bound_texs.first; bound_tex; bound_tex = bound_tex->next) {
+ GPU_texture_unbind(bound_tex->tex);
+ }
+ DST.tex_bind_id = 0;
+ BLI_freelistN(&DST.bound_texs);
+
+ if (DST.shader) {
+ GPU_shader_unbind();
+ DST.shader = NULL;
+ }
+
+ if (!pass->wasdrawn) {
+ glEndQuery(GL_TIME_ELAPSED);
+ }
+
+ pass->wasdrawn = true;
+}
+
+void DRW_draw_callbacks_pre_scene(void)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
+}
+
+void DRW_draw_callbacks_post_scene(void)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
+}
+
+/* Reset state to not interfer with other UI drawcall */
+void DRW_state_reset_ex(DRWState state)
+{
+ DST.state = ~state;
+ DRW_state_set(state);
+}
+
+void DRW_state_reset(void)
+{
+ DRW_state_reset_ex(DRW_STATE_DEFAULT);
+}
+
+/** \} */
+
+
+struct DRWTextStore *DRW_text_cache_ensure(void)
+{
+ BLI_assert(DST.text_store_p);
+ if (*DST.text_store_p == NULL) {
+ *DST.text_store_p = DRW_text_cache_create();
+ }
+ return *DST.text_store_p;
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Settings
+ * \{ */
+
+bool DRW_object_is_renderable(Object *ob)
+{
+ Scene *scene = DST.draw_ctx.scene;
+ Object *obedit = scene->obedit;
+
+ if (ob->type == OB_MESH) {
+ if (ob == obedit) {
+ IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
+ bool do_show_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire");
+ if (do_show_occlude_wire) {
+ return false;
+ }
+ bool do_show_weight = BKE_collection_engine_property_value_get_bool(props, "show_weight");
+ if (do_show_weight) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool DRW_object_is_flat_normal(Object *ob)
+{
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Framebuffers (DRW_framebuffer)
+ * \{ */
+
+static GPUTextureFormat convert_tex_format(int fbo_format, int *channels, bool *is_depth)
+{
+ *is_depth = ELEM(fbo_format, DRW_TEX_DEPTH_16, DRW_TEX_DEPTH_24);
+
+ switch (fbo_format) {
+ case DRW_TEX_R_16: *channels = 1; return GPU_R16F;
+ case DRW_TEX_R_32: *channels = 1; return GPU_R32F;
+ case DRW_TEX_RG_16: *channels = 2; return GPU_RG16F;
+ case DRW_TEX_RGBA_8: *channels = 4; return GPU_RGBA8;
+ case DRW_TEX_RGBA_16: *channels = 4; return GPU_RGBA16F;
+ case DRW_TEX_RGBA_32: *channels = 4; return GPU_RGBA32F;
+ case DRW_TEX_DEPTH_24: *channels = 1; return GPU_DEPTH_COMPONENT24;
+ case DRW_TEX_RGB_11_11_10: *channels = 3; return GPU_R11F_G11F_B10F;
+ default:
+ BLI_assert(false && "Texture format unsupported as render target!");
+ *channels = 4; return GPU_RGBA8;
+ }
+}
+
+void DRW_framebuffer_init(
+ struct GPUFrameBuffer **fb, void *engine_type, int width, int height,
+ DRWFboTexture textures[MAX_FBO_TEX], int textures_len)
+{
+ BLI_assert(textures_len <= MAX_FBO_TEX);
+
+ bool create_fb = false;
+ int color_attachment = -1;
+
+ if (!*fb) {
+ *fb = GPU_framebuffer_create();
+ create_fb = true;
+ }
+
+ for (int i = 0; i < textures_len; ++i) {
+ int channels;
+ bool is_depth;
+
+ DRWFboTexture fbotex = textures[i];
+ bool is_temp = (fbotex.flag & DRW_TEX_TEMP) != 0;
+
+ GPUTextureFormat gpu_format = convert_tex_format(fbotex.format, &channels, &is_depth);
+
+ if (!*fbotex.tex || is_temp) {
+ /* Temp textures need to be queried each frame, others not. */
+ if (is_temp) {
+ *fbotex.tex = GPU_viewport_texture_pool_query(DST.viewport, engine_type, width, height, channels, gpu_format);
+ }
+ else if (create_fb) {
+ *fbotex.tex = GPU_texture_create_2D_custom(width, height, channels, gpu_format, NULL, NULL);
+ }
+ }
+
+ if (create_fb) {
+ if (!is_depth) {
+ ++color_attachment;
+ }
+ drw_texture_set_parameters(*fbotex.tex, fbotex.flag);
+ GPU_framebuffer_texture_attach(*fb, *fbotex.tex, color_attachment, 0);
+ }
+ }
+
+ if (create_fb) {
+ if (!GPU_framebuffer_check_valid(*fb, NULL)) {
+ printf("Error invalid framebuffer\n");
+ }
+
+ /* Detach temp textures */
+ for (int i = 0; i < textures_len; ++i) {
+ DRWFboTexture fbotex = textures[i];
+
+ if ((fbotex.flag & DRW_TEX_TEMP) != 0) {
+ GPU_framebuffer_texture_detach(*fbotex.tex);
+ }
+ }
+
+ GPU_framebuffer_bind(DST.default_framebuffer);
+ }
+}
+
+void DRW_framebuffer_free(struct GPUFrameBuffer *fb)
+{
+ GPU_framebuffer_free(fb);
+}
+
+void DRW_framebuffer_bind(struct GPUFrameBuffer *fb)
+{
+ GPU_framebuffer_bind(fb);
+}
+
+void DRW_framebuffer_clear(bool color, bool depth, bool stencil, float clear_col[4], float clear_depth)
+{
+ if (color) {
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
+ }
+ if (depth) {
+ glDepthMask(GL_TRUE);
+ glClearDepth(clear_depth);
+ }
+ if (stencil) {
+ glStencilMask(0xFF);
+ }
+ glClear(((color) ? GL_COLOR_BUFFER_BIT : 0) |
+ ((depth) ? GL_DEPTH_BUFFER_BIT : 0) |
+ ((stencil) ? GL_STENCIL_BUFFER_BIT : 0));
+}
+
+void DRW_framebuffer_read_data(int x, int y, int w, int h, int channels, int slot, float *data)
+{
+ GLenum type;
+ switch (channels) {
+ case 1: type = GL_RED; break;
+ case 2: type = GL_RG; break;
+ case 3: type = GL_RGB; break;
+ case 4: type = GL_RGBA; break;
+ default:
+ BLI_assert(false && "wrong number of read channels");
+ return;
+ }
+ glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
+ glReadPixels(x, y, w, h, type, GL_FLOAT, data);
+}
+
+void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
+{
+ GPU_framebuffer_texture_attach(fb, tex, slot, mip);
+}
+
+void DRW_framebuffer_texture_detach(GPUTexture *tex)
+{
+ GPU_framebuffer_texture_detach(tex);
+}
+
+void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth)
+{
+ GPU_framebuffer_blit(fb_read, 0, fb_write, 0, depth);
+}
+
+void DRW_framebuffer_viewport_size(struct GPUFrameBuffer *UNUSED(fb_read), int w, int h)
+{
+ glViewport(0, 0, w, h);
+}
+
+/* Use color management profile to draw texture to framebuffer */
+void DRW_transform_to_display(GPUTexture *tex)
+{
+ DRW_state_set(DRW_STATE_WRITE_COLOR);
+
+ VertexFormat *vert_format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(vert_format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texco = VertexFormat_add_attrib(vert_format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+
+ const float dither = 1.0f;
+
+ bool use_ocio = false;
+
+ if (DST.draw_ctx.evil_C != NULL) {
+ use_ocio = IMB_colormanagement_setup_glsl_draw_from_space_ctx(DST.draw_ctx.evil_C, NULL, dither, false);
+ }
+
+ if (!use_ocio) {
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
+ immUniform1i("image", 0);
+ }
+
+ GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
+
+ float mat[4][4];
+ unit_m4(mat);
+ immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
+
+ /* Full screen triangle */
+ immBegin(PRIM_TRIANGLES, 3);
+ immAttrib2f(texco, 0.0f, 0.0f);
+ immVertex2f(pos, -1.0f, -1.0f);
+
+ immAttrib2f(texco, 2.0f, 0.0f);
+ immVertex2f(pos, 3.0f, -1.0f);
+
+ immAttrib2f(texco, 0.0f, 2.0f);
+ immVertex2f(pos, -1.0f, 3.0f);
+ immEnd();
+
+ GPU_texture_unbind(tex);
+
+ if (use_ocio) {
+ IMB_colormanagement_finish_glsl_draw();
+ }
+ else {
+ immUnbindProgram();
+ }
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Viewport (DRW_viewport)
+ * \{ */
+
+static void *DRW_viewport_engine_data_get(void *engine_type)
+{
+ void *data = GPU_viewport_engine_data_get(DST.viewport, engine_type);
+
+ if (data == NULL) {
+ data = GPU_viewport_engine_data_create(DST.viewport, engine_type);
+ }
+ return data;
+}
+
+void DRW_engine_viewport_data_size_get(
+ const void *engine_type_v,
+ int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len)
+{
+ const DrawEngineType *engine_type = engine_type_v;
+
+ if (r_fbl_len) {
+ *r_fbl_len = engine_type->vedata_size->fbl_len;
+ }
+ if (r_txl_len) {
+ *r_txl_len = engine_type->vedata_size->txl_len;
+ }
+ if (r_psl_len) {
+ *r_psl_len = engine_type->vedata_size->psl_len;
+ }
+ if (r_stl_len) {
+ *r_stl_len = engine_type->vedata_size->stl_len;
+ }
+}
+
+const float *DRW_viewport_size_get(void)
+{
+ return &DST.size[0];
+}
+
+const float *DRW_viewport_screenvecs_get(void)
+{
+ return &DST.screenvecs[0][0];
+}
+
+const float *DRW_viewport_pixelsize_get(void)
+{
+ return &DST.pixsize;
+}
+
+/* It also stores viewport variable to an immutable place: DST
+ * This is because a cache uniform only store reference
+ * to its value. And we don't want to invalidate the cache
+ * if this value change per viewport */
+static void DRW_viewport_var_init(void)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+
+ /* Refresh DST.size */
+ if (DST.viewport) {
+ int size[2];
+ GPU_viewport_size_get(DST.viewport, size);
+ DST.size[0] = size[0];
+ DST.size[1] = size[1];
+
+ DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
+ DST.default_framebuffer = fbl->default_fb;
+ }
+ else {
+ DST.size[0] = 0;
+ DST.size[1] = 0;
+
+ DST.default_framebuffer = NULL;
+ }
+ /* Refresh DST.screenvecs */
+ copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
+ copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
+ normalize_v3(DST.screenvecs[0]);
+ normalize_v3(DST.screenvecs[1]);
+
+ /* Refresh DST.pixelsize */
+ DST.pixsize = rv3d->pixsize;
+}
+
+void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+
+ switch (type) {
+ case DRW_MAT_PERS:
+ copy_m4_m4(mat, rv3d->persmat);
+ break;
+ case DRW_MAT_PERSINV:
+ copy_m4_m4(mat, rv3d->persinv);
+ break;
+ case DRW_MAT_VIEW:
+ copy_m4_m4(mat, rv3d->viewmat);
+ break;
+ case DRW_MAT_VIEWINV:
+ copy_m4_m4(mat, rv3d->viewinv);
+ break;
+ case DRW_MAT_WIN:
+ copy_m4_m4(mat, rv3d->winmat);
+ break;
+ case DRW_MAT_WININV:
+ invert_m4_m4(mat, rv3d->winmat);
+ break;
+ default:
+ BLI_assert(!"Matrix type invalid");
+ break;
+ }
+}
+
+bool DRW_viewport_is_persp_get(void)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+ return rv3d->is_persp;
+}
+
+DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
+{
+ return GPU_viewport_framebuffer_list_get(DST.viewport);
+}
+
+DefaultTextureList *DRW_viewport_texture_list_get(void)
+{
+ return GPU_viewport_texture_list_get(DST.viewport);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/** \name SceneLayers (DRW_scenelayer)
+ * \{ */
+
+void **DRW_scene_layer_engine_data_get(DrawEngineType *engine_type, void (*callback)(void *storage))
+{
+ SceneLayerEngineData *sled;
+
+ for (sled = DST.draw_ctx.sl->drawdata.first; sled; sled = sled->next) {
+ if (sled->engine_type == engine_type) {
+ return &sled->storage;
+ }
+ }
+
+ sled = MEM_callocN(sizeof(SceneLayerEngineData), "SceneLayerEngineData");
+ sled->engine_type = engine_type;
+ sled->free = callback;
+ BLI_addtail(&DST.draw_ctx.sl->drawdata, sled);
+
+ return &sled->storage;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Objects (DRW_object)
+ * \{ */
+
+void **DRW_object_engine_data_get(
+ Object *ob, DrawEngineType *engine_type, void (*callback)(void *storage))
+{
+ ObjectEngineData *oed;
+
+ for (oed = ob->drawdata.first; oed; oed = oed->next) {
+ if (oed->engine_type == engine_type) {
+ return &oed->storage;
+ }
+ }
+
+ oed = MEM_callocN(sizeof(ObjectEngineData), "ObjectEngineData");
+ oed->engine_type = engine_type;
+ oed->free = callback;
+ BLI_addtail(&ob->drawdata, oed);
+
+ return &oed->storage;
+}
+
+/* XXX There is definitly some overlap between this and DRW_object_engine_data_get.
+ * We should get rid of one of the two. */
+LampEngineData *DRW_lamp_engine_data_get(Object *ob, RenderEngineType *engine_type)
+{
+ BLI_assert(ob->type == OB_LAMP);
+
+ Scene *scene = DST.draw_ctx.scene;
+
+ /* TODO Dupliobjects */
+ /* TODO Should be per scenelayer */
+ return GPU_lamp_engine_data_get(scene, ob, NULL, engine_type);
+}
+
+void DRW_lamp_engine_data_free(LampEngineData *led)
+{
+ GPU_lamp_engine_data_free(led);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Rendering (DRW_engines)
+ * \{ */
+
+#define TIMER_FALLOFF 0.1f
+
+static void DRW_engines_init(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (engine->engine_init) {
+ engine->engine_init(data);
+ }
+
+ double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
+ data->init_time = data->init_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
+ }
+}
+
+static void DRW_engines_cache_init(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+
+ if (data->text_draw_cache) {
+ DRW_text_cache_destroy(data->text_draw_cache);
+ data->text_draw_cache = NULL;
+ }
+ if (DST.text_store_p == NULL) {
+ DST.text_store_p = &data->text_draw_cache;
+ }
+
+ double stime = PIL_check_seconds_timer();
+ data->cache_time = 0.0;
+
+ if (engine->cache_init) {
+ engine->cache_init(data);
+ }
+
+ data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
+ }
+}
+
+static void DRW_engines_cache_populate(Object *ob)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (engine->cache_populate) {
+ engine->cache_populate(data, ob);
+ }
+
+ data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
+ }
+}
+
+static void DRW_engines_cache_finish(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (engine->cache_finish) {
+ engine->cache_finish(data);
+ }
+
+ data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
+ }
+}
+
+static void DRW_engines_draw_background(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (engine->draw_background) {
+ engine->draw_background(data);
+ return;
+ }
+
+ double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
+ data->background_time = data->background_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
+ }
+
+ /* No draw_background found, doing default background */
+ DRW_draw_background();
+}
+
+static void DRW_engines_draw_scene(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (engine->draw_scene) {
+ engine->draw_scene(data);
+ }
+
+ double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
+ data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
+ }
+}
+
+static void DRW_engines_draw_text(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (data->text_draw_cache) {
+ DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.v3d, DST.draw_ctx.ar, false);
+ }
+
+ double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
+ data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
+ }
+}
+
+#define MAX_INFO_LINES 10
+
+/**
+ * Returns the offset required for the drawing of engines info.
+ */
+int DRW_draw_region_engine_info_offset(void)
+{
+ int lines = 0;
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+
+ /* Count the number of lines. */
+ if (data->info[0] != '\0') {
+ lines++;
+ char *c = data->info;
+ while (*c++ != '\0') {
+ if (*c == '\n') {
+ lines++;
+ }
+ }
+ }
+ }
+ return MIN2(MAX_INFO_LINES, lines) * UI_UNIT_Y;
+}
+
+/**
+ * Actual drawing;
+ */
+void DRW_draw_region_engine_info(void)
+{
+ const char *info_array_final[MAX_INFO_LINES + 1];
+ char info_array[MAX_INFO_LINES][GPU_INFO_SIZE]; /* This should be maxium number of engines running at the same time. */
+ int i = 0;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ARegion *ar = draw_ctx->ar;
+ float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
+
+ UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
+ mul_v3_fl(fill_color, fill_color[3]);
+
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+
+ if (data->info[0] != '\0') {
+ char *chr_current = data->info;
+ char *chr_start = chr_current;
+ int line_len = 0;
+
+ while (*chr_current++ != '\0') {
+ line_len++;
+ if (*chr_current == '\n') {
+ BLI_strncpy(info_array[i++], chr_start, line_len + 1);
+ /* Re-start counting. */
+ chr_start = chr_current + 1;
+ line_len = -1;
+ }
+ }
+
+ BLI_strncpy(info_array[i++], chr_start, line_len + 1);
+
+ if (i >= MAX_INFO_LINES) {
+ break;
+ }
+ }
+ }
+
+ for (int j = 0; j < i; j++) {
+ info_array_final[j] = info_array[j];
+ }
+ info_array_final[i] = NULL;
+
+ if (info_array[0] != NULL) {
+ ED_region_info_draw_multiline(ar, info_array_final, fill_color, true);
+ }
+}
+
+#undef MAX_INFO_LINES
+
+static void use_drw_engine(DrawEngineType *engine)
+{
+ LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
+ ld->data = engine;
+ BLI_addtail(&DST.enabled_engines, ld);
+}
+
+/* TODO revisit this when proper layering is implemented */
+/* Gather all draw engines needed and store them in DST.enabled_engines
+ * That also define the rendering order of engines */
+static void DRW_engines_enable_from_engine(const Scene *scene)
+{
+ /* TODO layers */
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ if (type->draw_engine != NULL) {
+ use_drw_engine(type->draw_engine);
+ }
+
+ if ((type->flag & RE_INTERNAL) == 0) {
+ DRW_engines_enable_external();
+ }
+}
+
+static void DRW_engines_enable_from_object_mode(void)
+{
+ use_drw_engine(&draw_engine_object_type);
+}
+
+static void DRW_engines_enable_from_mode(int mode)
+{
+ switch (mode) {
+ case CTX_MODE_EDIT_MESH:
+ use_drw_engine(&draw_engine_edit_mesh_type);
+ break;
+ case CTX_MODE_EDIT_CURVE:
+ use_drw_engine(&draw_engine_edit_curve_type);
+ break;
+ case CTX_MODE_EDIT_SURFACE:
+ use_drw_engine(&draw_engine_edit_surface_type);
+ break;
+ case CTX_MODE_EDIT_TEXT:
+ use_drw_engine(&draw_engine_edit_text_type);
+ break;
+ case CTX_MODE_EDIT_ARMATURE:
+ use_drw_engine(&draw_engine_edit_armature_type);
+ break;
+ case CTX_MODE_EDIT_METABALL:
+ use_drw_engine(&draw_engine_edit_metaball_type);
+ break;
+ case CTX_MODE_EDIT_LATTICE:
+ use_drw_engine(&draw_engine_edit_lattice_type);
+ break;
+ case CTX_MODE_POSE:
+ use_drw_engine(&draw_engine_pose_type);
+ break;
+ case CTX_MODE_SCULPT:
+ use_drw_engine(&draw_engine_sculpt_type);
+ break;
+ case CTX_MODE_PAINT_WEIGHT:
+ use_drw_engine(&draw_engine_pose_type);
+ use_drw_engine(&draw_engine_paint_weight_type);
+ break;
+ case CTX_MODE_PAINT_VERTEX:
+ use_drw_engine(&draw_engine_paint_vertex_type);
+ break;
+ case CTX_MODE_PAINT_TEXTURE:
+ use_drw_engine(&draw_engine_paint_texture_type);
+ break;
+ case CTX_MODE_PARTICLE:
+ use_drw_engine(&draw_engine_particle_type);
+ break;
+ case CTX_MODE_OBJECT:
+ break;
+ default:
+ BLI_assert(!"Draw mode invalid");
+ break;
+ }
+}
+
+/**
+ * Use for select and depth-drawing.
+ */
+static void DRW_engines_enable_basic(void)
+{
+ use_drw_engine(DRW_engine_viewport_basic_type.draw_engine);
+}
+
+/**
+ * Use for external render engines.
+ */
+static void DRW_engines_enable_external(void)
+{
+ use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
+}
+
+static void DRW_engines_enable(const Scene *scene, SceneLayer *sl, const View3D *v3d)
+{
+ const int mode = CTX_data_mode_enum_ex(scene->obedit, OBACT_NEW);
+ DRW_engines_enable_from_engine(scene);
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ DRW_engines_enable_from_object_mode();
+ DRW_engines_enable_from_mode(mode);
+ }
+}
+
+static void DRW_engines_disable(void)
+{
+ BLI_freelistN(&DST.enabled_engines);
+}
+
+static unsigned int DRW_engines_get_hash(void)
+{
+ unsigned int hash = 0;
+ /* The cache depends on enabled engines */
+ /* FIXME : if collision occurs ... segfault */
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ hash += BLI_ghashutil_strhash_p(engine->idname);
+ }
+
+ return hash;
+}
+
+static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size)
+{
+ BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit,
+ rect->ymax - (3 + v++) * U.widget_unit, 0.0f,
+ txt, size);
+}
+
+/* CPU stats */
+static void DRW_debug_cpu_stats(void)
+{
+ int u, v;
+ double cache_tot_time = 0.0, init_tot_time = 0.0, background_tot_time = 0.0, render_tot_time = 0.0, tot_time = 0.0;
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ rcti rect;
+ struct ARegion *ar = DST.draw_ctx.ar;
+ ED_region_visible_rect(ar, &rect);
+
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+
+ /* row by row */
+ v = 0; u = 0;
+ /* Label row */
+ char col_label[32];
+ sprintf(col_label, "Engine");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(col_label, "Cache");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(col_label, "Init");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(col_label, "Background");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(col_label, "Render");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(col_label, "Total (w/o cache)");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ v++;
+
+ /* Engines rows */
+ char time_to_txt[16];
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ u = 0;
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+
+ draw_stat(&rect, u++, v, engine->idname, sizeof(engine->idname));
+
+ cache_tot_time += data->cache_time;
+ sprintf(time_to_txt, "%.2fms", data->cache_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+
+ init_tot_time += data->init_time;
+ sprintf(time_to_txt, "%.2fms", data->init_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+
+ background_tot_time += data->background_time;
+ sprintf(time_to_txt, "%.2fms", data->background_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+
+ render_tot_time += data->render_time;
+ sprintf(time_to_txt, "%.2fms", data->render_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+
+ tot_time += data->init_time + data->background_time + data->render_time;
+ sprintf(time_to_txt, "%.2fms", data->init_time + data->background_time + data->render_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+ v++;
+ }
+
+ /* Totals row */
+ u = 0;
+ sprintf(col_label, "Sub Total");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(time_to_txt, "%.2fms", cache_tot_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+ sprintf(time_to_txt, "%.2fms", init_tot_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+ sprintf(time_to_txt, "%.2fms", background_tot_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+ sprintf(time_to_txt, "%.2fms", render_tot_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+ sprintf(time_to_txt, "%.2fms", tot_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+}
+
+/* Display GPU time for each passes */
+static void DRW_debug_gpu_stats(void)
+{
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ rcti rect;
+ struct ARegion *ar = DST.draw_ctx.ar;
+ ED_region_visible_rect(ar, &rect);
+
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+
+ char time_to_txt[16];
+ char pass_name[MAX_PASS_NAME + 16];
+ int v = BLI_listbase_count(&DST.enabled_engines) + 3;
+ GLuint64 tot_time = 0;
+
+ if (G.debug_value > 666) {
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ GLuint64 engine_time = 0;
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ int vsta = v;
+
+ draw_stat(&rect, 0, v, engine->idname, sizeof(engine->idname));
+ v++;
+
+ for (int i = 0; i < engine->vedata_size->psl_len; ++i) {
+ DRWPass *pass = data->psl->passes[i];
+ if (pass != NULL && pass->wasdrawn) {
+ GLuint64 time;
+ glGetQueryObjectui64v(pass->timer_queries[pass->front_idx], GL_QUERY_RESULT, &time);
+
+ sprintf(pass_name, " |--> %s", pass->name);
+ draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
+
+ sprintf(time_to_txt, "%.2fms", time / 1000000.0);
+ engine_time += time;
+ tot_time += time;
+
+ draw_stat(&rect, 2, v++, time_to_txt, sizeof(time_to_txt));
+
+ pass->wasdrawn = false;
+ }
+ }
+ /* engine total time */
+ sprintf(time_to_txt, "%.2fms", engine_time / 1000000.0);
+ draw_stat(&rect, 2, vsta, time_to_txt, sizeof(time_to_txt));
+ v++;
+ }
+
+ sprintf(pass_name, "Total GPU time %.2fms (%.1f fps)", tot_time / 1000000.0, 1000000000.0 / tot_time);
+ draw_stat(&rect, 0, v++, pass_name, sizeof(pass_name));
+ v++;
+ }
+
+ /* Memory Stats */
+ unsigned int tex_mem = GPU_texture_memory_usage_get();
+ unsigned int vbo_mem = VertexBuffer_get_memory_usage();
+
+ sprintf(pass_name, "GPU Memory");
+ draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
+ sprintf(pass_name, "%.2fMB", (float)(tex_mem + vbo_mem) / 1000000.0);
+ draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name));
+ sprintf(pass_name, " |--> Textures");
+ draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
+ sprintf(pass_name, "%.2fMB", (float)tex_mem / 1000000.0);
+ draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name));
+ sprintf(pass_name, " |--> Meshes");
+ draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
+ sprintf(pass_name, "%.2fMB", (float)vbo_mem / 1000000.0);
+ draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name));
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Main Draw Loops (DRW_draw)
+ * \{ */
+
+/* Everything starts here.
+ * This function takes care of calling all cache and rendering functions
+ * for each relevant engine / mode engine. */
+void DRW_draw_view(const bContext *C)
+{
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ DST.draw_ctx.evil_C = C;
+
+ DRW_draw_render_loop(graph, ar, v3d);
+}
+
+/**
+ * Used for both regular and off-screen drawing.
+ */
+void DRW_draw_render_loop(
+ struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d)
+{
+ Scene *scene = DEG_get_scene(graph);
+ SceneLayer *sl = DEG_get_scene_layer(graph);
+ RegionView3D *rv3d = ar->regiondata;
+
+ bool cache_is_dirty;
+ DST.viewport = rv3d->viewport;
+ v3d->zbuf = true;
+
+ /* Get list of enabled engines */
+ DRW_engines_enable(scene, sl, v3d);
+
+ /* Setup viewport */
+ cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash());
+
+ DST.draw_ctx = (DRWContextState){
+ ar, rv3d, v3d, scene, sl, OBACT_NEW,
+ /* reuse if caller sets */
+ DST.draw_ctx.evil_C,
+ };
+
+ DRW_viewport_var_init();
+
+ /* Update ubos */
+ DRW_globals_update();
+
+ /* Init engines */
+ DRW_engines_init();
+
+ /* TODO : tag to refresh by the deps graph */
+ /* ideally only refresh when objects are added/removed */
+ /* or render properties / materials change */
+ if (cache_is_dirty) {
+ DRW_engines_cache_init();
+
+ DEG_OBJECT_ITER(graph, ob);
+ {
+ DRW_engines_cache_populate(ob);
+ }
+ DEG_OBJECT_ITER_END
+
+ DRW_engines_cache_finish();
+ }
+
+ /* Start Drawing */
+ DRW_state_reset();
+ DRW_engines_draw_background();
+
+ DRW_draw_callbacks_pre_scene();
+ if (DST.draw_ctx.evil_C) {
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
+ }
+
+ DRW_engines_draw_scene();
+
+ DRW_draw_callbacks_post_scene();
+ if (DST.draw_ctx.evil_C) {
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
+ }
+
+ DRW_state_reset();
+
+ DRW_engines_draw_text();
+
+ if (DST.draw_ctx.evil_C) {
+ /* needed so manipulator isn't obscured */
+ glDisable(GL_DEPTH_TEST);
+ DRW_draw_manipulator();
+ glEnable(GL_DEPTH_TEST);
+
+ DRW_draw_region_info();
+ }
+
+ if (G.debug_value > 20) {
+ DRW_debug_cpu_stats();
+ DRW_debug_gpu_stats();
+ }
+
+ DRW_state_reset();
+ DRW_engines_disable();
+
+ /* avoid accidental reuse */
+ memset(&DST, 0x0, sizeof(DST));
+}
+
+void DRW_draw_render_loop_offscreen(
+ struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d, GPUOffScreen *ofs)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* backup */
+ void *backup_viewport = rv3d->viewport;
+ {
+ /* backup (_never_ use rv3d->viewport) */
+ rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
+ }
+
+ DST.draw_ctx.evil_C = NULL;
+
+ DRW_draw_render_loop(graph, ar, v3d);
+
+ /* restore */
+ {
+ /* don't free data owned by 'ofs' */
+ GPU_viewport_clear_from_offscreen(rv3d->viewport);
+ GPU_viewport_free(rv3d->viewport);
+ MEM_freeN(rv3d->viewport);
+
+ rv3d->viewport = backup_viewport;
+ }
+
+ /* we need to re-bind (annoying!) */
+ GPU_offscreen_bind(ofs, false);
+}
+
+/**
+ * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
+ */
+void DRW_draw_select_loop(
+ struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d,
+ bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect)
+{
+ Scene *scene = DEG_get_scene(graph);
+ SceneLayer *sl = DEG_get_scene_layer(graph);
+#ifndef USE_GPU_SELECT
+ UNUSED_VARS(vc, scene, sl, v3d, ar, rect);
+#else
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* backup (_never_ use rv3d->viewport) */
+ void *backup_viewport = rv3d->viewport;
+ rv3d->viewport = NULL;
+
+ bool use_obedit = false;
+ int obedit_mode = 0;
+ if (scene->obedit && scene->obedit->type == OB_MBALL) {
+ use_obedit = true;
+ DRW_engines_cache_populate(scene->obedit);
+ obedit_mode = CTX_MODE_EDIT_METABALL;
+ }
+ else if ((scene->obedit && scene->obedit->type == OB_ARMATURE)) {
+ /* if not drawing sketch, draw bones */
+ // if (!BDR_drawSketchNames(vc))
+ {
+ use_obedit = true;
+ obedit_mode = CTX_MODE_EDIT_ARMATURE;
+ }
+ }
+
+ struct GPUViewport *viewport = GPU_viewport_create();
+ GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)});
+
+ bool cache_is_dirty;
+ DST.viewport = viewport;
+ v3d->zbuf = true;
+
+ DST.options.is_select = true;
+
+ /* Get list of enabled engines */
+ if (use_obedit) {
+ DRW_engines_enable_from_mode(obedit_mode);
+ }
+ else {
+ DRW_engines_enable_basic();
+ DRW_engines_enable_from_object_mode();
+ }
+
+ /* Setup viewport */
+ cache_is_dirty = true;
+
+ /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
+ DST.draw_ctx = (DRWContextState){
+ ar, rv3d, v3d, scene, sl, OBACT_NEW, (bContext *)NULL,
+ };
+
+ DRW_viewport_var_init();
+
+ /* Update ubos */
+ DRW_globals_update();
+
+ /* Init engines */
+ DRW_engines_init();
+
+ /* TODO : tag to refresh by the deps graph */
+ /* ideally only refresh when objects are added/removed */
+ /* or render properties / materials change */
+ if (cache_is_dirty) {
+
+ DRW_engines_cache_init();
+
+ if (use_obedit) {
+ DRW_engines_cache_populate(scene->obedit);
+ }
+ else {
+ DEG_OBJECT_ITER(graph, ob)
+ {
+ if ((ob->base_flag & BASE_SELECTABLED) != 0) {
+ DRW_select_load_id(ob->base_selection_color);
+ DRW_engines_cache_populate(ob);
+ }
+ }
+ DEG_OBJECT_ITER_END
+ }
+
+ DRW_engines_cache_finish();
+ }
+
+ /* Start Drawing */
+ DRW_state_reset();
+ DRW_draw_callbacks_pre_scene();
+ DRW_engines_draw_scene();
+ DRW_draw_callbacks_post_scene();
+
+ DRW_state_reset();
+ DRW_engines_disable();
+
+ /* avoid accidental reuse */
+ memset(&DST, 0x0, sizeof(DST));
+
+ /* Cleanup for selection state */
+ GPU_viewport_free(viewport);
+ MEM_freeN(viewport);
+
+ /* restore */
+ rv3d->viewport = backup_viewport;
+#endif /* USE_GPU_SELECT */
+}
+
+/**
+ * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
+ */
+void DRW_draw_depth_loop(
+ Depsgraph *graph,
+ ARegion *ar, View3D *v3d)
+{
+ Scene *scene = DEG_get_scene(graph);
+ SceneLayer *sl = DEG_get_scene_layer(graph);
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* backup (_never_ use rv3d->viewport) */
+ void *backup_viewport = rv3d->viewport;
+ rv3d->viewport = NULL;
+
+ struct GPUViewport *viewport = GPU_viewport_create();
+ GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy});
+
+ bool cache_is_dirty;
+ DST.viewport = viewport;
+ v3d->zbuf = true;
+
+ DST.options.is_depth = true;
+
+ /* Get list of enabled engines */
+ {
+ DRW_engines_enable_basic();
+ DRW_engines_enable_from_object_mode();
+ }
+
+ /* Setup viewport */
+ cache_is_dirty = true;
+
+ /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
+ DST.draw_ctx = (DRWContextState){
+ ar, rv3d, v3d, scene, sl, OBACT_NEW, (bContext *)NULL,
+ };
+
+ DRW_viewport_var_init();
+
+ /* Update ubos */
+ DRW_globals_update();
+
+ /* Init engines */
+ DRW_engines_init();
+
+ /* TODO : tag to refresh by the deps graph */
+ /* ideally only refresh when objects are added/removed */
+ /* or render properties / materials change */
+ if (cache_is_dirty) {
+
+ DRW_engines_cache_init();
+
+ DEG_OBJECT_ITER(graph, ob)
+ {
+ DRW_engines_cache_populate(ob);
+ }
+ DEG_OBJECT_ITER_END
+
+ DRW_engines_cache_finish();
+ }
+
+ /* Start Drawing */
+ DRW_state_reset();
+ DRW_draw_callbacks_pre_scene();
+ DRW_engines_draw_scene();
+ DRW_draw_callbacks_post_scene();
+
+ DRW_state_reset();
+ DRW_engines_disable();
+
+ /* avoid accidental reuse */
+ memset(&DST, 0x0, sizeof(DST));
+
+ /* Cleanup for selection state */
+ GPU_viewport_free(viewport);
+ MEM_freeN(viewport);
+
+ /* restore */
+ rv3d->viewport = backup_viewport;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Draw Manager State (DRW_state)
+ * \{ */
+
+void DRW_state_dfdy_factors_get(float dfdyfac[2])
+{
+ GPU_get_dfdy_factors(dfdyfac);
+}
+
+/**
+ * When false, drawing doesn't output to a pixel buffer
+ * eg: Occlusion queries, or when we have setup a context to draw in already.
+ */
+bool DRW_state_is_fbo(void)
+{
+ return (DST.default_framebuffer != NULL);
+}
+
+/**
+ * For when engines need to know if this is drawing for selection or not.
+ */
+bool DRW_state_is_select(void)
+{
+ return DST.options.is_select;
+}
+
+bool DRW_state_is_depth(void)
+{
+ return DST.options.is_depth;
+}
+
+/**
+ * Should text draw in this mode?
+ */
+bool DRW_state_show_text(void)
+{
+ return (DST.options.is_select) == 0 &&
+ (DST.options.is_depth) == 0;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Context State (DRW_context_state)
+ * \{ */
+
+void DRW_context_state_init(const bContext *C, DRWContextState *r_draw_ctx)
+{
+ r_draw_ctx->ar = CTX_wm_region(C);
+ r_draw_ctx->rv3d = CTX_wm_region_view3d(C);
+ r_draw_ctx->v3d = CTX_wm_view3d(C);
+
+ r_draw_ctx->scene = CTX_data_scene(C);
+ r_draw_ctx->sl = CTX_data_scene_layer(C);
+ r_draw_ctx->obact = r_draw_ctx->sl->basact ? r_draw_ctx->sl->basact->object : NULL;
+
+ /* grr, cant avoid! */
+ r_draw_ctx->evil_C = C;
+}
+
+
+const DRWContextState *DRW_context_state_get(void)
+{
+ return &DST.draw_ctx;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Init/Exit (DRW_engines)
+ * \{ */
+
+void DRW_engine_register(DrawEngineType *draw_engine_type)
+{
+ BLI_addtail(&DRW_engines, draw_engine_type);
+}
+
+void DRW_engines_register(void)
+{
+#ifdef WITH_CLAY_ENGINE
+ RE_engines_register(NULL, &DRW_engine_viewport_clay_type);
+#endif
+ RE_engines_register(NULL, &DRW_engine_viewport_eevee_type);
+
+ DRW_engine_register(&draw_engine_object_type);
+ DRW_engine_register(&draw_engine_edit_armature_type);
+ DRW_engine_register(&draw_engine_edit_curve_type);
+ DRW_engine_register(&draw_engine_edit_lattice_type);
+ DRW_engine_register(&draw_engine_edit_mesh_type);
+ DRW_engine_register(&draw_engine_edit_metaball_type);
+ DRW_engine_register(&draw_engine_edit_surface_type);
+ DRW_engine_register(&draw_engine_edit_text_type);
+ DRW_engine_register(&draw_engine_paint_texture_type);
+ DRW_engine_register(&draw_engine_paint_vertex_type);
+ DRW_engine_register(&draw_engine_paint_weight_type);
+ DRW_engine_register(&draw_engine_particle_type);
+ DRW_engine_register(&draw_engine_pose_type);
+ DRW_engine_register(&draw_engine_sculpt_type);
+
+ /* setup callbacks */
+ {
+ /* BKE: curve.c */
+ extern void *BKE_curve_batch_cache_dirty_cb;
+ extern void *BKE_curve_batch_cache_free_cb;
+ /* BKE: mesh.c */
+ extern void *BKE_mesh_batch_cache_dirty_cb;
+ extern void *BKE_mesh_batch_cache_free_cb;
+ /* BKE: lattice.c */
+ extern void *BKE_lattice_batch_cache_dirty_cb;
+ extern void *BKE_lattice_batch_cache_free_cb;
+ /* BKE: particle.c */
+ extern void *BKE_particle_batch_cache_dirty_cb;
+ extern void *BKE_particle_batch_cache_free_cb;
+
+ BKE_curve_batch_cache_dirty_cb = DRW_curve_batch_cache_dirty;
+ BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
+
+ BKE_mesh_batch_cache_dirty_cb = DRW_mesh_batch_cache_dirty;
+ BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free;
+
+ BKE_lattice_batch_cache_dirty_cb = DRW_lattice_batch_cache_dirty;
+ BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free;
+
+ BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty;
+ BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free;
+ }
+}
+
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GPUTexture *globals_ramp; /* draw_common.c */
+void DRW_engines_free(void)
+{
+ DRW_shape_cache_free();
+
+ DrawEngineType *next;
+ for (DrawEngineType *type = DRW_engines.first; type; type = next) {
+ next = type->next;
+ BLI_remlink(&R_engines, type);
+
+ if (type->engine_free) {
+ type->engine_free();
+ }
+ }
+
+ if (globals_ubo)
+ GPU_uniformbuffer_free(globals_ubo);
+
+ if (globals_ramp)
+ GPU_texture_free(globals_ramp);
+
+#ifdef WITH_CLAY_ENGINE
+ BLI_remlink(&R_engines, &DRW_engine_viewport_clay_type);
+#endif
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c
new file mode 100644
index 00000000000..56255af98ce
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager_text.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/** \file blender/draw/intern/draw_manager_text.c
+ * \ingroup draw
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_math.h"
+
+#include "BIF_gl.h"
+
+#include "GPU_matrix.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "UI_resources.h"
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "BLF_api.h"
+
+#include "draw_manager_text.h"
+
+typedef struct ViewCachedString {
+ struct ViewCachedString *next, *prev;
+ float vec[3];
+ union {
+ unsigned char ub[4];
+ int pack;
+ } col;
+ short sco[2];
+ short xoffs;
+ short flag;
+ int str_len;
+
+ /* str is allocated past the end */
+ char str[0];
+} ViewCachedString;
+
+typedef struct DRWTextStore {
+ ListBase list;
+} DRWTextStore;
+
+DRWTextStore *DRW_text_cache_create(void)
+{
+ DRWTextStore *dt = MEM_callocN(sizeof(*dt), __func__);
+ return dt;
+}
+
+void DRW_text_cache_destroy(struct DRWTextStore *dt)
+{
+ BLI_freelistN(&dt->list);
+ MEM_freeN(dt);
+}
+
+void DRW_text_cache_add(
+ DRWTextStore *dt,
+ const float co[3],
+ const char *str, const int str_len,
+ short xoffs, short flag,
+ const unsigned char col[4])
+{
+ int alloc_len;
+ ViewCachedString *vos;
+
+ if (flag & DRW_TEXT_CACHE_STRING_PTR) {
+ BLI_assert(str_len == strlen(str));
+ alloc_len = sizeof(void *);
+ }
+ else {
+ alloc_len = str_len + 1;
+ }
+
+ vos = MEM_mallocN(sizeof(ViewCachedString) + alloc_len, __func__);
+
+ BLI_addtail(&dt->list, vos);
+
+ copy_v3_v3(vos->vec, co);
+ copy_v4_v4_uchar(vos->col.ub, col);
+ vos->xoffs = xoffs;
+ vos->flag = flag;
+ vos->str_len = str_len;
+
+ /* allocate past the end */
+ if (flag & DRW_TEXT_CACHE_STRING_PTR) {
+ memcpy(vos->str, &str, alloc_len);
+ }
+ else {
+ memcpy(vos->str, str, alloc_len);
+ }
+}
+
+void DRW_text_cache_draw(
+ DRWTextStore *dt,
+ View3D *v3d, ARegion *ar, bool depth_write)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ ViewCachedString *vos;
+ int tot = 0;
+
+ /* project first and test */
+ for (vos = dt->list.first; vos; vos = vos->next) {
+ if (ED_view3d_project_short_ex(
+ ar,
+ (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;
+ }
+ }
+
+ if (tot) {
+ int col_pack_prev = 0;
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+
+ float original_proj[4][4];
+ gpuGetProjectionMatrix(original_proj);
+ wmOrtho2_region_pixelspace(ar);
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ if (depth_write) {
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ }
+ else {
+ glDepthMask(GL_FALSE);
+ }
+
+ const int font_id = BLF_default();
+
+ const uiStyle *style = UI_style_get();
+
+ BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
+
+ for (vos = dt->list.first; vos; vos = vos->next) {
+ 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]), (depth_write) ? 0.0f : 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);
+ }
+ }
+
+ if (depth_write) {
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+ else {
+ glDepthMask(GL_TRUE);
+ }
+
+ gpuPopMatrix();
+ gpuLoadProjectionMatrix(original_proj);
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_enable();
+ }
+ }
+}
diff --git a/source/blender/draw/intern/draw_manager_text.h b/source/blender/draw/intern/draw_manager_text.h
new file mode 100644
index 00000000000..a58e167be0d
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager_text.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/** \file blender/draw/intern/draw_manager_text.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_MANAGER_TEXT_H__
+#define __DRAW_MANAGER_TEXT_H__
+
+struct DRWTextStore;
+
+struct DRWTextStore *DRW_text_cache_create(void);
+void DRW_text_cache_destroy(struct DRWTextStore *dt);
+
+void DRW_text_cache_add(
+ struct DRWTextStore *dt,
+ const float co[3],
+ const char *str, const int str_len,
+ short xoffs, short flag,
+ const unsigned char col[4]);
+
+void DRW_text_cache_draw(
+ struct DRWTextStore *dt,
+ struct View3D *v3d, struct ARegion *ar, bool depth_write);
+
+enum {
+ DRW_TEXT_CACHE_ASCII = (1 << 0),
+ DRW_TEXT_CACHE_GLOBALSPACE = (1 << 1),
+ DRW_TEXT_CACHE_LOCALCLIP = (1 << 2),
+ /* reference the string by pointer */
+ DRW_TEXT_CACHE_STRING_PTR = (1 << 3),
+};
+
+/* draw_manager.c */
+struct DRWTextStore *DRW_text_cache_ensure(void);
+
+#endif /* __DRAW_MANAGER_TEXT_H__ */
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
new file mode 100644
index 00000000000..b4d0a9309dd
--- /dev/null
+++ b/source/blender/draw/intern/draw_view.c
@@ -0,0 +1,732 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/intern/draw_view.c
+ * \ingroup draw
+ *
+ * Contains dynamic drawing using immediate mode
+ */
+
+#include "DNA_brush_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+
+#include "ED_screen.h"
+#include "ED_transform.h"
+#include "ED_view3d.h"
+
+#include "GPU_draw.h"
+#include "GPU_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BKE_global.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_unit.h"
+
+#include "DRW_render.h"
+
+#include "view3d_intern.h"
+
+#include "draw_view.h"
+
+/* ******************** region info ***************** */
+
+void DRW_draw_region_info(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ARegion *ar = draw_ctx->ar;
+ int offset;
+
+ DRW_draw_cursor();
+
+ offset = DRW_draw_region_engine_info_offset();
+
+ view3d_draw_region_info(draw_ctx->evil_C, ar, offset);
+
+ if (offset > 0) {
+ DRW_draw_region_engine_info();
+ }
+}
+
+/* ************************* Grid ************************** */
+
+static void gridline_range(double x0, double dx, double max, int *r_first, int *r_count)
+{
+ /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y
+ * x0 is gridline 0, the axis in screen space
+ * Area covers [0 .. max) pixels */
+
+ int first = (int)ceil(-x0 / dx);
+ int last = (int)floor((max - x0) / dx);
+
+ if (first <= last) {
+ *r_first = first;
+ *r_count = last - first + 1;
+ }
+ else {
+ *r_first = 0;
+ *r_count = 0;
+ }
+}
+
+static int gridline_count(ARegion *ar, double x0, double y0, double dx)
+{
+ /* x0 & y0 establish the "phase" of the grid within this 2D region
+ * dx is the frequency, shared by x & y directions
+ * pass in dx of smallest (highest precision) grid we want to draw */
+
+ int first, x_ct, y_ct;
+
+ gridline_range(x0, dx, ar->winx, &first, &x_ct);
+ gridline_range(y0, dx, ar->winy, &first, &y_ct);
+
+ int total_ct = x_ct + y_ct;
+
+ return total_ct;
+}
+
+static bool drawgrid_draw(
+ ARegion *ar, double x0, double y0, double dx, int skip_mod,
+ unsigned pos, unsigned col, GLubyte col_value[3])
+{
+ /* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw
+ * always skip exact x0 & y0 axes; they will be drawn later in color
+ *
+ * set grid color once, just before the first line is drawn
+ * it's harmless to set same color for every line, or every vertex
+ * but if no lines are drawn, color must not be set! */
+
+ const float x_max = (float)ar->winx;
+ const float y_max = (float)ar->winy;
+
+ int first, ct;
+ int x_ct = 0, y_ct = 0; /* count of lines actually drawn */
+ int lines_skipped_for_next_unit = 0;
+
+ /* draw vertical lines */
+ gridline_range(x0, dx, x_max, &first, &ct);
+
+ for (int i = first; i < first + ct; ++i) {
+ if (i == 0)
+ continue;
+ else if (skip_mod && (i % skip_mod) == 0) {
+ ++lines_skipped_for_next_unit;
+ continue;
+ }
+
+ if (x_ct == 0)
+ immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
+
+ float x = (float)(x0 + i * dx);
+ immVertex2f(pos, x, 0.0f);
+ immVertex2f(pos, x, y_max);
+ ++x_ct;
+ }
+
+ /* draw horizontal lines */
+ gridline_range(y0, dx, y_max, &first, &ct);
+
+ for (int i = first; i < first + ct; ++i) {
+ if (i == 0)
+ continue;
+ else if (skip_mod && (i % skip_mod) == 0) {
+ ++lines_skipped_for_next_unit;
+ continue;
+ }
+
+ if (x_ct + y_ct == 0)
+ immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
+
+ float y = (float)(y0 + i * dx);
+ immVertex2f(pos, 0.0f, y);
+ immVertex2f(pos, x_max, y);
+ ++y_ct;
+ }
+
+ return lines_skipped_for_next_unit > 0;
+}
+
+#define GRID_MIN_PX_D 6.0
+#define GRID_MIN_PX_F 6.0f
+
+static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ double fx = rv3d->persmat[3][0];
+ double fy = rv3d->persmat[3][1];
+ double fw = rv3d->persmat[3][3];
+
+ const double wx = 0.5 * ar->winx; /* use double precision to avoid rounding errors */
+ const double wy = 0.5 * ar->winy;
+
+ double x = wx * fx / fw;
+ double y = wy * fy / fw;
+
+ double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 };
+ mul_m4_v4d(rv3d->persmat, vec4);
+ fx = vec4[0];
+ fy = vec4[1];
+ fw = vec4[3];
+
+ double dx = fabs(x - wx * fx / fw);
+ if (dx == 0) dx = fabs(y - wy * fy / fw);
+
+ x += wx;
+ y += wy;
+
+ /* now x, y, and dx have their final values
+ * (x,y) is the world origin (0,0,0) mapped to Area-relative screen space
+ * dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */
+
+ glLineWidth(1.0f);
+
+#if 0 /* TODO: write to UI/widget depth buffer, not scene depth */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer */
+#endif
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ unsigned char col[3], col2[3];
+ UI_GetThemeColor3ubv(TH_GRID, col);
+
+ if (unit->system) {
+ const void *usys;
+ int len;
+
+ bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
+
+ bool first = true;
+
+ if (usys) {
+ int i = len;
+ while (i--) {
+ double scalar = bUnit_GetScaler(usys, i);
+
+ double dx_scalar = dx * scalar / (double)unit->scale_length;
+ if (dx_scalar < (GRID_MIN_PX_D * 2.0)) {
+ /* very very small grid items are less useful when dealing with units */
+ continue;
+ }
+
+ if (first) {
+ first = false;
+
+ /* Store the smallest drawn grid size units name so users know how big each grid cell is */
+ *grid_unit = bUnit_GetNameDisplay(usys, i);
+ rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
+
+ int gridline_ct = gridline_count(ar, x, y, dx_scalar);
+ if (gridline_ct == 0)
+ goto drawgrid_cleanup; /* nothing to draw */
+
+ immBegin(PRIM_LINES, gridline_ct * 2);
+ }
+
+ float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
+ /* tweak to have the fade a bit nicer */
+ blend_fac = (blend_fac * blend_fac) * 2.0f;
+ CLAMP(blend_fac, 0.3f, 1.0f);
+
+ UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2);
+
+ const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar);
+ if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2))
+ break;
+ }
+ }
+ }
+ else {
+ const double sublines = v3d->gridsubdiv;
+ const float sublines_fl = v3d->gridsubdiv;
+
+ int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */
+
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1;
+ }
+ }
+ }
+ else {
+ if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
+ rv3d->gridview /= sublines_fl;
+ dx /= sublines;
+ if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
+ rv3d->gridview /= sublines_fl;
+ dx /= sublines;
+ if (dx > (GRID_MIN_PX_D * 10.0)) {
+ grids_to_draw = 1;
+ }
+ }
+ }
+ }
+
+ int gridline_ct = gridline_count(ar, x, y, dx);
+ if (gridline_ct == 0)
+ goto drawgrid_cleanup; /* nothing to draw */
+
+ immBegin(PRIM_LINES, gridline_ct * 2);
+
+ if (grids_to_draw == 2) {
+ UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2);
+ if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2)) {
+ drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col);
+ }
+ }
+ else if (grids_to_draw == 1) {
+ drawgrid_draw(ar, x, y, dx, 0, pos, color, col);
+ }
+ }
+
+ /* draw visible axes */
+ /* horizontal line */
+ if (0 <= y && y < ar->winy) {
+ UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X');
+ immAttrib3ub(color, col2[0], col2[1], col2[2]);
+ immVertex2f(pos, 0.0f, y);
+ immVertex2f(pos, (float)ar->winx, y);
+ }
+
+ /* vertical line */
+ if (0 <= x && x < ar->winx) {
+ UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z');
+ immAttrib3ub(color, col2[0], col2[1], col2[2]);
+ immVertex2f(pos, x, 0.0f);
+ immVertex2f(pos, x, (float)ar->winy);
+ }
+
+ immEnd();
+
+drawgrid_cleanup:
+ immUnbindProgram();
+
+#if 0 /* depth write is left enabled above */
+ glDepthMask(GL_TRUE); /* enable write in zbuffer */
+#endif
+}
+
+#undef DEBUG_GRID
+#undef GRID_MIN_PX_D
+#undef GRID_MIN_PX_F
+
+static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
+{
+ /* draw only if there is something to draw */
+ if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
+ /* draw how many lines?
+ * trunc(v3d->gridlines / 2) * 4
+ * + 2 for xy axes (possibly with special colors)
+ * + 1 for z axis (the only line not in xy plane)
+ * even v3d->gridlines are honored, odd rounded down */
+ const int gridlines = v3d->gridlines / 2;
+ const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
+ const float grid = gridlines * grid_scale;
+
+ const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1;
+
+ bool show_axis_x = (v3d->gridflag & V3D_SHOW_X) != 0;
+ bool show_axis_y = (v3d->gridflag & V3D_SHOW_Y) != 0;
+ bool show_axis_z = (v3d->gridflag & V3D_SHOW_Z) != 0;
+
+ unsigned char col_grid[3], col_axis[3];
+
+ glLineWidth(1.0f);
+
+ UI_GetThemeColor3ubv(TH_GRID, col_grid);
+
+ if (show_floor) {
+ const unsigned vertex_ct = 2 * (gridlines * 4 + 2);
+ const int sublines = v3d->gridsubdiv;
+
+ unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3];
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ immBegin(PRIM_LINES, vertex_ct);
+
+ /* draw normal grid lines */
+ UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
+
+ for (int a = 1; a <= gridlines; a++) {
+ /* skip emphasised divider lines */
+ if (a % sublines != 0) {
+ const float line = a * grid_scale;
+
+ immAttrib3ubv(color, col_grid_light);
+
+ immVertex2f(pos, -grid, -line);
+ immVertex2f(pos, +grid, -line);
+ immVertex2f(pos, -grid, +line);
+ immVertex2f(pos, +grid, +line);
+
+ immVertex2f(pos, -line, -grid);
+ immVertex2f(pos, -line, +grid);
+ immVertex2f(pos, +line, -grid);
+ immVertex2f(pos, +line, +grid);
+ }
+ }
+
+ /* draw emphasised grid lines */
+ UI_GetThemeColor3ubv(TH_BACK, col_bg);
+ /* emphasise division lines lighter instead of darker, if background is darker than grid */
+ UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
+ (col_grid[0] + col_grid[1] + col_grid[2] + 30 >
+ col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10);
+
+ if (sublines <= gridlines) {
+ immAttrib3ubv(color, col_grid_emphasise);
+
+ for (int a = sublines; a <= gridlines; a += sublines) {
+ const float line = a * grid_scale;
+
+ immVertex2f(pos, -grid, -line);
+ immVertex2f(pos, +grid, -line);
+ immVertex2f(pos, -grid, +line);
+ immVertex2f(pos, +grid, +line);
+
+ immVertex2f(pos, -line, -grid);
+ immVertex2f(pos, -line, +grid);
+ immVertex2f(pos, +line, -grid);
+ immVertex2f(pos, +line, +grid);
+ }
+ }
+
+ /* draw X axis */
+ if (show_axis_x) {
+ show_axis_x = false; /* drawing now, won't need to draw later */
+ UI_make_axis_color(col_grid, col_axis, 'X');
+ immAttrib3ubv(color, col_axis);
+ }
+ else
+ immAttrib3ubv(color, col_grid_emphasise);
+
+ immVertex2f(pos, -grid, 0.0f);
+ immVertex2f(pos, +grid, 0.0f);
+
+ /* draw Y axis */
+ if (show_axis_y) {
+ show_axis_y = false; /* drawing now, won't need to draw later */
+ UI_make_axis_color(col_grid, col_axis, 'Y');
+ immAttrib3ubv(color, col_axis);
+ }
+ else
+ immAttrib3ubv(color, col_grid_emphasise);
+
+ immVertex2f(pos, 0.0f, -grid);
+ immVertex2f(pos, 0.0f, +grid);
+
+ immEnd();
+ immUnbindProgram();
+
+ /* done with XY plane */
+ }
+
+ if (show_axis_x || show_axis_y || show_axis_z) {
+ /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+ immBegin(PRIM_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2);
+
+ if (show_axis_x) {
+ UI_make_axis_color(col_grid, col_axis, 'X');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, -grid, 0.0f, 0.0f);
+ immVertex3f(pos, +grid, 0.0f, 0.0f);
+ }
+
+ if (show_axis_y) {
+ UI_make_axis_color(col_grid, col_axis, 'Y');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, 0.0f, -grid, 0.0f);
+ immVertex3f(pos, 0.0f, +grid, 0.0f);
+ }
+
+ if (show_axis_z) {
+ UI_make_axis_color(col_grid, col_axis, 'Z');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, 0.0f, 0.0f, -grid);
+ immVertex3f(pos, 0.0f, 0.0f, +grid);
+ }
+
+ immEnd();
+ immUnbindProgram();
+ }
+ }
+}
+
+void DRW_draw_grid(void)
+{
+ /* TODO viewport
+ * Missing is the flags to check whether to draw it
+ * for now now we are using the flags in v3d itself.
+ *
+ * Also for now always assume depth is there, so we
+ * draw on top of it.
+ */
+ /**
+ * Calculate pixel-size factor once, is used for lamps and object centers.
+ * Used by #ED_view3d_pixel_size and typically not accessed directly.
+ *
+ * \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value,
+ * passed to #RE_SetPixelSize, in ortho mode this is compatible with this value,
+ * but in perspective mode its offset by the near-clip.
+ *
+ * 'RegionView3D.pixsize' is used for viewport drawing, not rendering.
+ */
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ View3D *v3d = draw_ctx->v3d;
+ ARegion *ar = draw_ctx->ar;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+
+ const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
+ const char *grid_unit = NULL;
+
+ /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
+ * objects if done last
+ * needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views.
+ */
+ rv3d->gridview = ED_view3d_grid_scale(scene, v3d, &grid_unit);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ if (!draw_floor) {
+ /* Do not get in front of overlays */
+ glDepthMask(GL_FALSE);
+
+ ED_region_pixelspace(ar);
+ *(&grid_unit) = NULL; /* drawgrid need this to detect/affect smallest valid unit... */
+ drawgrid(&scene->unit, ar, v3d, &grid_unit);
+
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ }
+ else {
+ glDepthMask(GL_TRUE);
+ drawfloor(scene, v3d, &grid_unit);
+ }
+}
+
+/* ************************* Background ************************** */
+
+void DRW_draw_background(void)
+{
+ /* Just to make sure */
+ glDepthMask(GL_TRUE);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glStencilMask(0xFF);
+
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ float m[4][4];
+ unit_m4(m);
+
+ /* Gradient background Color */
+ glDisable(GL_DEPTH_TEST);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ unsigned char col_hi[3], col_lo[3];
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
+ gpuLoadProjectionMatrix(m);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo);
+ UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi);
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immAttrib3ubv(color, col_lo);
+ immVertex2f(pos, -1.0f, -1.0f);
+ immVertex2f(pos, 1.0f, -1.0f);
+
+ immAttrib3ubv(color, col_hi);
+ immVertex2f(pos, 1.0f, 1.0f);
+ immVertex2f(pos, -1.0f, 1.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ glEnable(GL_DEPTH_TEST);
+ }
+ else {
+ /* Solid background Color */
+ UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ }
+}
+
+/* **************************** 3D Cursor ******************************** */
+
+static bool is_cursor_visible(Scene *scene, SceneLayer *sl)
+{
+ Object *ob = OBACT_NEW;
+
+ /* don't draw cursor in paint modes, but with a few exceptions */
+ if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ /* exception: object is in weight paint and has deforming armature in pose mode */
+ if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (BKE_object_pose_armature_get(ob) != NULL) {
+ return true;
+ }
+ }
+ /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
+ else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ const Paint *p = BKE_paint_get_active(scene, sl);
+
+ if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
+ if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
+ return true;
+ }
+ }
+ }
+
+ /* no exception met? then don't draw cursor! */
+ return false;
+ }
+
+ return true;
+}
+
+void DRW_draw_cursor(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ Scene *scene = draw_ctx->scene;
+ SceneLayer *sl = draw_ctx->sl;
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glLineWidth(1.0f);
+
+ if (is_cursor_visible(scene, sl)) {
+ float *co = ED_view3d_cursor3d_get(scene, v3d);
+ unsigned char crosshair_color[3];
+
+ const float f5 = 0.25f;
+ const float f10 = 0.5f;
+ const float f20 = 1.0f;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ unsigned int wpos = VertexFormat_add_attrib(format, "world_pos", COMP_F32, 3, KEEP_FLOAT);
+
+ /* XXX Using instance shader without instance */
+ immBindBuiltinProgram(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR);
+ immUniform1f("size", U.widget_unit);
+ immUniform1f("pixel_size", *DRW_viewport_pixelsize_get());
+ immUniformArray3fv("screen_vecs", DRW_viewport_screenvecs_get(), 2);
+ immUniformMatrix4fv("ViewProjectionMatrix", rv3d->persmat);
+
+ const int segments = 16;
+
+ immBegin(PRIM_LINE_LOOP, segments);
+ immAttrib3fv(wpos, co);
+
+ for (int i = 0; i < segments; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)segments);
+ float x = f10 * cosf(angle);
+ float y = f10 * sinf(angle);
+
+ if (i % 2 == 0)
+ immAttrib3ub(color, 255, 0, 0);
+ else
+ immAttrib3ub(color, 255, 255, 255);
+
+ immVertex2f(pos, x, y);
+ }
+ immEnd();
+
+ UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color);
+
+ immBegin(PRIM_LINES, 8);
+ immAttrib3ubv(color, crosshair_color);
+ immAttrib3fv(wpos, co);
+
+ immVertex2f(pos, -f20, 0);
+ immVertex2f(pos, -f5, 0);
+ immVertex2f(pos, +f5, 0);
+ immVertex2f(pos, +f20, 0);
+ immVertex2f(pos, 0, -f20);
+ immVertex2f(pos, 0, -f5);
+ immVertex2f(pos, 0, +f5);
+ immVertex2f(pos, 0, +f20);
+ immEnd();
+
+ immUnbindProgram();
+ }
+}
+
+/* **************************** 3D Manipulator ******************************** */
+
+void DRW_draw_manipulator(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ v3d->zbuf = false;
+ ARegion *ar = draw_ctx->ar;
+
+
+ /* TODO, only draws 3D manipulators right now, need to see how 2D drawing will work in new viewport */
+
+ /* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
+ /* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
+ * later become _IN_SCENE (and draw _3D separate) */
+ WM_manipulatormap_draw(ar->manipulator_map, draw_ctx->evil_C, WM_MANIPULATORMAP_DRAWSTEP_3D);
+}
diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h
new file mode 100644
index 00000000000..b400ceeffa2
--- /dev/null
+++ b/source/blender/draw/intern/draw_view.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_view.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_VIEW_H__
+#define __DRAW_VIEW_H__
+
+void DRW_draw_grid(void);
+void DRW_draw_region_info(void);
+void DRW_draw_background(void);
+void DRW_draw_cursor(void);
+void DRW_draw_manipulator(void);
+
+#endif /* __DRAW_VIEW_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/modes/draw_mode_engines.h b/source/blender/draw/modes/draw_mode_engines.h
new file mode 100644
index 00000000000..23fedbba5a5
--- /dev/null
+++ b/source/blender/draw/modes/draw_mode_engines.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/draw_mode_engines.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_MODE_ENGINES_H__
+#define __DRAW_MODE_ENGINES_H__
+
+extern DrawEngineType draw_engine_object_type;
+extern DrawEngineType draw_engine_edit_armature_type;
+extern DrawEngineType draw_engine_edit_curve_type;
+extern DrawEngineType draw_engine_edit_lattice_type;
+extern DrawEngineType draw_engine_edit_mesh_type;
+extern DrawEngineType draw_engine_edit_metaball_type;
+extern DrawEngineType draw_engine_edit_surface_type;
+extern DrawEngineType draw_engine_edit_text_type;
+extern DrawEngineType draw_engine_paint_texture_type;
+extern DrawEngineType draw_engine_paint_vertex_type;
+extern DrawEngineType draw_engine_paint_weight_type;
+extern DrawEngineType draw_engine_particle_type;
+extern DrawEngineType draw_engine_pose_type;
+extern DrawEngineType draw_engine_sculpt_type;
+
+#endif /* __DRAW_MODE_ENGINES_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c
new file mode 100644
index 00000000000..3487ceba141
--- /dev/null
+++ b/source/blender/draw/modes/edit_armature_mode.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_armature_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_armature_types.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+extern GlobalsUboStorage ts;
+
+/* *********** LISTS *********** */
+typedef struct EDIT_ARMATURE_PassList {
+ struct DRWPass *bone_solid;
+ struct DRWPass *bone_wire;
+ struct DRWPass *bone_envelope;
+ struct DRWPass *relationship;
+} EDIT_ARMATURE_PassList;
+
+typedef struct EDIT_ARMATURE_StorageList {
+ struct EDIT_ARMATURE_PrivateData *g_data;
+} EDIT_ARMATURE_StorageList;
+
+typedef struct EDIT_ARMATURE_Data {
+ void *engine_type;
+ DRWViewportEmptyList *fbl;
+ DRWViewportEmptyList *txl;
+ EDIT_ARMATURE_PassList *psl;
+ EDIT_ARMATURE_StorageList *stl;
+} EDIT_ARMATURE_Data;
+
+/* *********** STATIC *********** */
+
+typedef struct EDIT_ARMATURE_PrivateData {
+ DRWShadingGroup *relationship_lines;
+} EDIT_ARMATURE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+static void EDIT_ARMATURE_cache_init(void *vedata)
+{
+ EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl;
+ EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Solid bones */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+ psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
+ }
+
+ {
+ /* Wire bones */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
+ }
+
+ {
+ /* distance outline around envelope bones */
+ DRWState state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->bone_envelope = DRW_pass_create("Bone Envelope Outline Pass", state);
+ }
+
+ {
+ /* Non Meshes Pass (Camera, empties, lamps ...) */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ psl->relationship = DRW_pass_create("Bone Relationship Pass", state);
+
+ /* Relationship Lines */
+ stl->g_data->relationship_lines = shgroup_dynlines_uniform_color(psl->relationship, ts.colorWire);
+ DRW_shgroup_state_enable(stl->g_data->relationship_lines, DRW_STATE_STIPPLE_3);
+ }
+}
+
+static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob)
+{
+ bArmature *arm = ob->data;
+ EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl;
+ EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl;
+
+ if (ob->type == OB_ARMATURE) {
+ if (arm->edbo) {
+ DRW_shgroup_armature_edit(
+ ob, psl->bone_solid, psl->bone_wire, psl->bone_envelope, stl->g_data->relationship_lines);
+ }
+ }
+}
+
+static void EDIT_ARMATURE_draw_scene(void *vedata)
+{
+ EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl;
+
+ DRW_draw_pass(psl->bone_envelope);
+ DRW_draw_pass(psl->bone_solid);
+ DRW_draw_pass(psl->bone_wire);
+ DRW_draw_pass(psl->relationship);
+}
+
+#if 0
+void EDIT_ARMATURE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ //BKE_collection_engine_property_add_int(ces, "show_occlude_wire", false);
+}
+#endif
+
+static const DrawEngineDataSize EDIT_ARMATURE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_ARMATURE_Data);
+
+DrawEngineType draw_engine_edit_armature_type = {
+ NULL, NULL,
+ N_("EditArmatureMode"),
+ &EDIT_ARMATURE_data_size,
+ NULL,
+ NULL,
+ &EDIT_ARMATURE_cache_init,
+ &EDIT_ARMATURE_cache_populate,
+ NULL,
+ NULL,
+ &EDIT_ARMATURE_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c
new file mode 100644
index 00000000000..ae3201fa297
--- /dev/null
+++ b/source/blender/draw/modes/edit_curve_mode.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_curve_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_curve_types.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+#include "GPU_batch.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* If needed, contains all global/Theme colors
+ * Add needed theme colors / values to DRW_globals_update() and update UBO
+ * Not needed for constant color. */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_edit_curve_overlay_loosevert_vert_glsl[];
+extern char datatoc_edit_curve_overlay_frag_glsl[];
+
+extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use EDIT_CURVE_engine_init() to
+ * initialize most of them and EDIT_CURVE_cache_init()
+ * for EDIT_CURVE_PassList */
+
+typedef struct EDIT_CURVE_PassList {
+ /* Declare all passes here and init them in
+ * EDIT_CURVE_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *wire_pass;
+ struct DRWPass *overlay_edge_pass;
+ struct DRWPass *overlay_vert_pass;
+} EDIT_CURVE_PassList;
+
+typedef struct EDIT_CURVE_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} EDIT_CURVE_FramebufferList;
+
+typedef struct EDIT_CURVE_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} EDIT_CURVE_TextureList;
+
+typedef struct EDIT_CURVE_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct EDIT_CURVE_PrivateData *g_data;
+} EDIT_CURVE_StorageList;
+
+typedef struct EDIT_CURVE_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ EDIT_CURVE_FramebufferList *fbl;
+ EDIT_CURVE_TextureList *txl;
+ EDIT_CURVE_PassList *psl;
+ EDIT_CURVE_StorageList *stl;
+} EDIT_CURVE_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in EDIT_CURVE_engine_init();
+ * free in EDIT_CURVE_engine_free(); */
+
+ GPUShader *wire_sh;
+
+ GPUShader *overlay_edge_sh; /* handles and nurbs control cage */
+ GPUShader *overlay_vert_sh;
+
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EDIT_CURVE_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in EDIT_CURVE_cache_populate() */
+
+ /* resulting curve as 'wire' for curves (and optionally normals) */
+ DRWShadingGroup *wire_shgrp;
+
+ DRWShadingGroup *overlay_edge_shgrp;
+ DRWShadingGroup *overlay_vert_shgrp;
+} EDIT_CURVE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void EDIT_CURVE_engine_init(void *vedata)
+{
+ EDIT_CURVE_TextureList *txl = ((EDIT_CURVE_Data *)vedata)->txl;
+ EDIT_CURVE_FramebufferList *fbl = ((EDIT_CURVE_Data *)vedata)->fbl;
+ EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.wire_sh) {
+ e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!e_data.overlay_edge_sh) {
+ e_data.overlay_edge_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!e_data.overlay_vert_sh) {
+ e_data.overlay_vert_sh = DRW_shader_create_with_lib(
+ datatoc_edit_curve_overlay_loosevert_vert_glsl, NULL,
+ datatoc_edit_curve_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void EDIT_CURVE_cache_init(void *vedata)
+{
+ EDIT_CURVE_PassList *psl = ((EDIT_CURVE_Data *)vedata)->psl;
+ EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Center-Line (wire) */
+ psl->wire_pass = DRW_pass_create(
+ "Curve Wire",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE);
+ stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass);
+
+
+ /* TODO: following handle theme colors,
+ * For now use overlay vert shader for handles (we want them colored):
+ * TH_NURB_ULINE, TH_NURB_SEL_ULINE, TH_HANDLE_* */
+ psl->overlay_edge_pass = DRW_pass_create(
+ "Curve Handle Overlay",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_WIRE);
+ /* TODO: following handle theme colors,
+ * For now use overlay vert shader for handles (we want them colored) */
+ stl->g_data->overlay_edge_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->overlay_edge_pass);
+
+ psl->overlay_vert_pass = DRW_pass_create(
+ "Curve Vert Overlay",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_POINT);
+ stl->g_data->overlay_vert_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->overlay_vert_pass);
+ }
+
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
+{
+ EDIT_CURVE_PassList *psl = ((EDIT_CURVE_Data *)vedata)->psl;
+ EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene = draw_ctx->scene;
+ const Object *obedit = scene->obedit;
+
+ UNUSED_VARS(psl, stl);
+
+ if (ob->type == OB_CURVE) {
+ if (ob == obedit) {
+ Curve *cu = ob->data;
+ /* Get geometry cache */
+ struct Batch *geom;
+
+ geom = DRW_cache_curve_edge_wire_get(ob);
+ DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
+
+ if ((cu->flag & CU_3D) && (cu->drawflag & CU_HIDE_NORMALS) == 0) {
+ geom = DRW_cache_curve_edge_normal_get(ob, scene->toolsettings->normalsize);
+ DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
+ }
+
+ /* Add geom to a shading group */
+ geom = DRW_cache_curve_edge_overlay_get(ob);
+ if (geom) {
+ DRW_shgroup_call_add(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
+ }
+
+ geom = DRW_cache_curve_vert_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
+ }
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void EDIT_CURVE_cache_finish(void *vedata)
+{
+ EDIT_CURVE_PassList *psl = ((EDIT_CURVE_Data *)vedata)->psl;
+ EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void EDIT_CURVE_draw_scene(void *vedata)
+{
+ EDIT_CURVE_PassList *psl = ((EDIT_CURVE_Data *)vedata)->psl;
+ EDIT_CURVE_FramebufferList *fbl = ((EDIT_CURVE_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ /* ... or just render passes on default framebuffer. */
+ DRW_draw_pass(psl->wire_pass);
+ DRW_draw_pass(psl->overlay_edge_pass);
+ DRW_draw_pass(psl->overlay_vert_pass);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void EDIT_CURVE_engine_free(void)
+{
+ // DRW_SHADER_FREE_SAFE(custom_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void EDIT_CURVE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize EDIT_CURVE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_CURVE_Data);
+
+DrawEngineType draw_engine_edit_curve_type = {
+ NULL, NULL,
+ N_("EditCurveMode"),
+ &EDIT_CURVE_data_size,
+ &EDIT_CURVE_engine_init,
+ &EDIT_CURVE_engine_free,
+ &EDIT_CURVE_cache_init,
+ &EDIT_CURVE_cache_populate,
+ &EDIT_CURVE_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &EDIT_CURVE_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c
new file mode 100644
index 00000000000..2993719ee1c
--- /dev/null
+++ b/source/blender/draw/modes/edit_lattice_mode.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_lattice_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* If needed, contains all global/Theme colors
+ * Add needed theme colors / values to DRW_globals_update() and update UBO
+ * Not needed for constant color. */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_edit_lattice_overlay_loosevert_vert_glsl[];
+extern char datatoc_edit_lattice_overlay_frag_glsl[];
+
+extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use EDIT_LATTICE_engine_init() to
+ * initialize most of them and EDIT_LATTICE_cache_init()
+ * for EDIT_LATTICE_PassList */
+
+typedef struct EDIT_LATTICE_PassList {
+ /* Declare all passes here and init them in
+ * EDIT_LATTICE_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *wire_pass;
+ struct DRWPass *vert_pass;
+} EDIT_LATTICE_PassList;
+
+typedef struct EDIT_LATTICE_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} EDIT_LATTICE_FramebufferList;
+
+typedef struct EDIT_LATTICE_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} EDIT_LATTICE_TextureList;
+
+typedef struct EDIT_LATTICE_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct EDIT_LATTICE_PrivateData *g_data;
+} EDIT_LATTICE_StorageList;
+
+typedef struct EDIT_LATTICE_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ EDIT_LATTICE_FramebufferList *fbl;
+ EDIT_LATTICE_TextureList *txl;
+ EDIT_LATTICE_PassList *psl;
+ EDIT_LATTICE_StorageList *stl;
+} EDIT_LATTICE_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in EDIT_LATTICE_engine_init();
+ * free in EDIT_LATTICE_engine_free(); */
+ GPUShader *wire_sh;
+
+ GPUShader *overlay_vert_sh;
+
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EDIT_LATTICE_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in EDIT_LATTICE_cache_populate() */
+ DRWShadingGroup *wire_shgrp;
+ DRWShadingGroup *vert_shgrp;
+} EDIT_LATTICE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void EDIT_LATTICE_engine_init(void *vedata)
+{
+ EDIT_LATTICE_TextureList *txl = ((EDIT_LATTICE_Data *)vedata)->txl;
+ EDIT_LATTICE_FramebufferList *fbl = ((EDIT_LATTICE_Data *)vedata)->fbl;
+ EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.wire_sh) {
+ e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!e_data.overlay_vert_sh) {
+ e_data.overlay_vert_sh = DRW_shader_create_with_lib(
+ datatoc_edit_lattice_overlay_loosevert_vert_glsl, NULL,
+ datatoc_edit_lattice_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void EDIT_LATTICE_cache_init(void *vedata)
+{
+ EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
+ EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ psl->wire_pass = DRW_pass_create(
+ "Lattice Wire",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE);
+ stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass);
+
+ psl->vert_pass = DRW_pass_create(
+ "Lattice Verts",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_POINT);
+ stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->vert_pass);
+ }
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob)
+{
+ EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
+ EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ Object *obedit = scene->obedit;
+
+ UNUSED_VARS(psl);
+
+ if (ob->type == OB_LATTICE) {
+ if (ob == obedit) {
+ /* Get geometry cache */
+ struct Batch *geom;
+
+ geom = DRW_cache_lattice_wire_get(ob);
+ DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
+
+ geom = DRW_cache_lattice_vert_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->vert_shgrp, geom, ob->obmat);
+ }
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void EDIT_LATTICE_cache_finish(void *vedata)
+{
+ EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
+ EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void EDIT_LATTICE_draw_scene(void *vedata)
+{
+ EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
+ EDIT_LATTICE_FramebufferList *fbl = ((EDIT_LATTICE_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ /* ... or just render passes on default framebuffer. */
+ DRW_draw_pass(psl->wire_pass);
+ DRW_draw_pass(psl->vert_pass);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void EDIT_LATTICE_engine_free(void)
+{
+ // Currently built-in, dont free
+ DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void EDIT_LATTICE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize EDIT_LATTICE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_LATTICE_Data);
+
+DrawEngineType draw_engine_edit_lattice_type = {
+ NULL, NULL,
+ N_("EditLatticeMode"),
+ &EDIT_LATTICE_data_size,
+ &EDIT_LATTICE_engine_init,
+ &EDIT_LATTICE_engine_free,
+ &EDIT_LATTICE_cache_init,
+ &EDIT_LATTICE_cache_populate,
+ &EDIT_LATTICE_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &EDIT_LATTICE_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
new file mode 100644
index 00000000000..286d277f0e3
--- /dev/null
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_mesh_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "GPU_shader.h"
+#include "DNA_view3d_types.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+extern char datatoc_edit_mesh_overlay_frag_glsl[];
+extern char datatoc_edit_mesh_overlay_vert_glsl[];
+extern char datatoc_edit_mesh_overlay_geom_tri_glsl[];
+extern char datatoc_edit_mesh_overlay_geom_edge_glsl[];
+extern char datatoc_edit_mesh_overlay_loosevert_vert_glsl[];
+extern char datatoc_edit_mesh_overlay_facedot_frag_glsl[];
+extern char datatoc_edit_mesh_overlay_facedot_vert_glsl[];
+extern char datatoc_edit_mesh_overlay_mix_vert_glsl[];
+extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
+extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
+extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
+extern char datatoc_edit_normals_vert_glsl[];
+extern char datatoc_edit_normals_geom_glsl[];
+extern char datatoc_common_globals_lib_glsl[];
+
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+
+/* *********** LISTS *********** */
+typedef struct EDIT_MESH_PassList {
+ struct DRWPass *vcolor_faces;
+ struct DRWPass *depth_hidden_wire;
+ struct DRWPass *edit_face_overlay;
+ struct DRWPass *edit_face_occluded;
+ struct DRWPass *mix_occlude;
+ struct DRWPass *facefill_occlude;
+ struct DRWPass *normals;
+} EDIT_MESH_PassList;
+
+typedef struct EDIT_MESH_FramebufferList {
+ struct GPUFrameBuffer *occlude_wire_fb;
+} EDIT_MESH_FramebufferList;
+
+typedef struct EDIT_MESH_StorageList {
+ struct EDIT_MESH_PrivateData *g_data;
+} EDIT_MESH_StorageList;
+
+typedef struct EDIT_MESH_Data {
+ void *engine_type;
+ EDIT_MESH_FramebufferList *fbl;
+ DRWViewportEmptyList *txl;
+ EDIT_MESH_PassList *psl;
+ EDIT_MESH_StorageList *stl;
+} EDIT_MESH_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* weight/vert-color */
+ GPUShader *vcolor_face_shader;
+ GPUShader *overlay_tri_sh;
+ GPUShader *overlay_tri_fast_sh;
+ GPUShader *overlay_tri_vcol_sh;
+ GPUShader *overlay_tri_vcol_fast_sh;
+ GPUShader *overlay_edge_sh;
+ GPUShader *overlay_edge_vcol_sh;
+ GPUShader *overlay_vert_sh;
+ GPUShader *overlay_facedot_sh;
+ GPUShader *overlay_mix_sh;
+ GPUShader *overlay_facefill_sh;
+ GPUShader *normals_face_sh;
+ GPUShader *normals_loop_sh;
+ GPUShader *normals_sh;
+ GPUShader *depth_sh;
+ /* temp buffer texture */
+ struct GPUTexture *occlude_wire_depth_tx;
+ struct GPUTexture *occlude_wire_color_tx;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EDIT_MESH_PrivateData {
+ /* weight/vert-color */
+ DRWShadingGroup *fvcolor_shgrp;
+ DRWShadingGroup *depth_shgrp_hidden_wire;
+
+ DRWShadingGroup *fnormals_shgrp;
+ DRWShadingGroup *vnormals_shgrp;
+ DRWShadingGroup *lnormals_shgrp;
+
+ DRWShadingGroup *face_overlay_shgrp;
+ DRWShadingGroup *ledges_overlay_shgrp;
+ DRWShadingGroup *lverts_overlay_shgrp;
+ DRWShadingGroup *facedot_overlay_shgrp;
+
+ DRWShadingGroup *face_occluded_shgrp;
+ DRWShadingGroup *ledges_occluded_shgrp;
+ DRWShadingGroup *lverts_occluded_shgrp;
+ DRWShadingGroup *facedot_occluded_shgrp;
+ DRWShadingGroup *facefill_occluded_shgrp;
+
+} EDIT_MESH_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+static void EDIT_MESH_engine_init(void *vedata)
+{
+ EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
+
+ const float *viewport_size = DRW_viewport_size_get();
+
+ DRWFboTexture tex[2] = {{
+ &e_data.occlude_wire_depth_tx, DRW_TEX_DEPTH_24, DRW_TEX_TEMP},
+ {&e_data.occlude_wire_color_tx, DRW_TEX_RGBA_8, DRW_TEX_FILTER | DRW_TEX_TEMP}
+ };
+ DRW_framebuffer_init(
+ &fbl->occlude_wire_fb, &draw_engine_edit_mesh_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ tex, ARRAY_SIZE(tex));
+
+ if (!e_data.vcolor_face_shader) {
+ e_data.vcolor_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
+ }
+
+ if (!e_data.overlay_tri_sh) {
+ e_data.overlay_tri_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_vert_glsl,
+ datatoc_edit_mesh_overlay_geom_tri_glsl,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl, "#define EDGE_FIX\n");
+ }
+ if (!e_data.overlay_tri_fast_sh) {
+ e_data.overlay_tri_fast_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_vert_glsl,
+ datatoc_edit_mesh_overlay_geom_tri_glsl,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+ if (!e_data.overlay_tri_vcol_sh) {
+ e_data.overlay_tri_vcol_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_vert_glsl,
+ datatoc_edit_mesh_overlay_geom_tri_glsl,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define EDGE_FIX\n"
+ "#define VERTEX_SELECTION\n");
+ }
+ if (!e_data.overlay_tri_vcol_fast_sh) {
+ e_data.overlay_tri_vcol_fast_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_vert_glsl,
+ datatoc_edit_mesh_overlay_geom_tri_glsl,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define VERTEX_SELECTION\n");
+ }
+ if (!e_data.overlay_edge_sh) {
+ e_data.overlay_edge_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_vert_glsl,
+ datatoc_edit_mesh_overlay_geom_edge_glsl,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+ if (!e_data.overlay_edge_vcol_sh) {
+ e_data.overlay_edge_vcol_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_vert_glsl,
+ datatoc_edit_mesh_overlay_geom_edge_glsl,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define VERTEX_SELECTION\n");
+ }
+ if (!e_data.overlay_vert_sh) {
+ e_data.overlay_vert_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_loosevert_vert_glsl, NULL,
+ datatoc_edit_mesh_overlay_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define VERTEX_SELECTION\n");
+ }
+ if (!e_data.overlay_facedot_sh) {
+ e_data.overlay_facedot_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL,
+ datatoc_edit_mesh_overlay_facedot_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+ if (!e_data.overlay_mix_sh) {
+ e_data.overlay_mix_sh = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
+ }
+ if (!e_data.overlay_facefill_sh) {
+ e_data.overlay_facefill_sh = DRW_shader_create_with_lib(
+ datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL,
+ datatoc_edit_mesh_overlay_facefill_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+ if (!e_data.normals_face_sh) {
+ e_data.normals_face_sh = DRW_shader_create(
+ datatoc_edit_normals_vert_glsl,
+ datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ "#define FACE_NORMALS\n");
+ }
+ if (!e_data.normals_loop_sh) {
+ e_data.normals_loop_sh = DRW_shader_create(
+ datatoc_edit_normals_vert_glsl,
+ datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ "#define LOOP_NORMALS\n");
+ }
+ if (!e_data.normals_sh) {
+ e_data.normals_sh = DRW_shader_create(
+ datatoc_edit_normals_vert_glsl,
+ datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
+ }
+ if (!e_data.depth_sh) {
+ e_data.depth_sh = DRW_shader_create_3D_depth_only();
+ }
+}
+
+static DRWPass *edit_mesh_create_overlay_pass(
+ float *faceAlpha, DRWState statemod,
+ DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_ledges_shgrp,
+ DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp)
+{
+ GPUShader *tri_sh, *ledge_sh;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ Scene *scene = draw_ctx->scene;
+ ToolSettings *tsettings = scene->toolsettings;
+
+ if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
+ ledge_sh = e_data.overlay_edge_vcol_sh;
+
+ if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
+ tri_sh = e_data.overlay_tri_vcol_fast_sh;
+ else
+ tri_sh = e_data.overlay_tri_vcol_sh;
+ }
+ else {
+ ledge_sh = e_data.overlay_edge_sh;
+
+ if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
+ tri_sh = e_data.overlay_tri_fast_sh;
+ else
+ tri_sh = e_data.overlay_tri_sh;
+ }
+
+ DRWPass *pass = DRW_pass_create(
+ "Edit Mesh Face Overlay Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
+
+ *r_face_shgrp = DRW_shgroup_create(tri_sh, pass);
+ DRW_shgroup_uniform_block(*r_face_shgrp, "globalsBlock", globals_ubo);
+ DRW_shgroup_uniform_vec2(*r_face_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_float(*r_face_shgrp, "faceAlphaMod", faceAlpha, 1);
+
+ *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
+ DRW_shgroup_uniform_block(*r_ledges_shgrp, "globalsBlock", globals_ubo);
+ DRW_shgroup_uniform_vec2(*r_ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+
+ if ((tsettings->selectmode & (SCE_SELECT_VERTEX)) != 0) {
+ *r_lverts_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, pass);
+ DRW_shgroup_uniform_block(*r_lverts_shgrp, "globalsBlock", globals_ubo);
+ DRW_shgroup_uniform_vec2(*r_lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ }
+
+ if ((tsettings->selectmode & (SCE_SELECT_FACE)) != 0) {
+ *r_facedot_shgrp = DRW_shgroup_create(e_data.overlay_facedot_sh, pass);
+ DRW_shgroup_uniform_block(*r_facedot_shgrp, "globalsBlock", globals_ubo);
+ }
+
+ return pass;
+}
+
+static float backwire_opacity;
+static float face_mod;
+static float size_normal;
+
+static void EDIT_MESH_cache_init(void *vedata)
+{
+ EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
+ EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+
+ bool do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0);
+
+ static float zero = 0.0f;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ psl->vcolor_faces = DRW_pass_create(
+ "Vert Color Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->fvcolor_shgrp = DRW_shgroup_create(e_data.vcolor_face_shader, psl->vcolor_faces);
+
+ static float light[3] = {-0.3f, 0.5f, 1.0f};
+ static float alpha = 1.0f;
+ static float world_light = 1.0f; /* XXX, see: paint_vertex_mode.c */
+ DRW_shgroup_uniform_vec3(stl->g_data->fvcolor_shgrp, "light", light, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "alpha", &alpha, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "global", &world_light, 1);
+ }
+
+ {
+ /* Complementary Depth Pass */
+ psl->depth_hidden_wire = DRW_pass_create(
+ "Depth Pass Hidden Wire",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
+ }
+
+ {
+ /* Normals */
+ psl->normals = DRW_pass_create(
+ "Edit Mesh Normals Pass",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->fnormals_shgrp = DRW_shgroup_create(e_data.normals_face_sh, psl->normals);
+ DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", ts.colorNormal, 1);
+
+ stl->g_data->vnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
+ DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", ts.colorVNormal, 1);
+
+ stl->g_data->lnormals_shgrp = DRW_shgroup_create(e_data.normals_loop_sh, psl->normals);
+ DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", ts.colorLNormal, 1);
+ }
+
+ if (!do_zbufclip) {
+ psl->edit_face_overlay = edit_mesh_create_overlay_pass(
+ &face_mod, DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND,
+ &stl->g_data->face_overlay_shgrp, &stl->g_data->ledges_overlay_shgrp,
+ &stl->g_data->lverts_overlay_shgrp, &stl->g_data->facedot_overlay_shgrp);
+ }
+ else {
+ /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
+ psl->edit_face_occluded = edit_mesh_create_overlay_pass(
+ &zero, DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH,
+ &stl->g_data->face_occluded_shgrp, &stl->g_data->ledges_occluded_shgrp,
+ &stl->g_data->lverts_occluded_shgrp, &stl->g_data->facedot_occluded_shgrp);
+
+ /* however we loose the front faces value (because we need the depth of occluded wires and
+ * faces are alpha blended ) so we recover them in a new pass. */
+ psl->facefill_occlude = DRW_pass_create(
+ "Front Face Color",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+ stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(e_data.overlay_facefill_sh, psl->facefill_occlude);
+ DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo);
+
+ /* we need a full screen pass to combine the result */
+ struct Batch *quad = DRW_cache_fullscreen_quad_get();
+
+ psl->mix_occlude = DRW_pass_create(
+ "Mix Occluded Wires",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
+ DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.overlay_mix_sh, psl->mix_occlude);
+ DRW_shgroup_call_add(mix_shgrp, quad, NULL);
+ DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
+ DRW_shgroup_uniform_buffer(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
+ DRW_shgroup_uniform_buffer(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
+ DRW_shgroup_uniform_buffer(mix_shgrp, "sceneDepth", &dtxl->depth);
+ }
+}
+
+static void edit_mesh_add_ob_to_pass(
+ Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp,
+ DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp)
+{
+ struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
+ ToolSettings *tsettings = scene->toolsettings;
+
+ DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
+ DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
+ DRW_shgroup_call_add(ledges_shgrp, geo_ovl_ledges, ob->obmat);
+
+ if (facefill_shgrp) {
+ DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
+ }
+
+ if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
+ DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
+ }
+
+ if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) {
+ geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
+ DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
+ }
+}
+
+static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
+{
+ EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ Scene *scene = draw_ctx->scene;
+ Object *obedit = scene->obedit;
+ struct Batch *geom;
+
+ if (ob->type == OB_MESH) {
+ if (ob == obedit) {
+ IDProperty *ces_mode_ed = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
+ bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
+ bool do_show_weight = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_weight");
+
+ /* Updating uniform */
+ backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity");
+
+ bool fnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "face_normals_show");
+ bool vnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "vert_normals_show");
+ bool lnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "loop_normals_show");
+ /* Updating uniform */
+ size_normal = BKE_collection_engine_property_value_get_float(ces_mode_ed, "normals_length");
+
+ face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
+
+ if (do_show_weight) {
+ geom = DRW_cache_mesh_surface_weights_get(ob);
+ DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat);
+ }
+
+ if (do_occlude_wire) {
+ geom = DRW_cache_mesh_surface_get(ob);
+ DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
+ }
+
+ if (fnormals_do) {
+ geom = DRW_cache_face_centers_get(ob);
+ DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
+ }
+
+ if (vnormals_do || lnormals_do) {
+ struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts;
+ DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
+
+ if (vnormals_do) {
+ DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_tris, ob->obmat);
+ DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_ledges, ob->obmat);
+ DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_lverts, ob->obmat);
+ }
+
+ if (lnormals_do) {
+ DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geo_ovl_tris, ob->obmat);
+ }
+ }
+
+ if ((v3d->flag & V3D_ZBUF_SELECT) == 0) {
+ edit_mesh_add_ob_to_pass(
+ scene, ob, stl->g_data->face_occluded_shgrp, stl->g_data->ledges_occluded_shgrp,
+ stl->g_data->lverts_occluded_shgrp, stl->g_data->facedot_occluded_shgrp,
+ stl->g_data->facefill_occluded_shgrp);
+ }
+ else {
+ edit_mesh_add_ob_to_pass(
+ scene, ob, stl->g_data->face_overlay_shgrp, stl->g_data->ledges_overlay_shgrp,
+ stl->g_data->lverts_overlay_shgrp, stl->g_data->facedot_overlay_shgrp, NULL);
+ }
+ }
+ }
+}
+
+static void EDIT_MESH_draw_scene(void *vedata)
+{
+ EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
+ EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ DRW_draw_pass(psl->vcolor_faces);
+
+ DRW_draw_pass(psl->depth_hidden_wire);
+
+ if (psl->edit_face_occluded) {
+ float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ /* render facefill */
+ DRW_draw_pass(psl->facefill_occlude);
+
+ /* attach temp textures */
+ DRW_framebuffer_texture_attach(fbl->occlude_wire_fb, e_data.occlude_wire_depth_tx, 0, 0);
+ DRW_framebuffer_texture_attach(fbl->occlude_wire_fb, e_data.occlude_wire_color_tx, 0, 0);
+
+ /* Render wires on a separate framebuffer */
+ DRW_framebuffer_bind(fbl->occlude_wire_fb);
+ DRW_framebuffer_clear(true, true, false, clearcol, 1.0f);
+ DRW_draw_pass(psl->normals);
+ DRW_draw_pass(psl->edit_face_occluded);
+
+ /* detach textures */
+ DRW_framebuffer_texture_detach(dtxl->depth);
+
+ /* Combine with scene buffer */
+ DRW_framebuffer_bind(dfbl->default_fb);
+ DRW_draw_pass(psl->mix_occlude);
+
+ /* detach temp textures */
+ DRW_framebuffer_texture_detach(e_data.occlude_wire_depth_tx);
+ DRW_framebuffer_texture_detach(e_data.occlude_wire_color_tx);
+
+ /* reattach */
+ DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ }
+ else {
+ DRW_draw_pass(psl->normals);
+ DRW_draw_pass(psl->edit_face_overlay);
+ }
+}
+
+void EDIT_MESH_collection_settings_create(IDProperty *properties)
+{
+ BLI_assert(properties &&
+ properties->type == IDP_GROUP &&
+ properties->subtype == IDP_GROUP_SUB_MODE_EDIT);
+ BKE_collection_engine_property_add_int(properties, "show_occlude_wire", false);
+ BKE_collection_engine_property_add_int(properties, "show_weight", false);
+ BKE_collection_engine_property_add_int(properties, "face_normals_show", false);
+ BKE_collection_engine_property_add_int(properties, "vert_normals_show", false);
+ BKE_collection_engine_property_add_int(properties, "loop_normals_show", false);
+ BKE_collection_engine_property_add_float(properties, "normals_length", 0.1);
+ BKE_collection_engine_property_add_float(properties, "backwire_opacity", 0.5);
+}
+
+static void EDIT_MESH_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_tri_fast_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_tri_vcol_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_tri_vcol_fast_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_edge_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_edge_vcol_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_facedot_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_mix_sh);
+ DRW_SHADER_FREE_SAFE(e_data.overlay_facefill_sh);
+ DRW_SHADER_FREE_SAFE(e_data.normals_loop_sh);
+ DRW_SHADER_FREE_SAFE(e_data.normals_face_sh);
+ DRW_SHADER_FREE_SAFE(e_data.normals_sh);
+}
+
+static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
+
+DrawEngineType draw_engine_edit_mesh_type = {
+ NULL, NULL,
+ N_("EditMeshMode"),
+ &EDIT_MESH_data_size,
+ &EDIT_MESH_engine_init,
+ &EDIT_MESH_engine_free,
+ &EDIT_MESH_cache_init,
+ &EDIT_MESH_cache_populate,
+ NULL,
+ NULL,
+ &EDIT_MESH_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
new file mode 100644
index 00000000000..a5857ba362a
--- /dev/null
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_metaball_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* If needed, contains all global/Theme colors
+ * Add needed theme colors / values to DRW_globals_update() and update UBO
+ * Not needed for constant color. */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use EDIT_METABALL_engine_init() to
+ * initialize most of them and EDIT_METABALL_cache_init()
+ * for EDIT_METABALL_PassList */
+
+typedef struct EDIT_METABALL_PassList {
+ /* Declare all passes here and init them in
+ * EDIT_METABALL_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *pass;
+} EDIT_METABALL_PassList;
+
+typedef struct EDIT_METABALL_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} EDIT_METABALL_FramebufferList;
+
+typedef struct EDIT_METABALL_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} EDIT_METABALL_TextureList;
+
+typedef struct EDIT_METABALL_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct EDIT_METABALL_PrivateData *g_data;
+} EDIT_METABALL_StorageList;
+
+typedef struct EDIT_METABALL_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ EDIT_METABALL_FramebufferList *fbl;
+ EDIT_METABALL_TextureList *txl;
+ EDIT_METABALL_PassList *psl;
+ EDIT_METABALL_StorageList *stl;
+} EDIT_METABALL_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in EDIT_METABALL_engine_init();
+ * free in EDIT_METABALL_engine_free(); */
+ struct GPUShader *custom_shader;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EDIT_METABALL_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in EDIT_METABALL_cache_populate() */
+ DRWShadingGroup *group;
+} EDIT_METABALL_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void EDIT_METABALL_engine_init(void *vedata)
+{
+ EDIT_METABALL_TextureList *txl = ((EDIT_METABALL_Data *)vedata)->txl;
+ EDIT_METABALL_FramebufferList *fbl = ((EDIT_METABALL_Data *)vedata)->fbl;
+ EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.custom_shader) {
+ e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void EDIT_METABALL_cache_init(void *vedata)
+{
+ EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
+ EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create a pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ psl->pass = DRW_pass_create("My Pass", state);
+
+ /* Create a shadingGroup using a function in draw_common.c or custom one */
+ /*
+ * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
+ * -- or --
+ * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+ */
+ stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+
+ /* Uniforms need a pointer to it's value so be sure it's accessible at
+ * any given time (i.e. use static vars) */
+ static float color[4] = {0.0f, 1.0f, 0.0f, 1.0};
+ DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
+ }
+
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
+{
+ EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
+ EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
+
+ UNUSED_VARS(psl, stl);
+
+ if (ob->type == OB_MESH) {
+ /* Get geometry cache */
+ struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+
+ /* Add geom to a shading group */
+ DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void EDIT_METABALL_cache_finish(void *vedata)
+{
+ EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
+ EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void EDIT_METABALL_draw_scene(void *vedata)
+{
+ EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
+ EDIT_METABALL_FramebufferList *fbl = ((EDIT_METABALL_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ /* ... or just render passes on default framebuffer. */
+ DRW_draw_pass(psl->pass);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void EDIT_METABALL_engine_free(void)
+{
+ // DRW_SHADER_FREE_SAFE(custom_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void EDIT_METABALL_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize EDIT_METABALL_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_METABALL_Data);
+
+DrawEngineType draw_engine_edit_metaball_type = {
+ NULL, NULL,
+ N_("EditMetaballMode"),
+ &EDIT_METABALL_data_size,
+ &EDIT_METABALL_engine_init,
+ &EDIT_METABALL_engine_free,
+ &EDIT_METABALL_cache_init,
+ &EDIT_METABALL_cache_populate,
+ &EDIT_METABALL_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &EDIT_METABALL_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c
new file mode 100644
index 00000000000..577b84e38c6
--- /dev/null
+++ b/source/blender/draw/modes/edit_surface_mode.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_surface_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* If needed, contains all global/Theme colors
+ * Add needed theme colors / values to DRW_globals_update() and update UBO
+ * Not needed for constant color. */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use EDIT_SURFACE_engine_init() to
+ * initialize most of them and EDIT_SURFACE_cache_init()
+ * for EDIT_SURFACE_PassList */
+
+typedef struct EDIT_SURFACE_PassList {
+ /* Declare all passes here and init them in
+ * EDIT_SURFACE_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *pass;
+} EDIT_SURFACE_PassList;
+
+typedef struct EDIT_SURFACE_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} EDIT_SURFACE_FramebufferList;
+
+typedef struct EDIT_SURFACE_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} EDIT_SURFACE_TextureList;
+
+typedef struct EDIT_SURFACE_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct EDIT_SURFACE_PrivateData *g_data;
+} EDIT_SURFACE_StorageList;
+
+typedef struct EDIT_SURFACE_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ EDIT_SURFACE_FramebufferList *fbl;
+ EDIT_SURFACE_TextureList *txl;
+ EDIT_SURFACE_PassList *psl;
+ EDIT_SURFACE_StorageList *stl;
+} EDIT_SURFACE_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in EDIT_SURFACE_engine_init();
+ * free in EDIT_SURFACE_engine_free(); */
+ struct GPUShader *custom_shader;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EDIT_SURFACE_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in EDIT_SURFACE_cache_populate() */
+ DRWShadingGroup *group;
+} EDIT_SURFACE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void EDIT_SURFACE_engine_init(void *vedata)
+{
+ EDIT_SURFACE_TextureList *txl = ((EDIT_SURFACE_Data *)vedata)->txl;
+ EDIT_SURFACE_FramebufferList *fbl = ((EDIT_SURFACE_Data *)vedata)->fbl;
+ EDIT_SURFACE_StorageList *stl = ((EDIT_SURFACE_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.custom_shader) {
+ e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void EDIT_SURFACE_cache_init(void *vedata)
+{
+ EDIT_SURFACE_PassList *psl = ((EDIT_SURFACE_Data *)vedata)->psl;
+ EDIT_SURFACE_StorageList *stl = ((EDIT_SURFACE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create a pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ psl->pass = DRW_pass_create("My Pass", state);
+
+ /* Create a shadingGroup using a function in draw_common.c or custom one */
+ /*
+ * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
+ * -- or --
+ * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+ */
+ stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+
+ /* Uniforms need a pointer to it's value so be sure it's accessible at
+ * any given time (i.e. use static vars) */
+ static float color[4] = {0.0f, 0.0f, 1.0f, 1.0};
+ DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
+ }
+
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void EDIT_SURFACE_cache_populate(void *vedata, Object *ob)
+{
+ EDIT_SURFACE_PassList *psl = ((EDIT_SURFACE_Data *)vedata)->psl;
+ EDIT_SURFACE_StorageList *stl = ((EDIT_SURFACE_Data *)vedata)->stl;
+
+ UNUSED_VARS(psl, stl);
+
+ if (ob->type == OB_MESH) {
+ /* Get geometry cache */
+ struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+
+ /* Add geom to a shading group */
+ DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void EDIT_SURFACE_cache_finish(void *vedata)
+{
+ EDIT_SURFACE_PassList *psl = ((EDIT_SURFACE_Data *)vedata)->psl;
+ EDIT_SURFACE_StorageList *stl = ((EDIT_SURFACE_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void EDIT_SURFACE_draw_scene(void *vedata)
+{
+ EDIT_SURFACE_PassList *psl = ((EDIT_SURFACE_Data *)vedata)->psl;
+ EDIT_SURFACE_FramebufferList *fbl = ((EDIT_SURFACE_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ /* ... or just render passes on default framebuffer. */
+ DRW_draw_pass(psl->pass);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void EDIT_SURFACE_engine_free(void)
+{
+ // DRW_SHADER_FREE_SAFE(custom_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void EDIT_SURFACE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize EDIT_SURFACE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_SURFACE_Data);
+
+DrawEngineType draw_engine_edit_surface_type = {
+ NULL, NULL,
+ N_("EditSurfaceMode"),
+ &EDIT_SURFACE_data_size,
+ &EDIT_SURFACE_engine_init,
+ &EDIT_SURFACE_engine_free,
+ &EDIT_SURFACE_cache_init,
+ &EDIT_SURFACE_cache_populate,
+ &EDIT_SURFACE_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &EDIT_SURFACE_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c
new file mode 100644
index 00000000000..13c8015e628
--- /dev/null
+++ b/source/blender/draw/modes/edit_text_mode.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/edit_text_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_curve_types.h"
+
+#include "BIF_glutil.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+#include "GPU_batch.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* If needed, contains all global/Theme colors
+ * Add needed theme colors / values to DRW_globals_update() and update UBO
+ * Not needed for constant color. */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use EDIT_TEXT_engine_init() to
+ * initialize most of them and EDIT_TEXT_cache_init()
+ * for EDIT_TEXT_PassList */
+
+typedef struct EDIT_TEXT_PassList {
+ /* Declare all passes here and init them in
+ * EDIT_TEXT_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *wire_pass;
+ struct DRWPass *overlay_select_pass;
+ struct DRWPass *overlay_cursor_pass;
+} EDIT_TEXT_PassList;
+
+typedef struct EDIT_TEXT_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} EDIT_TEXT_FramebufferList;
+
+typedef struct EDIT_TEXT_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} EDIT_TEXT_TextureList;
+
+typedef struct EDIT_TEXT_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct EDIT_TEXT_PrivateData *g_data;
+} EDIT_TEXT_StorageList;
+
+typedef struct EDIT_TEXT_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ EDIT_TEXT_FramebufferList *fbl;
+ EDIT_TEXT_TextureList *txl;
+ EDIT_TEXT_PassList *psl;
+ EDIT_TEXT_StorageList *stl;
+} EDIT_TEXT_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in EDIT_TEXT_engine_init();
+ * free in EDIT_TEXT_engine_free(); */
+ GPUShader *wire_sh;
+ GPUShader *overlay_select_sh;
+ GPUShader *overlay_cursor_sh;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct EDIT_TEXT_PrivateData {
+ /* resulting curve as 'wire' for fast editmode drawing */
+ DRWShadingGroup *wire_shgrp;
+ DRWShadingGroup *overlay_select_shgrp;
+ DRWShadingGroup *overlay_cursor_shgrp;
+} EDIT_TEXT_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void EDIT_TEXT_engine_init(void *vedata)
+{
+ EDIT_TEXT_TextureList *txl = ((EDIT_TEXT_Data *)vedata)->txl;
+ EDIT_TEXT_FramebufferList *fbl = ((EDIT_TEXT_Data *)vedata)->fbl;
+ EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.wire_sh) {
+ e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!e_data.overlay_select_sh) {
+ e_data.overlay_select_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!e_data.overlay_cursor_sh) {
+ e_data.overlay_cursor_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void EDIT_TEXT_cache_init(void *vedata)
+{
+ EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl;
+ EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Text outline (fast drawing!) */
+ psl->wire_pass = DRW_pass_create(
+ "Font Wire",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE);
+ stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass);
+
+ psl->overlay_select_pass = DRW_pass_create(
+ "Font Select",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH);
+ stl->g_data->overlay_select_shgrp = DRW_shgroup_create(e_data.overlay_select_sh, psl->overlay_select_pass);
+
+ psl->overlay_cursor_pass = DRW_pass_create(
+ "Font Cursor",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH);
+ stl->g_data->overlay_cursor_shgrp = DRW_shgroup_create(e_data.overlay_cursor_sh, psl->overlay_cursor_pass);
+ }
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void EDIT_TEXT_cache_populate(void *vedata, Object *ob)
+{
+ EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl;
+ EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ Object *obedit = scene->obedit;
+
+ UNUSED_VARS(psl, stl);
+
+ if (ob->type == OB_FONT) {
+ if (ob == obedit) {
+ const Curve *cu = ob->data;
+ /* Get geometry cache */
+ struct Batch *geom;
+
+ if (cu->flag & CU_FAST) {
+ geom = DRW_cache_text_edge_wire_get(ob);
+ if (geom) {
+ DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
+ }
+ }
+ else {
+ /* object mode draws */
+ }
+
+ geom = DRW_cache_text_select_overlay_get(ob);
+ if (geom) {
+ DRW_shgroup_call_add(stl->g_data->overlay_select_shgrp, geom, ob->obmat);
+ }
+
+ geom = DRW_cache_text_cursor_overlay_get(ob);
+ if (geom) {
+ DRW_shgroup_call_add(stl->g_data->overlay_cursor_shgrp, geom, ob->obmat);
+ }
+ }
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void EDIT_TEXT_cache_finish(void *vedata)
+{
+ EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl;
+ EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void EDIT_TEXT_draw_scene(void *vedata)
+{
+ EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl;
+ EDIT_TEXT_FramebufferList *fbl = ((EDIT_TEXT_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ DRW_draw_pass(psl->wire_pass);
+
+ set_inverted_drawing(1);
+ DRW_draw_pass(psl->overlay_select_pass);
+ DRW_draw_pass(psl->overlay_cursor_pass);
+ set_inverted_drawing(0);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void EDIT_TEXT_engine_free(void)
+{
+ // DRW_SHADER_FREE_SAFE(custom_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void EDIT_TEXT_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize EDIT_TEXT_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_TEXT_Data);
+
+DrawEngineType draw_engine_edit_text_type = {
+ NULL, NULL,
+ N_("EditTextMode"),
+ &EDIT_TEXT_data_size,
+ &EDIT_TEXT_engine_init,
+ &EDIT_TEXT_engine_free,
+ &EDIT_TEXT_cache_init,
+ &EDIT_TEXT_cache_populate,
+ &EDIT_TEXT_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &EDIT_TEXT_draw_scene
+};
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
new file mode 100644
index 00000000000..8abe59b1cbf
--- /dev/null
+++ b/source/blender/draw/modes/object_mode.c
@@ -0,0 +1,1736 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/object_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_userdef_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+
+#include "BIF_gl.h"
+
+#include "BKE_anim.h"
+#include "BKE_camera.h"
+#include "BKE_curve.h"
+#include "BKE_global.h"
+#include "BKE_particle.h"
+#include "BKE_image.h"
+#include "BKE_texture.h"
+
+#include "ED_view3d.h"
+#include "ED_view3d.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "UI_resources.h"
+
+#include "draw_mode_engines.h"
+#include "draw_manager_text.h"
+#include "draw_common.h"
+
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GPUTexture *globals_ramp; /* draw_common.c */
+extern GlobalsUboStorage ts;
+
+extern char datatoc_object_outline_resolve_frag_glsl[];
+extern char datatoc_object_outline_detect_frag_glsl[];
+extern char datatoc_object_outline_expand_frag_glsl[];
+extern char datatoc_object_grid_frag_glsl[];
+extern char datatoc_object_grid_vert_glsl[];
+extern char datatoc_object_empty_image_frag_glsl[];
+extern char datatoc_object_empty_image_vert_glsl[];
+extern char datatoc_object_particle_prim_vert_glsl[];
+extern char datatoc_object_particle_prim_frag_glsl[];
+extern char datatoc_object_particle_dot_vert_glsl[];
+extern char datatoc_object_particle_dot_frag_glsl[];
+extern char datatoc_common_globals_lib_glsl[];
+
+/* *********** LISTS *********** */
+typedef struct OBJECT_PassList {
+ struct DRWPass *non_meshes;
+ struct DRWPass *ob_center;
+ struct DRWPass *outlines;
+ struct DRWPass *outlines_search;
+ struct DRWPass *outlines_expand;
+ struct DRWPass *outlines_fade1;
+ struct DRWPass *outlines_fade2;
+ struct DRWPass *outlines_fade3;
+ struct DRWPass *outlines_fade4;
+ struct DRWPass *outlines_fade5;
+ struct DRWPass *outlines_resolve;
+ struct DRWPass *grid;
+ struct DRWPass *bone_solid;
+ struct DRWPass *bone_wire;
+ struct DRWPass *bone_envelope;
+ struct DRWPass *particle;
+ /* use for empty/background images */
+ struct DRWPass *reference_image;
+} OBJECT_PassList;
+
+typedef struct OBJECT_FramebufferList {
+ struct GPUFrameBuffer *outlines;
+ struct GPUFrameBuffer *blur;
+} OBJECT_FramebufferList;
+
+typedef struct OBJECT_StorageList {
+ struct OBJECT_PrivateData *g_data;
+} OBJECT_StorageList;
+
+typedef struct OBJECT_Data {
+ void *engine_type;
+ OBJECT_FramebufferList *fbl;
+ DRWViewportEmptyList *txl;
+ OBJECT_PassList *psl;
+ OBJECT_StorageList *stl;
+} OBJECT_Data;
+
+/* *********** STATIC *********** */
+
+typedef struct OBJECT_PrivateData{
+ /* Empties */
+ DRWShadingGroup *plain_axes;
+ DRWShadingGroup *cube;
+ DRWShadingGroup *circle;
+ DRWShadingGroup *sphere;
+ DRWShadingGroup *cone;
+ DRWShadingGroup *single_arrow;
+ DRWShadingGroup *single_arrow_line;
+ DRWShadingGroup *arrows;
+ DRWShadingGroup *axis_names;
+ /* GPUTexture -> EmptyImageShadingGroupData */
+ GHash *image_plane_map;
+
+ /* Force Field */
+ DRWShadingGroup *field_wind;
+ DRWShadingGroup *field_force;
+ DRWShadingGroup *field_vortex;
+ DRWShadingGroup *field_curve_sta;
+ DRWShadingGroup *field_curve_end;
+ DRWShadingGroup *field_tube_limit;
+ DRWShadingGroup *field_cone_limit;
+
+ /* Speaker */
+ DRWShadingGroup *speaker;
+
+ /* Lamps */
+ DRWShadingGroup *lamp_center;
+ DRWShadingGroup *lamp_center_group;
+ DRWShadingGroup *lamp_groundpoint;
+ DRWShadingGroup *lamp_groundline;
+ DRWShadingGroup *lamp_circle;
+ DRWShadingGroup *lamp_circle_shadow;
+ DRWShadingGroup *lamp_sunrays;
+ DRWShadingGroup *lamp_distance;
+ DRWShadingGroup *lamp_buflimit;
+ DRWShadingGroup *lamp_buflimit_points;
+ DRWShadingGroup *lamp_area;
+ DRWShadingGroup *lamp_hemi;
+ DRWShadingGroup *lamp_spot_cone;
+ DRWShadingGroup *lamp_spot_blend;
+ DRWShadingGroup *lamp_spot_pyramid;
+ DRWShadingGroup *lamp_spot_blend_rect;
+
+ /* Helpers */
+ DRWShadingGroup *relationship_lines;
+
+ /* Objects Centers */
+ DRWShadingGroup *center_active;
+ DRWShadingGroup *center_selected;
+ DRWShadingGroup *center_deselected;
+ DRWShadingGroup *center_selected_lib;
+ DRWShadingGroup *center_deselected_lib;
+
+ /* Camera */
+ DRWShadingGroup *camera;
+ DRWShadingGroup *camera_tria;
+ DRWShadingGroup *camera_focus;
+ DRWShadingGroup *camera_clip;
+ DRWShadingGroup *camera_clip_points;
+ DRWShadingGroup *camera_mist;
+ DRWShadingGroup *camera_mist_points;
+
+ /* Outlines */
+ DRWShadingGroup *outlines_active;
+ DRWShadingGroup *outlines_active_group;
+ DRWShadingGroup *outlines_select;
+ DRWShadingGroup *outlines_select_group;
+ DRWShadingGroup *outlines_transform;
+
+ /* Wire */
+ DRWShadingGroup *wire;
+ DRWShadingGroup *wire_active;
+ DRWShadingGroup *wire_active_group;
+ DRWShadingGroup *wire_select;
+ DRWShadingGroup *wire_select_group;
+ DRWShadingGroup *wire_transform;
+} OBJECT_PrivateData; /* Transient data */
+
+static struct {
+ /* fullscreen shaders */
+ GPUShader *outline_resolve_sh;
+ GPUShader *outline_detect_sh;
+ GPUShader *outline_fade_sh;
+
+ /* regular shaders */
+ GPUShader *object_empty_image_sh;
+ GPUShader *object_empty_image_wire_sh;
+ GPUShader *grid_sh;
+ GPUShader *part_dot_sh;
+ GPUShader *part_prim_sh;
+ GPUShader *part_axis_sh;
+ float camera_pos[3];
+ float screenvecs[3][4];
+ float grid_settings[5];
+ float grid_mat[4][4];
+ int grid_flag;
+ float grid_normal[3];
+ float grid_axes[3];
+ int zpos_flag;
+ int zneg_flag;
+ float zplane_normal[3];
+ float zplane_axes[3];
+ bool draw_grid;
+ /* Temp buffer textures */
+ struct GPUTexture *outlines_depth_tx;
+ struct GPUTexture *outlines_color_tx;
+ struct GPUTexture *outlines_blur_tx;
+} e_data = {NULL}; /* Engine data */
+
+
+enum {
+ SHOW_AXIS_X = (1 << 0),
+ SHOW_AXIS_Y = (1 << 1),
+ SHOW_AXIS_Z = (1 << 2),
+ SHOW_GRID = (1 << 3),
+ PLANE_XY = (1 << 4),
+ PLANE_XZ = (1 << 5),
+ PLANE_YZ = (1 << 6),
+ CLIP_ZPOS = (1 << 7),
+ CLIP_ZNEG = (1 << 8),
+};
+
+/* *********** FUNCTIONS *********** */
+
+static void OBJECT_engine_init(void *vedata)
+{
+ OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
+
+ const float *viewport_size = DRW_viewport_size_get();
+
+ if (DRW_state_is_fbo()) {
+ DRWFboTexture tex[2] = {
+ {&e_data.outlines_depth_tx, DRW_TEX_DEPTH_24, DRW_TEX_TEMP},
+ {&e_data.outlines_color_tx, DRW_TEX_RGBA_8, DRW_TEX_FILTER | DRW_TEX_TEMP},
+ };
+
+ DRW_framebuffer_init(
+ &fbl->outlines, &draw_engine_object_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ tex, 2);
+
+ DRWFboTexture blur_tex = {&e_data.outlines_blur_tx, DRW_TEX_RGBA_8, DRW_TEX_FILTER | DRW_TEX_TEMP};
+ DRW_framebuffer_init(
+ &fbl->blur, &draw_engine_object_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &blur_tex, 1);
+ }
+
+ if (!e_data.outline_resolve_sh) {
+ e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL);
+ }
+
+ if (!e_data.outline_detect_sh) {
+ e_data.outline_detect_sh = DRW_shader_create_fullscreen(datatoc_object_outline_detect_frag_glsl, NULL);
+ }
+
+ if (!e_data.outline_fade_sh) {
+ e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL);
+ }
+
+ if (!e_data.object_empty_image_sh) {
+ e_data.object_empty_image_sh = DRW_shader_create_with_lib(
+ datatoc_object_empty_image_vert_glsl, NULL,
+ datatoc_object_empty_image_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+
+ if (!e_data.object_empty_image_wire_sh) {
+ e_data.object_empty_image_wire_sh = DRW_shader_create_with_lib(
+ datatoc_object_empty_image_vert_glsl, NULL,
+ datatoc_object_empty_image_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define USE_WIRE\n");
+ }
+
+ if (!e_data.grid_sh) {
+ e_data.grid_sh = DRW_shader_create_with_lib(
+ datatoc_object_grid_vert_glsl, NULL,
+ datatoc_object_grid_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+
+ if (!e_data.part_prim_sh) {
+ e_data.part_prim_sh = DRW_shader_create(datatoc_object_particle_prim_vert_glsl, NULL, datatoc_object_particle_prim_frag_glsl, NULL);
+ }
+
+ if (!e_data.part_axis_sh) {
+ e_data.part_axis_sh = DRW_shader_create(datatoc_object_particle_prim_vert_glsl, NULL, datatoc_object_particle_prim_frag_glsl, "#define USE_AXIS\n");
+ }
+
+ if (!e_data.part_dot_sh) {
+ e_data.part_dot_sh = DRW_shader_create(datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL);
+ }
+
+ {
+ /* Grid precompute */
+ float invviewmat[4][4], invwinmat[4][4];
+ float viewmat[4][4], winmat[4][4];
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ Scene *scene = draw_ctx->scene;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ float grid_scale = ED_view3d_grid_scale(scene, v3d, NULL);
+ float grid_res, offs;
+
+ const bool show_axis_x = (v3d->gridflag & V3D_SHOW_X) != 0;
+ const bool show_axis_y = (v3d->gridflag & V3D_SHOW_Y) != 0;
+ const bool show_axis_z = (v3d->gridflag & V3D_SHOW_Z) != 0;
+ const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) != 0;
+ e_data.draw_grid = show_axis_x || show_axis_y || show_axis_z || show_floor;
+
+ DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(invwinmat, DRW_MAT_WININV);
+ DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
+
+ /* Setup camera pos */
+ copy_v3_v3(e_data.camera_pos, invviewmat[3]);
+
+ /* if perps */
+ if (winmat[3][3] == 0.0f) {
+ float fov;
+ float viewvecs[2][4] = {
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f}
+ };
+
+ /* convert the view vectors to view space */
+ for (int i = 0; i < 2; i++) {
+ mul_m4_v4(invwinmat, viewvecs[i]);
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); /* perspective divide */
+ }
+
+ fov = angle_v3v3(viewvecs[0], viewvecs[1]) / 2.0f;
+ grid_res = fabsf(tanf(fov)) / grid_scale;
+
+ /* Grid matrix polygon offset (fix depth fighting) */
+ /* see ED_view3d_polygon_offset */
+ offs = winmat[3][2] * -0.0025f;
+
+ e_data.grid_flag = (1 << 4); /* XY plane */
+ if (show_axis_x)
+ e_data.grid_flag |= SHOW_AXIS_X;
+ if (show_axis_y)
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ if (show_floor)
+ e_data.grid_flag |= SHOW_GRID;
+
+ }
+ else {
+ float viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
+ grid_res = viewdist / grid_scale;
+
+ /* Grid matrix polygon offset (fix depth fighting) */
+ /* see ED_view3d_polygon_offset */
+ offs = 0.00001f * viewdist;
+ if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
+ e_data.grid_flag = PLANE_YZ;
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ e_data.grid_flag |= SHOW_AXIS_Z;
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
+ e_data.grid_flag = PLANE_XY;
+ e_data.grid_flag |= SHOW_AXIS_X;
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
+ e_data.grid_flag = PLANE_XZ;
+ e_data.grid_flag |= SHOW_AXIS_X;
+ e_data.grid_flag |= SHOW_AXIS_Z;
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ else { /* RV3D_VIEW_USER */
+ e_data.grid_flag = PLANE_XY;
+ if (show_axis_x)
+ e_data.grid_flag |= SHOW_AXIS_X;
+ if (show_axis_y)
+ e_data.grid_flag |= SHOW_AXIS_Y;
+ if (show_floor)
+ e_data.grid_flag |= SHOW_GRID;
+ }
+ }
+
+ e_data.grid_normal[0] = (float)((e_data.grid_flag & PLANE_YZ) != 0);
+ e_data.grid_normal[1] = (float)((e_data.grid_flag & PLANE_XZ) != 0);
+ e_data.grid_normal[2] = (float)((e_data.grid_flag & PLANE_XY) != 0);
+
+ e_data.grid_axes[0] = (float)((e_data.grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
+ e_data.grid_axes[1] = (float)((e_data.grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
+ e_data.grid_axes[2] = (float)((e_data.grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
+
+ /* Vectors to recover pixel world position. Fix grid precision issue. */
+ /* Using pixel at z = 0.0f in ndc space : gives average precision between
+ * near and far plane. Note that it might not be the best choice. */
+ copy_v4_fl4(e_data.screenvecs[0], 1.0f, -1.0f, 0.0f, 1.0f);
+ copy_v4_fl4(e_data.screenvecs[1], -1.0f, 1.0f, 0.0f, 1.0f);
+ copy_v4_fl4(e_data.screenvecs[2], -1.0f, -1.0f, 0.0f, 1.0f);
+
+ for (int i = 0; i < 3; i++) {
+ /* Doing 2 steps to recover world position of the corners of the frustum.
+ * Using the inverse perspective matrix is giving very low precision output. */
+ mul_m4_v4(invwinmat, e_data.screenvecs[i]);
+ e_data.screenvecs[i][0] /= e_data.screenvecs[i][3]; /* perspective divide */
+ e_data.screenvecs[i][1] /= e_data.screenvecs[i][3]; /* perspective divide */
+ e_data.screenvecs[i][2] /= e_data.screenvecs[i][3]; /* perspective divide */
+ e_data.screenvecs[i][3] = 1.0f;
+ /* main instability come from this one */
+ /* TODO : to make things even more stable, don't use
+ * invviewmat and derive vectors from camera properties */
+ mul_m4_v4(invviewmat, e_data.screenvecs[i]);
+ }
+
+ sub_v3_v3(e_data.screenvecs[0], e_data.screenvecs[2]);
+ sub_v3_v3(e_data.screenvecs[1], e_data.screenvecs[2]);
+
+ /* Z axis if needed */
+ if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
+ e_data.zpos_flag = SHOW_AXIS_Z;
+
+ float zvec[4] = {0.0f, 0.0f, -1.0f, 0.0f};
+ mul_m4_v4(invviewmat, zvec);
+
+ /* z axis : chose the most facing plane */
+ if (fabsf(zvec[0]) < fabsf(zvec[1])) {
+ e_data.zpos_flag |= PLANE_XZ;
+ }
+ else {
+ e_data.zpos_flag |= PLANE_YZ;
+ }
+
+ e_data.zneg_flag = e_data.zpos_flag;
+
+ /* Persp : If camera is below floor plane, we switch clipping
+ * Ortho : If eye vector is looking up, we switch clipping */
+ if (((winmat[3][3] == 0.0f) && (e_data.camera_pos[2] > 0.0f)) ||
+ ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
+ e_data.zpos_flag |= CLIP_ZPOS;
+ e_data.zneg_flag |= CLIP_ZNEG;
+ }
+ else {
+ e_data.zpos_flag |= CLIP_ZNEG;
+ e_data.zneg_flag |= CLIP_ZPOS;
+ }
+
+ e_data.zplane_normal[0] = (float)((e_data.zpos_flag & PLANE_YZ) != 0);
+ e_data.zplane_normal[1] = (float)((e_data.zpos_flag & PLANE_XZ) != 0);
+ e_data.zplane_normal[2] = (float)((e_data.zpos_flag & PLANE_XY) != 0);
+
+ e_data.zplane_axes[0] = (float)((e_data.zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
+ e_data.zplane_axes[1] = (float)((e_data.zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
+ e_data.zplane_axes[2] = (float)((e_data.zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
+
+ }
+ else {
+ e_data.zneg_flag = e_data.zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
+ }
+
+ winmat[3][2] -= offs;
+ mul_m4_m4m4(e_data.grid_mat, winmat, viewmat);
+
+ float dist = (rv3d->persp == RV3D_CAMOB && v3d->camera)
+ ? ((Camera *)v3d->camera)->clipend : v3d->far;
+
+ e_data.grid_settings[0] = dist / 2.0f; /* gridDistance */
+ e_data.grid_settings[1] = grid_res; /* gridResolution */
+ e_data.grid_settings[2] = grid_scale; /* gridScale */
+ e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */
+ e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / log(v3d->gridsubdiv) : 0.0; /* 1/log(gridSubdiv) */
+ }
+}
+
+static void OBJECT_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh);
+ DRW_SHADER_FREE_SAFE(e_data.outline_fade_sh);
+ DRW_SHADER_FREE_SAFE(e_data.object_empty_image_sh);
+ DRW_SHADER_FREE_SAFE(e_data.object_empty_image_wire_sh);
+ DRW_SHADER_FREE_SAFE(e_data.grid_sh);
+ DRW_SHADER_FREE_SAFE(e_data.part_prim_sh);
+ DRW_SHADER_FREE_SAFE(e_data.part_axis_sh);
+ DRW_SHADER_FREE_SAFE(e_data.part_dot_sh);
+}
+
+static DRWShadingGroup *shgroup_outline(DRWPass *pass, const float col[4], GPUShader *sh)
+{
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
+ DRW_shgroup_uniform_vec4(grp, "color", col, 1);
+
+ return grp;
+}
+
+/* currently same as 'shgroup_outline', new function to avoid confustion */
+static DRWShadingGroup *shgroup_wire(DRWPass *pass, const float col[4], GPUShader *sh)
+{
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
+ DRW_shgroup_uniform_vec4(grp, "color", col, 1);
+
+ return grp;
+}
+
+static DRWShadingGroup *shgroup_theme_id_to_outline_or(
+ OBJECT_StorageList *stl, int theme_id, DRWShadingGroup *fallback)
+{
+ switch (theme_id) {
+ case TH_ACTIVE:
+ return stl->g_data->outlines_active;
+ case TH_SELECT:
+ return stl->g_data->outlines_select;
+ case TH_GROUP_ACTIVE:
+ return stl->g_data->outlines_select_group;
+ case TH_TRANSFORM:
+ return stl->g_data->outlines_transform;
+ default:
+ return fallback;
+ }
+}
+
+static DRWShadingGroup *shgroup_theme_id_to_wire_or(
+ OBJECT_StorageList *stl, int theme_id, DRWShadingGroup *fallback)
+{
+ switch (theme_id) {
+ case TH_ACTIVE:
+ return stl->g_data->wire_active;
+ case TH_SELECT:
+ return stl->g_data->wire_select;
+ case TH_GROUP_ACTIVE:
+ return stl->g_data->wire_select_group;
+ case TH_TRANSFORM:
+ return stl->g_data->wire_transform;
+ default:
+ return fallback;
+ }
+}
+
+static void image_calc_aspect(Image *ima, ImageUser *iuser, float r_image_aspect[2])
+{
+ float ima_x, ima_y;
+ if (ima) {
+ int w, h;
+ BKE_image_get_size(ima, iuser, &w, &h);
+ ima_x = w;
+ ima_y = h;
+ }
+ else {
+ /* if no image, make it a 1x1 empty square, honor scale & offset */
+ ima_x = ima_y = 1.0f;
+ }
+ /* Get the image aspect even if the buffer is invalid */
+ float sca_x = 1.0f, sca_y = 1.0f;
+ if (ima) {
+ if (ima->aspx > ima->aspy) {
+ sca_y = ima->aspy / ima->aspx;
+ }
+ else if (ima->aspx < ima->aspy) {
+ sca_x = ima->aspx / ima->aspy;
+ }
+ }
+
+ const float scale_x_inv = ima_x * sca_x;
+ const float scale_y_inv = ima_y * sca_y;
+ if (scale_x_inv > scale_y_inv) {
+ r_image_aspect[0] = 1.0f;
+ r_image_aspect[1] = scale_y_inv / scale_x_inv;
+ }
+ else {
+ r_image_aspect[0] = scale_x_inv / scale_y_inv;
+ r_image_aspect[1] = 1.0f;
+ }
+}
+
+/* per-image shading groups for image-type empty objects */
+struct EmptyImageShadingGroupData {
+ DRWShadingGroup *shgrp_image;
+ DRWShadingGroup *shgrp_wire;
+ float image_aspect[2];
+};
+
+static void DRW_shgroup_empty_image(
+ OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, const float color[3])
+{
+ /* TODO: 'StereoViews', see draw_empty_image. */
+
+ if (stl->g_data->image_plane_map == NULL) {
+ stl->g_data->image_plane_map = BLI_ghash_ptr_new(__func__);
+ }
+
+ struct EmptyImageShadingGroupData *empty_image_data;
+
+ GPUTexture *tex = ob->data ?
+ GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false, false, false) : NULL;
+ void **val_p;
+
+ /* Create on demand, 'tex' may be NULL. */
+ if (BLI_ghash_ensure_p(stl->g_data->image_plane_map, tex, &val_p)) {
+ empty_image_data = *val_p;
+ }
+ else {
+ empty_image_data = MEM_mallocN(sizeof(*empty_image_data), __func__);
+
+ image_calc_aspect(ob->data, ob->iuser, empty_image_data->image_aspect);
+
+ if (tex) {
+ struct Batch *geom = DRW_cache_image_plane_get();
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ e_data.object_empty_image_sh, psl->non_meshes, geom);
+ DRW_shgroup_attrib_float(grp, "objectColor", 4);
+ DRW_shgroup_attrib_float(grp, "size", 1);
+ DRW_shgroup_attrib_float(grp, "offset", 2);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+ DRW_shgroup_uniform_texture(grp, "image", tex);
+ DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
+
+ empty_image_data->shgrp_image = grp;
+ }
+ else {
+ empty_image_data->shgrp_image = NULL;
+ }
+
+ {
+ struct Batch *geom = DRW_cache_image_plane_wire_get();
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ e_data.object_empty_image_wire_sh, psl->non_meshes, geom);
+ DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_attrib_float(grp, "size", 1);
+ DRW_shgroup_attrib_float(grp, "offset", 2);
+ DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+ DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
+
+ empty_image_data->shgrp_wire = grp;
+ }
+
+ *val_p = empty_image_data;
+ }
+
+ if (empty_image_data->shgrp_image != NULL) {
+ DRW_shgroup_call_dynamic_add(
+ empty_image_data->shgrp_image,
+ ob->col,
+ &ob->empty_drawsize,
+ ob->ima_ofs,
+ ob->obmat);
+ }
+
+ DRW_shgroup_call_dynamic_add(
+ empty_image_data->shgrp_wire,
+ color,
+ &ob->empty_drawsize,
+ ob->ima_ofs,
+ ob->obmat);
+}
+
+static void OBJECT_cache_init(void *vedata)
+{
+ OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
+ OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
+ psl->outlines = DRW_pass_create("Outlines Pass", state);
+
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ /* Select */
+ stl->g_data->outlines_select = shgroup_outline(psl->outlines, ts.colorSelect, sh);
+ stl->g_data->outlines_select_group = shgroup_outline(psl->outlines, ts.colorGroupActive, sh);
+
+ /* Transform */
+ stl->g_data->outlines_transform = shgroup_outline(psl->outlines, ts.colorTransform, sh);
+
+ /* Active */
+ stl->g_data->outlines_active = shgroup_outline(psl->outlines, ts.colorActive, sh);
+ stl->g_data->outlines_active_group = shgroup_outline(psl->outlines, ts.colorGroupActive, sh);
+ }
+
+ {
+ DRWState state = DRW_STATE_WRITE_COLOR;
+ struct Batch *quad = DRW_cache_fullscreen_quad_get();
+ static float alphaOcclu = 0.35f;
+ static float one = 1.0f;
+ static float alpha1 = 5.0f / 6.0f;
+ static float alpha2 = 4.0f / 5.0f;
+ static float alpha3 = 3.0f / 4.0f;
+ static float alpha4 = 2.0f / 3.0f;
+ static float alpha5 = 1.0f / 2.0f;
+ static bool bTrue = true;
+ static bool bFalse = false;
+
+ psl->outlines_search = DRW_pass_create("Outlines Expand Pass", state);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_detect_sh, psl->outlines_search);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_buffer(grp, "sceneDepth", &dtxl->depth);
+ DRW_shgroup_uniform_float(grp, "alphaOcclu", &alphaOcclu, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->outlines_expand = DRW_pass_create("Outlines Expand Pass", state);
+
+ grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_expand);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_blur_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_float(grp, "alpha", &one, 1);
+ DRW_shgroup_uniform_bool(grp, "doExpand", &bTrue, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->outlines_fade1 = DRW_pass_create("Outlines Fade 1 Pass", state);
+
+ grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade1);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_float(grp, "alpha", &alpha1, 1);
+ DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->outlines_fade2 = DRW_pass_create("Outlines Fade 2 Pass", state);
+
+ grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade2);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_blur_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_float(grp, "alpha", &alpha2, 1);
+ DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->outlines_fade3 = DRW_pass_create("Outlines Fade 3 Pass", state);
+
+ grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade3);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_float(grp, "alpha", &alpha3, 1);
+ DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->outlines_fade4 = DRW_pass_create("Outlines Fade 4 Pass", state);
+
+ grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade4);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_blur_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_float(grp, "alpha", &alpha4, 1);
+ DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->outlines_fade5 = DRW_pass_create("Outlines Fade 5 Pass", state);
+
+ grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade5);
+ DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx);
+ DRW_shgroup_uniform_buffer(grp, "outlineDepth", &e_data.outlines_depth_tx);
+ DRW_shgroup_uniform_float(grp, "alpha", &alpha5, 1);
+ DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+
+ {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
+ psl->outlines_resolve = DRW_pass_create("Outlines Resolve Pass", state);
+
+ struct Batch *quad = DRW_cache_fullscreen_quad_get();
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_sh, psl->outlines_resolve);
+ DRW_shgroup_uniform_buffer(grp, "outlineBluredColor", &e_data.outlines_blur_tx);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+
+ {
+ /* Grid pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->grid = DRW_pass_create("Infinite Grid Pass", state);
+
+ struct Batch *quad = DRW_cache_fullscreen_quad_get();
+ static float mat[4][4];
+ unit_m4(mat);
+
+ /* Create 3 quads to render ordered transparency Z axis */
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
+ DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zneg_flag, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.zplane_normal, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
+ DRW_shgroup_uniform_mat4(grp, "ViewProjectionOffsetMatrix", (float *)e_data.grid_mat);
+ DRW_shgroup_uniform_vec3(grp, "cameraPos", e_data.camera_pos, 1);
+ DRW_shgroup_uniform_vec4(grp, "screenvecs[0]", e_data.screenvecs[0], 3);
+ DRW_shgroup_uniform_vec4(grp, "gridSettings", e_data.grid_settings, 1);
+ DRW_shgroup_uniform_float(grp, "gridOneOverLogSubdiv", &e_data.grid_settings[4], 1);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
+ DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
+ DRW_shgroup_call_add(grp, quad, mat);
+
+ grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
+ DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.grid_normal, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.grid_axes, 1);
+ DRW_shgroup_call_add(grp, quad, mat);
+
+ grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
+ DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.zplane_normal, 1);
+ DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
+ DRW_shgroup_call_add(grp, quad, mat);
+ }
+
+ {
+ /* Solid bones */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+ psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
+ }
+
+ {
+ /* Wire bones */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
+ }
+
+ {
+ /* distance outline around envelope bones */
+ DRWState state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->bone_envelope = DRW_pass_create("Bone Envelope Outline Pass", state);
+ }
+
+ {
+ /* Non Meshes Pass (Camera, empties, lamps ...) */
+ struct Batch *geom;
+
+ DRWState state =
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_POINT;
+ state |= DRW_STATE_WIRE;
+ psl->non_meshes = DRW_pass_create("Non Meshes Pass", state);
+
+ /* Empties */
+ geom = DRW_cache_plain_axes_get();
+ stl->g_data->plain_axes = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_cube_get();
+ stl->g_data->cube = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_circle_get();
+ stl->g_data->circle = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_empty_sphere_get();
+ stl->g_data->sphere = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_empty_cone_get();
+ stl->g_data->cone = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_single_arrow_get();
+ stl->g_data->single_arrow = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_single_line_get();
+ stl->g_data->single_arrow_line = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_arrows_get();
+ stl->g_data->arrows = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_axis_names_get();
+ stl->g_data->axis_names = shgroup_instance_axis_names(psl->non_meshes, geom);
+
+ /* initialize on first use */
+ stl->g_data->image_plane_map = NULL;
+
+ /* Force Field */
+ geom = DRW_cache_field_wind_get();
+ stl->g_data->field_wind = shgroup_instance_scaled(psl->non_meshes, geom);
+
+ geom = DRW_cache_field_force_get();
+ stl->g_data->field_force = shgroup_instance_screen_aligned(psl->non_meshes, geom);
+
+ geom = DRW_cache_field_vortex_get();
+ stl->g_data->field_vortex = shgroup_instance_scaled(psl->non_meshes, geom);
+
+ geom = DRW_cache_screenspace_circle_get();
+ stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom);
+
+ /* Speaker */
+ geom = DRW_cache_speaker_get();
+ stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom);
+
+ /* Camera */
+ geom = DRW_cache_camera_get();
+ stl->g_data->camera = shgroup_camera_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_camera_tria_get();
+ stl->g_data->camera_tria = shgroup_camera_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_plain_axes_get();
+ stl->g_data->camera_focus = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_single_line_get();
+ stl->g_data->camera_clip = shgroup_distance_lines_instance(psl->non_meshes, geom);
+ stl->g_data->camera_mist = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_single_line_endpoints_get();
+ stl->g_data->camera_clip_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
+ stl->g_data->camera_mist_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+ }
+
+ {
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ /* Unselected */
+ stl->g_data->wire = shgroup_wire(psl->non_meshes, ts.colorWire, sh);
+
+ /* Select */
+ stl->g_data->wire_select = shgroup_wire(psl->non_meshes, ts.colorSelect, sh);
+ stl->g_data->wire_select_group = shgroup_wire(psl->non_meshes, ts.colorGroupActive, sh);
+
+ /* Transform */
+ stl->g_data->wire_transform = shgroup_wire(psl->non_meshes, ts.colorTransform, sh);
+
+ /* Active */
+ stl->g_data->wire_active = shgroup_wire(psl->non_meshes, ts.colorActive, sh);
+ stl->g_data->wire_active_group = shgroup_wire(psl->non_meshes, ts.colorGroupActive, sh);
+ }
+
+ {
+ /* Lamps */
+ /* TODO
+ * for now we create multiple times the same VBO with only lamp center coordinates
+ * but ideally we would only create it once */
+ struct Batch *geom;
+
+ /* start with buflimit because we don't want stipples */
+ geom = DRW_cache_single_line_get();
+ stl->g_data->lamp_buflimit = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+ stl->g_data->lamp_center = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorLampNoAlpha, &ts.sizeLampCenter);
+ stl->g_data->lamp_center_group = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorGroup, &ts.sizeLampCenter);
+
+ geom = DRW_cache_lamp_get();
+ stl->g_data->lamp_circle = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
+ stl->g_data->lamp_circle_shadow = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircleShadow);
+
+ geom = DRW_cache_lamp_sunrays_get();
+ stl->g_data->lamp_sunrays = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
+
+ stl->g_data->lamp_groundline = shgroup_groundlines_uniform_color(psl->non_meshes, ts.colorLamp);
+ stl->g_data->lamp_groundpoint = shgroup_groundpoints_uniform_color(psl->non_meshes, ts.colorLamp);
+
+ geom = DRW_cache_lamp_area_get();
+ stl->g_data->lamp_area = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_lamp_hemi_get();
+ stl->g_data->lamp_hemi = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_single_line_get();
+ stl->g_data->lamp_distance = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_single_line_endpoints_get();
+ stl->g_data->lamp_buflimit_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_lamp_spot_get();
+ stl->g_data->lamp_spot_cone = shgroup_spot_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_circle_get();
+ stl->g_data->lamp_spot_blend = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_lamp_spot_square_get();
+ stl->g_data->lamp_spot_pyramid = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_square_get();
+ stl->g_data->lamp_spot_blend_rect = shgroup_instance(psl->non_meshes, geom);
+ }
+
+ {
+ /* -------- STIPPLES ------- */
+ /* TODO port to shader stipple */
+ struct Batch *geom;
+
+ /* Relationship Lines */
+ stl->g_data->relationship_lines = shgroup_dynlines_uniform_color(psl->non_meshes, ts.colorWire);
+ DRW_shgroup_state_enable(stl->g_data->relationship_lines, DRW_STATE_STIPPLE_3);
+
+ /* Force Field Curve Guide End (here because of stipple) */
+ geom = DRW_cache_screenspace_circle_get();
+ stl->g_data->field_curve_end = shgroup_instance_screen_aligned(psl->non_meshes, geom);
+
+ /* Force Field Limits */
+ geom = DRW_cache_field_tube_limit_get();
+ stl->g_data->field_tube_limit = shgroup_instance_scaled(psl->non_meshes, geom);
+
+ geom = DRW_cache_field_cone_limit_get();
+ stl->g_data->field_cone_limit = shgroup_instance_scaled(psl->non_meshes, geom);
+ }
+
+ {
+ /* Object Center pass grouped by State */
+ DRWShadingGroup *grp;
+ static float outlineWidth, size;
+
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
+ psl->ob_center = DRW_pass_create("Obj Center Pass", state);
+
+ outlineWidth = 1.0f * U.pixelsize;
+ size = U.obcenter_dia * U.pixelsize + outlineWidth;
+
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+
+ /* Active */
+ grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ DRW_shgroup_uniform_float(grp, "size", &size, 1);
+ DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
+ DRW_shgroup_uniform_vec4(grp, "color", ts.colorActive, 1);
+ DRW_shgroup_uniform_vec4(grp, "outlineColor", ts.colorOutline, 1);
+ stl->g_data->center_active = grp;
+
+ /* Select */
+ grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ DRW_shgroup_uniform_vec4(grp, "color", ts.colorSelect, 1);
+ stl->g_data->center_selected = grp;
+
+ /* Deselect */
+ grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ DRW_shgroup_uniform_vec4(grp, "color", ts.colorDeselect, 1);
+ stl->g_data->center_deselected = grp;
+
+ /* Select (library) */
+ grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ DRW_shgroup_uniform_vec4(grp, "color", ts.colorLibrarySelect, 1);
+ stl->g_data->center_selected_lib = grp;
+
+ /* Deselect (library) */
+ grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ DRW_shgroup_uniform_vec4(grp, "color", ts.colorLibrary, 1);
+ stl->g_data->center_deselected_lib = grp;
+ }
+
+ {
+ /* Particle Pass */
+ psl->particle = DRW_pass_create("Particle Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_POINT | DRW_STATE_BLEND);
+ }
+
+ {
+ /* Empty/Background Image Pass */
+ psl->reference_image = DRW_pass_create(
+ "Refrence Image Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+ }
+}
+
+static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
+{
+ Lamp *la = ob->data;
+ float *color;
+ int theme_id = DRW_object_wire_theme_get(ob, sl, &color);
+ static float zero = 0.0f;
+
+ float **la_mats = (float **)DRW_object_engine_data_get(ob, &draw_engine_object_type, NULL);
+ if (*la_mats == NULL) {
+ /* we need 2 matrices */
+ *la_mats = MEM_mallocN(sizeof(float) * 16 * 2, "Lamp Object Mode Matrices");
+ }
+
+ float (*shapemat)[4], (*spotblendmat)[4];
+ shapemat = (float (*)[4])(*la_mats);
+ spotblendmat = (float (*)[4])(*la_mats + 16);
+
+ /* Don't draw the center if it's selected or active */
+ if (theme_id == TH_GROUP)
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_center_group, ob->obmat[3]);
+ else if (theme_id == TH_LAMP)
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_center, ob->obmat[3]);
+
+ /* First circle */
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle, ob->obmat[3], color);
+
+ /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
+ if (la->type != LA_HEMI) {
+ if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle_shadow, ob->obmat[3], color);
+ }
+ }
+
+ /* Distance */
+ if (ELEM(la->type, LA_HEMI, LA_SUN, LA_AREA)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_distance, color, &zero, &la->dist, ob->obmat);
+ }
+
+ copy_m4_m4(shapemat, ob->obmat);
+
+ if (la->type == LA_SUN) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_sunrays, ob->obmat[3], color);
+ }
+ else if (la->type == LA_SPOT) {
+ float size[3], sizemat[4][4];
+ static float one = 1.0f;
+ float blend = 1.0f - pow2f(la->spotblend);
+
+ size[0] = size[1] = sinf(la->spotsize * 0.5f) * la->dist;
+ size[2] = cosf(la->spotsize * 0.5f) * la->dist;
+
+ size_to_mat4(sizemat, size);
+ mul_m4_m4m4(shapemat, ob->obmat, sizemat);
+
+ size[0] = size[1] = blend; size[2] = 1.0f;
+ size_to_mat4(sizemat, size);
+ translate_m4(sizemat, 0.0f, 0.0f, -1.0f);
+ rotate_m4(sizemat, 'X', M_PI / 2.0f);
+ mul_m4_m4m4(spotblendmat, shapemat, sizemat);
+
+ if (la->mode & LA_SQUARE) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_pyramid, color, &one, shapemat);
+
+ /* hide line if it is zero size or overlaps with outer border,
+ * previously it adjusted to always to show it but that seems
+ * confusing because it doesn't show the actual blend size */
+ if (blend != 0.0f && blend != 1.0f) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_blend_rect, color, &one, spotblendmat);
+ }
+ }
+ else {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_cone, color, shapemat);
+
+ /* hide line if it is zero size or overlaps with outer border,
+ * previously it adjusted to always to show it but that seems
+ * confusing because it doesn't show the actual blend size */
+ if (blend != 0.0f && blend != 1.0f) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_blend, color, &one, spotblendmat);
+ }
+ }
+
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_buflimit, color, &la->clipsta, &la->clipend, ob->obmat);
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat);
+ }
+ else if (la->type == LA_HEMI) {
+ static float hemisize = 2.0f;
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_hemi, color, &hemisize, shapemat);
+ }
+ else if (la->type == LA_AREA) {
+ float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
+
+ if (la->area_shape == LA_AREA_RECT) {
+ size[1] = la->area_sizey / la->area_size;
+ size_to_mat4(sizemat, size);
+ mul_m4_m4m4(shapemat, shapemat, sizemat);
+ }
+
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area, color, &la->area_size, shapemat);
+ }
+
+ /* Line and point going to the ground */
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_groundline, ob->obmat[3]);
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_groundpoint, ob->obmat[3]);
+}
+
+static void DRW_shgroup_camera(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ Scene *scene = draw_ctx->scene;
+
+ Camera *cam = ob->data;
+ const bool is_active = (ob == v3d->camera);
+ float *color;
+ DRW_object_wire_theme_get(ob, sl, &color);
+
+ float vec[4][3], asp[2], shift[2], scale[3], drawsize;
+
+ scale[0] = 1.0f / len_v3(ob->obmat[0]);
+ scale[1] = 1.0f / len_v3(ob->obmat[1]);
+ scale[2] = 1.0f / len_v3(ob->obmat[2]);
+
+ BKE_camera_view_frame_ex(scene, cam, cam->drawsize, false, scale,
+ asp, shift, &drawsize, vec);
+
+ // /* Frame coords */
+ copy_v2_v2(cam->drwcorners[0], vec[0]);
+ copy_v2_v2(cam->drwcorners[1], vec[1]);
+ copy_v2_v2(cam->drwcorners[2], vec[2]);
+ copy_v2_v2(cam->drwcorners[3], vec[3]);
+
+ /* depth */
+ cam->drwdepth = vec[0][2];
+
+ /* tria */
+ cam->drwtria[0][0] = shift[0] + ((0.7f * drawsize) * scale[0]);
+ cam->drwtria[0][1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
+ cam->drwtria[1][0] = shift[0];
+ cam->drwtria[1][1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
+
+ DRW_shgroup_call_dynamic_add(stl->g_data->camera, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
+
+ /* Active cam */
+ if (is_active) {
+ DRW_shgroup_call_dynamic_add(
+ stl->g_data->camera_tria, color,
+ cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
+ }
+
+ /* draw the rest in normalize object space */
+ copy_m4_m4(cam->drwnormalmat, ob->obmat);
+ normalize_m4(cam->drwnormalmat);
+
+ if (cam->flag & CAM_SHOWLIMITS) {
+ static float col[3] = {0.5f, 0.5f, 0.25f}, col_hi[3] = {1.0f, 1.0f, 0.5f};
+ float sizemat[4][4], size[3] = {1.0f, 1.0f, 0.0f};
+ float focusdist = BKE_camera_object_dof_distance(ob);
+
+ copy_m4_m4(cam->drwfocusmat, cam->drwnormalmat);
+ translate_m4(cam->drwfocusmat, 0.0f, 0.0f, -focusdist);
+ size_to_mat4(sizemat, size);
+ mul_m4_m4m4(cam->drwfocusmat, cam->drwfocusmat, sizemat);
+
+ DRW_shgroup_call_dynamic_add(
+ stl->g_data->camera_focus, (is_active ? col_hi : col),
+ &cam->drawsize, cam->drwfocusmat);
+
+ DRW_shgroup_call_dynamic_add(
+ stl->g_data->camera_clip, color,
+ &cam->clipsta, &cam->clipend, cam->drwnormalmat);
+ DRW_shgroup_call_dynamic_add(
+ stl->g_data->camera_clip_points, (is_active ? col_hi : col),
+ &cam->clipsta, &cam->clipend, cam->drwnormalmat);
+ }
+
+ if (cam->flag & CAM_SHOWMIST) {
+ World *world = scene->world;
+
+ if (world) {
+ static float col[3] = {0.5f, 0.5f, 0.5f}, col_hi[3] = {1.0f, 1.0f, 1.0f};
+ world->mistend = world->miststa + world->mistdist;
+ DRW_shgroup_call_dynamic_add(
+ stl->g_data->camera_mist, color,
+ &world->miststa, &world->mistend, cam->drwnormalmat);
+ DRW_shgroup_call_dynamic_add(
+ stl->g_data->camera_mist_points, (is_active ? col_hi : col),
+ &world->miststa, &world->mistend, cam->drwnormalmat);
+ }
+ }
+}
+
+static void DRW_shgroup_empty(OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, SceneLayer *sl)
+{
+ float *color;
+ DRW_object_wire_theme_get(ob, sl, &color);
+
+ switch (ob->empty_drawtype) {
+ case OB_PLAINAXES:
+ DRW_shgroup_call_dynamic_add(stl->g_data->plain_axes, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_SINGLE_ARROW:
+ DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow, color, &ob->empty_drawsize, ob->obmat);
+ DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow_line, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_CUBE:
+ DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_CIRCLE:
+ DRW_shgroup_call_dynamic_add(stl->g_data->circle, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_EMPTY_SPHERE:
+ DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_EMPTY_CONE:
+ DRW_shgroup_call_dynamic_add(stl->g_data->cone, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_ARROWS:
+ DRW_shgroup_call_dynamic_add(stl->g_data->arrows, color, &ob->empty_drawsize, ob->obmat);
+ DRW_shgroup_call_dynamic_add(stl->g_data->axis_names, color, &ob->empty_drawsize, ob->obmat);
+ break;
+ case OB_EMPTY_IMAGE:
+ DRW_shgroup_empty_image(stl, psl, ob, color);
+ break;
+ }
+}
+
+static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
+{
+ int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ float *color = DRW_color_background_blend_get(theme_id);
+ PartDeflect *pd = ob->pd;
+ Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL;
+
+ /* TODO Move this to depsgraph */
+ float tmp[3];
+ copy_v3_fl(pd->drawvec1, ob->empty_drawsize);
+
+ switch (pd->forcefield) {
+ case PFIELD_WIND:
+ pd->drawvec1[2] = pd->f_strength;
+ break;
+ case PFIELD_VORTEX:
+ if (pd->f_strength < 0.0f) {
+ pd->drawvec1[1] = -pd->drawvec1[1];
+ }
+ break;
+ case PFIELD_GUIDE:
+ if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
+ where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL);
+ where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL);
+ }
+ break;
+ }
+
+ if (pd->falloff == PFIELD_FALL_TUBE) {
+ pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f;
+ pd->drawvec_falloff_max[2] = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
+
+ pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
+ pd->drawvec_falloff_min[2] = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
+ }
+ else if (pd->falloff == PFIELD_FALL_CONE) {
+ float radius, distance;
+
+ radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f);
+ distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
+ pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = distance * sinf(radius);
+ pd->drawvec_falloff_max[2] = distance * cosf(radius);
+
+ radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
+ distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
+
+ pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = distance * sinf(radius);
+ pd->drawvec_falloff_min[2] = distance * cosf(radius);
+ }
+ /* End of things that should go to depthgraph */
+
+ switch (pd->forcefield) {
+ case PFIELD_WIND:
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_wind, color, &pd->drawvec1, ob->obmat);
+ break;
+ case PFIELD_FORCE:
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_force, color, &pd->drawvec1, ob->obmat);
+ break;
+ case PFIELD_VORTEX:
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat);
+ break;
+ case PFIELD_GUIDE:
+ if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat);
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat);
+ }
+ break;
+ }
+
+ if (pd->falloff == PFIELD_FALL_SPHERE) {
+ /* as last, guide curve alters it */
+ if ((pd->flag & PFIELD_USEMAX) != 0) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->maxdist, ob->obmat);
+ }
+
+ if ((pd->flag & PFIELD_USEMIN) != 0) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->mindist, ob->obmat);
+ }
+ }
+ else if (pd->falloff == PFIELD_FALL_TUBE) {
+ if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat);
+ }
+
+ if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat);
+ }
+ }
+ else if (pd->falloff == PFIELD_FALL_CONE) {
+ if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat);
+ }
+
+ if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat);
+ }
+ }
+}
+
+static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
+{
+ float *color;
+ static float one = 1.0f;
+ DRW_object_wire_theme_get(ob, sl, &color);
+
+ DRW_shgroup_call_dynamic_add(stl->g_data->speaker, color, &one, ob->obmat);
+}
+
+static void DRW_shgroup_relationship_lines(OBJECT_StorageList *stl, Object *ob)
+{
+ if (ob->parent && ((ob->parent->base_flag & BASE_VISIBLED) != 0)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->obmat[3]);
+ DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->parent->obmat[3]);
+ }
+}
+
+static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob)
+{
+ const bool is_library = ob->id.us > 1 || ID_IS_LINKED_DATABLOCK(ob);
+ DRWShadingGroup *shgroup;
+
+ if ((ob->base_flag & BASE_SELECTED) != 0) {
+ if (is_library) {
+ shgroup = stl->g_data->center_selected_lib;
+ }
+ else {
+ shgroup = stl->g_data->center_selected;
+ }
+ }
+ else {
+ if (is_library) {
+ shgroup = stl->g_data->center_deselected_lib;
+ }
+ else {
+ shgroup = stl->g_data->center_deselected;
+ }
+ }
+
+ DRW_shgroup_call_dynamic_add(shgroup, ob->obmat[3]);
+}
+
+static void OBJECT_cache_populate_particles(Object *ob,
+ OBJECT_PassList *psl)
+{
+ for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
+ if (psys_check_enabled(ob, psys, false)) {
+ ParticleSettings *part = psys->part;
+ int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+
+ if (draw_as == PART_DRAW_PATH && !psys->pathcache && !psys->childcache) {
+ draw_as = PART_DRAW_DOT;
+ }
+
+ static float mat[4][4];
+ unit_m4(mat);
+
+ if (draw_as != PART_DRAW_PATH) {
+ struct Batch *geom = DRW_cache_particles_get_dots(psys);
+ DRWShadingGroup *shgrp = NULL;
+ static int screen_space[2] = {0, 1};
+ static float def_prim_col[3] = {0.5f, 0.5f, 0.5f};
+ static float def_sec_col[3] = {1.0f, 1.0f, 1.0f};
+
+ Material *ma = give_current_material(ob, part->omat);
+
+ switch (draw_as) {
+ case PART_DRAW_DOT:
+ shgrp = DRW_shgroup_create(e_data.part_dot_sh, psl->particle);
+ DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "outlineColor", ma ? &ma->specr : def_sec_col, 1);
+ DRW_shgroup_uniform_short_to_int(shgrp, "size", &part->draw_size, 1);
+ DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
+ DRW_shgroup_call_add(shgrp, geom, mat);
+ break;
+ case PART_DRAW_CROSS:
+ shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS));
+ DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
+ DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
+ DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
+ break;
+ case PART_DRAW_CIRC:
+ shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC));
+ DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
+ DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
+ DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[1], 1);
+ break;
+ case PART_DRAW_AXIS:
+ shgrp = DRW_shgroup_instance_create(e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS));
+ DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
+ break;
+ default:
+ break;
+ }
+
+ if (shgrp) {
+ if (draw_as != PART_DRAW_DOT) {
+ DRW_shgroup_uniform_short_to_int(shgrp, "draw_size", &part->draw_size, 1);
+ DRW_shgroup_uniform_float(shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
+ DRW_shgroup_instance_batch(shgrp, geom);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void OBJECT_cache_populate(void *vedata, Object *ob)
+{
+ OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
+ OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ SceneLayer *sl = draw_ctx->sl;
+ int theme_id = TH_UNDEFINED;
+
+ //CollectionEngineSettings *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
+
+ //bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
+ bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0);
+
+ if (do_outlines) {
+ Object *obedit = scene->obedit;
+ if (ob != obedit && !((ob == draw_ctx->obact) && (ob->mode & OB_MODE_ALL_PAINT))) {
+ struct Batch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or(stl, theme_id, NULL);
+ if (shgroup != NULL) {
+ DRW_shgroup_call_add(shgroup, geom, ob->obmat);
+ }
+ }
+ }
+ }
+
+ switch (ob->type) {
+ case OB_MESH:
+ {
+ Mesh *me = ob->data;
+ if (me->totpoly == 0) {
+ Object *obedit = scene->obedit;
+ if (ob != obedit) {
+ struct Batch *geom = DRW_cache_mesh_edges_get(ob);
+ if (geom) {
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
+
+ DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
+ DRW_shgroup_call_add(shgroup, geom, ob->obmat);
+ }
+ }
+ }
+
+ OBJECT_cache_populate_particles(ob, psl);
+ break;
+ }
+ case OB_SURF:
+ break;
+ case OB_LATTICE:
+ {
+ Object *obedit = scene->obedit;
+ if (ob != obedit) {
+ struct Batch *geom = DRW_cache_lattice_wire_get(ob);
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
+
+ DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
+ DRW_shgroup_call_add(shgroup, geom, ob->obmat);
+ }
+ break;
+ }
+
+ case OB_CURVE:
+ {
+ Object *obedit = scene->obedit;
+ if (ob != obedit) {
+ struct Batch *geom = DRW_cache_curve_edge_wire_get(ob);
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
+ DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
+ DRW_shgroup_call_add(shgroup, geom, ob->obmat);
+ }
+ break;
+ }
+ case OB_LAMP:
+ DRW_shgroup_lamp(stl, ob, sl);
+ break;
+ case OB_CAMERA:
+ DRW_shgroup_camera(stl, ob, sl);
+ break;
+ case OB_EMPTY:
+ DRW_shgroup_empty(stl, psl, ob, sl);
+ break;
+ case OB_SPEAKER:
+ DRW_shgroup_speaker(stl, ob, sl);
+ break;
+ case OB_ARMATURE:
+ {
+ bArmature *arm = ob->data;
+ if (arm->edbo == NULL) {
+ if (DRW_state_is_select() || !DRW_pose_mode_armature(ob, draw_ctx->obact)) {
+ DRW_shgroup_armature_object(
+ ob, sl, psl->bone_solid, psl->bone_wire, psl->bone_envelope,
+ stl->g_data->relationship_lines);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (ob->pd && ob->pd->forcefield) {
+ DRW_shgroup_forcefield(stl, ob, sl);
+ }
+
+ /* don't show object extras in set's */
+ if ((ob->base_flag & BASE_FROM_SET) == 0) {
+ DRW_shgroup_object_center(stl, ob);
+ DRW_shgroup_relationship_lines(stl, ob);
+
+ if ((ob->dtx & OB_DRAWNAME) && DRW_state_show_text()) {
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
+
+ unsigned char color[4];
+ UI_GetThemeColor4ubv(theme_id, color);
+
+ DRW_text_cache_add(
+ dt, ob->obmat[3],
+ ob->id.name + 2, strlen(ob->id.name + 2),
+ 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
+ }
+ }
+}
+
+static void OBJECT_cache_finish(void *vedata)
+{
+ OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
+ if (stl->g_data->image_plane_map) {
+ BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN);
+ }
+}
+
+static void OBJECT_draw_scene(void *vedata)
+{
+
+ OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
+ OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ if (DRW_state_is_fbo()) {
+ /* attach temp textures */
+ DRW_framebuffer_texture_attach(fbl->outlines, e_data.outlines_depth_tx, 0, 0);
+ DRW_framebuffer_texture_attach(fbl->outlines, e_data.outlines_color_tx, 0, 0);
+ DRW_framebuffer_texture_attach(fbl->blur, e_data.outlines_blur_tx, 0, 0);
+
+ /* Render filled polygon on a separate framebuffer */
+ DRW_framebuffer_bind(fbl->outlines);
+ DRW_framebuffer_clear(true, true, false, clearcol, 1.0f);
+ DRW_draw_pass(psl->outlines);
+
+ /* detach textures */
+ DRW_framebuffer_texture_detach(e_data.outlines_depth_tx);
+
+ /* Search outline pixels */
+ DRW_framebuffer_bind(fbl->blur);
+ DRW_draw_pass(psl->outlines_search);
+
+ /* Expand and fade gradually */
+ DRW_framebuffer_bind(fbl->outlines);
+ DRW_draw_pass(psl->outlines_expand);
+
+ DRW_framebuffer_bind(fbl->blur);
+ DRW_draw_pass(psl->outlines_fade1);
+
+ DRW_framebuffer_bind(fbl->outlines);
+ DRW_draw_pass(psl->outlines_fade2);
+
+ DRW_framebuffer_bind(fbl->blur);
+ DRW_draw_pass(psl->outlines_fade3);
+
+ DRW_framebuffer_bind(fbl->outlines);
+ DRW_draw_pass(psl->outlines_fade4);
+
+ DRW_framebuffer_bind(fbl->blur);
+ DRW_draw_pass(psl->outlines_fade5);
+
+ /* detach temp textures */
+ DRW_framebuffer_texture_detach(e_data.outlines_color_tx);
+ DRW_framebuffer_texture_detach(e_data.outlines_blur_tx);
+
+ /* restore main framebuffer */
+ DRW_framebuffer_bind(dfbl->default_fb);
+ }
+
+ /* This needs to be drawn after the oultine */
+// DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */
+ DRW_draw_pass(psl->bone_wire);
+ DRW_draw_pass(psl->bone_solid);
+ DRW_draw_pass(psl->non_meshes);
+ DRW_draw_pass(psl->ob_center);
+ DRW_draw_pass(psl->particle);
+ DRW_draw_pass(psl->reference_image);
+
+ if (!DRW_state_is_select()) {
+ if (e_data.draw_grid) {
+ DRW_draw_pass(psl->grid);
+ }
+
+ /* Combine with scene buffer last */
+ DRW_draw_pass(psl->outlines_resolve);
+ }
+}
+
+void OBJECT_collection_settings_create(IDProperty *props)
+{
+ BLI_assert(props &&
+ props->type == IDP_GROUP &&
+ props->subtype == IDP_GROUP_SUB_MODE_OBJECT);
+ BKE_collection_engine_property_add_int(props, "show_wire", false);
+ BKE_collection_engine_property_add_int(props, "show_backface_culling", false);
+}
+
+static const DrawEngineDataSize OBJECT_data_size = DRW_VIEWPORT_DATA_SIZE(OBJECT_Data);
+
+DrawEngineType draw_engine_object_type = {
+ NULL, NULL,
+ N_("ObjectMode"),
+ &OBJECT_data_size,
+ &OBJECT_engine_init,
+ &OBJECT_engine_free,
+ &OBJECT_cache_init,
+ &OBJECT_cache_populate,
+ &OBJECT_cache_finish,
+ NULL,
+ &OBJECT_draw_scene
+};
diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c
new file mode 100644
index 00000000000..9521fb08d34
--- /dev/null
+++ b/source/blender/draw/modes/paint_texture_mode.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/paint_texture_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "BIF_gl.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+#include "DNA_mesh_types.h"
+
+extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_paint_texture_vert_glsl[];
+extern char datatoc_paint_texture_frag_glsl[];
+extern char datatoc_paint_wire_vert_glsl[];
+extern char datatoc_paint_wire_frag_glsl[];
+
+/* If needed, contains all global/Theme colors
+ * Add needed theme colors / values to DRW_globals_update() and update UBO
+ * Not needed for constant color. */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use PAINT_TEXTURE_engine_init() to
+ * initialize most of them and PAINT_TEXTURE_cache_init()
+ * for PAINT_TEXTURE_PassList */
+
+typedef struct PAINT_TEXTURE_PassList {
+ /* Declare all passes here and init them in
+ * PAINT_TEXTURE_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *image_faces;
+
+ struct DRWPass *wire_overlay;
+ struct DRWPass *face_overlay;
+} PAINT_TEXTURE_PassList;
+
+typedef struct PAINT_TEXTURE_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} PAINT_TEXTURE_FramebufferList;
+
+typedef struct PAINT_TEXTURE_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} PAINT_TEXTURE_TextureList;
+
+typedef struct PAINT_TEXTURE_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct PAINT_TEXTURE_PrivateData *g_data;
+} PAINT_TEXTURE_StorageList;
+
+typedef struct PAINT_TEXTURE_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ PAINT_TEXTURE_FramebufferList *fbl;
+ PAINT_TEXTURE_TextureList *txl;
+ PAINT_TEXTURE_PassList *psl;
+ PAINT_TEXTURE_StorageList *stl;
+} PAINT_TEXTURE_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in PAINT_TEXTURE_engine_init();
+ * free in PAINT_TEXTURE_engine_free(); */
+ struct GPUShader *fallback_sh;
+ struct GPUShader *image_sh;
+
+ struct GPUShader *wire_overlay_shader;
+ struct GPUShader *face_overlay_shader;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct PAINT_TEXTURE_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in PAINT_TEXTURE_cache_populate() */
+ DRWShadingGroup *shgroup_fallback;
+ DRWShadingGroup **shgroup_image_array;
+
+ /* face-mask */
+ DRWShadingGroup *lwire_shgrp;
+ DRWShadingGroup *face_shgrp;
+} PAINT_TEXTURE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void PAINT_TEXTURE_engine_init(void *vedata)
+{
+ PAINT_TEXTURE_TextureList *txl = ((PAINT_TEXTURE_Data *)vedata)->txl;
+ PAINT_TEXTURE_FramebufferList *fbl = ((PAINT_TEXTURE_Data *)vedata)->fbl;
+ PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.fallback_sh) {
+ e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ if (!e_data.image_sh) {
+ e_data.image_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ e_data.image_sh = DRW_shader_create_with_lib(
+ datatoc_paint_texture_vert_glsl, NULL,
+ datatoc_paint_texture_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+
+ }
+
+ if (!e_data.wire_overlay_shader) {
+ e_data.wire_overlay_shader = DRW_shader_create_with_lib(
+ datatoc_paint_wire_vert_glsl, NULL,
+ datatoc_paint_wire_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define VERTEX_MODE\n");
+ }
+
+ if (!e_data.face_overlay_shader) {
+ e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+}
+#include "BKE_global.h"
+#include "BKE_main.h"
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void PAINT_TEXTURE_cache_init(void *vedata)
+{
+ PAINT_TEXTURE_PassList *psl = ((PAINT_TEXTURE_Data *)vedata)->psl;
+ PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ stl->g_data->shgroup_image_array = NULL;
+ }
+
+ {
+ /* Create a pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS |
+ DRW_STATE_BLEND | DRW_STATE_WIRE;
+ psl->image_faces = DRW_pass_create("Image Color Pass", state);
+
+ /* Create a shadingGroup using a function in draw_common.c or custom one */
+ /*
+ * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
+ * -- or --
+ * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+ */
+ stl->g_data->shgroup_fallback = DRW_shgroup_create(e_data.fallback_sh, psl->image_faces);
+
+ /* Uniforms need a pointer to it's value so be sure it's accessible at
+ * any given time (i.e. use static vars) */
+ static float color[4] = {1.0f, 0.0f, 1.0f, 1.0};
+ DRW_shgroup_uniform_vec4(stl->g_data->shgroup_fallback, "color", color, 1);
+
+ MEM_SAFE_FREE(stl->g_data->shgroup_image_array);
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Object *ob = draw_ctx->obact;
+ if (ob && ob->type == OB_MESH) {
+ Scene *scene = draw_ctx->scene;
+ bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL);
+ const Mesh *me = ob->data;
+
+ stl->g_data->shgroup_image_array = MEM_mallocN(
+ sizeof(*stl->g_data->shgroup_image_array) * (use_material_slots ? me->totcol : 1), __func__);
+
+ if (use_material_slots) {
+ for (int i = 0; i < me->totcol; i++) {
+ Material *ma = give_current_material(ob, i + 1);
+ Image *ima = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
+ GPUTexture *tex = ima ?
+ GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false, false, false) : NULL;
+
+ if (tex) {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces);
+ DRW_shgroup_uniform_texture(grp, "image", tex);
+ stl->g_data->shgroup_image_array[i] = grp;
+ }
+ else {
+ stl->g_data->shgroup_image_array[i] = NULL;
+ }
+ }
+ }
+ else {
+ Image *ima = scene->toolsettings->imapaint.canvas;
+ GPUTexture *tex = ima ?
+ GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false, false, false) : NULL;
+
+ if (tex) {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces);
+ DRW_shgroup_uniform_texture(grp, "image", tex);
+ stl->g_data->shgroup_image_array[0] = grp;
+ }
+ else {
+ stl->g_data->shgroup_image_array[0] = NULL;
+ }
+ }
+ }
+ }
+
+ /* Face Mask */
+ {
+ psl->wire_overlay = DRW_pass_create(
+ "Wire Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
+ }
+
+ {
+ psl->face_overlay = DRW_pass_create(
+ "Face Mask Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+
+ stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
+
+ static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
+ DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
+ }
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
+{
+ PAINT_TEXTURE_PassList *psl = ((PAINT_TEXTURE_Data *)vedata)->psl;
+ PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ UNUSED_VARS(psl, stl);
+
+ if ((ob->type == OB_MESH) && (draw_ctx->obact == ob)) {
+ /* Get geometry cache */
+ const Mesh *me = ob->data;
+ Scene *scene = draw_ctx->scene;
+ bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL);
+ bool ok = false;
+
+ if (me->mloopuv != NULL) {
+ if (use_material_slots) {
+ struct Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL;
+ if ((me->totcol == 0) || (geom_array == NULL)) {
+ struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+ DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat);
+ ok = true;
+ }
+ else {
+ for (int i = 0; i < me->totcol; i++) {
+ if (stl->g_data->shgroup_image_array[i]) {
+ DRW_shgroup_call_add(stl->g_data->shgroup_image_array[i], geom_array[i], ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom_array[i], ob->obmat);
+ }
+ ok = true;
+ }
+ }
+ }
+ else {
+ struct Batch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob);
+ if (geom && stl->g_data->shgroup_image_array[0]) {
+ DRW_shgroup_call_add(stl->g_data->shgroup_image_array[0], geom, ob->obmat);
+ ok = true;
+ }
+ }
+ }
+
+ if (!ok) {
+ struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+ DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat);
+ }
+
+ /* Face Mask */
+ const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
+ if (use_face_sel) {
+ struct Batch *geom;
+ /* Note: ideally selected faces wouldn't show interior wire. */
+ const bool use_wire = true;
+ geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel);
+ DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
+
+ geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
+ }
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void PAINT_TEXTURE_cache_finish(void *vedata)
+{
+ PAINT_TEXTURE_PassList *psl = ((PAINT_TEXTURE_Data *)vedata)->psl;
+ PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl);
+
+ MEM_SAFE_FREE(stl->g_data->shgroup_image_array);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void PAINT_TEXTURE_draw_scene(void *vedata)
+{
+ PAINT_TEXTURE_PassList *psl = ((PAINT_TEXTURE_Data *)vedata)->psl;
+ PAINT_TEXTURE_FramebufferList *fbl = ((PAINT_TEXTURE_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ DRW_draw_pass(psl->image_faces);
+
+ DRW_draw_pass(psl->face_overlay);
+ DRW_draw_pass(psl->wire_overlay);
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void PAINT_TEXTURE_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.image_sh);
+ DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void PAINT_TEXTURE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize PAINT_TEXTURE_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_TEXTURE_Data);
+
+DrawEngineType draw_engine_paint_texture_type = {
+ NULL, NULL,
+ N_("PaintTextureMode"),
+ &PAINT_TEXTURE_data_size,
+ &PAINT_TEXTURE_engine_init,
+ &PAINT_TEXTURE_engine_free,
+ &PAINT_TEXTURE_cache_init,
+ &PAINT_TEXTURE_cache_populate,
+ &PAINT_TEXTURE_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &PAINT_TEXTURE_draw_scene
+};
diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c
new file mode 100644
index 00000000000..f65db8686c0
--- /dev/null
+++ b/source/blender/draw/modes/paint_vertex_mode.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/paint_vertex_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+#include "DNA_mesh_types.h"
+
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+extern char datatoc_paint_wire_vert_glsl[];
+extern char datatoc_paint_wire_frag_glsl[];
+extern char datatoc_common_globals_lib_glsl[];
+
+/* *********** LISTS *********** */
+
+typedef struct PAINT_VERTEX_PassList {
+ struct DRWPass *vcolor_faces;
+ struct DRWPass *wire_overlay;
+ struct DRWPass *face_overlay;
+} PAINT_VERTEX_PassList;
+
+typedef struct PAINT_VERTEX_StorageList {
+ struct PAINT_VERTEX_PrivateData *g_data;
+} PAINT_VERTEX_StorageList;
+
+typedef struct PAINT_VERTEX_Data {
+ void *engine_type; /* Required */
+ DRWViewportEmptyList *fbl;
+ DRWViewportEmptyList *txl;
+ PAINT_VERTEX_PassList *psl;
+ PAINT_VERTEX_StorageList *stl;
+} PAINT_VERTEX_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ struct GPUShader *vcolor_face_shader;
+ struct GPUShader *wire_overlay_shader;
+ struct GPUShader *face_overlay_shader;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct PAINT_VERTEX_PrivateData {
+ DRWShadingGroup *fvcolor_shgrp;
+ DRWShadingGroup *lwire_shgrp;
+ DRWShadingGroup *face_shgrp;
+} PAINT_VERTEX_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
+{
+ if (!e_data.vcolor_face_shader) {
+ e_data.vcolor_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
+ }
+
+ if (!e_data.wire_overlay_shader) {
+ e_data.wire_overlay_shader = DRW_shader_create_with_lib(
+ datatoc_paint_wire_vert_glsl, NULL,
+ datatoc_paint_wire_frag_glsl,
+ datatoc_common_globals_lib_glsl, "#define VERTEX_MODE\n");
+ }
+
+ if (!e_data.face_overlay_shader) {
+ e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+}
+
+static float world_light;
+
+static void PAINT_VERTEX_cache_init(void *vedata)
+{
+ PAINT_VERTEX_PassList *psl = ((PAINT_VERTEX_Data *)vedata)->psl;
+ PAINT_VERTEX_StorageList *stl = ((PAINT_VERTEX_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create a pass */
+ psl->vcolor_faces = DRW_pass_create("Vert Color Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->fvcolor_shgrp = DRW_shgroup_create(e_data.vcolor_face_shader, psl->vcolor_faces);
+
+ static float light[3] = {-0.3f, 0.5f, 1.0f};
+ static float alpha = 1.0f;
+ DRW_shgroup_uniform_vec3(stl->g_data->fvcolor_shgrp, "light", light, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "alpha", &alpha, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "global", &world_light, 1);
+ }
+
+ {
+ psl->wire_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
+ }
+
+ {
+ psl->face_overlay = DRW_pass_create("Face Mask Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+
+ stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
+
+ static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
+ DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
+ }
+}
+
+static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob)
+{
+ PAINT_VERTEX_StorageList *stl = ((PAINT_VERTEX_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if ((ob->type == OB_MESH) && (ob == draw_ctx->obact)) {
+ IDProperty *ces_mode_pw = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_PAINT_VERTEX, "");
+ bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire");
+ const Mesh *me = ob->data;
+ const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
+ struct Batch *geom;
+
+ world_light = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_shading") ? 0.5f : 1.0f;
+
+ geom = DRW_cache_mesh_surface_vert_colors_get(ob);
+ DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat);
+
+ if (use_face_sel || use_wire) {
+ geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel);
+ DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
+ }
+
+ if (use_face_sel) {
+ geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
+ }
+ }
+}
+
+static void PAINT_VERTEX_draw_scene(void *vedata)
+{
+ PAINT_VERTEX_PassList *psl = ((PAINT_VERTEX_Data *)vedata)->psl;
+
+ DRW_draw_pass(psl->vcolor_faces);
+ DRW_draw_pass(psl->face_overlay);
+ DRW_draw_pass(psl->wire_overlay);
+}
+
+static void PAINT_VERTEX_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
+}
+
+void PAINT_VERTEX_collection_settings_create(IDProperty *properties)
+{
+ BLI_assert(properties &&
+ properties->type == IDP_GROUP &&
+ properties->subtype == IDP_GROUP_SUB_MODE_PAINT_VERTEX);
+
+ BKE_collection_engine_property_add_bool(properties, "use_shading", true);
+ BKE_collection_engine_property_add_bool(properties, "use_wire", false);
+}
+
+static const DrawEngineDataSize PAINT_VERTEX_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_VERTEX_Data);
+
+DrawEngineType draw_engine_paint_vertex_type = {
+ NULL, NULL,
+ N_("PaintVertexMode"),
+ &PAINT_VERTEX_data_size,
+ &PAINT_VERTEX_engine_init,
+ &PAINT_VERTEX_engine_free,
+ &PAINT_VERTEX_cache_init,
+ &PAINT_VERTEX_cache_populate,
+ NULL,
+ NULL,
+ &PAINT_VERTEX_draw_scene
+};
diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c
new file mode 100644
index 00000000000..d880d1d9f23
--- /dev/null
+++ b/source/blender/draw/modes/paint_weight_mode.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/paint_weight_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+#include "DNA_mesh_types.h"
+
+#include "BKE_mesh.h"
+
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
+
+extern char datatoc_paint_wire_vert_glsl[];
+extern char datatoc_paint_wire_frag_glsl[];
+extern char datatoc_paint_vert_frag_glsl[];
+extern char datatoc_common_globals_lib_glsl[];
+
+/* *********** LISTS *********** */
+
+typedef struct PAINT_WEIGHT_PassList {
+ struct DRWPass *weight_faces;
+ struct DRWPass *wire_overlay;
+ struct DRWPass *face_overlay;
+ struct DRWPass *vert_overlay;
+} PAINT_WEIGHT_PassList;
+
+typedef struct PAINT_WEIGHT_StorageList {
+ struct PAINT_WEIGHT_PrivateData *g_data;
+} PAINT_WEIGHT_StorageList;
+
+typedef struct PAINT_WEIGHT_Data {
+ void *engine_type;
+ DRWViewportEmptyList *fbl;
+ DRWViewportEmptyList *txl;
+ PAINT_WEIGHT_PassList *psl;
+ PAINT_WEIGHT_StorageList *stl;
+} PAINT_WEIGHT_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ struct GPUShader *weight_face_shader;
+ struct GPUShader *wire_overlay_shader;
+ struct GPUShader *face_overlay_shader;
+ struct GPUShader *vert_overlay_shader;
+ int actdef;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct PAINT_WEIGHT_PrivateData {
+ DRWShadingGroup *fweights_shgrp;
+ DRWShadingGroup *lwire_shgrp;
+ DRWShadingGroup *face_shgrp;
+ DRWShadingGroup *vert_shgrp;
+} PAINT_WEIGHT_PrivateData;
+
+/* *********** FUNCTIONS *********** */
+
+static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (e_data.actdef != draw_ctx->obact->actdef) {
+ e_data.actdef = draw_ctx->obact->actdef;
+
+ BKE_mesh_batch_cache_dirty(draw_ctx->obact->data, BKE_MESH_BATCH_DIRTY_PAINT);
+ }
+
+ if (!e_data.weight_face_shader) {
+ e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
+ }
+
+ if (!e_data.wire_overlay_shader) {
+ e_data.wire_overlay_shader = DRW_shader_create_with_lib(
+ datatoc_paint_wire_vert_glsl, NULL,
+ datatoc_paint_wire_frag_glsl,
+ datatoc_common_globals_lib_glsl, "#define WEIGHT_MODE\n");
+ }
+
+ if (!e_data.face_overlay_shader) {
+ e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ if (!e_data.vert_overlay_shader) {
+ e_data.vert_overlay_shader = DRW_shader_create_with_lib(
+ datatoc_paint_wire_vert_glsl, NULL,
+ datatoc_paint_vert_frag_glsl,
+ datatoc_common_globals_lib_glsl, NULL);
+ }
+}
+
+static float world_light;
+
+static void PAINT_WEIGHT_cache_init(void *vedata)
+{
+ PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
+ PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create a pass */
+ psl->weight_faces = DRW_pass_create(
+ "Weight Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
+
+ static float light[3] = {-0.3f, 0.5f, 1.0f};
+ static float alpha = 1.0f;
+ DRW_shgroup_uniform_vec3(stl->g_data->fweights_shgrp, "light", light, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "alpha", &alpha, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "global", &world_light, 1);
+ }
+
+ {
+ psl->wire_overlay = DRW_pass_create(
+ "Wire Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
+ }
+
+ {
+ psl->face_overlay = DRW_pass_create(
+ "Face Mask Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+
+ stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
+
+ static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
+ DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
+ }
+
+ {
+ psl->vert_overlay = DRW_pass_create(
+ "Vert Mask Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
+ }
+}
+
+static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
+{
+ PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if ((ob->type == OB_MESH) && (ob == draw_ctx->obact)) {
+ IDProperty *ces_mode_pw = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_PAINT_WEIGHT, "");
+ bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire");
+ const Mesh *me = ob->data;
+ const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
+ const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
+ struct Batch *geom;
+
+ world_light = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_shading") ? 0.5f : 1.0f;
+
+ geom = DRW_cache_mesh_surface_weights_get(ob);
+ DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
+
+ if (use_face_sel || use_wire) {
+ geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel);
+ DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
+ }
+
+ if (use_face_sel) {
+ geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
+ }
+
+ if (use_vert_sel) {
+ geom = DRW_cache_mesh_verts_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->vert_shgrp, geom, ob->obmat);
+ }
+ }
+}
+
+static void PAINT_WEIGHT_draw_scene(void *vedata)
+{
+ PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
+
+ DRW_draw_pass(psl->weight_faces);
+ DRW_draw_pass(psl->face_overlay);
+ DRW_draw_pass(psl->wire_overlay);
+ DRW_draw_pass(psl->vert_overlay);
+}
+
+static void PAINT_WEIGHT_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
+ DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader);
+}
+
+void PAINT_WEIGHT_collection_settings_create(IDProperty *properties)
+{
+ BLI_assert(properties &&
+ properties->type == IDP_GROUP &&
+ properties->subtype == IDP_GROUP_SUB_MODE_PAINT_WEIGHT);
+
+ BKE_collection_engine_property_add_bool(properties, "use_shading", true);
+ BKE_collection_engine_property_add_bool(properties, "use_wire", false);
+}
+
+static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data);
+
+DrawEngineType draw_engine_paint_weight_type = {
+ NULL, NULL,
+ N_("PaintWeightMode"),
+ &PAINT_WEIGHT_data_size,
+ &PAINT_WEIGHT_engine_init,
+ &PAINT_WEIGHT_engine_free,
+ &PAINT_WEIGHT_cache_init,
+ &PAINT_WEIGHT_cache_populate,
+ NULL,
+ NULL,
+ &PAINT_WEIGHT_draw_scene
+};
diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c
new file mode 100644
index 00000000000..4b63a00d0a5
--- /dev/null
+++ b/source/blender/draw/modes/particle_mode.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/particle_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use PARTICLE_engine_init() to
+ * initialize most of them and PARTICLE_cache_init()
+ * for PARTICLE_PassList */
+
+typedef struct PARTICLE_PassList {
+ /* Declare all passes here and init them in
+ * PARTICLE_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *pass;
+} PARTICLE_PassList;
+
+typedef struct PARTICLE_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} PARTICLE_FramebufferList;
+
+typedef struct PARTICLE_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} PARTICLE_TextureList;
+
+typedef struct PARTICLE_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct PARTICLE_PrivateData *g_data;
+} PARTICLE_StorageList;
+
+typedef struct PARTICLE_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ PARTICLE_FramebufferList *fbl;
+ PARTICLE_TextureList *txl;
+ PARTICLE_PassList *psl;
+ PARTICLE_StorageList *stl;
+} PARTICLE_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in PARTICLE_engine_init();
+ * free in PARTICLE_engine_free(); */
+ struct GPUShader *custom_shader;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct PARTICLE_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in PARTICLE_cache_populate() */
+ DRWShadingGroup *group;
+} PARTICLE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void PARTICLE_engine_init(void *vedata)
+{
+ PARTICLE_TextureList *txl = ((PARTICLE_Data *)vedata)->txl;
+ PARTICLE_FramebufferList *fbl = ((PARTICLE_Data *)vedata)->fbl;
+ PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.custom_shader) {
+ e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void PARTICLE_cache_init(void *vedata)
+{
+ PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl;
+ PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create a pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ psl->pass = DRW_pass_create("My Pass", state);
+
+ /* Create a shadingGroup using a function in draw_common.c or custom one */
+ /*
+ * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
+ * -- or --
+ * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+ */
+ stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+
+ /* Uniforms need a pointer to it's value so be sure it's accessible at
+ * any given time (i.e. use static vars) */
+ static float color[4] = {0.2f, 0.5f, 0.3f, 1.0};
+ DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
+ }
+
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void PARTICLE_cache_populate(void *vedata, Object *ob)
+{
+ PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl;
+ PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl;
+
+ UNUSED_VARS(psl, stl);
+
+ if (ob->type == OB_MESH) {
+ /* Get geometry cache */
+ struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+
+ /* Add geom to a shading group */
+ DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void PARTICLE_cache_finish(void *vedata)
+{
+ PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl;
+ PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void PARTICLE_draw_scene(void *vedata)
+{
+
+ PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl;
+ PARTICLE_FramebufferList *fbl = ((PARTICLE_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ /* ... or just render passes on default framebuffer. */
+ DRW_draw_pass(psl->pass);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void PARTICLE_engine_free(void)
+{
+ // DRW_SHADER_FREE_SAFE(custom_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void PARTICLE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize PARTICLE_data_size = DRW_VIEWPORT_DATA_SIZE(PARTICLE_Data);
+
+DrawEngineType draw_engine_particle_type = {
+ NULL, NULL,
+ N_("ParticleMode"),
+ &PARTICLE_data_size,
+ &PARTICLE_engine_init,
+ &PARTICLE_engine_free,
+ &PARTICLE_cache_init,
+ &PARTICLE_cache_populate,
+ &PARTICLE_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &PARTICLE_draw_scene
+};
diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c
new file mode 100644
index 00000000000..d3233d713a1
--- /dev/null
+++ b/source/blender/draw/modes/pose_mode.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/pose_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+extern GlobalsUboStorage ts;
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use POSE_engine_init() to
+ * initialize most of them and POSE_cache_init()
+ * for POSE_PassList */
+
+typedef struct POSE_PassList {
+ struct DRWPass *bone_solid;
+ struct DRWPass *bone_wire;
+ struct DRWPass *bone_envelope;
+ struct DRWPass *relationship;
+} POSE_PassList;
+
+typedef struct POSE_StorageList {
+ struct POSE_PrivateData *g_data;
+} POSE_StorageList;
+
+typedef struct POSE_Data {
+ void *engine_type;
+ DRWViewportEmptyList *fbl;
+ DRWViewportEmptyList *txl;
+ POSE_PassList *psl;
+ POSE_StorageList *stl;
+} POSE_Data;
+
+/* *********** STATIC *********** */
+
+typedef struct POSE_PrivateData {
+ DRWShadingGroup *relationship_lines;
+} POSE_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void POSE_cache_init(void *vedata)
+{
+ POSE_PassList *psl = ((POSE_Data *)vedata)->psl;
+ POSE_StorageList *stl = ((POSE_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Solid bones */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+ psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
+ }
+
+ {
+ /* Wire bones */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
+ }
+
+ {
+ /* distance outline around envelope bones */
+ DRWState state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+ psl->bone_envelope = DRW_pass_create("Bone Envelope Outline Pass", state);
+ }
+
+ {
+ /* Non Meshes Pass (Camera, empties, lamps ...) */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ psl->relationship = DRW_pass_create("Bone Relationship Pass", state);
+
+ /* Relationship Lines */
+ stl->g_data->relationship_lines = shgroup_dynlines_uniform_color(psl->relationship, ts.colorWire);
+ DRW_shgroup_state_enable(stl->g_data->relationship_lines, DRW_STATE_STIPPLE_3);
+ }
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void POSE_cache_populate(void *vedata, Object *ob)
+{
+ POSE_PassList *psl = ((POSE_Data *)vedata)->psl;
+ POSE_StorageList *stl = ((POSE_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ /* In the future this will allow us to implement face manipulators,
+ * and similar functionalities. For now we handle only pose bones. */
+
+ if (ob->type == OB_ARMATURE) {
+ if (DRW_pose_mode_armature(ob, draw_ctx->obact)) {
+ DRW_shgroup_armature_pose(
+ ob, psl->bone_solid, psl->bone_wire, psl->bone_envelope,
+ stl->g_data->relationship_lines);
+ }
+ }
+}
+
+/**
+ * Return true if armature should be handled by the pose mode engine.
+ */
+bool DRW_pose_mode_armature(Object *ob, Object *active_ob)
+{
+ /* Pode armature is handled by pose mode engine. */
+ if ((ob == active_ob) && ((ob->mode & OB_MODE_POSE) != 0)) {
+ return true;
+ }
+
+ /* Armature parent is also handled by pose mode engine. */
+ if ((active_ob != NULL) && ((active_ob->mode & OB_MODE_WEIGHT_PAINT) != 0)) {
+ if (active_ob->parent == ob) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void POSE_draw_scene(void *vedata)
+{
+ POSE_PassList *psl = ((POSE_Data *)vedata)->psl;
+
+ DRW_draw_pass(psl->bone_envelope);
+ DRW_draw_pass(psl->bone_wire);
+ DRW_draw_pass(psl->bone_solid);
+ DRW_draw_pass(psl->relationship);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void POSE_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "foo", 37);
+}
+#endif
+
+static const DrawEngineDataSize POSE_data_size = DRW_VIEWPORT_DATA_SIZE(POSE_Data);
+
+DrawEngineType draw_engine_pose_type = {
+ NULL, NULL,
+ N_("PoseMode"),
+ &POSE_data_size,
+ NULL,
+ NULL,
+ &POSE_cache_init,
+ &POSE_cache_populate,
+ NULL,
+ NULL,
+ &POSE_draw_scene
+};
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
new file mode 100644
index 00000000000..a3f29b5bb8f
--- /dev/null
+++ b/source/blender/draw/modes/sculpt_mode.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/modes/sculpt_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_pbvh.h"
+#include "BKE_paint.h"
+
+/* If builtin shaders are needed */
+#include "GPU_shader.h"
+#include "GPU_matrix.h"
+
+#include "draw_common.h"
+
+#include "draw_mode_engines.h"
+
+/* *********** LISTS *********** */
+/* All lists are per viewport specific datas.
+ * They are all free when viewport changes engines
+ * or is free itself. Use SCULPT_engine_init() to
+ * initialize most of them and SCULPT_cache_init()
+ * for SCULPT_PassList */
+
+typedef struct SCULPT_PassList {
+ /* Declare all passes here and init them in
+ * SCULPT_cache_init().
+ * Only contains (DRWPass *) */
+ struct DRWPass *pass;
+} SCULPT_PassList;
+
+typedef struct SCULPT_FramebufferList {
+ /* Contains all framebuffer objects needed by this engine.
+ * Only contains (GPUFrameBuffer *) */
+ struct GPUFrameBuffer *fb;
+} SCULPT_FramebufferList;
+
+typedef struct SCULPT_TextureList {
+ /* Contains all framebuffer textures / utility textures
+ * needed by this engine. Only viewport specific textures
+ * (not per object). Only contains (GPUTexture *) */
+ struct GPUTexture *texture;
+} SCULPT_TextureList;
+
+typedef struct SCULPT_StorageList {
+ /* Contains any other memory block that the engine needs.
+ * Only directly MEM_(m/c)allocN'ed blocks because they are
+ * free with MEM_freeN() when viewport is freed.
+ * (not per object) */
+ struct CustomStruct *block;
+ struct SCULPT_PrivateData *g_data;
+} SCULPT_StorageList;
+
+typedef struct SCULPT_Data {
+ /* Struct returned by DRW_viewport_engine_data_get.
+ * If you don't use one of these, just make it a (void *) */
+ // void *fbl;
+ void *engine_type; /* Required */
+ SCULPT_FramebufferList *fbl;
+ SCULPT_TextureList *txl;
+ SCULPT_PassList *psl;
+ SCULPT_StorageList *stl;
+} SCULPT_Data;
+
+/* *********** STATIC *********** */
+
+static struct {
+ /* Custom shaders :
+ * Add sources to source/blender/draw/modes/shaders
+ * init in SCULPT_engine_init();
+ * free in SCULPT_engine_free(); */
+ struct GPUShader *shader_flat;
+ struct GPUShader *shader_smooth;
+} e_data = {NULL}; /* Engine data */
+
+typedef struct SCULPT_PrivateData {
+ /* This keeps the references of the shading groups for
+ * easy access in SCULPT_cache_populate() */
+ DRWShadingGroup *group_flat;
+ DRWShadingGroup *group_smooth;
+} SCULPT_PrivateData; /* Transient data */
+
+/* *********** FUNCTIONS *********** */
+
+/* Init Textures, Framebuffers, Storage and Shaders.
+ * It is called for every frames.
+ * (Optional) */
+static void SCULPT_engine_init(void *vedata)
+{
+ SCULPT_TextureList *txl = ((SCULPT_Data *)vedata)->txl;
+ SCULPT_FramebufferList *fbl = ((SCULPT_Data *)vedata)->fbl;
+ SCULPT_StorageList *stl = ((SCULPT_Data *)vedata)->stl;
+
+ UNUSED_VARS(txl, fbl, stl);
+
+ /* Init Framebuffers like this: order is attachment order (for color texs) */
+ /*
+ * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
+ * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
+ */
+
+ /* DRW_framebuffer_init takes care of checking if
+ * the framebuffer is valid and has the right size*/
+ /*
+ * float *viewport_size = DRW_viewport_size_get();
+ * DRW_framebuffer_init(&fbl->occlude_wire_fb,
+ * (int)viewport_size[0], (int)viewport_size[1],
+ * tex, 2);
+ */
+
+ if (!e_data.shader_flat) {
+ e_data.shader_flat = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
+ }
+ if (!e_data.shader_smooth) {
+ e_data.shader_smooth = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+}
+
+/* Here init all passes and shading groups
+ * Assume that all Passes are NULL */
+static void SCULPT_cache_init(void *vedata)
+{
+ SCULPT_PassList *psl = ((SCULPT_Data *)vedata)->psl;
+ SCULPT_StorageList *stl = ((SCULPT_Data *)vedata)->stl;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create a pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY;
+ psl->pass = DRW_pass_create("Sculpt Pass", state);
+
+ /* Create a shadingGroup using a function in draw_common.c or custom one */
+ /*
+ * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
+ * -- or --
+ * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
+ */
+ stl->g_data->group_flat = DRW_shgroup_create(e_data.shader_flat, psl->pass);
+ stl->g_data->group_smooth = DRW_shgroup_create(e_data.shader_smooth, psl->pass);
+ }
+}
+
+static bool object_is_flat(const Object *ob)
+{
+ Mesh *me = ob->data;
+ if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+/* Add geometry to shadingGroups. Execute for each objects */
+static void SCULPT_cache_populate(void *vedata, Object *ob)
+{
+ SCULPT_PassList *psl = ((SCULPT_Data *)vedata)->psl;
+ SCULPT_StorageList *stl = ((SCULPT_Data *)vedata)->stl;
+
+ UNUSED_VARS(psl, stl);
+
+ if (ob->type == OB_MESH) {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (ob->sculpt && (ob == draw_ctx->obact)) {
+
+ /* XXX, needed for dyntopo-undo (which clears).
+ * probably depsgraph should handlle? in 2.7x getting derived-mesh does this (mesh_build_data) */
+ if (ob->sculpt->pbvh == NULL) {
+ /* create PBVH immediately (would be created on the fly too,
+ * but this avoids waiting on first stroke) */
+ Scene *scene = draw_ctx->scene;
+
+ BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false);
+ }
+
+ PBVH *pbvh = ob->sculpt->pbvh;
+ if (pbvh && pbvh_has_mask(pbvh)) {
+ /* Get geometry cache */
+ DRWShadingGroup *shgroup = object_is_flat(ob) ? stl->g_data->group_flat : stl->g_data->group_smooth;
+
+ /* Add geom to a shading group */
+ DRW_shgroup_call_sculpt_add(shgroup, ob, ob->obmat);
+ }
+ }
+ }
+}
+
+/* Optional: Post-cache_populate callback */
+static void SCULPT_cache_finish(void *vedata)
+{
+ SCULPT_PassList *psl = ((SCULPT_Data *)vedata)->psl;
+ SCULPT_StorageList *stl = ((SCULPT_Data *)vedata)->stl;
+
+ /* Do something here! dependant on the objects gathered */
+ UNUSED_VARS(psl, stl);
+}
+
+/* Draw time ! Control rendering pipeline from here */
+static void SCULPT_draw_scene(void *vedata)
+{
+ SCULPT_PassList *psl = ((SCULPT_Data *)vedata)->psl;
+ SCULPT_FramebufferList *fbl = ((SCULPT_Data *)vedata)->fbl;
+
+ /* Default framebuffer and texture */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ UNUSED_VARS(fbl, dfbl, dtxl);
+
+ /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
+ /*
+ * DRW_framebuffer_texture_detach(dtxl->depth);
+ * DRW_framebuffer_bind(fbl->custom_fb);
+ * DRW_draw_pass(psl->pass);
+ * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
+ * DRW_framebuffer_bind(dfbl->default_fb);
+ */
+
+ /* ... or just render passes on default framebuffer. */
+ DRW_draw_pass(psl->pass);
+
+ /* If you changed framebuffer, double check you rebind
+ * the default one with its textures attached before finishing */
+}
+
+/* Cleanup when destroying the engine.
+ * This is not per viewport ! only when quitting blender.
+ * Mostly used for freeing shaders */
+static void SCULPT_engine_free(void)
+{
+ // DRW_SHADER_FREE_SAFE(custom_shader);
+}
+
+/* Create collection settings here.
+ *
+ * Be sure to add this function there :
+ * source/blender/draw/DRW_engine.h
+ * source/blender/blenkernel/intern/layer.c
+ * source/blenderplayer/bad_level_call_stubs/stubs.c
+ *
+ * And relevant collection settings to :
+ * source/blender/makesrna/intern/rna_scene.c
+ * source/blender/blenkernel/intern/layer.c
+ */
+#if 0
+void SCULPT_collection_settings_create(CollectionEngineSettings *ces)
+{
+ BLI_assert(ces);
+ // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
+ // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
+ // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+}
+#endif
+
+static const DrawEngineDataSize SCULPT_data_size = DRW_VIEWPORT_DATA_SIZE(SCULPT_Data);
+
+DrawEngineType draw_engine_sculpt_type = {
+ NULL, NULL,
+ N_("SculptMode"),
+ &SCULPT_data_size,
+ &SCULPT_engine_init,
+ &SCULPT_engine_free,
+ &SCULPT_cache_init,
+ &SCULPT_cache_populate,
+ &SCULPT_cache_finish,
+ NULL, /* draw_background but not needed by mode engines */
+ &SCULPT_draw_scene
+};
diff --git a/source/blender/draw/modes/shaders/common_globals_lib.glsl b/source/blender/draw/modes/shaders/common_globals_lib.glsl
new file mode 100644
index 00000000000..dc36d252926
--- /dev/null
+++ b/source/blender/draw/modes/shaders/common_globals_lib.glsl
@@ -0,0 +1,58 @@
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroupSelect;
+ vec4 colorGroup;
+ vec4 colorLibrarySelect;
+ vec4 colorLibrary;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ vec4 colorBackground;
+
+ vec4 colorGrid;
+ vec4 colorGridEmphasise;
+ vec4 colorGridAxisX;
+ vec4 colorGridAxisY;
+ vec4 colorGridAxisZ;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeFaceDot;
+
+ float gridDistance;
+ float gridResolution;
+ float gridSubdivisions;
+ float gridScale;
+};
diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl
new file mode 100644
index 00000000000..e78462b6915
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl
@@ -0,0 +1,22 @@
+
+flat in int vertFlag;
+
+#define VERTEX_SELECTED (1 << 0)
+#define VERTEX_ACTIVE (1 << 1)
+
+out vec4 FragColor;
+
+void main()
+{
+ /* TODO: vertex size */
+
+ if ((vertFlag & VERTEX_SELECTED) != 0) {
+ FragColor = colorVertexSelect;
+ }
+ else if ((vertFlag & VERTEX_ACTIVE) != 0) {
+ FragColor = colorEditMeshActive;
+ }
+ else {
+ FragColor = colorVertex;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl
new file mode 100644
index 00000000000..9150ef8cd63
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl
@@ -0,0 +1,39 @@
+
+/* Draw Curve Vertices */
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec3 pos;
+in int data;
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out int vertFlag;
+flat out int clipCase;
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+void main()
+{
+ clipCase = 0;
+
+ vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ /* only vertex position 0 is used */
+ eData1 = eData2 = vec4(1e10);
+ eData2.zw = proj(pPos);
+
+ vertFlag = data;
+
+ gl_Position = pPos;
+ gl_PointSize = sizeVertex;
+}
diff --git a/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl
new file mode 100644
index 00000000000..e78462b6915
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl
@@ -0,0 +1,22 @@
+
+flat in int vertFlag;
+
+#define VERTEX_SELECTED (1 << 0)
+#define VERTEX_ACTIVE (1 << 1)
+
+out vec4 FragColor;
+
+void main()
+{
+ /* TODO: vertex size */
+
+ if ((vertFlag & VERTEX_SELECTED) != 0) {
+ FragColor = colorVertexSelect;
+ }
+ else if ((vertFlag & VERTEX_ACTIVE) != 0) {
+ FragColor = colorEditMeshActive;
+ }
+ else {
+ FragColor = colorVertex;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl
new file mode 100644
index 00000000000..0cbc66a2b1f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl
@@ -0,0 +1,39 @@
+
+/* Draw Lattice Vertices */
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec3 pos;
+in int data;
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out int vertFlag;
+flat out int clipCase;
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+void main()
+{
+ clipCase = 0;
+
+ vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ /* only vertex position 0 is used */
+ eData1 = eData2 = vec4(1e10);
+ eData2.zw = proj(pPos);
+
+ vertFlag = data;
+
+ gl_PointSize = sizeVertex;
+ gl_Position = pPos;
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl
new file mode 100644
index 00000000000..9b3fe6286e8
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_frag.glsl
@@ -0,0 +1,12 @@
+
+flat in int isSelected;
+
+out vec4 FragColor;
+
+void main()
+{
+ if (isSelected != 0)
+ FragColor = colorFaceDot;
+ else
+ FragColor = colorWireEdit;
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl
new file mode 100644
index 00000000000..2e541fa75e6
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facedot_vert.glsl
@@ -0,0 +1,14 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in vec4 norAndFlag;
+
+flat out int isSelected;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = sizeFaceDot;
+ isSelected = int(norAndFlag.w);
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_frag.glsl
new file mode 100644
index 00000000000..049333c8e4f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_frag.glsl
@@ -0,0 +1,29 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+flat in vec4 faceColor;
+flat in int faceActive;
+
+out vec4 FragColor;
+
+const mat4 stipple_matrix = mat4(
+ vec4(1.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 0.0)
+);
+
+void main()
+{
+ FragColor = faceColor;
+
+ if (faceActive == 1) {
+ int x = int(gl_FragCoord.x) & 0x3; /* mod 4 */
+ int y = int(gl_FragCoord.y) & 0x3; /* mod 4 */
+ FragColor *= stipple_matrix[x][y];
+ }
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl
new file mode 100644
index 00000000000..3b9aa77306f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl
@@ -0,0 +1,29 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in ivec4 data;
+
+flat out vec4 faceColor;
+flat out int faceActive;
+
+#define FACE_ACTIVE (1 << 2)
+#define FACE_SELECTED (1 << 3)
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ if ((data.x & FACE_ACTIVE) != 0) {
+ faceColor = colorEditMeshActive;
+ faceActive = 1;
+ }
+ else if ((data.x & FACE_SELECTED) != 0) {
+ faceColor = colorFaceSelect;
+ faceActive = 0;
+ }
+ else {
+ faceColor = colorFace;
+ faceActive = 0;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
new file mode 100644
index 00000000000..a8f74ac3e0f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
@@ -0,0 +1,187 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+uniform float faceAlphaMod;
+
+flat in vec3 edgesCrease;
+flat in vec3 edgesBweight;
+flat in ivec3 flag;
+flat in vec4 faceColor;
+flat in int clipCase;
+#ifdef VERTEX_SELECTION
+in vec3 vertexColor;
+#endif
+
+/* We use a vec4[2] interface to pass edge data
+ * (without fragmenting memory accesses)
+ *
+ * There are 2 cases :
+ *
+ * - Simple case : geometry shader return edge distances
+ * in the first 2 components of the first vec4.
+ * This needs noperspective interpolation.
+ * The rest is filled with vertex screen positions.
+ * eData1.zw actually contain v2
+ * eData2.xy actually contain v1
+ * eData2.zw actually contain v0
+ *
+ * - Hard case : two 2d edge corner are described by each
+ * vec4 as origin and direction. This is constant over
+ * the triangle and use to detect the correct case. */
+
+noperspective in vec4 eData1;
+flat in vec4 eData2;
+
+out vec4 FragColor;
+
+#define EDGE_EXISTS (1 << 0)
+#define EDGE_ACTIVE (1 << 1)
+#define EDGE_SELECTED (1 << 2)
+#define EDGE_SEAM (1 << 3)
+#define EDGE_SHARP (1 << 4)
+/* Vertex flag is shifted and combined with the edge flag */
+#define VERTEX_ACTIVE (1 << (0 + 8))
+#define VERTEX_SELECTED (1 << (1 + 8))
+#define FACE_ACTIVE (1 << (2 + 8))
+
+/* Style Parameters in pixel */
+
+/* Array to retrieve vert/edge indices */
+const ivec3 clipEdgeIdx[6] = ivec3[6](
+ ivec3(1, 0, 2),
+ ivec3(2, 0, 1),
+ ivec3(2, 1, 0),
+ ivec3(2, 1, 0),
+ ivec3(2, 0, 1),
+ ivec3(1, 0, 2)
+);
+
+const ivec3 clipPointIdx[6] = ivec3[6](
+ ivec3(0, 1, 2),
+ ivec3(0, 2, 1),
+ ivec3(0, 2, 1),
+ ivec3(1, 2, 0),
+ ivec3(1, 2, 0),
+ ivec3(2, 1, 0)
+);
+
+const mat4 stipple_matrix = mat4(
+ vec4(1.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 0.0)
+);
+
+void colorDist(vec4 color, float dist)
+{
+ FragColor = (dist < 0) ? color : FragColor;
+}
+
+float distToEdge(vec2 o, vec2 dir)
+{
+ vec2 af = gl_FragCoord.xy - o;
+ float daf = dot(dir, af);
+ return sqrt(abs(dot(af, af) - daf * daf));
+}
+
+void main()
+{
+ vec3 e, p;
+
+ /* Step 1 : Computing Distances */
+
+ if (clipCase == 0) {
+ e.xy = eData1.xy;
+
+ /* computing missing distance */
+ vec2 dir = normalize(eData2.zw - eData2.xy);
+ e.z = distToEdge(eData2.zw, dir);
+
+ p.x = distance(eData2.zw, gl_FragCoord.xy);
+ p.y = distance(eData2.xy, gl_FragCoord.xy);
+ p.z = distance(eData1.zw, gl_FragCoord.xy);
+ }
+ else {
+ ivec3 eidxs = clipEdgeIdx[clipCase - 1];
+ ivec3 pidxs = clipPointIdx[clipCase - 1];
+
+ e[eidxs.x] = distToEdge(eData1.xy, eData1.zw);
+ e[eidxs.y] = distToEdge(eData2.xy, eData2.zw);
+
+ /* Three edges visible cases */
+ if (clipCase == 1 || clipCase == 2 || clipCase == 4) {
+ e[eidxs.z] = distToEdge(eData1.xy, normalize(eData2.xy - eData1.xy));
+ p[pidxs.y] = distance(eData2.xy, gl_FragCoord.xy);
+ }
+ else {
+ e[eidxs.z] = 1e10; /* off screen */
+ p[pidxs.y] = 1e10; /* off screen */
+ }
+
+ p[pidxs.x] = distance(eData1.xy, gl_FragCoord.xy);
+ p[pidxs.z] = 1e10; /* off screen */
+ }
+
+ /* Step 2 : coloring (order dependant) */
+
+ /* First */
+ FragColor = faceColor;
+
+ if ((flag[0] & FACE_ACTIVE) != 0) {
+ int x = int(gl_FragCoord.x) & 0x3; /* mod 4 */
+ int y = int(gl_FragCoord.y) & 0x3; /* mod 4 */
+ FragColor *= stipple_matrix[x][y];
+ }
+ else {
+ FragColor.a *= faceAlphaMod;
+ }
+
+ /* Edges */
+ for (int v = 0; v < 3; ++v) {
+ if ((flag[v] & EDGE_EXISTS) != 0) {
+ float largeEdge = e[v] - sizeEdge * 2.0;
+ float innerEdge = e[v] - sizeEdge;
+
+ if ((flag[v] & EDGE_SEAM) != 0)
+ colorDist(colorEdgeSeam, largeEdge);
+ else if (edgesBweight[v] > 0.0)
+ colorDist(vec4(colorEdgeBWeight.rgb, edgesBweight[v]), largeEdge);
+ else if (edgesCrease[v] > 0.0)
+ colorDist(vec4(colorEdgeCrease.rgb, edgesCrease[v]), largeEdge);
+ else if ((flag[v] & EDGE_SHARP) != 0)
+ colorDist(colorEdgeSharp, largeEdge);
+#ifndef VERTEX_SELECTION
+ else
+ colorDist(colorWireEdit, innerEdge);
+
+ if ((flag[v] & EDGE_ACTIVE) != 0)
+ colorDist(vec4(colorEditMeshActive.xyz, 1.0), innerEdge);
+ else if ((flag[v] & EDGE_SELECTED) != 0)
+ colorDist(colorEdgeSelect, innerEdge);
+#else
+ colorDist(vec4(vertexColor, 1.0), innerEdge);
+#endif
+ }
+ }
+
+ /* Points */
+#ifdef VERTEX_SELECTION
+ for (int v = 0; v < 3; ++v) {
+ float size = p[v] - sizeVertex;
+
+ if ((flag[v] & VERTEX_ACTIVE) != 0)
+ colorDist(vec4(colorEditMeshActive.xyz, 1.0), size);
+ else if ((flag[v] & VERTEX_SELECTED) != 0)
+ colorDist(colorVertexSelect, size);
+ else
+ colorDist(colorVertex, size);
+ }
+#endif
+
+ /* don't write depth if not opaque */
+ if (FragColor.a == 0.0) discard;
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl
new file mode 100644
index 00000000000..5e3ecd59cb4
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl
@@ -0,0 +1,143 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+layout(lines) in;
+layout(triangle_strip, max_vertices=6) out;
+
+uniform mat4 ProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec4 vPos[];
+in vec4 pPos[];
+in ivec4 vData[];
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out vec3 edgesCrease;
+flat out vec3 edgesBweight;
+flat out ivec3 flag;
+flat out vec4 faceColor;
+flat out int clipCase;
+#ifdef VERTEX_SELECTION
+out vec3 vertexColor;
+#endif
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+#define VERTEX_ACTIVE (1 << 0)
+#define VERTEX_SELECTED (1 << 1)
+
+#define FACE_ACTIVE (1 << 2)
+#define FACE_SELECTED (1 << 3)
+
+/* Table 1. Triangle Projection Cases */
+const ivec4 clipPointsIdx[6] = ivec4[6](
+ ivec4(0, 1, 2, 2),
+ ivec4(0, 2, 1, 1),
+ ivec4(0, 0, 1, 2),
+ ivec4(1, 2, 0, 0),
+ ivec4(1, 1, 0, 2),
+ ivec4(2, 2, 0, 1)
+);
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+float dist(vec2 pos[3], vec2 vpos, int v)
+{
+ /* endpoints of opposite edge */
+ vec2 e1 = pos[(v + 1) % 3];
+ vec2 e2 = pos[(v + 2) % 3];
+ /* Edge normalized vector */
+ vec2 dir = normalize(e2 - e1);
+ /* perpendicular to dir */
+ vec2 orthogonal = vec2(-dir.y, dir.x);
+
+ return abs(dot(vpos - e1, orthogonal));
+}
+
+vec3 getVertexColor(int v)
+{
+ if ((vData[v].x & (VERTEX_ACTIVE | VERTEX_SELECTED)) != 0)
+ return colorEdgeSelect.rgb;
+ else
+ return colorWireEdit.rgb;
+}
+
+void doVertex(int v, vec4 pos)
+{
+#ifdef VERTEX_SELECTION
+ vertexColor = getVertexColor(v);
+#endif
+
+ gl_Position = pos;
+
+ EmitVertex();
+}
+
+void main()
+{
+ clipCase = 0;
+
+ /* Face */
+ faceColor = vec4(0.0);
+
+ /* Proj Vertex */
+ vec2 pos[2] = vec2[2](proj(pPos[0]), proj(pPos[1]));
+
+ /* little optimization use a vec4 to vectorize
+ * following operations */
+ vec4 dirs1, dirs2;
+
+ /* Edge normalized vector */
+ dirs1.xy = normalize(pos[1] - pos[0]);
+
+ /* perpendicular to dir */
+ dirs1.zw = vec2(-dirs1.y, dirs1.x);
+
+ /* Make it view independent */
+ dirs1 *= sizeEdgeFix / viewportSize.xyxy;
+
+ dirs2 = dirs1;
+
+ /* Perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ /* vPos[i].z is negative and we don't want
+ * our fixvec to be flipped */
+ dirs1 *= -vPos[0].z;
+ dirs2 *= -vPos[1].z;
+ }
+
+ /* Edge / Vert data */
+ eData1 = vec4(1e10);
+ eData2.zw = pos[0];
+ eData2.xy = pos[1];
+ flag[0] = (vData[0].x << 8);
+ flag[1] = (vData[1].x << 8);
+ flag[2] = 0;
+
+ doVertex(0, pPos[0] + vec4(-dirs1.xy, 0.0, 0.0));
+ doVertex(0, pPos[0] + vec4( dirs1.zw, 0.0, 0.0));
+ doVertex(0, pPos[0] + vec4(-dirs1.zw, 0.0, 0.0));
+
+ flag[2] = vData[0].y | (vData[0].x << 8);
+ edgesCrease[2] = vData[0].z / 255.0;
+ edgesBweight[2] = vData[0].w / 255.0;
+
+ doVertex(1, pPos[1] + vec4( dirs2.zw, 0.0, 0.0));
+ doVertex(1, pPos[1] + vec4(-dirs2.zw, 0.0, 0.0));
+
+ flag[2] = 0;
+ doVertex(1, pPos[1] + vec4( dirs2.xy, 0.0, 0.0));
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl
new file mode 100644
index 00000000000..64809a37d11
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl
@@ -0,0 +1,277 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+layout(triangles) in;
+
+#ifdef EDGE_FIX
+/* To fix the edge artifacts, we render
+ * an outline strip around the screenspace
+ * triangle. Order is important.
+ * TODO diagram
+ */
+
+#ifdef VERTEX_SELECTION
+layout(triangle_strip, max_vertices=23) out;
+#else
+layout(triangle_strip, max_vertices=17) out;
+#endif
+#else
+layout(triangle_strip, max_vertices=3) out;
+#endif
+
+uniform mat4 ProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec4 vPos[];
+in vec4 pPos[];
+in ivec4 vData[];
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out vec3 edgesCrease;
+flat out vec3 edgesBweight;
+flat out ivec3 flag;
+flat out vec4 faceColor;
+flat out int clipCase;
+#ifdef VERTEX_SELECTION
+out vec3 vertexColor;
+#endif
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+
+#define VERTEX_ACTIVE (1 << 0)
+#define VERTEX_SELECTED (1 << 1)
+
+#define FACE_ACTIVE (1 << 2)
+#define FACE_SELECTED (1 << 3)
+
+/* Table 1. Triangle Projection Cases */
+const ivec4 clipPointsIdx[6] = ivec4[6](
+ ivec4(0, 1, 2, 2),
+ ivec4(0, 2, 1, 1),
+ ivec4(0, 0, 1, 2),
+ ivec4(1, 2, 0, 0),
+ ivec4(1, 1, 0, 2),
+ ivec4(2, 2, 0, 1)
+);
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+float dist(vec2 pos[3], vec2 vpos, int v)
+{
+ /* endpoints of opposite edge */
+ vec2 e1 = pos[(v + 1) % 3];
+ vec2 e2 = pos[(v + 2) % 3];
+ /* Edge normalized vector */
+ vec2 dir = normalize(e2 - e1);
+ /* perpendicular to dir */
+ vec2 orthogonal = vec2(-dir.y, dir.x);
+
+ return abs(dot(vpos - e1, orthogonal));
+}
+
+vec3 getVertexColor(int v)
+{
+ if ((vData[v].x & (VERTEX_ACTIVE | VERTEX_SELECTED)) != 0)
+ return colorEdgeSelect.rgb;
+ else
+ return colorWireEdit.rgb;
+}
+
+vec4 getClipData(vec2 pos[3], ivec2 vidx)
+{
+ vec2 A = pos[vidx.x];
+ vec2 Adir = normalize(A - pos[vidx.y]);
+
+ return vec4(A, Adir);
+}
+
+void doVertex(int v, vec4 pos)
+{
+#ifdef VERTEX_SELECTION
+ vertexColor = getVertexColor(v);
+#endif
+
+ gl_Position = pos;
+
+ EmitVertex();
+}
+
+void main()
+{
+ /* First we detect which case we are in */
+ clipCase = 0;
+
+ /* if perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ /* See Table 1. Triangle Projection Cases */
+ clipCase += int(pPos[0].z / pPos[0].w < -1 || vPos[0].z > 0.0) * 4;
+ clipCase += int(pPos[1].z / pPos[1].w < -1 || vPos[1].z > 0.0) * 2;
+ clipCase += int(pPos[2].z / pPos[2].w < -1 || vPos[2].z > 0.0) * 1;
+ }
+
+ /* If triangle is behind nearplane, early out */
+ if (clipCase == 7)
+ return;
+
+ /* Edge */
+ ivec3 eflag; vec3 ecrease, ebweight;
+ for (int v = 0; v < 3; ++v) {
+ flag[v] = eflag[v] = vData[v].y | (vData[v].x << 8);
+ edgesCrease[v] = ecrease[v] = vData[v].z / 255.0;
+ edgesBweight[v] = ebweight[v] = vData[v].w / 255.0;
+ }
+
+ /* Face */
+ if ((vData[0].x & FACE_ACTIVE) != 0)
+ faceColor = colorEditMeshActive;
+ else if ((vData[0].x & FACE_SELECTED) != 0)
+ faceColor = colorFaceSelect;
+ else
+ faceColor = colorFace;
+
+ /* Vertex */
+ vec2 pos[3] = vec2[3](proj(pPos[0]), proj(pPos[1]), proj(pPos[2]));
+
+ /* Simple case : compute edge distances in geometry shader */
+ if (clipCase == 0) {
+
+ /* Packing screen positions and 2 distances */
+ eData1 = vec4(0.0, 0.0, pos[2]);
+ eData2 = vec4(pos[1], pos[0]);
+
+ /* Only pass the first 2 distances */
+ for (int v = 0; v < 2; ++v) {
+ eData1[v] = dist(pos, pos[v], v);
+ doVertex(v, pPos[v]);
+ eData1[v] = 0.0;
+ }
+
+ /* and the last vertex */
+ doVertex(2, pPos[2]);
+
+#ifdef EDGE_FIX
+ vec2 fixvec[6];
+ vec2 fixvecaf[6];
+ vec2 cornervec[3];
+
+ /* This fix the case when 2 vertices are perfectly aligned
+ * and corner vectors have nowhere to go.
+ * ie: length(cornervec[i]) == 0 */
+ const float epsilon = 1e-2; /* in pixel so not that much */
+ const vec2 bias[3] = vec2[3](
+ vec2( epsilon, epsilon),
+ vec2(-epsilon, epsilon),
+ vec2( 0.0, -epsilon)
+ );
+
+ for (int i = 0; i < 3; ++i) {
+ int i1 = (i + 1) % 3;
+ int i2 = (i + 2) % 3;
+
+ vec2 v1 = pos[i] + bias[i];
+ vec2 v2 = pos[i1] + bias[i1];
+ vec2 v3 = pos[i2] + bias[i2];
+
+ /* Edge normalized vector */
+ vec2 dir = normalize(v2 - v1);
+ vec2 dir2 = normalize(v3 - v1);
+
+ cornervec[i] = -normalize(dir + dir2);
+
+ /* perpendicular to dir */
+ vec2 perp = vec2(-dir.y, dir.x);
+
+ /* Backface case */
+ if (dot(perp, dir2) > 0) {
+ perp = -perp;
+ }
+
+ /* Make it view independent */
+ perp *= sizeEdgeFix / viewportSize;
+ cornervec[i] *= sizeEdgeFix / viewportSize;
+ fixvec[i] = fixvecaf[i] = perp;
+
+ /* Perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ /* vPos[i].z is negative and we don't want
+ * our fixvec to be flipped */
+ fixvec[i] *= -vPos[i].z;
+ fixvecaf[i] *= -vPos[i1].z;
+ cornervec[i] *= -vPos[i].z;
+ }
+ }
+
+ /* to not let face color bleed */
+ faceColor = vec4(0.0);
+
+ /* we don't want other edges : make them far */
+ eData1 = vec4(1e10);
+
+ /* Start with the same last vertex to create a
+ * degenerate triangle in order to "create"
+ * a new triangle strip */
+ for (int i = 2; i < 5; ++i) {
+ int vbe = (i - 1) % 3;
+ int vaf = (i + 1) % 3;
+ int v = i % 3;
+
+ /* Position of the "hidden" third vertex */
+ eData1.zw = pos[vbe];
+
+ doVertex(v, pPos[v]);
+ doVertex(v, pPos[v] + vec4(fixvec[v], 0.0, 0.0));
+
+ /* Now one triangle only shade one edge
+ * so we use the edge distance calculated
+ * in the fragment shader, the third edge;
+ * we do this because we need flat interp to
+ * draw a continuous triangle strip */
+ eData2.xy = pos[vaf];
+ eData2.zw = pos[v];
+ flag[0] = (vData[v].x << 8);
+ flag[1] = (vData[vaf].x << 8);
+ flag[2] = eflag[vbe];
+ edgesCrease[2] = ecrease[vbe];
+ edgesBweight[2] = ebweight[vbe];
+
+ doVertex(vaf, pPos[vaf]);
+ doVertex(vaf, pPos[vaf] + vec4(fixvecaf[v], 0.0, 0.0));
+
+ /* corner vertices should not draw edges but draw point only */
+ flag[2] = (vData[vbe].x << 8);
+#ifdef VERTEX_SELECTION
+ doVertex(vaf, pPos[vaf]);
+ doVertex(vaf, pPos[vaf] + vec4(cornervec[vaf], 0.0, 0.0));
+#endif
+ }
+
+ /* finish the loop strip */
+ doVertex(2, pPos[2]);
+ doVertex(2, pPos[2] + vec4(fixvec[2], 0.0, 0.0));
+#endif
+ }
+ /* Harder case : compute visible edges vectors */
+ else {
+ ivec4 vindices = clipPointsIdx[clipCase - 1];
+
+ eData1 = getClipData(pos, vindices.xz);
+ eData2 = getClipData(pos, vindices.yw);
+
+ for (int v = 0; v < 3; ++v)
+ doVertex(v, pPos[v]);
+ }
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_loosevert_vert.glsl
new file mode 100644
index 00000000000..0a396a5325f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_loosevert_vert.glsl
@@ -0,0 +1,59 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec3 pos;
+in ivec4 data;
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out vec3 edgesCrease;
+flat out vec3 edgesBweight;
+flat out ivec3 flag;
+flat out vec4 faceColor;
+flat out int clipCase;
+#ifdef VERTEX_SELECTION
+out vec3 vertexColor;
+#endif
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+void main()
+{
+ clipCase = 0;
+ edgesCrease = vec3(0.0);
+ edgesBweight = vec3(0.0);
+
+ vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ /* there is no face */
+ faceColor = vec4(0.0);
+
+#ifdef VERTEX_SELECTION
+ vertexColor = vec3(0.0);
+#endif
+
+ /* only vertex position 0 is used */
+ eData1 = eData2 = vec4(1e10);
+ eData2.zw = proj(pPos);
+
+ flag = ivec3(0);
+ flag[0] = (data.x << 8);
+
+ gl_PointSize = sizeEdgeFix;
+ gl_Position = pPos;
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl
new file mode 100644
index 00000000000..f567a3a5cbd
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mix_frag.glsl
@@ -0,0 +1,24 @@
+
+out vec4 FragColor;
+
+uniform sampler2D wireColor;
+uniform sampler2D wireDepth;
+uniform sampler2D sceneDepth;
+uniform float alpha;
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float wire_depth = texelFetch(wireDepth, uv, 0).r;
+ float scene_depth = texelFetch(sceneDepth, uv, 0).r;
+ vec4 wire_color = texelFetch(wireColor, uv, 0).rgba;
+
+ FragColor = wire_color;
+
+ /* this works because not rendered depth is 1.0 and the
+ * following test is always true even when no wires */
+ if ((wire_depth > scene_depth) && (wire_color.a > 0)) {
+ /* Note : Using wire_color.a * alpha produce unwanted result */
+ FragColor.a = alpha;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
new file mode 100644
index 00000000000..5bc9a8bef85
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
@@ -0,0 +1,23 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in ivec4 data;
+
+out vec4 vPos;
+out vec4 pPos;
+out ivec4 vData;
+
+void main()
+{
+ vPos = ModelViewMatrix * vec4(pos, 1.0);
+ pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vData = data;
+}
diff --git a/source/blender/draw/modes/shaders/edit_normals_geom.glsl b/source/blender/draw/modes/shaders/edit_normals_geom.glsl
new file mode 100644
index 00000000000..d17823f2f5a
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_geom.glsl
@@ -0,0 +1,15 @@
+
+layout(points) in;
+layout(line_strip, max_vertices=2) out;
+
+flat in vec4 v1[1];
+flat in vec4 v2[1];
+
+void main()
+{
+ gl_Position = v1[0];
+ EmitVertex();
+ gl_Position = v2[0];
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_normals_vert.glsl b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
new file mode 100644
index 00000000000..3ce7e618511
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
@@ -0,0 +1,30 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+uniform mat4 ProjectionMatrix;
+uniform float normalSize;
+
+in vec3 pos;
+
+#ifdef LOOP_NORMALS
+in vec3 lnor;
+#define nor lnor
+
+#elif defined(FACE_NORMALS)
+in vec4 norAndFlag;
+#define nor norAndFlag.xyz
+#else
+
+in vec3 vnor;
+#define nor vnor
+#endif
+
+flat out vec4 v1;
+flat out vec4 v2;
+
+void main()
+{
+ v1 = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 n = normalize(NormalMatrix * nor); /* viewspace */
+ v2 = v1 + ProjectionMatrix * vec4(n * normalSize, 0.0);
+}
diff --git a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl
new file mode 100644
index 00000000000..eab107354d1
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl
@@ -0,0 +1,21 @@
+
+flat in vec4 finalColor;
+
+#ifndef USE_WIRE
+in vec2 texCoord_interp;
+#endif
+
+out vec4 fragColor;
+
+#ifndef USE_WIRE
+uniform sampler2D image;
+#endif
+
+void main()
+{
+#ifdef USE_WIRE
+ fragColor = finalColor;
+#else
+ fragColor = finalColor * texture(image, texCoord_interp);
+#endif
+}
diff --git a/source/blender/draw/modes/shaders/object_empty_image_vert.glsl b/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
new file mode 100644
index 00000000000..c629fdcb7ef
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
@@ -0,0 +1,38 @@
+
+uniform mat4 ViewProjectionMatrix;
+uniform vec2 aspect;
+
+/* ---- Instanciated Attribs ---- */
+in vec2 texCoord;
+in vec2 pos;
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+
+#ifdef USE_WIRE
+in vec3 color;
+#else
+in vec4 objectColor;
+#endif
+
+in float size;
+in vec2 offset;
+
+flat out vec4 finalColor;
+
+#ifndef USE_WIRE
+out vec2 texCoord_interp;
+#endif
+
+void main()
+{
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(
+ (pos[0] + offset[0]) * (size * aspect[0]),
+ (pos[1] + offset[1]) * (size * aspect[1]),
+ 0.0, 1.0);
+#ifdef USE_WIRE
+ finalColor = vec4(color, 1.0);
+#else
+ texCoord_interp = texCoord;
+ finalColor = objectColor;
+#endif
+}
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl
new file mode 100644
index 00000000000..0196b1a6f98
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl
@@ -0,0 +1,189 @@
+
+/* Infinite grid
+ * Clément Foucault */
+
+
+out vec4 FragColor;
+
+uniform mat4 ProjectionMatrix;
+uniform vec3 cameraPos;
+uniform vec3 planeNormal;
+uniform vec3 planeAxes;
+uniform vec3 eye;
+uniform vec4 gridSettings;
+uniform vec2 viewportSize;
+uniform vec4 screenvecs[3];
+uniform float gridOneOverLogSubdiv;
+
+#define gridDistance gridSettings.x
+#define gridResolution gridSettings.y
+#define gridScale gridSettings.z
+#define gridSubdiv gridSettings.w
+
+uniform int gridFlag;
+
+#define AXIS_X (1 << 0)
+#define AXIS_Y (1 << 1)
+#define AXIS_Z (1 << 2)
+#define GRID (1 << 3)
+#define PLANE_XY (1 << 4)
+#define PLANE_XZ (1 << 5)
+#define PLANE_YZ (1 << 6)
+
+#define GRID_LINE_SMOOTH 1.15
+
+float get_grid(vec3 co, vec3 fwidthCos, float grid_size)
+{
+ float half_size = grid_size / 2.0;
+ /* triangular wave pattern, amplitude is [0, grid_size] */
+ vec3 grid_domain = abs(mod(co + half_size, grid_size) - half_size);
+ /* modulate by the absolute rate of change of the coordinates
+ * (make lines have the same width under perspective) */
+ grid_domain /= fwidthCos;
+
+ /* collapse waves and normalize */
+ grid_domain.x = min(grid_domain.x, min(grid_domain.y, grid_domain.z)) / grid_size;
+
+ return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH / grid_size, grid_domain.x);
+}
+
+vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
+{
+ vec3 axes_domain = abs(co);
+ /* modulate by the absolute rate of change of the coordinates
+ * (make line have the same width under perspective) */
+ axes_domain /= fwidthCos;
+
+ return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH, axes_domain - line_size);
+}
+
+vec3 get_floor_pos(vec2 uv, out vec3 wPos)
+{
+ vec3 camera_vec, camera_pos, corner_pos;
+ vec3 floored_pos = planeAxes * floor(screenvecs[2].xyz);
+ corner_pos = screenvecs[2].xyz - floored_pos;
+
+ vec3 pixel_pos = corner_pos + uv.x * screenvecs[0].xyz + uv.y * screenvecs[1].xyz;
+
+ /* if perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ camera_pos = cameraPos - floored_pos;
+ camera_vec = normalize(pixel_pos - camera_pos);
+ }
+ else {
+ camera_pos = pixel_pos;
+ camera_vec = normalize(eye);
+ }
+
+ float p = -dot(planeNormal, camera_pos) / dot(planeNormal, camera_vec);
+ vec3 plane = camera_pos + camera_vec * p;
+
+ /* fix residual imprecision */
+ plane *= planeAxes;
+
+ /* Recover non-offseted world position */
+ wPos = plane + floored_pos;
+
+ return plane;
+}
+
+void main()
+{
+ vec2 sPos = gl_FragCoord.xy / viewportSize; /* Screen [0,1] position */
+
+ /* To reduce artifacts, use a local version of the positions
+ * to compute derivatives since they are not position dependant.
+ * This gets rid of the blocky artifacts. Unfortunately we still
+ * need the world position for the grid to scale properly from the origin. */
+ vec3 gPos, wPos; /* Grid pos., World pos. */
+ gPos = get_floor_pos(sPos, wPos);
+
+ vec3 fwidthPos = fwidth(gPos);
+
+ float dist, fade;
+ /* if persp */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ vec3 viewvec = cameraPos - wPos;
+ dist = length(viewvec);
+ viewvec /= dist;
+
+ float angle;
+ if ((gridFlag & PLANE_XZ) > 0)
+ angle = viewvec.y;
+ else if ((gridFlag & PLANE_YZ) > 0)
+ angle = viewvec.x;
+ else
+ angle = viewvec.z;
+
+ angle = 1.0 - abs(angle);
+ fade = 1.0 - angle * angle;
+ fade *= 1.0 - smoothstep(0.0, gridDistance, dist - gridDistance);
+ }
+ else {
+ dist = abs(gl_FragCoord.z * 2.0 - 1.0);
+ fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5);
+ dist = 1.0; /* avoid branch after */
+
+ if ((gridFlag & PLANE_XY) > 0) {
+ float angle = 1.0 - abs(eye.z);
+ fade *= 1.0 - angle * angle * angle;
+ dist = 1.0 + angle * 2.0;
+ }
+ }
+
+ if ((gridFlag & GRID) > 0) {
+ float grid_res = log(dist * gridResolution) * gridOneOverLogSubdiv;
+
+ float blend = fract(-max(grid_res, 0.0));
+ float lvl = floor(grid_res);
+
+ /* from biggest to smallest */
+ float scaleA = gridScale * pow(gridSubdiv, max(lvl - 1.0, 0.0));
+ float scaleB = gridScale * pow(gridSubdiv, max(lvl + 0.0, 0.0));
+ float scaleC = gridScale * pow(gridSubdiv, max(lvl + 1.0, 1.0));
+
+ float gridA = get_grid(wPos, fwidthPos, scaleA);
+ float gridB = get_grid(wPos, fwidthPos, scaleB);
+ float gridC = get_grid(wPos, fwidthPos, scaleC);
+
+ FragColor = vec4(colorGrid.rgb, gridA * blend);
+ FragColor = mix(FragColor, vec4(mix(colorGrid.rgb, colorGridEmphasise.rgb, blend), 1.0), gridB);
+ FragColor = mix(FragColor, vec4(colorGridEmphasise.rgb, 1.0), gridC);
+ }
+ else {
+ FragColor = vec4(colorGrid.rgb, 0.0);
+ }
+
+ if ((gridFlag & (AXIS_X | AXIS_Y | AXIS_Z)) > 0) {
+ /* Setup axes 'domains' */
+ vec3 axes_dist, axes_fwidth;
+
+ if ((gridFlag & AXIS_X) > 0) {
+ axes_dist.x = dot(wPos.yz, planeAxes.yz);
+ axes_fwidth.x = dot(fwidthPos.yz, planeAxes.yz);
+ }
+ if ((gridFlag & AXIS_Y) > 0) {
+ axes_dist.y = dot(wPos.xz, planeAxes.xz);
+ axes_fwidth.y = dot(fwidthPos.xz, planeAxes.xz);
+ }
+ if ((gridFlag & AXIS_Z) > 0) {
+ axes_dist.z = dot(wPos.xy, planeAxes.xy);
+ axes_fwidth.z = dot(fwidthPos.xy, planeAxes.xy);
+ }
+
+ /* Computing all axes at once using vec3 */
+ vec3 axes = get_axes(axes_dist, axes_fwidth, 0.1);
+
+ if ((gridFlag & AXIS_X) > 0) {
+ FragColor = mix(FragColor, colorGridAxisX, axes.x);
+ }
+ if ((gridFlag & AXIS_Y) > 0) {
+ FragColor = mix(FragColor, colorGridAxisY, axes.y);
+ }
+ if ((gridFlag & AXIS_Z) > 0) {
+ FragColor = mix(FragColor, colorGridAxisZ, axes.z);
+ }
+ }
+
+ FragColor.a *= fade;
+} \ No newline at end of file
diff --git a/source/blender/draw/modes/shaders/object_grid_vert.glsl b/source/blender/draw/modes/shaders/object_grid_vert.glsl
new file mode 100644
index 00000000000..2ecbfa8e11f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_grid_vert.glsl
@@ -0,0 +1,63 @@
+
+/* Infinite grid
+ * Clément Foucault */
+
+uniform mat4 ViewProjectionOffsetMatrix;
+uniform mat4 ProjectionMatrix;
+uniform vec3 cameraPos;
+uniform vec4 gridSettings;
+
+#define gridDistance gridSettings.x
+#define gridResolution gridSettings.y
+#define gridScale gridSettings.z
+#define gridSubdiv gridSettings.w
+
+uniform int gridFlag;
+
+#define PLANE_XY (1 << 4)
+#define PLANE_XZ (1 << 5)
+#define PLANE_YZ (1 << 6)
+#define CLIP_Z_POS (1 << 7)
+#define CLIP_Z_NEG (1 << 8)
+
+in vec3 pos;
+
+void main()
+{
+ vec3 vert_pos, proj_camera_pos;
+
+ /* Project camera pos to the needed plane */
+ if ((gridFlag & PLANE_XY) > 0) {
+ vert_pos = vec3(pos.x, pos.y, 0.0);
+ proj_camera_pos = vec3(cameraPos.x, cameraPos.y, 0.0);
+ }
+ else if ((gridFlag & PLANE_XZ) > 0) {
+ vert_pos = vec3(pos.x, 0.0, pos.y);
+ proj_camera_pos = vec3(cameraPos.x, 0.0, cameraPos.z);
+ }
+ else {
+ vert_pos = vec3(0.0, pos.x, pos.y);
+ proj_camera_pos = vec3(0.0, cameraPos.y, cameraPos.z);
+ }
+
+ /* if persp */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ vert_pos *= gridDistance * 2.0;
+ }
+ else {
+ float viewdist = 1.0 / min(abs(ProjectionMatrix[0][0]), abs(ProjectionMatrix[1][1]));
+ vert_pos *= viewdist * gridDistance * 2.0;
+ }
+
+ vec3 realPos = proj_camera_pos + vert_pos;
+
+ /* Used for additional Z axis */
+ if ((gridFlag & CLIP_Z_POS) > 0) {
+ realPos.z = max(realPos.z, 0.0);
+ }
+ if ((gridFlag & CLIP_Z_NEG) > 0) {
+ realPos.z = min(-realPos.z, 0.0);
+ }
+
+ gl_Position = ViewProjectionOffsetMatrix * vec4(realPos, 1.0);
+}
diff --git a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
new file mode 100644
index 00000000000..5565a0f1e09
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
@@ -0,0 +1,61 @@
+
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+uniform sampler2D outlineColor;
+uniform sampler2D outlineDepth;
+uniform sampler2D sceneDepth;
+
+uniform float alphaOcclu;
+uniform vec2 viewportSize;
+
+void search_outline(ivec2 uv, vec4 ref_col, inout bool ref_occlu, inout bool outline)
+{
+ if (!outline) {
+ vec4 color = texelFetch(outlineColor, uv, 0).rgba;
+ if (color != ref_col) {
+ outline = true;
+ }
+ else {
+ float depth = texelFetch(outlineDepth, uv, 0).r;
+ float scene_depth = texelFetch(sceneDepth, uv, 0).r;
+ bool occlu = (depth > scene_depth);
+
+ if (occlu != ref_occlu && !ref_occlu) {
+ outline = true;
+ }
+ }
+ }
+}
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ vec4 ref_col = texelFetch(outlineColor, uv, 0).rgba;
+
+ float depth = texelFetch(outlineDepth, uv, 0).r;
+ /* Modulate color if occluded */
+ float scene_depth = texelFetch(sceneDepth, uv, 0).r;
+
+ bool ref_occlu = (depth > scene_depth);
+
+ bool outline = false;
+
+ search_outline(uv + ivec2( 1, 0), ref_col, ref_occlu, outline);
+ search_outline(uv + ivec2( 0, 1), ref_col, ref_occlu, outline);
+ search_outline(uv + ivec2(-1, 0), ref_col, ref_occlu, outline);
+ search_outline(uv + ivec2( 0, -1), ref_col, ref_occlu, outline);
+
+ FragColor = ref_col;
+
+ /* We Hit something ! */
+ if (outline) {
+ if (ref_occlu) {
+ FragColor.a *= alphaOcclu;
+ }
+ }
+ else {
+ FragColor.a = 0.0;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl
new file mode 100644
index 00000000000..e0568d1157a
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl
@@ -0,0 +1,45 @@
+
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+uniform sampler2D outlineColor;
+uniform sampler2D outlineDepth;
+
+uniform float alpha;
+uniform bool doExpand;
+
+void search_outline(ivec2 uv, inout bool found_edge)
+{
+ if (!found_edge) {
+ vec4 color = texelFetch(outlineColor, uv, 0).rgba;
+ if (color.a != 0.0) {
+ if (doExpand || color.a != 1.0) {
+ FragColor = color;
+ found_edge = true;
+ }
+ }
+ }
+}
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ FragColor = texelFetch(outlineColor, uv, 0).rgba;
+ float depth = texelFetch(outlineDepth, uv, 0).r;
+
+ if (FragColor.a != 0.0 || (depth == 1.0 && !doExpand))
+ return;
+
+ bool found_edge = false;
+ search_outline(uv + ivec2( 1, 0), found_edge);
+ search_outline(uv + ivec2( 0, 1), found_edge);
+ search_outline(uv + ivec2(-1, 0), found_edge);
+ search_outline(uv + ivec2( 0, -1), found_edge);
+
+ /* We Hit something ! */
+ if (found_edge) {
+ /* only change alpha */
+ FragColor.a *= alpha;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl b/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl
new file mode 100644
index 00000000000..3937828eca2
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl
@@ -0,0 +1,11 @@
+
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+uniform sampler2D outlineBluredColor;
+
+void main()
+{
+ FragColor = texture(outlineBluredColor, uvcoordsvar.st).rgba;
+}
diff --git a/source/blender/draw/modes/shaders/object_particle_dot_frag.glsl b/source/blender/draw/modes/shaders/object_particle_dot_frag.glsl
new file mode 100644
index 00000000000..e8bf7884701
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_particle_dot_frag.glsl
@@ -0,0 +1,52 @@
+
+uniform vec3 color;
+uniform vec3 outlineColor;
+uniform sampler1D ramp;
+
+in vec4 radii;
+flat in float finalVal;
+
+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 point color
+// ...
+// dist = 0 at center of point
+
+ float midStroke = 0.5 * (radii[1] + radii[2]);
+
+ if (dist > midStroke) {
+ if (finalVal < 0.0) {
+ fragColor.rgb = outlineColor;
+ }
+ else {
+ fragColor.rgb = texture(ramp, finalVal).rgb;
+ }
+
+ fragColor.a = mix(1.0, 0.0, smoothstep(radii[1], radii[0], dist));
+ }
+ else {
+ if (finalVal < 0.0) {
+ fragColor.rgb = mix(color, outlineColor, smoothstep(radii[3], radii[2], dist));
+ }
+ else {
+ fragColor.rgb = texture(ramp, finalVal).rgb;
+ }
+
+ fragColor.a = 1.0;
+ }
+
+ if (fragColor.a == 0.0) {
+ discard;
+ }
+}
diff --git a/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl b/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl
new file mode 100644
index 00000000000..7b163dbdc31
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl
@@ -0,0 +1,28 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform int size;
+
+in vec3 pos;
+in float val;
+
+out vec4 radii;
+flat out float finalVal;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = size;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * size;
+
+ // start at the outside and progress toward the center
+ radii[0] = radius;
+ radii[1] = radius - 1.0;
+ radii[2] = radius - 1.0;
+ radii[3] = radius - 2.0;
+
+ // convert to PointCoord units
+ radii /= size;
+
+ finalVal = val;
+}
diff --git a/source/blender/draw/modes/shaders/object_particle_prim_frag.glsl b/source/blender/draw/modes/shaders/object_particle_prim_frag.glsl
new file mode 100644
index 00000000000..aa455a85cf0
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_particle_prim_frag.glsl
@@ -0,0 +1,9 @@
+
+flat in vec4 finalColor;
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor;
+}
diff --git a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
new file mode 100644
index 00000000000..55b183b6933
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
@@ -0,0 +1,64 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ViewProjectionMatrix;
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform int screen_space;
+uniform float pixel_size;
+uniform int draw_size;
+uniform vec3 color;
+uniform sampler1D ramp;
+
+in vec3 pos;
+in vec4 rot;
+in float val;
+in vec3 inst_pos;
+in int axis;
+
+flat out vec4 finalColor;
+
+vec3 rotate(vec3 vec, vec4 quat)
+{
+ /* The quaternion representation here stores the w component in the first index */
+ return vec + 2.0 * cross(quat.yzw, cross(quat.yzw, vec) + quat.x * vec);
+}
+
+float mul_project_m4_v3_zfac(in vec3 co)
+{
+ return (ViewProjectionMatrix[0][3] * co.x) +
+ (ViewProjectionMatrix[1][3] * co.y) +
+ (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatrix[3][3];
+}
+
+void main()
+{
+ float pix_size = mul_project_m4_v3_zfac(pos) * pixel_size;
+
+ if (screen_space == 1) {
+ gl_Position = ModelViewMatrix * vec4(pos, 1.0) + vec4(inst_pos * pix_size * draw_size, 0.0);
+ gl_Position = ProjectionMatrix * gl_Position;
+ }
+ else {
+ int size = draw_size;
+
+ if (axis > -1) {
+ size *= 2;
+ }
+
+ gl_Position = ModelViewProjectionMatrix * vec4(pos + rotate(inst_pos * pix_size * size, rot), 1.0);
+ }
+
+#ifdef USE_AXIS
+ finalColor.rgb = vec3(0.0);
+ finalColor[axis] = 1.0;
+#else
+ if (val < 0.0) {
+ finalColor.rgb = color;
+ }
+ else {
+ finalColor.rgb = texture(ramp, val).rgb;
+ }
+#endif
+
+ finalColor.a = 1.0;
+}
diff --git a/source/blender/draw/modes/shaders/paint_texture_frag.glsl b/source/blender/draw/modes/shaders/paint_texture_frag.glsl
new file mode 100644
index 00000000000..18c58a54dca
--- /dev/null
+++ b/source/blender/draw/modes/shaders/paint_texture_frag.glsl
@@ -0,0 +1,11 @@
+
+in vec2 uv_interp;
+out vec4 fragColor;
+
+uniform sampler2D image;
+
+
+void main()
+{
+ fragColor = texture(image, uv_interp);
+}
diff --git a/source/blender/draw/modes/shaders/paint_texture_vert.glsl b/source/blender/draw/modes/shaders/paint_texture_vert.glsl
new file mode 100644
index 00000000000..4ce12e048fa
--- /dev/null
+++ b/source/blender/draw/modes/shaders/paint_texture_vert.glsl
@@ -0,0 +1,15 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 uv;
+in vec3 pos;
+
+out vec2 uv_interp;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ uv_interp = uv;
+
+}
diff --git a/source/blender/draw/modes/shaders/paint_vert_frag.glsl b/source/blender/draw/modes/shaders/paint_vert_frag.glsl
new file mode 100644
index 00000000000..c22e1c04b96
--- /dev/null
+++ b/source/blender/draw/modes/shaders/paint_vert_frag.glsl
@@ -0,0 +1,26 @@
+
+flat in int finalFlag;
+out vec4 fragColor;
+
+#define VERTEX_SELECTED (1 << 0)
+#define VERTEX_HIDE (1 << 4)
+
+void main()
+{
+ if (bool(finalFlag & VERTEX_HIDE)) {
+ discard;
+ }
+
+ vec2 centered = gl_PointCoord - vec2(0.5);
+ float dist_squared = dot(centered, centered);
+ const float rad_squared = 0.25;
+ const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 colUnsel = vec4(0.5, 0.5, 0.5, 1.0);
+
+ // round point with jaggy edges
+ if (dist_squared > rad_squared) {
+ discard;
+ }
+
+ fragColor = bool(finalFlag & VERTEX_SELECTED) ? colSel : colUnsel;
+}
diff --git a/source/blender/draw/modes/shaders/paint_wire_frag.glsl b/source/blender/draw/modes/shaders/paint_wire_frag.glsl
new file mode 100644
index 00000000000..e4214a4c6d1
--- /dev/null
+++ b/source/blender/draw/modes/shaders/paint_wire_frag.glsl
@@ -0,0 +1,24 @@
+
+flat in int finalFlag;
+out vec4 fragColor;
+
+#define VERTEX_SELECTED (1 << 0)
+#define VERTEX_HIDE (1 << 4)
+
+void main()
+{
+ if (bool(finalFlag & VERTEX_HIDE)) {
+ discard;
+ }
+
+#ifdef VERTEX_MODE
+ vec4 colSel = colorEdgeSelect;
+ colSel.rgb = clamp(colSel.rgb - 0.2, 0.0, 1.0);
+#else
+ const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0);
+#endif
+
+ const vec4 colUnsel = vec4(0.5, 0.5, 0.5, 1.0);
+
+ fragColor = bool(finalFlag & VERTEX_SELECTED) ? colSel : colUnsel;
+}
diff --git a/source/blender/draw/modes/shaders/paint_wire_vert.glsl b/source/blender/draw/modes/shaders/paint_wire_vert.glsl
new file mode 100644
index 00000000000..253c21745e2
--- /dev/null
+++ b/source/blender/draw/modes/shaders/paint_wire_vert.glsl
@@ -0,0 +1,14 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in int data;
+
+flat out int finalFlag;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ finalFlag = data;
+}
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 5852ee72b19..0ebd556a0f5 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -68,6 +68,8 @@
#include "BKE_nla.h"
#include "BKE_context.h"
+#include "GPU_immediate.h"
+
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
@@ -76,7 +78,6 @@
#include "ED_keyframing.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -119,11 +120,10 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
+ UI_draw_roundbox_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
}
@@ -141,13 +141,19 @@ static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale
View2D *v2d = &ac->ar->v2d;
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
-
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fv(color);
+
/* no rounded corner - just rectangular box */
- glRectf(offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+ immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+
+ immUnbindProgram();
}
/* helper method to test if group colors should be drawn */
@@ -224,13 +230,19 @@ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, f
View2D *v2d = &ac->ar->v2d;
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fv(color);
/* no rounded corners - just rectangular box */
- glRectf(offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+ immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+
+ immUnbindProgram();
}
/* Indention + Offset ------------------------------------------- */
@@ -421,14 +433,13 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
/* rounded corners on LHS only
* - top and bottom
* - special hack: make the top a bit higher, since we are first...
*/
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
- UI_draw_roundbox_gl_mode(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
+ UI_draw_roundbox_3fvAlpha(true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
}
/* name for summary entries */
@@ -617,7 +628,7 @@ static bAnimChannelType ACF_SCENE =
static int acf_object_icon(bAnimListElem *ale)
{
- Base *base = (Base *)ale->data;
+ BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
/* icon depends on object-type */
@@ -652,7 +663,7 @@ static int acf_object_icon(bAnimListElem *ale)
/* name for object */
static void acf_object_name(bAnimListElem *ale, char *name)
{
- Base *base = (Base *)ale->data;
+ BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
/* just copy the name... */
@@ -672,7 +683,7 @@ static bool acf_object_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN
/* check if some setting exists for this channel */
static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
- Base *base = (Base *)ale->data;
+ BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
switch (setting) {
@@ -729,7 +740,7 @@ static int acf_object_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
/* get pointer to the setting */
static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Base *base = (Base *)ale->data;
+ BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
/* clear extra return data first */
@@ -814,11 +825,10 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
+ UI_draw_roundbox_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
}
/* name for group entries */
@@ -1071,11 +1081,10 @@ static void acf_nla_controls_backdrop(bAnimContext *ac, bAnimListElem *ale, floa
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
- /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+ /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5);
+ UI_draw_roundbox_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
}
/* name for nla controls expander entries */
@@ -2018,7 +2027,7 @@ static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
- return PART_DS_EXPAND;
+ return 0;
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
@@ -2036,22 +2045,18 @@ static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
}
/* get pointer to the setting */
-static void *acf_dspart_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dspart_setting_ptr(bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting, short *type)
{
- ParticleSettings *part = (ParticleSettings *)ale->data;
-
/* clear extra return data first */
*type = 0;
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(part->flag, type);
+ return NULL;
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (part->adt)
- return GET_ACF_FLAG_PTR(part->adt->flag, type);
return NULL;
default: /* unsupported */
@@ -3420,24 +3425,20 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y
*/
nla_action_get_color(adt, (bAction *)ale->data, color);
- if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
- /* Yes, the color vector has 4 components, BUT we only want to be using 3 of them! */
- glColor3fv(color);
- }
- else {
- float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
- glColor4f(color[0], color[1], color[2], alpha);
- }
-
- /* only on top left corner, to show that this channel sits on top of the preceding ones
+ if (adt && (adt->flag & ADT_NLA_EDIT_ON))
+ color[3] = 1.0f;
+ else
+ color[3] = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
+
+ /* only on top left corner, to show that this channel sits on top of the preceding ones
* while still linking into the action line strip to the right
*/
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT);
-
+
/* draw slightly shifted up vertically to look like it has more separation from other channels,
* but we then need to slightly shorten it so that it doesn't look like it overlaps
*/
- UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8);
+ UI_draw_roundbox_4fv(true, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8, color);
}
/* name for nla action entries */
@@ -3861,15 +3862,20 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* for F-Curves, draw color-preview of curve behind checkbox */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
FCurve *fcu = (FCurve *)ale->data;
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever
* color the curve has stored
*/
- glColor3fv(fcu->color);
+ immUniformColor3fv(fcu->color);
/* just a solid color rect
*/
- glRectf(offset, yminc, offset + ICON_WIDTH, ymaxc);
+ immRectf(pos, offset, yminc, offset + ICON_WIDTH, ymaxc);
+
+ immUnbindProgram();
}
/* icon is drawn as widget now... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
@@ -3894,27 +3900,39 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
if (acf->name && !achannel_is_being_renamed(ac, acf, channel_index)) {
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
-
+ unsigned char col[4];
+
/* set text color */
/* XXX: if active, highlight differently? */
+
if (selected)
- UI_ThemeColor(TH_TEXT_HI);
+ UI_GetThemeColor4ubv(TH_TEXT_HI, col);
else
- UI_ThemeColor(TH_TEXT);
-
+ UI_GetThemeColor4ubv(TH_TEXT, col);
+
/* get name */
acf->name(ale, name);
offset += 3;
- UI_fontstyle_draw_simple(fstyle, offset, ytext, name);
+ UI_fontstyle_draw_simple(fstyle, offset, ytext, name, col);
/* draw red underline if channel is disabled */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* FIXME: replace hardcoded color here, and check on extents! */
- glColor3f(1.0f, 0.0f, 0.0f);
- glLineWidth(2.0);
- fdrawline((float)(offset), yminc,
- (float)(v2d->cur.xmax), yminc);
+ immUniformColor3f(1.0f, 0.0f, 0.0f);
+
+ glLineWidth(2.0f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, (float)offset, yminc);
+ immVertex2f(pos, (float)v2d->cur.xmax, yminc);
+ immEnd();
+
+ immUnbindProgram();
}
}
@@ -3928,10 +3946,13 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
short draw_sliders = 0;
float ymin_ofs = 0.0f;
float color[3];
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* get and set backdrop color */
acf->get_backdrop_color(ac, ale, color);
- glColor3fv(color);
+ immUniformColor3fv(color);
/* check if we need to show the sliders */
if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
@@ -3989,7 +4010,9 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
* - starts from the point where the first toggle/slider starts,
* - ends past the space that might be reserved for a scroller
*/
- glRectf(v2d->cur.xmax - (float)offset, yminc + ymin_ofs, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+ immRectf(pos, v2d->cur.xmax - (float)offset, yminc + ymin_ofs, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+
+ immUnbindProgram();
}
}
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 117b8549712..22578b6a518 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -57,6 +57,7 @@
#include "BKE_context.h"
#include "BKE_mask.h"
#include "BKE_global.h"
+#include "BKE_scene.h"
#include "UI_view2d.h"
@@ -2682,31 +2683,31 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
{
bDopeSheet *ads = (bDopeSheet *)ac->data;
Scene *sce = (Scene *)ads->source;
- Base *base = (Base *)ale->data;
+ BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
AnimData *adt = ob->adt;
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
- base->flag ^= SELECT;
- ob->flag = base->flag;
+ base->flag_legacy ^= SELECT;
+ BKE_scene_base_flag_sync_from_base(base);
if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
- Base *b;
+ BaseLegacy *b;
/* deselect all */
/* TODO: should this deselect all other types of channels too? */
for (b = sce->base.first; b; b = b->next) {
- b->flag &= ~SELECT;
- b->object->flag = b->flag;
+ b->flag_legacy &= ~SELECT;
+ BKE_scene_base_flag_sync_from_base(b);
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}
/* select object now */
- base->flag |= SELECT;
+ base->flag_legacy |= SELECT;
ob->flag |= SELECT;
if (adt) adt->flag |= ADT_UI_SELECTED;
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index a6febdb575e..6127f77d7d6 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -58,12 +58,13 @@
#include "RNA_access.h"
-#include "BIF_gl.h"
-
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
/* *************************************************** */
/* CURRENT FRAME DRAWING */
@@ -71,13 +72,17 @@
static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const bool time)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- float xscale, yscale, x, y;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned char col[4];
+ float xscale, x, y;
char numstr[32] = " t"; /* t is the character to start replacing from */
int slen;
/* because the frame number text is subject to the same scaling as the contents of the view */
- UI_view2d_scale_get(v2d, &xscale, &yscale);
- glScalef(1.0f / xscale, 1.0f, 1.0f);
+ UI_view2d_scale_get(v2d, &xscale, NULL);
+ gpuPushMatrix();
+ gpuScale2f(1.0f / xscale, 1.0f);
/* get timecode string
* - padding on str-buf passed so that it doesn't sit on the frame indicator
@@ -96,17 +101,21 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const
/* get starting coordinates for drawing */
x = cfra * xscale;
y = 0.9f * U.widget_unit;
-
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* draw green box around/behind text */
- UI_ThemeColorShade(TH_CFRAME, 0);
- glRectf(x, y, x + slen, y + 0.75f * U.widget_unit);
-
- /* draw current frame number - black text */
- UI_ThemeColor(TH_TEXT);
- UI_fontstyle_draw_simple(fstyle, x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr);
-
+ immUniformThemeColorShade(TH_CFRAME, 0);
+
+ immRectf(pos, x, y, x + slen, y + 0.75f * U.widget_unit);
+ immUnbindProgram();
+
+ /* draw current frame number */
+ UI_GetThemeColor4ubv(TH_TEXT, col);
+ UI_fontstyle_draw_simple(fstyle, x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr, col);
+
/* restore view transform */
- glScalef(xscale, 1.0, 1.0);
+ gpuPopMatrix();
}
/* General call for drawing current frame indicator in animation editor */
@@ -114,18 +123,24 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
{
Scene *scene = CTX_data_scene(C);
- /* Draw a light green line to indicate current frame */
- UI_ThemeColor(TH_CFRAME);
-
const float time = scene->r.cfra + scene->r.subframe;
const float x = (float)(time * scene->r.framelen);
glLineWidth((flag & DRAWCFRA_WIDE) ? 3.0 : 2.0);
- glBegin(GL_LINES);
- glVertex2f(x, v2d->cur.ymin - 500.0f); /* XXX arbitrary... want it go to bottom */
- glVertex2f(x, v2d->cur.ymax);
- glEnd();
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* Draw a light green line to indicate current frame */
+ immUniformThemeColor(TH_CFRAME);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, x, v2d->cur.ymin - 500.0f); /* XXX arbitrary... want it go to bottom */
+ immVertex2f(pos, x, v2d->cur.ymax);
+ immEnd();
+ immUnbindProgram();
/* Draw current frame number in a little box */
if (flag & DRAWCFRA_SHOW_NUMBOX) {
@@ -147,17 +162,24 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
if (PRVRANGEON) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
-
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+
/* only draw two separate 'curtains' if there's no overlap between them */
if (PSFRA < PEFRA + end_frame_width) {
- glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
- glRectf((float)(PEFRA + end_frame_width), v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
+ immRectf(pos, (float)(PEFRA + end_frame_width), v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
else {
- glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
-
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 2f73eb6b71c..5b7ae216c55 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -74,6 +74,7 @@
#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_layer_types.h"
#include "MEM_guardedalloc.h"
@@ -90,6 +91,7 @@
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
@@ -130,11 +132,11 @@ static void animedit_get_yscale_factor(bAnimContext *ac)
/* Note: there's a similar function in key.c (BKE_key_from_object) */
static Key *actedit_get_shapekeys(bAnimContext *ac)
{
- Scene *scene = ac->scene;
+ SceneLayer *sl = ac->scene_layer;
Object *ob;
Key *key;
- ob = OBACT;
+ ob = OBACT_NEW;
if (ob == NULL)
return NULL;
@@ -378,8 +380,9 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->scene = scene;
if (scene) {
ac->markers = ED_context_get_markers(C);
- ac->obact = (scene->basact) ? scene->basact->object : NULL;
}
+ ac->scene_layer = CTX_data_scene_layer(C);
+ ac->obact = (ac->scene_layer->basact) ? ac->scene_layer->basact->object : NULL;
ac->sa = sa;
ac->ar = ar;
ac->sl = sl;
@@ -1683,15 +1686,16 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
if (ads->filterflag & ADS_FILTER_GP_3DONLY) {
Scene *scene = (Scene *)ads->source;
+ SceneLayer *sl = (SceneLayer *)ac->scene_layer;
Base *base;
-
+
/* Active scene's GPencil block first - No parent item needed... */
if (scene->gpd) {
items += animdata_filter_gpencil_data(anim_data, ads, scene->gpd, filter_mode);
}
/* Objects in the scene */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
/* Only consider this object if it has got some GP data (saving on all the other tests) */
if (base->object && base->object->gpd) {
Object *ob = base->object;
@@ -1707,14 +1711,14 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((scene->lay & (ob->lay | base->lay)) == 0) continue;
+ if ((base->flag & BASE_VISIBLED) == 0) continue;
/* outliner restrict-flag */
if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
}
/* check selection and object type filters */
- if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == scene->basact)*/) ) {
+ if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == scene->basact)*/) ) {
/* only selected should be shown */
continue;
}
@@ -2629,7 +2633,7 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
/* check if filtering by selection */
// XXX: double-check on this - most of the time, a lot of tools need to filter out these channels!
- if (ANIMCHANNEL_SELOK((base->flag & SELECT))) {
+ if (ANIMCHANNEL_SELOK((base->flag & BASE_SELECTED))) {
/* check if filtering by active status */
if (ANIMCHANNEL_ACTIVEOK(ob)) {
ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob);
@@ -2853,7 +2857,7 @@ static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *a
}
/* Helper for animdata_filter_dopesheet() - For checking if an object should be included or not */
-static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base, int filter_mode)
+static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_mode)
{
Object *ob = base->object;
@@ -2871,7 +2875,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((scene->lay & (ob->lay | base->lay)) == 0)
+ if ((base->flag & BASE_VISIBLED) == 0)
return false;
/* outliner restrict-flag */
@@ -2906,7 +2910,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base
}
/* check selection and object type filters */
- if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/)) {
+ if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == sce->basact)*/)) {
/* only selected should be shown */
return false;
}
@@ -2934,15 +2938,15 @@ static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr)
}
/* Get a sorted list of all the bases - for inclusion in dopesheet (when drawing channels) */
-static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, Scene *scene, int filter_mode, size_t *r_usable_bases)
+static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, SceneLayer *sl, int filter_mode, size_t *r_usable_bases)
{
/* Create an array with space for all the bases, but only containing the usable ones */
- size_t tot_bases = BLI_listbase_count(&scene->base);
+ size_t tot_bases = BLI_listbase_count(&sl->object_bases);
size_t num_bases = 0;
Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
- for (Base *base = scene->base.first; base; base = base->next) {
- if (animdata_filter_base_is_ok(ads, scene, base, filter_mode)) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
sorted_bases[num_bases++] = base;
}
}
@@ -2960,8 +2964,9 @@ static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, Scene *scene, int
static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
{
Scene *scene = (Scene *)ads->source;
+ SceneLayer *sl = (SceneLayer *)ac->scene_layer;
size_t items = 0;
-
+
/* check that we do indeed have a scene */
if ((ads->source == NULL) || (GS(ads->source->name) != ID_SCE)) {
printf("Dope Sheet Error: No scene!\n");
@@ -2998,14 +3003,14 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
* - Don't do this if there's just a single object
*/
if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && !(ads->flag & ADS_FLAG_NO_DB_SORT) &&
- (scene->base.first != scene->base.last))
+ (sl->object_bases.first != sl->object_bases.last))
{
/* Filter list of bases (i.e. objects), sort them, then add their contents normally... */
// TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort...
Base **sorted_bases;
size_t num_bases;
- sorted_bases = animdata_filter_ds_sorted_bases(ads, scene, filter_mode, &num_bases);
+ sorted_bases = animdata_filter_ds_sorted_bases(ads, sl, filter_mode, &num_bases);
if (sorted_bases) {
/* Add the necessary channels for these bases... */
for (size_t i = 0; i < num_bases; i++) {
@@ -3022,8 +3027,8 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
/* Filter and add contents of each base (i.e. object) without them sorting first
* NOTE: This saves performance in cases where order doesn't matter
*/
- for (Base *base = scene->base.first; base; base = base->next) {
- if (animdata_filter_base_is_ok(ads, scene, base, filter_mode)) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
/* since we're still here, this object should be usable */
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index aafd7ebb1f9..7ec19d12fb6 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -36,13 +36,14 @@
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math_base.h"
+#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -56,9 +57,11 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_view2d.h"
@@ -348,19 +351,30 @@ static void draw_marker(
if (flag & DRAW_MARKERS_LINES)
#endif
{
- setlinestyle(3);
-
- if (marker->flag & SELECT)
- glColor4ub(255, 255, 255, 96);
- else
- glColor4ub(0, 0, 0, 96);
-
- glBegin(GL_LINES);
- glVertex2f(xpos + 0.5f, 12.0f);
- glVertex2f(xpos + 0.5f, (v2d->cur.ymax + 12.0f) * yscale);
- glEnd();
-
- setlinestyle(0);
+ VertexFormat *format = immVertexFormat();
+ uint pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ if (marker->flag & SELECT) {
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.38f);
+ }
+ else {
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.38f);
+ }
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, xpos + 0.5f, 12.0f);
+ immVertex2f(pos, xpos + 0.5f, (v2d->cur.ymax + 12.0f) * yscale);
+ immEnd();
+
+ immUnbindProgram();
}
/* 5 px to offset icon to align properly, space / pixels corrects for zoom */
@@ -380,19 +394,20 @@ static void draw_marker(
/* and the marker name too, shifted slightly to the top-right */
if (marker->name[0]) {
+ unsigned char text_col[4];
float x, y;
/* minimal y coordinate which wouldn't be occluded by scroll */
int min_y = 17.0f * UI_DPI_FAC;
if (marker->flag & SELECT) {
- UI_ThemeColor(TH_TEXT_HI);
+ UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
x = xpos + 4.0f * UI_DPI_FAC;
y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
y = max_ii(y, min_y);
}
else {
- UI_ThemeColor(TH_TEXT);
+ UI_GetThemeColor4ubv(TH_TEXT, text_col);
if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) {
x = xpos + 8.0f * UI_DPI_FAC;
y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
@@ -406,14 +421,11 @@ static void draw_marker(
#ifdef DURIAN_CAMERA_SWITCH
if (marker->camera && (marker->camera->restrictflag & OB_RESTRICT_RENDER)) {
- float col[4];
- glGetFloatv(GL_CURRENT_COLOR, col);
- col[3] = 0.4;
- glColor4fv(col);
+ text_col[3] = 100;
}
#endif
- UI_fontstyle_draw_simple(fstyle, x, y, marker->name);
+ UI_fontstyle_draw_simple(fstyle, x, y, marker->name, text_col);
}
}
@@ -440,21 +452,27 @@ void ED_markers_draw(const bContext *C, int flag)
v2d = UI_view2d_fromcontext(C);
if (flag & DRAW_MARKERS_MARGIN) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
const unsigned char shade[4] = {0, 0, 0, 16};
- glColor4ubv(shade);
+ immUniformColor4ubv(shade);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glRectf(v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y);
+ immRectf(pos, v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y);
glDisable(GL_BLEND);
+
+ immUnbindProgram();
}
/* no time correction for framelen! space is drawn with old values */
ypixels = BLI_rcti_size_y(&v2d->mask);
UI_view2d_scale_get(v2d, &xscale, &yscale);
- glScalef(1.0f / xscale, 1.0f, 1.0f);
+ gpuPushMatrix();
+ gpuScale2f(1.0f / xscale, 1.0f);
/* x-bounds with offset for text (adjust for long string, avoid checking string width) */
font_width_max = (10 * UI_DPI_FAC) / xscale;
@@ -477,7 +495,7 @@ void ED_markers_draw(const bContext *C, int flag)
}
}
- glScalef(xscale, 1.0f, 1.0f);
+ gpuPopMatrix();
}
/* ************************ Marker Wrappers API ********************* */
@@ -1125,6 +1143,7 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
if (camera) {
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base;
TimeMarker *marker;
int sel = 0;
@@ -1142,11 +1161,11 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
for (marker = markers->first; marker; marker = marker->next) {
if (marker->camera) {
if (marker->frame == cfra) {
- base = BKE_scene_base_find(scene, marker->camera);
+ base = BKE_scene_layer_base_find(sl, marker->camera);
if (base) {
- ED_base_object_select(base, sel);
+ ED_object_base_select(base, sel);
if (sel)
- ED_base_object_activate(C, base);
+ ED_object_base_activate(C, base);
}
}
}
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 5f675e690b9..5dca4be4de1 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -52,7 +52,8 @@
#include "BKE_fcurve.h"
-#include "BIF_gl.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -463,49 +464,15 @@ bool actkeyblock_is_valid(ActKeyBlock *ab, DLRBT_Tree *keys)
/* *************************** Keyframe Drawing *************************** */
-/* coordinates for diamond shape */
-static const float _unit_diamond_shape[4][2] = {
- {0.0f, 1.0f}, /* top vert */
- {1.0f, 0.0f}, /* mid-right */
- {0.0f, -1.0f}, /* bottom vert */
- {-1.0f, 0.0f} /* mid-left */
-};
-
-/* draw a simple diamond shape with OpenGL */
-void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, short key_type, short mode, float alpha)
+void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha,
+ unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id)
{
- static GLuint displist1 = 0;
- static GLuint displist2 = 0;
-
- /* initialize 2 display lists for diamond shape - one empty, one filled */
- if (displist1 == 0) {
- displist1 = glGenLists(1);
- glNewList(displist1, GL_COMPILE);
-
- glBegin(GL_LINE_LOOP);
- glVertex2fv(_unit_diamond_shape[0]);
- glVertex2fv(_unit_diamond_shape[1]);
- glVertex2fv(_unit_diamond_shape[2]);
- glVertex2fv(_unit_diamond_shape[3]);
- glEnd();
-
- glEndList();
- }
- if (displist2 == 0) {
- displist2 = glGenLists(1);
- glNewList(displist2, GL_COMPILE);
-
- glBegin(GL_QUADS);
- glVertex2fv(_unit_diamond_shape[0]);
- glVertex2fv(_unit_diamond_shape[1]);
- glVertex2fv(_unit_diamond_shape[2]);
- glVertex2fv(_unit_diamond_shape[3]);
- glEnd();
-
- glEndList();
- }
-
- /* tweak size of keyframe shape according to type of keyframe
+ bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
+ bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
+
+ BLI_assert(draw_fill || draw_outline);
+
+ /* tweak size of keyframe shape according to type of keyframe
* - 'proper' keyframes have key_type = 0, so get drawn at full size
*/
switch (key_type) {
@@ -513,120 +480,93 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel,
break;
case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
- hsize *= 0.85f;
+ size *= 0.85f;
break;
case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes (but by less than for breakdowns) */
- //hsize *= 0.72f;
- hsize *= 0.95f;
+ size *= 0.925f;
break;
case BEZT_KEYTYPE_EXTREME: /* slightly larger */
- hsize *= 1.2f;
+ size *= 1.2f;
break;
default:
- hsize -= 0.5f * key_type;
- break;
+ size -= 0.5f * key_type;
}
-
- /* adjust view transform before starting */
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, hsize, 1.0f);
-
- /* anti-aliased lines for more consistent appearance */
- glEnable(GL_LINE_SMOOTH);
-
+
+ unsigned char fill_col[4];
+ unsigned char outline_col[4];
+
/* draw! */
- if (ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH)) {
- float inner_col[4];
-
+ if (draw_fill) {
/* get interior colors from theme (for selected and unselected only) */
switch (key_type) {
case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */
- {
- if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_BREAKDOWN_SELECT, inner_col);
- else UI_GetThemeColor4fv(TH_KEYTYPE_BREAKDOWN, inner_col);
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_BREAKDOWN_SELECT : TH_KEYTYPE_BREAKDOWN, fill_col);
break;
- }
case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */
- {
- if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_EXTREME_SELECT, inner_col);
- else UI_GetThemeColor4fv(TH_KEYTYPE_EXTREME, inner_col);
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_EXTREME_SELECT : TH_KEYTYPE_EXTREME, fill_col);
break;
- }
case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */
- {
- if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_JITTER_SELECT, inner_col);
- else UI_GetThemeColor4fv(TH_KEYTYPE_JITTER, inner_col);
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_JITTER_SELECT : TH_KEYTYPE_JITTER, fill_col);
break;
- }
case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
- {
/* XXX: Should these get their own theme options instead? */
- if (sel) UI_GetThemeColorShade4fv(TH_STRIP_SELECT, 35, inner_col);
- else UI_GetThemeColorShade4fv(TH_STRIP, 50, inner_col);
-
- inner_col[3] = 1.0f; /* full opacity, to avoid problems with visual glitches */
+ if (sel) UI_GetThemeColorShade3ubv(TH_STRIP_SELECT, 35, fill_col);
+ else UI_GetThemeColorShade3ubv(TH_STRIP, 50, fill_col);
+ fill_col[3] = 255; /* full opacity, to avoid problems with visual glitches */
break;
- }
case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
default:
- {
- if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_KEYFRAME_SELECT, inner_col);
- else UI_GetThemeColor4fv(TH_KEYTYPE_KEYFRAME, inner_col);
- break;
- }
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);
}
/* NOTE: we don't use the straight alpha from the theme, or else effects such as
* graying out protected/muted channels doesn't work correctly!
*/
- inner_col[3] *= alpha;
- glColor4fv(inner_col);
-
- /* draw the "filled in" interior poly now */
- glCallList(displist2);
+ fill_col[3] *= alpha;
+
+ if (!draw_outline) {
+ /* force outline color to match */
+ outline_col[0] = fill_col[0];
+ outline_col[1] = fill_col[1];
+ outline_col[2] = fill_col[2];
+ outline_col[3] = fill_col[3];
+ }
}
-
- if (ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH)) {
- float border_col[4];
-
+
+ if (draw_outline) {
/* exterior - black frame */
- if (sel) UI_GetThemeColor4fv(TH_KEYBORDER_SELECT, border_col);
- else UI_GetThemeColor4fv(TH_KEYBORDER, border_col);
-
- border_col[3] *= alpha;
- glColor4fv(border_col);
-
- glCallList(displist1);
+ UI_GetThemeColor4ubv(sel ? TH_KEYBORDER_SELECT : TH_KEYBORDER, outline_col);
+ outline_col[3] *= alpha;
+
+ if (!draw_fill) {
+ /* fill color needs to be (outline.rgb, 0) */
+ fill_col[0] = outline_col[0];
+ fill_col[1] = outline_col[1];
+ fill_col[2] = outline_col[2];
+ fill_col[3] = 0;
+ }
}
-
- glDisable(GL_LINE_SMOOTH);
-
- /* restore view transform */
- glScalef(xscale / hsize, 1.0f / hsize, 1.0f);
- glTranslatef(-x, -y, 0.0f);
+
+ immAttrib1f(size_id, size);
+ immAttrib4ubv(color_id, fill_col);
+ immAttrib4ubv(outline_color_id, outline_col);
+ immVertex2f(pos_id, x, y);
}
static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, float yscale_fac, bool channelLocked)
{
- ActKeyColumn *ak;
- ActKeyBlock *ab;
- float alpha;
- float xscale;
-
- const float iconsize = (U.widget_unit / 4.0f) * yscale_fac;
- const float mhsize = iconsize * 0.7f;
+ const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
+ const float half_icon_sz = 0.5f * icon_sz;
+ const float smaller_sz = 0.35f * icon_sz;
glEnable(GL_BLEND);
- /* get View2D scaling factor */
- UI_view2d_scale_get(v2d, &xscale, NULL);
-
/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
/* TODO: allow this opacity factor to be themed? */
- alpha = (channelLocked) ? 0.25f : 1.0f;
+ float alpha = channelLocked ? 0.25f : 1.0f;
/* draw keyblocks */
if (blocks) {
@@ -644,45 +584,59 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
sel_mhcol[3] *= 0.8f;
copy_v4_v4(unsel_mhcol, unsel_color);
unsel_mhcol[3] *= 0.8f;
-
+
+ unsigned int pos_id = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */
- for (ab = blocks->first; ab; ab = ab->next) {
+ for (ActKeyBlock *ab = blocks->first; ab; ab = ab->next) {
if (actkeyblock_is_valid(ab, keys)) {
if (ab->flag & ACTKEYBLOCK_FLAG_MOVING_HOLD) {
/* draw "moving hold" long-keyframe block - slightly smaller */
- if (ab->sel)
- glColor4fv(sel_mhcol);
- else
- glColor4fv(unsel_mhcol);
-
- glRectf(ab->start, ypos - mhsize, ab->end, ypos + mhsize);
+ immUniformColor4fv(ab->sel ? sel_mhcol : unsel_mhcol);
+ immRectf(pos_id, ab->start, ypos - smaller_sz, ab->end, ypos + smaller_sz);
}
else {
/* draw standard long-keyframe block */
- if (ab->sel)
- glColor4fv(sel_color);
- else
- glColor4fv(unsel_color);
-
- glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize);
+ immUniformColor4fv(ab->sel ? sel_color : unsel_color);
+ immRectf(pos_id, ab->start, ypos - half_icon_sz, ab->end, ypos + half_icon_sz);
}
}
}
+ immUnbindProgram();
}
- /* draw keys */
if (keys) {
- for (ak = keys->first; ak; ak = ak->next) {
+ /* count keys */
+ unsigned int key_ct = 0;
+ for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
/* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
* - this might give some improvements, since we current have to flip between view/region matrices
*/
- if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0)
- continue;
-
- /* draw using OpenGL - uglier but faster */
- /* NOTE1: a previous version of this didn't work nice for some intel cards
- * NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */
- draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha);
+ if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax))
+ key_ct++;
+ }
+
+ if (key_ct > 0) {
+ /* draw keys */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int size_id = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color_id = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ unsigned int outline_color_id = VertexFormat_add_attrib(format, "outlineColor", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, key_ct);
+
+ for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
+ if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) {
+ draw_keyframe_shape(ak->cfra, ypos, icon_sz, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha,
+ pos_id, size_id, color_id, outline_color_id);
+ }
+ }
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
}
}
@@ -938,7 +892,7 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *bl
int filter;
bAnimListElem dummychan = {NULL};
- Base dummybase = {NULL};
+ BaseLegacy dummybase = {NULL};
if (ob == NULL)
return;
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 4571df0f077..f4922fec385 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -193,7 +193,7 @@ static short ob_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Object *o
int ret = 0;
bAnimListElem dummychan = {NULL};
- Base dummybase = {NULL};
+ BaseLegacy dummybase = {NULL};
if (ob == NULL)
return 0;
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 190b0610059..8c1083dc290 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -37,7 +37,7 @@ struct wmOperatorType;
struct bContext;
struct Scene;
struct Object;
-struct Base;
+struct BaseLegacy;
struct bAction;
struct bPoseChannel;
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 1c342657eec..0dc97483dfc 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -50,6 +50,7 @@
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -400,7 +401,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
}
/* Free the old object data */
- ED_base_object_free_and_unlink(bmain, scene, base);
+ ED_base_object_free_and_unlink(bmain, scene, base->object);
}
}
CTX_DATA_END;
@@ -579,6 +580,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Object *oldob, *newob;
Base *oldbase, *newbase;
@@ -602,14 +604,18 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* TODO: use context iterators for this? */
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
{
- if (base->object == obedit) base->flag |= SELECT;
- else base->flag &= ~SELECT;
+ if (base->object == obedit) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ else {
+ ED_object_base_select(base, BA_DESELECT);
+ }
}
CTX_DATA_END;
/* 1) store starting settings and exit editmode */
oldob = obedit;
- oldbase = BASACT;
+ oldbase = sl->basact;
oldob->mode &= ~OB_MODE_POSE;
//oldbase->flag &= ~OB_POSEMODE;
@@ -617,13 +623,13 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
ED_armature_edit_free(obedit->data);
/* 2) duplicate base */
- newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
+ newbase = ED_object_add_duplicate(bmain, scene, sl, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
DAG_relations_tag_update(bmain);
newob = newbase->object;
- newbase->flag &= ~SELECT;
-
-
+ newbase->flag &= ~BASE_SELECTED;
+
+
/* 3) remove bones that shouldn't still be around on both armatures */
separate_armature_bones(oldob, 1);
separate_armature_bones(newob, 0);
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index ed44214591c..8db1cb7d6c0 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -180,7 +180,7 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel)
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
if (hits > 0)
- return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel, true);
+ return get_bone_from_selectbuffer(vc.scene, vc.scene_layer->basact, buffer, hits, findunsel, true);
return NULL;
}
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index bba486bc65c..957048bcc42 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -33,6 +33,7 @@
#include "BKE_context.h"
#include "BKE_sketch.h"
+#include "BKE_layer.h"
#include "RNA_define.h"
#include "RNA_access.h"
@@ -53,6 +54,10 @@
#include "WM_types.h"
#include "GPU_select.h"
+#include "GPU_matrix.h"
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
typedef int (*GestureDetectFct)(bContext *, SK_Gesture *, SK_Sketch *);
typedef void (*GestureApplyFct)(bContext *, SK_Gesture *, SK_Sketch *);
@@ -140,9 +145,8 @@ static RigGraph *TEMPLATE_RIGG = NULL;
void BIF_makeListTemplates(const bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
- Base *base;
int index = 0;
if (TEMPLATES_HASH != NULL) {
@@ -152,9 +156,8 @@ void BIF_makeListTemplates(const bContext *C)
TEMPLATES_HASH = BLI_ghash_int_new("makeListTemplates gh");
TEMPLATES_CURRENT = 0;
- for (base = FIRSTBASE; base; base = base->next) {
- Object *ob = base->object;
-
+ FOREACH_OBJECT(sl, ob)
+ {
if (ob != obedit && ob->type == OB_ARMATURE) {
index++;
BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
@@ -164,6 +167,7 @@ void BIF_makeListTemplates(const bContext *C)
}
}
}
+ FOREACH_OBJECT_END
}
#if 0 /* UNUSED */
@@ -420,7 +424,6 @@ static void sk_retargetStroke(bContext *C, SK_Stroke *stk)
}
/**************************************************************/
-
static void sk_cancelStroke(SK_Sketch *sketch)
{
if (sketch->active_stroke != NULL) {
@@ -435,17 +438,33 @@ static float sk_clampPointSize(SK_Point *pt, float size)
return max_ff(size * pt->size, size / 2);
}
-static void sk_drawPoint(GLUquadric *quad, SK_Point *pt, float size)
+static void sk_drawPoint(SK_Point *pt, float size, float color[4])
{
- glTranslate3fv(pt->p);
- gluSphere(quad, sk_clampPointSize(pt, size), 8, 8);
+ Batch *batch = NULL;
+
+ gpuTranslate3fv(pt->p);
+
+ gpuPushMatrix();
+
+ gpuScaleUniform(sk_clampPointSize(pt, size));
+
+ batch = Batch_get_sphere(0);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform4fv(batch, "color", color);
+
+ Batch_draw(batch);
+
+ gpuPopMatrix();
}
-static void sk_drawEdge(GLUquadric *quad, SK_Point *pt0, SK_Point *pt1, float size)
+static void sk_drawEdge(SK_Point *pt0, SK_Point *pt1, float size, float color[4])
{
- float vec1[3], vec2[3] = {0, 0, 1}, axis[3];
+ float vec1[3], vec2[3] = { 0, 0, 1 }, axis[3];
float angle, length;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
sub_v3_v3v3(vec1, pt1->p, pt0->p);
length = normalize_v3(vec1);
cross_v3_v3v3(axis, vec2, vec1);
@@ -454,19 +473,26 @@ static void sk_drawEdge(GLUquadric *quad, SK_Point *pt0, SK_Point *pt1, float si
axis[1] = 1;
}
- angle = angle_normalized_v3v3(vec2, vec1);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
- glRotate3fv(angle * (float)(180.0 / M_PI) + 180.0f, axis);
+ angle = angle_normalized_v3v3(vec2, vec1);
+ gpuRotate3fv(angle * (float)(180.0 / M_PI) + 180.0f, axis);
+ imm_draw_cylinder_fill_3d(pos, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8);
- gluCylinder(quad, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8);
+ immUnbindProgram();
}
-static void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float height)
+static void sk_drawNormal(SK_Point *pt, float size, float height)
{
- float vec2[3] = {0, 0, 1}, axis[3];
+ float vec2[3] = { 0, 0, 1 }, axis[3];
float angle;
-
- glPushMatrix();
+ float color[3] = { 0.0f, 1.0f, 1.0f };
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ gpuPushMatrix();
cross_v3_v3v3(axis, vec2, pt->no);
@@ -474,41 +500,44 @@ static void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float heig
axis[1] = 1;
}
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+
angle = angle_normalized_v3v3(vec2, pt->no);
+ gpuRotate3fv(angle * (float)(180.0 / M_PI), axis);
- glRotate3fv(angle * (float)(180.0 / M_PI), axis);
+ imm_draw_cylinder_fill_3d(pos, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2);
- glColor3f(0, 1, 1);
- gluCylinder(quad, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2);
+ immUnbindProgram();
- glPopMatrix();
+ gpuPopMatrix();
}
static void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end)
{
float rgb[3];
+ float zero_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
int i;
- GLUquadric *quad = gluNewQuadric();
- gluQuadricNormals(quad, GLU_SMOOTH);
if (id != -1) {
GPU_select_load_id(id);
for (i = 0; i < stk->nb_points; i++) {
- glPushMatrix();
+ gpuPushMatrix();
- sk_drawPoint(quad, stk->points + i, 0.1);
+ sk_drawPoint(stk->points + i, 0.1, zero_color);
if (i > 0) {
- sk_drawEdge(quad, stk->points + i - 1, stk->points + i, 0.1);
+ sk_drawEdge(stk->points + i - 1, stk->points + i, 0.1, zero_color);
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
else {
- float d_rgb[3] = {1, 1, 1};
+ float d_rgb[3] = { 1, 1, 1 };
+ float tmp_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
copy_v3_v3(rgb, color);
sub_v3_v3(d_rgb, rgb);
@@ -517,48 +546,44 @@ static void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int
for (i = 0; i < stk->nb_points; i++) {
SK_Point *pt = stk->points + i;
- glPushMatrix();
+ gpuPushMatrix();
if (pt->type == PT_EXACT) {
- glColor3f(0, 0, 0);
- sk_drawPoint(quad, pt, 0.15);
- sk_drawNormal(quad, pt, 0.05, 0.9);
+ sk_drawPoint(pt, 0.15, zero_color);
+ sk_drawNormal(pt, 0.05, 0.9);
}
if (i >= start && i <= end) {
- glColor3f(0.3, 0.3, 0.3);
+ copy_v4_fl4(tmp_color, 0.3f, 0.3f, 0.3f, 1.0f);
}
else {
- glColor3fv(rgb);
+ copy_v4_fl4(tmp_color, rgb[0], rgb[1], rgb[2], 1.0f);
}
if (pt->type != PT_EXACT) {
-
- sk_drawPoint(quad, pt, 0.1);
+ sk_drawPoint(pt, 0.1, tmp_color);
}
if (i > 0) {
- sk_drawEdge(quad, pt - 1, pt, 0.1);
+ sk_drawEdge(pt - 1, pt, 0.1, tmp_color);
}
- glPopMatrix();
+ gpuPopMatrix();
add_v3_v3(rgb, d_rgb);
}
}
- gluDeleteQuadric(quad);
}
static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *iter, NextSubdivisionFunc next_subdividion)
{
SK_Stroke *stk = ((SK_StrokeIterator *)iter)->stroke;
float head[3], tail[3];
+ float color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
int bone_start = 0;
int end = iter->length;
int index;
- GLUquadric *quad = gluNewQuadric();
- gluQuadricNormals(quad, GLU_SMOOTH);
iter->head(iter);
copy_v3_v3(head, iter->p);
@@ -567,22 +592,19 @@ static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *ite
while (index != -1) {
SK_Point *pt = stk->points + index;
- glPushMatrix();
+ gpuPushMatrix();
- glColor3f(0, 1, 0);
- sk_drawPoint(quad, pt, 0.15);
+ sk_drawPoint(pt, 0.15, color);
- sk_drawNormal(quad, pt, 0.05, 0.9);
+ sk_drawNormal(pt, 0.05, 0.9);
- glPopMatrix();
+ gpuPopMatrix();
copy_v3_v3(head, tail);
bone_start = index; // start next bone from current index
index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
}
-
- gluDeleteQuadric(quad);
}
static void sk_drawStrokeSubdivision(ToolSettings *toolsettings, SK_Stroke *stk)
@@ -974,7 +996,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
* the ideal would be to call this function only at the beginning of the snap operation,
* or at the beginning of the operator itself */
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), 0,
+ CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), 0,
CTX_wm_region(C), CTX_wm_view3d(C));
float mvalf[2] = {UNPACK2(dd->mval)};
@@ -1975,9 +1997,9 @@ static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch,
GPU_select_load_id(-1);
}
else {
- float selected_rgb[3] = {1, 0, 0};
- float unselected_rgb[3] = {1, 0.5, 0};
-
+ float selected_rgb[3] = { 1, 0, 0 };
+ float unselected_rgb[3] = { 1, 0.5, 0 };
+ float tmp_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (stk = sketch->strokes.first; stk; stk = stk->next) {
int start = -1;
int end = -1;
@@ -2001,75 +2023,37 @@ static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch,
}
if (last != NULL) {
- GLUquadric *quad = gluNewQuadric();
- gluQuadricNormals(quad, GLU_SMOOTH);
-
- glPushMatrix();
+ gpuPushMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
switch (sketch->next_point.mode) {
- case PT_SNAP:
- glColor3f(0, 1, 0);
- break;
- case PT_PROJECT:
- glColor3f(0, 0, 0);
- break;
+ case PT_SNAP:
+ copy_v4_fl4(tmp_color, 0.0f, 1.0f, 0.0f, 1.0f);
+ break;
+ case PT_PROJECT:
+ copy_v4_fl4(tmp_color, 0.0f, 0.0f, 0.0f, 1.0f);
+ break;
}
- sk_drawPoint(quad, &sketch->next_point, 0.1);
+ sk_drawPoint(&sketch->next_point, 0.1, tmp_color);
- glColor4f(selected_rgb[0], selected_rgb[1], selected_rgb[2], 0.3);
-
- sk_drawEdge(quad, last, &sketch->next_point, 0.1);
+ copy_v4_fl4(tmp_color, selected_rgb[0], selected_rgb[1], selected_rgb[2], 0.3);
+ sk_drawEdge(last, &sketch->next_point, 0.1f, tmp_color);
glDisable(GL_BLEND);
- glPopMatrix();
-
- gluDeleteQuadric(quad);
+ gpuPopMatrix();
}
}
}
-#if 0
- if (BLI_listbase_is_empty(&sketch->depth_peels) == false) {
- float colors[8][3] = {
- {1, 0, 0},
- {0, 1, 0},
- {0, 0, 1},
- {1, 1, 0},
- {1, 0, 1},
- {0, 1, 1},
- {1, 1, 1},
- {0, 0, 0}
- };
- DepthPeel *p;
- GLUquadric *quad = gluNewQuadric();
- gluQuadricNormals(quad, GLU_SMOOTH);
-
- for (p = sketch->depth_peels.first; p; p = p->next)
- {
- int index = GET_INT_FROM_POINTER(p->ob);
- index = (index >> 5) & 7;
-
- glColor3fv(colors[index]);
- glPushMatrix();
- glTranslate3fv(p->p);
- gluSphere(quad, 0.02, 8, 8);
- glPopMatrix();
- }
-
- gluDeleteQuadric(quad);
- }
-#endif
-
glDisable(GL_DEPTH_TEST);
/* only draw gesture in active area */
if (sketch->gesture != NULL /* && area_is_active_area(G.vd->area) */) {
- float gesture_rgb[3] = {0, 0.5, 1};
+ float gesture_rgb[3] = { 0, 0.5, 1 };
sk_drawStroke(sketch->gesture, -1, gesture_rgb, -1, -1);
}
}
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 6e328552411..fdc58f6e253 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -133,7 +133,7 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
bool ED_do_pose_selectbuffer(
- Scene *scene, Base *base, const unsigned int *buffer, short hits,
+ Scene *scene, SceneLayer *sl, Base *base, const unsigned int *buffer, short hits,
bool extend, bool deselect, bool toggle, bool do_nearest)
{
Object *ob = base->object;
@@ -145,7 +145,7 @@ bool ED_do_pose_selectbuffer(
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
- Object *ob_act = OBACT;
+ Object *ob_act = OBACT_NEW;
bArmature *arm = ob->data;
/* since we do unified select, we don't shift+select a bone if the
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 2bcf3099104..0eb44085bae 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -3199,237 +3199,3 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(bContext *C)
return rg;
#endif
}
-
-#if 0
-
-ReebGraph *BIF_ReebGraphFromEditMesh(void)
-{
- EditMesh *em = G.editMesh;
- EdgeIndex indexed_edges;
- VertexData *data;
- ReebGraph *rg = NULL;
-
- if (em == NULL)
- return NULL;
-
- data = allocVertexData(em);
-
- buildIndexedEdges(em, &indexed_edges);
-
- if (weightFromDistance(em, &indexed_edges) == 0)
- {
- error("No selected vertex\n");
- freeEdgeIndex(&indexed_edges);
- freeEdgeIndex(&indexed_edges);
- return NULL;
- }
-
- renormalizeWeight(em, 1.0f);
-
- if (G.scene->toolsettings->skgen_options & SKGEN_HARMONIC)
- {
- weightToHarmonic(em, &indexed_edges);
- }
-
- freeEdgeIndex(&indexed_edges);
-
-#ifdef DEBUG_REEB
-// weightToVCol(em, 1);
-#endif
-
- rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution);
-
-
- /* Remove arcs without embedding */
- filterNullReebGraph(rg);
-
- /* smart filter and loop filter on basic level */
- filterGraph(rg, SKGEN_FILTER_SMART, 0, 0);
-
- repositionNodes(rg);
-
- /* Filtering might have created degree 2 nodes, so remove them */
- removeNormalNodes(rg);
-
- joinSubgraphs(rg, 1.0);
-
- BLI_buildAdjacencyList((BGraph *)rg);
-
- /* calc length before copy, so we have same length on all levels */
- BLI_calcGraphLength((BGraph *)rg);
-
- filterGraph(rg, G.scene->toolsettings->skgen_options, G.scene->toolsettings->skgen_threshold_internal, G.scene->toolsettings->skgen_threshold_external);
-
- finalizeGraph(rg, G.scene->toolsettings->skgen_postpro_passes, G.scene->toolsettings->skgen_postpro);
-
-#ifdef DEBUG_REEB
- REEB_exportGraph(rg, -1);
-
- arcToVCol(rg, em, 0);
- //angleToVCol(em, 1);
-#endif
-
- printf("DONE\n");
- printf("%i subgraphs\n", BLI_FlagSubgraphs((BGraph *)rg));
-
- MEM_freeN(data);
-
- return rg;
-}
-
-void BIF_GlobalReebFree()
-{
- if (GLOBAL_RG != NULL)
- {
- REEB_freeGraph(GLOBAL_RG);
- GLOBAL_RG = NULL;
- }
-}
-
-void BIF_GlobalReebGraphFromEditMesh(void)
-{
- ReebGraph *rg;
-
- BIF_GlobalReebFree();
-
- rg = BIF_ReebGraphMultiFromEditMesh();
-
- GLOBAL_RG = rg;
-}
-
-void REEB_draw()
-{
- ReebGraph *rg;
- ReebArc *arc;
- int i = 0;
-
- if (GLOBAL_RG == NULL)
- {
- return;
- }
-
- if (GLOBAL_RG->link_up && G.scene->toolsettings->skgen_options & SKGEN_DISP_ORIG)
- {
- for (rg = GLOBAL_RG; rg->link_up; rg = rg->link_up) ;
- }
- else {
- i = G.scene->toolsettings->skgen_multi_level;
-
- for (rg = GLOBAL_RG; rg->multi_level != i && rg->link_up; rg = rg->link_up) ;
- }
-
- glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
-
- glDisable(GL_DEPTH_TEST);
- for (arc = rg->arcs.first; arc; arc = arc->next, i++)
- {
- ReebArcIterator arc_iter;
- BArcIterator *iter = (BArcIterator *)&arc_iter;
- float vec[3];
- char text[128];
- char *s = text;
-
- glLineWidth(BIF_GetThemeValuef(TH_VERTEX_SIZE) + 2);
- glColor3f(0, 0, 0);
- glBegin(GL_LINE_STRIP);
- glVertex3fv(arc->head->p);
-
- if (arc->bcount)
- {
- initArcIterator(iter, arc, arc->head);
- for (IT_next(iter); IT_stopped(iter) == 0; IT_next(iter))
- {
- glVertex3fv(iter->p);
- }
- }
-
- glVertex3fv(arc->tail->p);
- glEnd();
-
- glLineWidth(BIF_GetThemeValuef(TH_VERTEX_SIZE));
-
- if (arc->symmetry_level == 1)
- {
- glColor3f(1, 0, 0);
- }
- else if (arc->symmetry_flag == SYM_SIDE_POSITIVE || arc->symmetry_flag == SYM_SIDE_NEGATIVE)
- {
- glColor3f(1, 0.5f, 0);
- }
- else if (arc->symmetry_flag >= SYM_SIDE_RADIAL)
- {
- glColor3f(0.5f, 1, 0);
- }
- else {
- glColor3f(1, 1, 0);
- }
- glBegin(GL_LINE_STRIP);
- glVertex3fv(arc->head->p);
-
- if (arc->bcount)
- {
- initArcIterator(iter, arc, arc->head);
- for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
- {
- glVertex3fv(iter->p);
- }
- }
-
- glVertex3fv(arc->tail->p);
- glEnd();
-
-
- if (G.scene->toolsettings->skgen_options & SKGEN_DISP_EMBED)
- {
- glColor3f(1, 1, 1);
- glBegin(GL_POINTS);
- glVertex3fv(arc->head->p);
- glVertex3fv(arc->tail->p);
-
- glColor3f(0.5f, 0.5f, 1);
- if (arc->bcount)
- {
- initArcIterator(iter, arc, arc->head);
- for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
- {
- glVertex3fv(iter->p);
- }
- }
- glEnd();
- }
-
- if (G.scene->toolsettings->skgen_options & SKGEN_DISP_INDEX)
- {
- mid_v3_v3v3(vec, arc->head->p, arc->tail->p);
- s += sprintf(s, "%i (%i-%i-%i) ", i, arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group);
-
- if (G.scene->toolsettings->skgen_options & SKGEN_DISP_WEIGHT)
- {
- s += sprintf(s, "w:%0.3f ", arc->tail->weight - arc->head->weight);
- }
-
- if (G.scene->toolsettings->skgen_options & SKGEN_DISP_LENGTH)
- {
- s += sprintf(s, "l:%0.3f", arc->length);
- }
-
- glColor3f(0, 1, 0);
- glRasterPos3fv(vec);
- BMF_DrawString(G.fonts, text);
- }
-
- if (G.scene->toolsettings->skgen_options & SKGEN_DISP_INDEX)
- {
- sprintf(text, " %i", arc->head->index);
- glRasterPos3fv(arc->head->p);
- BMF_DrawString(G.fonts, text);
-
- sprintf(text, " %i", arc->tail->index);
- glRasterPos3fv(arc->tail->p);
- BMF_DrawString(G.fonts, text);
- }
- }
- glEnable(GL_DEPTH_TEST);
-}
-
-#endif
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a69264cd012..1dd32d6b1a2 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -50,6 +50,7 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -1285,6 +1286,7 @@ static int separate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *oldob, *newob;
Base *oldbase, *newbase;
Curve *oldcu, *newcu;
@@ -1312,7 +1314,7 @@ static int separate_exec(bContext *C, wmOperator *op)
}
/* 2. duplicate the object and data */
- newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */
+ newbase = ED_object_add_duplicate(bmain, scene, sl, oldbase, 0); /* 0 = fully linked */
DAG_relations_tag_update(bmain);
newob = newbase->object;
@@ -5013,7 +5015,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const float mval[2] = {UNPACK2(event->mval)};
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), vc.scene, 0,
+ CTX_data_main(C), vc.scene, vc.scene_layer, 0,
vc.ar, vc.v3d);
ED_transform_snap_object_project_view3d_mixed(
@@ -6039,7 +6041,7 @@ int join_curve_exec(bContext *C, wmOperator *op)
}
}
- ED_base_object_free_and_unlink(bmain, scene, base);
+ ED_base_object_free_and_unlink(bmain, scene, base->object);
}
}
}
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 34e026a3ef4..867aec61922 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -46,7 +46,11 @@
#include "ED_curve.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
+
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "curve_intern.h"
@@ -88,25 +92,17 @@ static float depth_read_zbuf(const ViewContext *vc, int x, int y)
}
static bool depth_unproject(
- const ARegion *ar, const bglMats *mats,
+ const ARegion *ar,
const int mval[2], const double depth,
float r_location_world[3])
{
- double p[3];
- if (gluUnProject(
- (double)ar->winrct.xmin + mval[0] + 0.5,
- (double)ar->winrct.ymin + mval[1] + 0.5,
- depth, mats->modelview, mats->projection, (const GLint *)mats->viewport,
- &p[0], &p[1], &p[2]))
- {
- copy_v3fl_v3db(r_location_world, p);
- return true;
- }
- return false;
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+ return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
}
static bool depth_read_normal(
- const ViewContext *vc, const bglMats *mats, const int mval[2],
+ const ViewContext *vc, const int mval[2],
float r_normal[3])
{
/* pixels surrounding */
@@ -122,7 +118,7 @@ static bool depth_read_normal(
const double depth = (double)depth_read_zbuf(vc, mval_ofs[0], mval_ofs[1]);
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (depth_unproject(ar, mats, mval_ofs, depth, coords[i])) {
+ if (depth_unproject(ar, mval_ofs, depth, coords[i])) {
depths_valid[i] = true;
}
}
@@ -224,7 +220,6 @@ struct CurveDrawData {
} prev;
ViewContext vc;
- bglMats mats;
enum {
CURVE_DRAW_IDLE = 0,
CURVE_DRAW_PAINTING = 1,
@@ -310,7 +305,7 @@ static bool stroke_elem_project(
{
const double depth = (double)depth_read_zbuf(&cdd->vc, mval_i[0], mval_i[1]);
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (depth_unproject(ar, &cdd->mats, mval_i, depth, r_location_world)) {
+ if (depth_unproject(ar, mval_i, depth, r_location_world)) {
is_location_world_set = true;
if (r_normal_world) {
zero_v3(r_normal_world);
@@ -319,7 +314,7 @@ static bool stroke_elem_project(
if (surface_offset != 0.0f) {
const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius;
float normal[3];
- if (depth_read_normal(&cdd->vc, &cdd->mats, mval_i, normal)) {
+ if (depth_read_normal(&cdd->vc, mval_i, normal)) {
madd_v3_v3fl(r_location_world, normal, offset * surface_offset);
if (r_normal_world) {
copy_v3_v3(r_normal_world, normal);
@@ -465,39 +460,43 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
Object *obedit = cdd->vc.obedit;
Curve *cu = obedit->data;
- UI_ThemeColor(TH_WIRE);
-
if (cu->ext2 > 0.0f) {
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_FILL);
-
BLI_mempool_iter iter;
const struct StrokeElem *selem;
const float location_zero[3] = {0};
const float *location_prev = location_zero;
+ float color[3];
+ UI_GetThemeColor3fv(TH_WIRE, color);
+
+ Batch *sphere = Batch_get_sphere(0);
+ Batch_set_builtin_program(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform3fv(sphere, "color", color);
+
/* scale to edit-mode space */
- glPushMatrix();
- glMultMatrixf(obedit->obmat);
+ gpuPushMatrix();
+ gpuMultMatrix(obedit->obmat);
BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- glTranslatef(
+ gpuTranslate3f(
selem->location_local[0] - location_prev[0],
selem->location_local[1] - location_prev[1],
selem->location_local[2] - location_prev[2]);
location_prev = selem->location_local;
+
const float radius = stroke_elem_radius(cdd, selem);
- gluSphere(qobj, radius, 12, 8);
+
+ gpuPushMatrix();
+ gpuScaleUniform(radius);
+ Batch_draw(sphere);
+ gpuPopMatrix();
location_prev = selem->location_local;
}
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
+ gpuPopMatrix();
}
if (stroke_len > 1) {
@@ -514,30 +513,45 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
}
{
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, coord_array);
-
- cpack(0x0);
+ imm_cpack(0x0);
+ immBegin(PRIM_LINE_STRIP, stroke_len);
glLineWidth(3.0f);
- glDrawArrays(GL_LINE_STRIP, 0, stroke_len);
- if (v3d->zbuf)
+ if (v3d->zbuf) {
glDisable(GL_DEPTH_TEST);
+ }
+
+ for (int i = 0; i < stroke_len; i++) {
+ immVertex3fv(pos, coord_array[i]);
+ }
+
+ immEnd();
- cpack(0xffffffff);
+ imm_cpack(0xffffffff);
+ immBegin(PRIM_LINE_STRIP, stroke_len);
glLineWidth(1.0f);
- glDrawArrays(GL_LINE_STRIP, 0, stroke_len);
- if (v3d->zbuf)
- glEnable(GL_DEPTH_TEST);
+ for (int i = 0; i < stroke_len; i++) {
+ immVertex3fv(pos, coord_array[i]);
+ }
+
+ immEnd();
- glDisableClientState(GL_VERTEX_ARRAY);
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ }
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
+
+ immUnbindProgram();
}
MEM_freeN(coord_array);
@@ -627,7 +641,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event)
CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW,
CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE))
{
- if (depth_read_normal(&cdd->vc, &cdd->mats, event->mval, normal)) {
+ if (depth_read_normal(&cdd->vc, event->mval, normal)) {
if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) {
float cross_a[3], cross_b[3];
cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal);
@@ -685,7 +699,9 @@ static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke)
}
}
else {
+ cdd->vc.depsgraph = CTX_data_depsgraph(C);
cdd->vc.scene = CTX_data_scene(C);
+ cdd->vc.scene_layer = CTX_data_scene_layer(C);
cdd->vc.obedit = CTX_data_edit_object(C);
}
@@ -1162,12 +1178,10 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) &&
(v3d->drawtype > OB_WIRE))
{
- view3d_get_transformation(cdd->vc.ar, cdd->vc.rv3d, NULL, &cdd->mats);
-
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
- ED_view3d_autodist_init(cdd->vc.scene, cdd->vc.ar, cdd->vc.v3d, 0);
+ ED_view3d_autodist_init(cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0);
if (cdd->vc.rv3d->depths) {
cdd->vc.rv3d->depths->damaged = true;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 57e731874b4..09a76553b2e 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -273,6 +273,8 @@ static void text_update_edited(bContext *C, Object *obedit, int mode)
}
}
+ BKE_curve_batch_cache_dirty(cu, BKE_CURVE_BATCH_DIRTY_SELECT);
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
@@ -420,6 +422,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Curve *cu;
Object *obedit;
Base *base;
@@ -429,8 +432,8 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
int a;
float rot[3] = {0.f, 0.f, 0.f};
- obedit = BKE_object_add(bmain, scene, OB_FONT, NULL);
- base = scene->basact;
+ obedit = BKE_object_add(bmain, scene, sl, OB_FONT, NULL);
+ base = sl->basact;
/* seems to assume view align ? TODO - look into this, could be an operator option */
ED_object_base_init_transform(C, base, NULL, rot);
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index ecab37c729f..a868b47053c 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -60,9 +60,11 @@
#include "WM_api.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+
#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -92,99 +94,194 @@ typedef enum eDrawStrokeFlags {
/* thickness above which we should use special drawing */
+#if 0
#define GP_DRAWTHICKNESS_SPECIAL 3
+#endif
+
+/* conversion utility (float --> normalized unsigned byte) */
+#define F2UB(x) (unsigned char)(255.0f * x)
/* ----- Tool Buffer Drawing ------ */
-/* helper function to set color of buffer point */
-static void gp_set_tpoint_color(tGPspoint *pt, float ink[4])
+/* helper functions to set color of buffer point */
+
+static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], unsigned attrib_id)
{
float alpha = ink[3] * pt->strength;
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
- glColor4f(ink[0], ink[1], ink[2], alpha);
+ immAttrib4ub(attrib_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha));
}
-/* helper function to set color of point */
-static void gp_set_point_color(bGPDspoint *pt, float ink[4])
+static void gp_set_point_uniform_color(const bGPDspoint *pt, const float ink[4])
{
float alpha = ink[3] * pt->strength;
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
- glColor4f(ink[0], ink[1], ink[2], alpha);
+ immUniformColor3fvAlpha(ink, alpha);
}
-/* helper function to set color and point */
-static void gp_set_color_and_tpoint(tGPspoint *pt, float ink[4])
+static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], unsigned attrib_id)
{
- gp_set_tpoint_color(pt, ink);
- glVertex2iv(&pt->x);
+ float alpha = ink[3] * pt->strength;
+ CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
+ immAttrib4ub(attrib_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha));
+}
+
+/* draw fills for buffer stroke */
+static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, float ink[4])
+{
+ if (totpoints < 3) {
+ return;
+ }
+ int tot_triangles = totpoints - 2;
+ /* allocate memory for temporary areas */
+ unsigned int(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation");
+ float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke buffer temp 2d points");
+
+ /* Convert points to array and triangulate
+ * Here a cache is not used because while drawing the information changes all the time, so the cache
+ * would be recalculated constantly, so it is better to do direct calculation for each function call
+ */
+ for (int i = 0; i < totpoints; i++) {
+ const tGPspoint *pt = &points[i];
+ points2d[i][0] = pt->x;
+ points2d[i][1] = pt->y;
+ }
+ BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)totpoints, 0, (unsigned int(*)[3])tmp_triangles);
+
+ /* draw triangulation data */
+ if (tot_triangles > 0) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ /* Draw all triangles for filling the polygon */
+ immBegin(PRIM_TRIANGLES, tot_triangles * 3);
+ /* TODO: use batch instead of immediate mode, to share vertices */
+
+ const tGPspoint *pt;
+ for (int i = 0; i < tot_triangles; i++) {
+ /* vertex 1 */
+ pt = &points[tmp_triangles[i][0]];
+ gp_set_tpoint_varying_color(pt, ink, color);
+ immVertex2iv(pos, &pt->x);
+ /* vertex 2 */
+ pt = &points[tmp_triangles[i][1]];
+ gp_set_tpoint_varying_color(pt, ink, color);
+ immVertex2iv(pos, &pt->x);
+ /* vertex 3 */
+ pt = &points[tmp_triangles[i][2]];
+ gp_set_tpoint_varying_color(pt, ink, color);
+ immVertex2iv(pos, &pt->x);
+ }
+
+ immEnd();
+ immUnbindProgram();
+ }
+
+ /* clear memory */
+ if (tmp_triangles) {
+ MEM_freeN(tmp_triangles);
+ }
+ if (points2d) {
+ MEM_freeN(points2d);
+ }
}
/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
-static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickness,
- short dflag, short sflag, float ink[4])
+static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short thickness,
+ short dflag, short sflag, float ink[4], float fill_ink[4])
{
- tGPspoint *pt;
- int i;
-
+ int draw_points = 0;
+
/* error checking */
if ((points == NULL) || (totpoints <= 0))
return;
-
+
/* check if buffer can be drawn */
if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
return;
-
+
+ if (sflag & GP_STROKE_ERASER) {
+ /* don't draw stroke at all! */
+ return;
+ }
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ const tGPspoint *pt = points;
+
if (totpoints == 1) {
/* if drawing a single point, draw it larger */
glPointSize((float)(thickness + 2) * points->pressure);
- glBegin(GL_POINTS);
-
- gp_set_color_and_tpoint(points, ink);
- glEnd();
- }
- else if (sflag & GP_STROKE_ERASER) {
- /* don't draw stroke at all! */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+ immBegin(PRIM_POINTS, 1);
+ gp_set_tpoint_varying_color(pt, ink, color);
+ immVertex2iv(pos, &pt->x);
}
else {
float oldpressure = points[0].pressure;
-
+
/* draw stroke curve */
- if (G.debug & G_DEBUG) setlinestyle(2);
-
glLineWidth(max_ff(oldpressure * thickness, 1.0));
- glBegin(GL_LINE_STRIP);
-
- for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ immBeginAtMost(PRIM_LINE_STRIP, totpoints);
+
+ /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
+
+ for (int i = 0; i < totpoints; i++, pt++) {
/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
* and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
*/
if (fabsf(pt->pressure - oldpressure) > 0.2f) {
- glEnd();
+ /* need to have 2 points to avoid immEnd assert error */
+ if (draw_points < 2) {
+ gp_set_tpoint_varying_color(pt - 1, ink, color);
+ immVertex2iv(pos, &(pt - 1)->x);
+ }
+
+ immEnd();
+ draw_points = 0;
+
glLineWidth(max_ff(pt->pressure * thickness, 1.0f));
- glBegin(GL_LINE_STRIP);
-
+ immBeginAtMost(PRIM_LINE_STRIP, totpoints - i + 1);
+
/* need to roll-back one point to ensure that there are no gaps in the stroke */
if (i != 0) {
- gp_set_color_and_tpoint((pt - 1), ink);
+ gp_set_tpoint_varying_color(pt - 1, ink, color);
+ immVertex2iv(pos, &(pt - 1)->x);
+ ++draw_points;
}
-
- /* now the point we want... */
- gp_set_color_and_tpoint(pt, ink);
-
- oldpressure = pt->pressure;
- }
- else {
- gp_set_color_and_tpoint(pt, ink);
+
+ oldpressure = pt->pressure; /* reset our threshold */
}
+
+ /* now the point we want */
+ gp_set_tpoint_varying_color(pt, ink, color);
+ immVertex2iv(pos, &pt->x);
+ ++draw_points;
}
- glEnd();
+ /* need to have 2 points to avoid immEnd assert error */
+ if (draw_points < 2) {
+ gp_set_tpoint_varying_color(pt - 1, ink, color);
+ immVertex2iv(pos, &(pt - 1)->x);
+ }
+ }
- if (G.debug & G_DEBUG) setlinestyle(0);
+ immEnd();
+ immUnbindProgram();
+
+ // draw fill
+ if (fill_ink[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
+ gp_draw_stroke_buffer_fill(points, totpoints, fill_ink);
}
}
/* --------- 2D Stroke Drawing Helpers --------- */
/* change in parameter list */
-static void gp_calc_2d_stroke_fxy(float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2])
+static void gp_calc_2d_stroke_fxy(const float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2])
{
if (sflag & GP_STROKE_2DSPACE) {
r_co[0] = pt[0];
@@ -210,203 +307,141 @@ static void gp_calc_2d_stroke_fxy(float pt[3], short sflag, int offsx, int offsy
/* draw a 2D buffer stroke in "volumetric" style
* NOTE: the stroke buffer doesn't have any coordinate offsets/transforms
*/
-static void gp_draw_stroke_volumetric_buffer(tGPspoint *points, int totpoints, short thickness,
- short dflag, short UNUSED(sflag), float ink[4])
+static void gp_draw_stroke_volumetric_buffer(const tGPspoint *points, int totpoints, short thickness,
+ short dflag, const float ink[4])
{
- GLUquadricObj *qobj = gluNewQuadric();
- float modelview[4][4];
-
- tGPspoint *pt;
- int i;
-
/* error checking */
if ((points == NULL) || (totpoints <= 0))
return;
-
+
/* check if buffer can be drawn */
if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
return;
-
- /* get basic matrix - should be camera space (i.e "identity") */
- glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview);
-
- /* draw points */
- glPushMatrix();
-
- for (i = 0, pt = points; i < totpoints; i++, pt++) {
- /* set the transformed position */
- // TODO: scale should change based on zoom level, which requires proper translation mult too!
- modelview[3][0] = pt->x;
- modelview[3][1] = pt->y;
-
- glLoadMatrixf((float *)modelview);
-
- /* draw the disk using the current state... */
- gp_set_tpoint_color(pt, ink);
- gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1);
-
-
- modelview[3][0] = modelview[3][1] = 0.0f;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int size = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, totpoints);
+
+ const tGPspoint *pt = points;
+ for (int i = 0; i < totpoints; i++, pt++) {
+ gp_set_tpoint_varying_color(pt, ink, color);
+ immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform (zoom level) */
+ immVertex2f(pos, pt->x, pt->y);
}
- glPopMatrix();
- gluDeleteQuadric(qobj);
+ immEnd();
+ immUnbindProgram();
+ GPU_disable_program_point_size();
}
/* draw a 2D strokes in "volumetric" style */
-static void gp_draw_stroke_volumetric_2d(bGPDspoint *points, int totpoints, short thickness,
- short dflag, short sflag,
+static void gp_draw_stroke_volumetric_2d(const bGPDspoint *points, int totpoints, short thickness,
+ short UNUSED(dflag), short sflag,
int offsx, int offsy, int winx, int winy,
- float diff_mat[4][4], float ink[4])
+ const float diff_mat[4][4], const float ink[4])
{
- GLUquadricObj *qobj = gluNewQuadric();
- float modelview[4][4];
- float baseloc[3];
- float scalefac = 1.0f;
-
- bGPDspoint *pt;
- int i;
- float fpt[3];
-
- /* HACK: We need a scale factor for the drawing in the image editor,
- * which seems to use 1 unit as it's maximum size, whereas everything
- * else assumes 1 unit = 1 pixel. Otherwise, we only get a massive blob.
- */
- if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
- scalefac = 0.001f;
- }
-
- /* get basic matrix */
- glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview);
- copy_v3_v3(baseloc, modelview[3]);
-
- /* draw points */
- glPushMatrix();
-
- for (i = 0, pt = points; i < totpoints; i++, pt++) {
- /* color of point */
- gp_set_point_color(pt, ink);
-
- /* set the transformed position */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int size = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, totpoints);
+
+ const bGPDspoint *pt = points;
+ for (int i = 0; i < totpoints; i++, pt++) {
+ /* transform position to 2D */
float co[2];
-
+ float fpt[3];
+
mul_v3_m4v3(fpt, diff_mat, &pt->x);
gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co);
- translate_m4(modelview, co[0], co[1], 0.0f);
-
- glLoadMatrixf((float *)modelview);
-
- /* draw the disk using the current state... */
- gluDisk(qobj, 0.0, pt->pressure * thickness * scalefac, 32, 1);
-
- /* restore matrix */
- copy_v3_v3(modelview[3], baseloc);
+
+ gp_set_point_varying_color(pt, ink, color);
+ immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */
+ immVertex2f(pos, co[0], co[1]);
}
-
- glPopMatrix();
- gluDeleteQuadric(qobj);
+
+ immEnd();
+ immUnbindProgram();
+ GPU_disable_program_point_size();
}
/* draw a 3D stroke in "volumetric" style */
static void gp_draw_stroke_volumetric_3d(
- bGPDspoint *points, int totpoints, short thickness,
- short UNUSED(dflag), short UNUSED(sflag), float diff_mat[4][4], float ink[4])
+ const bGPDspoint *points, int totpoints, short thickness,
+ const float ink[4])
{
- GLUquadricObj *qobj = gluNewQuadric();
-
- float base_modelview[4][4], modelview[4][4];
- float base_loc[3];
-
- bGPDspoint *pt;
- int i;
- float fpt[3];
-
- /* Get the basic modelview matrix we use for performing calculations */
- glGetFloatv(GL_MODELVIEW_MATRIX, (float *)base_modelview);
- copy_v3_v3(base_loc, base_modelview[3]);
-
- /* Create the basic view-aligned billboard matrix we're going to actually draw qobj with:
- * - We need to knock out the rotation so that we are
- * simply left with a camera-facing billboard
- * - The scale factors here are chosen so that the thickness
- * is relatively reasonable. Otherwise, it gets far too
- * large!
- */
- scale_m4_fl(modelview, 0.1f);
-
- /* draw each point as a disk... */
- glPushMatrix();
-
- for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
- /* color of point */
- gp_set_point_color(pt, ink);
-
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
-
- /* apply translation to base_modelview, so that the translated point is put in the right place */
- translate_m4(base_modelview, fpt[0], fpt[1], fpt[2]);
-
- /* copy the translation component to the billboard matrix we're going to use,
- * then reset the base matrix to the original values so that we can do the same
- * for the next point without accumulation/pollution effects
- */
- copy_v3_v3(modelview[3], base_modelview[3]); /* copy offset value */
- copy_v3_v3(base_modelview[3], base_loc); /* restore */
-
- /* apply our billboard matrix for drawing... */
- glLoadMatrixf((float *)modelview);
-
- /* draw the disk using the current state... */
- gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int size = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, totpoints);
+
+ const bGPDspoint *pt = points;
+ for (int i = 0; i < totpoints && pt; i++, pt++) {
+ gp_set_point_varying_color(pt, ink, color);
+ immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */
+ immVertex3fv(pos, &pt->x); /* we can adjust size in vertex shader based on view/projection! */
}
-
- glPopMatrix();
- gluDeleteQuadric(qobj);
+
+ immEnd();
+ immUnbindProgram();
+ GPU_disable_program_point_size();
}
/* --------------- Stroke Fills ----------------- */
/* Get points of stroke always flat to view not affected by camera view or view position */
-static void gp_stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction)
+static void gp_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction)
{
- bGPDspoint *pt0 = &points[0];
- bGPDspoint *pt1 = &points[1];
- bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
-
+ const bGPDspoint *pt0 = &points[0];
+ const bGPDspoint *pt1 = &points[1];
+ const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
+
float locx[3];
float locy[3];
float loc3[3];
float normal[3];
-
+
/* local X axis (p0 -> p1) */
sub_v3_v3v3(locx, &pt1->x, &pt0->x);
-
+
/* point vector at 3/4 */
sub_v3_v3v3(loc3, &pt3->x, &pt0->x);
-
+
/* vector orthogonal to polygon plane */
cross_v3_v3v3(normal, locx, loc3);
-
+
/* local Y axis (cross to normal/x axis) */
cross_v3_v3v3(locy, normal, locx);
-
+
/* Normalize vectors */
normalize_v3(locx);
normalize_v3(locy);
-
+
/* Get all points in local space */
for (int i = 0; i < totpoints; i++) {
- bGPDspoint *pt = &points[i];
+ const bGPDspoint *pt = &points[i];
float loc[3];
-
+
/* Get local space using first point as origin */
sub_v3_v3v3(loc, &pt->x, &pt0->x);
-
+
points2d[i][0] = dot_v3v3(loc, locx);
points2d[i][1] = dot_v3v3(loc, locy);
}
-
+
/* Concave (-1), Convex (1), or Autodetect (0)? */
*r_direction = (int)locy[2];
}
@@ -416,14 +451,14 @@ static void gp_stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d
static void gp_triangulate_stroke_fill(bGPDstroke *gps)
{
BLI_assert(gps->totpoints >= 3);
-
+
/* allocate memory for temporary areas */
gps->tot_triangles = gps->totpoints - 2;
unsigned int (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation");
float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points");
-
+
int direction = 0;
-
+
/* convert to 2d and triangulate */
gp_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)gps->totpoints, direction, (unsigned int(*)[3])tmp_triangles);
@@ -438,7 +473,7 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps)
else {
gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles);
}
-
+
for (int i = 0; i < gps->tot_triangles; i++) {
bGPDtriangle *stroke_triangle = &gps->triangles[i];
stroke_triangle->v1 = tmp_triangles[i][0];
@@ -450,15 +485,15 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps)
/* No triangles needed - Free anything allocated previously */
if (gps->triangles)
MEM_freeN(gps->triangles);
-
+
gps->triangles = NULL;
}
-
+
/* disable recalculation flag */
if (gps->flag & GP_STROKE_RECALC_CACHES) {
gps->flag &= ~GP_STROKE_RECALC_CACHES;
}
-
+
/* clear memory */
if (tmp_triangles) MEM_freeN(tmp_triangles);
if (points2d) MEM_freeN(points2d);
@@ -468,42 +503,55 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps)
/* draw fills for shapes */
static void gp_draw_stroke_fill(
bGPdata *gpd, bGPDstroke *gps,
- int offsx, int offsy, int winx, int winy, float diff_mat[4][4])
+ int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float color[4])
{
- bGPDpalettecolor *palcolor;
- int i;
float fpt[3];
BLI_assert(gps->totpoints >= 3);
- palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
+ bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
/* Triangulation fill if high quality flag is enabled */
if (palcolor->flag & PC_COLOR_HQ_FILL) {
- bGPDtriangle *stroke_triangle;
- bGPDspoint *pt;
-
/* Calculate triangles cache for filling area (must be done only after changes) */
if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
gp_triangulate_stroke_fill(gps);
}
- /* Draw all triangles for filling the polygon (cache must be calculated before) */
BLI_assert(gps->tot_triangles >= 1);
- glBegin(GL_TRIANGLES);
- for (i = 0, stroke_triangle = gps->triangles; i < gps->tot_triangles; i++, stroke_triangle++) {
+
+ unsigned int pos;
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ else {
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ }
+
+ immUniformColor4fv(color);
+
+ /* Draw all triangles for filling the polygon (cache must be calculated before) */
+ immBegin(PRIM_TRIANGLES, gps->tot_triangles * 3);
+ /* TODO: use batch instead of immediate mode, to share vertices */
+
+ bGPDtriangle *stroke_triangle = gps->triangles;
+ bGPDspoint *pt;
+
+ for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
if (gps->flag & GP_STROKE_3DSPACE) {
/* vertex 1 */
pt = &gps->points[stroke_triangle->v1];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
+ immVertex3fv(pos, fpt);
/* vertex 2 */
pt = &gps->points[stroke_triangle->v2];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
+ immVertex3fv(pos, fpt);
/* vertex 3 */
pt = &gps->points[stroke_triangle->v3];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
+ immVertex3fv(pos, fpt);
}
else {
float co[2];
@@ -511,49 +559,22 @@ static void gp_draw_stroke_fill(
pt = &gps->points[stroke_triangle->v1];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
+ immVertex2fv(pos, co);
/* vertex 2 */
pt = &gps->points[stroke_triangle->v2];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
+ immVertex2fv(pos, co);
/* vertex 3 */
pt = &gps->points[stroke_triangle->v3];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
+ immVertex2fv(pos, co);
}
}
- glEnd();
- }
- else {
- /* As an initial implementation, we use the OpenGL filled polygon drawing
- * here since it's the easiest option to implement for this case. It does
- * come with limitations (notably for concave shapes), though it shouldn't
- * be much of an issue in most cases.
- *
- * We keep this legacy implementation around despite now having the high quality
- * fills, as this is necessary for keeping everything working nicely for files
- * created using old versions of Blender which may have depended on the artifacts
- * the old fills created.
- */
- bGPDspoint *pt;
- glBegin(GL_POLYGON);
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if (gps->flag & GP_STROKE_3DSPACE) {
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
- }
- else {
- float co[2];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
- }
- }
-
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
}
@@ -561,153 +582,162 @@ static void gp_draw_stroke_fill(
/* draw a given stroke - just a single dot (only one point) */
static void gp_draw_stroke_point(
- bGPDspoint *points, short thickness, short dflag, short sflag,
- int offsx, int offsy, int winx, int winy, float diff_mat[4][4], float ink[4])
+ const bGPDspoint *points, short thickness, short UNUSED(dflag), short sflag,
+ int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4])
{
- float fpt[3];
- bGPDspoint *pt = &points[0];
-
- /* color of point */
- gp_set_point_color(pt, ink);
+ const bGPDspoint *pt = points;
- /* set point thickness (since there's only one of these) */
- glPointSize((float)(thickness + 2) * points->pressure);
-
/* get final position using parent matrix */
+ float fpt[3];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- /* draw point */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
if (sflag & GP_STROKE_3DSPACE) {
- glBegin(GL_POINTS);
- glVertex3fv(fpt);
- glEnd();
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
}
else {
- float co[2];
-
- /* get coordinates of point */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+
+ /* get 2D coordinates of point */
+ float co[3] = { 0.0f };
gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co);
-
- /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple dot looks ok
- * - also mandatory in if Image Editor 'image-based' dot
- */
- if ((thickness < GP_DRAWTHICKNESS_SPECIAL) ||
- ((dflag & GP_DRAWDATA_IEDITHACK) && (sflag & GP_STROKE_2DSPACE)))
- {
- glBegin(GL_POINTS);
- glVertex2fv(co);
- glEnd();
- }
- else {
- /* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_FILL);
-
- /* need to translate drawing position, but must reset after too! */
- glTranslate2fv(co);
- gluDisk(qobj, 0.0, thickness, 32, 1);
- glTranslatef(-co[0], -co[1], 0.0);
-
- gluDeleteQuadric(qobj);
- }
+ copy_v3_v3(fpt, co);
}
+
+ gp_set_point_uniform_color(pt, ink);
+ /* set point thickness (since there's only one of these) */
+ immUniform1f("size", (float)(thickness + 2) * pt->pressure);
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, fpt);
+ immEnd();
+
+ immUnbindProgram();
}
/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
-static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, bool debug,
- short UNUSED(sflag), float diff_mat[4][4], float ink[4], bool cyclic)
+static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug),
+ short UNUSED(sflag), const float diff_mat[4][4], const float ink[4], bool cyclic)
{
- bGPDspoint *pt, *pt2;
float curpressure = points[0].pressure;
- int i;
float fpt[3];
float cyclic_fpt[3];
+ int draw_points = 0;
+
+ /* if cyclic needs one vertex more */
+ int cyclic_add = 0;
+ if (cyclic) {
+ ++cyclic_add;
+ }
+
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+
+ /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
/* draw stroke curve */
glLineWidth(max_ff(curpressure * thickness, 1.0f));
- glBegin(GL_LINE_STRIP);
- for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
- gp_set_point_color(pt, ink);
+ immBeginAtMost(PRIM_LINE_STRIP, totpoints + cyclic_add);
+ const bGPDspoint *pt = points;
+ for (int i = 0; i < totpoints; i++, pt++) {
+ gp_set_point_varying_color(pt, ink, color);
/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
* and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
* Note: we want more visible levels of pressures when thickness is bigger.
*/
if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) {
- glEnd();
+ /* if the pressure changes before get at least 2 vertices, need to repeat last point to avoid assert in immEnd() */
+ if (draw_points < 2) {
+ const bGPDspoint *pt2 = pt - 1;
+ mul_v3_m4v3(fpt, diff_mat, &pt2->x);
+ immVertex3fv(pos, fpt);
+ }
+ immEnd();
+ draw_points = 0;
+
curpressure = pt->pressure;
glLineWidth(max_ff(curpressure * thickness, 1.0f));
- glBegin(GL_LINE_STRIP);
-
+ immBeginAtMost(PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add);
+
/* need to roll-back one point to ensure that there are no gaps in the stroke */
if (i != 0) {
- pt2 = pt - 1;
+ const bGPDspoint *pt2 = pt - 1;
mul_v3_m4v3(fpt, diff_mat, &pt2->x);
- glVertex3fv(fpt);
+ gp_set_point_varying_color(pt2, ink, color);
+ immVertex3fv(pos, fpt);
+ ++draw_points;
}
-
- /* now the point we want... */
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
}
- else {
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
- }
- /* saves first point to use in cyclic */
- if (i == 0) {
+
+ /* now the point we want */
+ mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ immVertex3fv(pos, fpt);
+ ++draw_points;
+
+ if (cyclic && i == 0) {
+ /* save first point to use in cyclic */
copy_v3_v3(cyclic_fpt, fpt);
}
}
- /* if cyclic draw line to first point */
+
if (cyclic) {
- glVertex3fv(cyclic_fpt);
+ /* draw line to first point to complete the cycle */
+ immVertex3fv(pos, cyclic_fpt);
+ ++draw_points;
}
- glEnd();
-
- /* draw debug points of curve on top? */
- /* XXX: for now, we represent "selected" strokes in the same way as debug, which isn't used anymore */
- if (debug) {
- glPointSize((float)(thickness + 2));
-
- glBegin(GL_POINTS);
- for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
- }
- glEnd();
+ /* if less of two points, need to repeat last point to avoid assert in immEnd() */
+ if (draw_points < 2) {
+ const bGPDspoint *pt2 = pt - 1;
+ mul_v3_m4v3(fpt, diff_mat, &pt2->x);
+ gp_set_point_varying_color(pt2, ink, color);
+ immVertex3fv(pos, fpt);
}
+
+ immEnd();
+ immUnbindProgram();
}
/* ----- Fancy 2D-Stroke Drawing ------ */
/* draw a given stroke in 2d */
-static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
- bool debug, int offsx, int offsy, int winx, int winy, float diff_mat[4][4], float ink[4])
+static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
+ bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4])
{
/* otherwise thickness is twice that of the 3D view */
float thickness = (float)thickness_s * 0.5f;
-
+
/* strokes in Image Editor need a scale factor, since units there are not pixels! */
float scalefac = 1.0f;
if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
scalefac = 0.001f;
}
-
- /* tessellation code - draw stroke as series of connected quads with connection
+
+ /* TODO: fancy++ with the magic of shaders */
+
+ /* tessellation code - draw stroke as series of connected quads (triangle strips in fact) with connection
* edges rotated to minimize shrinking artifacts, and rounded endcaps
*/
{
- bGPDspoint *pt1, *pt2;
+ const bGPDspoint *pt1, *pt2;
float s0[2], s1[2]; /* segment 'center' points */
float pm[2]; /* normal from previous segment. */
int i;
float fpt[3];
-
- glShadeModel(GL_FLAT);
- glBegin(GL_QUADS);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_TRIANGLE_STRIP, totpoints * 2 + 4);
/* get x and y coordinates from first point */
mul_v3_m4v3(fpt, diff_mat, &points->x);
@@ -722,19 +752,19 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness
/* get x and y coordinates from point2 (point1 has already been computed in previous iteration). */
mul_v3_m4v3(fpt, diff_mat, &pt2->x);
gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, s1);
-
+
/* calculate gradient and normal - 'angle'=(ny/nx) */
m1[1] = s1[1] - s0[1];
m1[0] = s1[0] - s0[0];
normalize_v2(m1);
m2[1] = -m1[0];
m2[0] = m1[1];
-
+
/* always use pressure from first point here */
pthick = (pt1->pressure * thickness * scalefac);
-
+
/* color of point */
- gp_set_point_color(pt1, ink);
+ gp_set_point_varying_color(pt1, ink, color);
/* if the first segment, start of segment is segment's normal */
if (i == 0) {
@@ -745,40 +775,39 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness
mt[1] = m2[1] * pthick * 0.5f;
sc[0] = s0[0] - (m1[0] * pthick * 0.75f);
sc[1] = s0[1] - (m1[1] * pthick * 0.75f);
-
+
t0[0] = sc[0] - mt[0];
t0[1] = sc[1] - mt[1];
t1[0] = sc[0] + mt[0];
t1[1] = sc[1] + mt[1];
-
- glVertex2fv(t0);
- glVertex2fv(t1);
-
+
+ /* First two points of cap. */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+
/* calculate points for start of segment */
mt[0] = m2[0] * pthick;
mt[1] = m2[1] * pthick;
-
+
t0[0] = s0[0] - mt[0];
t0[1] = s0[1] - mt[1];
t1[0] = s0[0] + mt[0];
t1[1] = s0[1] + mt[1];
-
- /* draw this line twice (first to finish off start cap, then for stroke) */
- glVertex2fv(t1);
- glVertex2fv(t0);
- glVertex2fv(t0);
- glVertex2fv(t1);
+
+ /* Last two points of start cap (and first two points of first segment). */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
}
/* if not the first segment, use bisector of angle between segments */
else {
float mb[2]; /* bisector normal */
float athick, dfac; /* actual thickness, difference between thicknesses */
-
+
/* calculate gradient of bisector (as average of normals) */
mb[0] = (pm[0] + m2[0]) / 2;
mb[1] = (pm[1] + m2[1]) / 2;
normalize_v2(mb);
-
+
/* calculate gradient to apply
* - as basis, use just pthick * bisector gradient
* - if cross-section not as thick as it should be, add extra padding to fix it
@@ -787,49 +816,44 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness
mt[1] = mb[1] * pthick;
athick = len_v2(mt);
dfac = pthick - (athick * 2);
-
+
if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) {
mt[0] += (mb[0] * dfac);
mt[1] += (mb[1] * dfac);
}
-
+
/* calculate points for start of segment */
t0[0] = s0[0] - mt[0];
t0[1] = s0[1] - mt[1];
t1[0] = s0[0] + mt[0];
t1[1] = s0[1] + mt[1];
-
- /* draw this line twice (once for end of current segment, and once for start of next) */
- glVertex2fv(t1);
- glVertex2fv(t0);
- glVertex2fv(t0);
- glVertex2fv(t1);
+
+ /* Last two points of previous segment, and first two points of current segment. */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
}
-
+
/* if last segment, also draw end of segment (defined as segment's normal) */
if (i == totpoints - 2) {
/* for once, we use second point's pressure (otherwise it won't be drawn) */
pthick = (pt2->pressure * thickness * scalefac);
-
+
/* color of point */
- gp_set_point_color(pt2, ink);
+ gp_set_point_varying_color(pt2, ink, color);
/* calculate points for end of segment */
mt[0] = m2[0] * pthick;
mt[1] = m2[1] * pthick;
-
+
t0[0] = s1[0] - mt[0];
t0[1] = s1[1] - mt[1];
t1[0] = s1[0] + mt[0];
t1[1] = s1[1] + mt[1];
-
- /* draw this line twice (once for end of stroke, and once for endcap)*/
- glVertex2fv(t1);
- glVertex2fv(t0);
- glVertex2fv(t0);
- glVertex2fv(t1);
-
-
+
+ /* Last two points of last segment (and first two points of end cap). */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+
/* draw end cap as last step
* - make points slightly closer to center (about halfway across)
*/
@@ -837,42 +861,25 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness
mt[1] = m2[1] * pthick * 0.5f;
sc[0] = s1[0] + (m1[0] * pthick * 0.75f);
sc[1] = s1[1] + (m1[1] * pthick * 0.75f);
-
+
t0[0] = sc[0] - mt[0];
t0[1] = sc[1] - mt[1];
t1[0] = sc[0] + mt[0];
t1[1] = sc[1] + mt[1];
-
- glVertex2fv(t1);
- glVertex2fv(t0);
+
+ /* Last two points of end cap. */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
}
-
+
/* store computed point2 coordinates as point1 ones of next segment. */
copy_v2_v2(s0, s1);
/* store stroke's 'natural' normal for next stroke to use */
copy_v2_v2(pm, m2);
}
-
- glEnd();
- glShadeModel(GL_SMOOTH);
- }
-
- /* draw debug points of curve on top? (original stroke points) */
- if (debug) {
- bGPDspoint *pt;
- int i;
- float fpt[3];
- glPointSize((float)(thickness_s + 2));
-
- glBegin(GL_POINTS);
- for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
- float co[2];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
- }
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
}
@@ -887,41 +894,41 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
return false;
if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE))
return false;
-
+
/* 2) Screen Space 2D Strokes */
if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE))
return false;
if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
return false;
-
+
/* 3) Image Space (2D) */
if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE))
return false;
if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE))
return false;
-
-
+
/* skip stroke if it doesn't have any valid data */
if ((gps->points == NULL) || (gps->totpoints < 1))
return false;
-
+
/* stroke can be drawn */
return true;
}
/* draw a set of strokes */
static void gp_draw_strokes(
- bGPdata *gpd, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
+ bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
bool debug, short lthick, const float opacity, const float tintcolor[4],
- const bool onion, const bool custonion, float diff_mat[4][4])
+ const bool onion, const bool custonion, const float diff_mat[4][4])
{
- bGPDstroke *gps;
float tcolor[4];
float tfill[4];
short sthickness;
float ink[4];
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ GPU_enable_program_point_size();
+
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
/* check if stroke can be drawn */
if (gp_can_draw_stroke(gps, dflag) == false) {
continue;
@@ -939,6 +946,10 @@ static void gp_draw_strokes(
/* calculate thickness */
sthickness = gps->thickness + lthick;
+ if (sthickness <= 0) {
+ continue;
+ }
+
/* check which stroke-drawer to use */
if (dflag & GP_DRAWDATA_ONLY3D) {
const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
@@ -952,10 +963,6 @@ static void gp_draw_strokes(
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
bglPolygonOffset(1.0f, 1.0f);
-#if 0
- glEnable(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(-1.0f, -1.0f);
-#endif
}
/* 3D Fill */
@@ -965,19 +972,20 @@ static void gp_draw_strokes(
interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]);
tfill[3] = palcolor->fill[3] * opacity;
if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
+ const float *color;
if (!onion) {
- glColor4fv(tfill);
+ color = tfill;
}
else {
if (custonion) {
- glColor4fv(tintcolor);
+ color = tintcolor;
}
else {
ARRAY_SET_ITEMS(tfill, UNPACK3(palcolor->fill), tintcolor[3]);
- glColor4fv(tfill);
+ color = tfill;
}
}
- gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat);
+ gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color);
}
}
@@ -999,7 +1007,7 @@ static void gp_draw_strokes(
}
if (palcolor->flag & PC_COLOR_VOLUMETRIC) {
/* volumetric stroke drawing */
- gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, dflag, gps->flag, diff_mat, ink);
+ gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink);
}
else {
/* 3D Lines - OpenGL primitives-based */
@@ -1017,10 +1025,6 @@ static void gp_draw_strokes(
glDisable(GL_DEPTH_TEST);
bglPolygonOffset(0.0, 0.0);
-#if 0
- glDisable(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(0, 0);
-#endif
}
}
else {
@@ -1030,20 +1034,21 @@ static void gp_draw_strokes(
interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]);
tfill[3] = palcolor->fill[3] * opacity;
if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
+ const float *color;
if (!onion) {
- glColor4fv(tfill);
+ color = tfill;
}
else {
if (custonion) {
- glColor4fv(tintcolor);
+ color = tintcolor;
}
else {
ARRAY_SET_ITEMS(tfill, palcolor->fill[0], palcolor->fill[1], palcolor->fill[2],
tintcolor[3]);
- glColor4fv(tfill);
+ color = tfill;
}
}
- gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat);
+ gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color);
}
}
@@ -1081,15 +1086,15 @@ static void gp_draw_strokes(
}
}
}
+
+ GPU_disable_program_point_size();
}
/* Draw selected verts for strokes being edited */
static void gp_draw_strokes_edit(
- bGPdata *gpd, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag,
- short lflag, float diff_mat[4][4], float alpha)
+ bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag,
+ short lflag, const float diff_mat[4][4], float alpha)
{
- bGPDstroke *gps;
-
/* if alpha 0 do not draw */
if (alpha == 0.0f)
return;
@@ -1103,36 +1108,28 @@ static void gp_draw_strokes_edit(
glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
glDepthMask(0);
glEnable(GL_DEPTH_TEST);
-
+
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
bglPolygonOffset(1.0f, 1.0f);
-#if 0
- glEnable(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(-1.0f, -1.0f);
-#endif
}
}
-
-
- /* draw stroke verts */
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- bGPDspoint *pt;
- float vsize, bsize;
- int i;
- float fpt[3];
+ GPU_enable_program_point_size();
+
+ /* draw stroke verts */
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
/* check if stroke can be drawn */
if (gp_can_draw_stroke(gps, dflag) == false)
continue;
-
+
/* Optimisation: only draw points for selected strokes
* We assume that selected points can only occur in
* strokes that are selected too.
*/
if ((gps->flag & GP_STROKE_SELECT) == 0)
continue;
-
+
/* verify palette color lock */
{
bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
@@ -1151,7 +1148,8 @@ static void gp_draw_strokes_edit(
* they stand out more.
* - We use the theme setting for size of the unselected verts
*/
- bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
+ float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
+ float vsize;
if ((int)bsize > 8) {
vsize = 10.0f;
bsize = 8.0f;
@@ -1159,89 +1157,83 @@ static void gp_draw_strokes_edit(
else {
vsize = bsize + 2;
}
-
- /* First Pass: Draw all the verts (i.e. these become the unselected state) */
+
/* for now, we assume that the base color of the points is not too close to the real color */
/* set color using palette */
bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
- glColor3fv(palcolor->color);
- glPointSize(bsize);
-
- glBegin(GL_POINTS);
- for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) {
+ float selectColor[4];
+ UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
+ selectColor[3] = alpha;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos; /* specified later */
+ unsigned int size = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
+ }
+ else {
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR);
+ }
+
+ immBegin(PRIM_POINTS, gps->totpoints);
+
+ /* Draw start and end point differently if enabled stroke direction hint */
+ bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
+
+ /* Draw all the stroke points (selected or not) */
+ bGPDspoint *pt = gps->points;
+ float fpt[3];
+ for (int i = 0; i < gps->totpoints; i++, pt++) {
+ /* size and color first */
+ if (show_direction_hint && i == 0) {
+ /* start point in green bigger */
+ immAttrib3f(color, 0.0f, 1.0f, 0.0f);
+ immAttrib1f(size, vsize + 4);
+ }
+ else if (show_direction_hint && (i == gps->totpoints - 1)) {
+ /* end point in red smaller */
+ immAttrib3f(color, 1.0f, 0.0f, 0.0f);
+ immAttrib1f(size, vsize + 1);
+ }
+ else if (pt->flag & GP_SPOINT_SELECT) {
+ immAttrib3fv(color, selectColor);
+ immAttrib1f(size, vsize);
+ }
+ else {
+ immAttrib3fv(color, palcolor->color);
+ immAttrib1f(size, bsize);
+ }
+
+ /* then position */
if (gps->flag & GP_STROKE_3DSPACE) {
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
+ immVertex3fv(pos, fpt);
}
else {
float co[2];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
+ immVertex2fv(pos, co);
}
}
- glEnd();
-
-
- /* Second Pass: Draw only verts which are selected */
- float curColor[4];
- UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, curColor);
- glColor4f(curColor[0], curColor[1], curColor[2], alpha);
- glPointSize(vsize);
-
- glBegin(GL_POINTS);
- for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) {
- if (pt->flag & GP_SPOINT_SELECT) {
- if (gps->flag & GP_STROKE_3DSPACE) {
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- glVertex3fv(fpt);
- }
- else {
- float co[2];
-
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- glVertex2fv(co);
- }
- }
- }
- glEnd();
-
- /* Draw start and end point if enabled stroke direction hint */
- if ((gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1)) {
- bGPDspoint *p;
-
- glPointSize(vsize + 4);
- glBegin(GL_POINTS);
-
- /* start point in green bigger */
- glColor3f(0.0f, 1.0f, 0.0f);
- p = &gps->points[0];
- mul_v3_m4v3(fpt, diff_mat, &p->x);
- glVertex3fv(fpt);
- glEnd();
-
- /* end point in red smaller */
- glPointSize(vsize + 1);
- glBegin(GL_POINTS);
-
- glColor3f(1.0f, 0.0f, 0.0f);
- p = &gps->points[gps->totpoints - 1];
- mul_v3_m4v3(fpt, diff_mat, &p->x);
- glVertex3fv(fpt);
- glEnd();
- }
+ immEnd();
+ immUnbindProgram();
}
-
-
+
+ GPU_disable_program_point_size();
+
/* clear depth mask */
if (dflag & GP_DRAWDATA_ONLY3D) {
if (no_xray) {
glDepthMask(mask_orig);
glDisable(GL_DEPTH_TEST);
-
+
bglPolygonOffset(0.0, 0.0);
#if 0
glDisable(GL_POLYGON_OFFSET_LINE);
@@ -1255,8 +1247,8 @@ static void gp_draw_strokes_edit(
/* draw onion-skinning for a layer */
static void gp_draw_onionskins(
- bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
- int UNUSED(cfra), int dflag, bool debug, float diff_mat[4][4])
+ bGPdata *gpd, const bGPDlayer *gpl, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
+ int UNUSED(cfra), int dflag, bool debug, const float diff_mat[4][4])
{
const float default_color[3] = {UNPACK3(U.gpencil_new_layer_col)};
const float alpha = 1.0f;
@@ -1269,17 +1261,14 @@ static void gp_draw_onionskins(
else {
copy_v3_v3(color, default_color);
}
-
+
if (gpl->gstep > 0) {
- bGPDframe *gf;
- float fac;
-
/* draw previous frames first */
- for (gf = gpf->prev; gf; gf = gf->prev) {
+ for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) {
/* check if frame is drawable */
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
- fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
+ float fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
color[3] = alpha * fac * 0.66f;
gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color,
true, gpl->flag & GP_LAYER_GHOST_PREVCOL, diff_mat);
@@ -1299,8 +1288,7 @@ static void gp_draw_onionskins(
else {
/* don't draw - disabled */
}
-
-
+
/* 2) Now draw next frames */
if (gpl->flag & GP_LAYER_GHOST_NEXTCOL) {
copy_v3_v3(color, gpl->gcolor_next);
@@ -1308,17 +1296,14 @@ static void gp_draw_onionskins(
else {
copy_v3_v3(color, default_color);
}
-
+
if (gpl->gstep_next > 0) {
- bGPDframe *gf;
- float fac;
-
/* now draw next frames */
- for (gf = gpf->next; gf; gf = gf->next) {
+ for (bGPDframe *gf = gpf->next; gf; gf = gf->next) {
/* check if frame is drawable */
if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) {
/* alpha decreases with distance from curframe index */
- fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
+ float fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
color[3] = alpha * fac * 0.66f;
gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color,
true, gpl->flag & GP_LAYER_GHOST_NEXTCOL, diff_mat);
@@ -1338,7 +1323,6 @@ static void gp_draw_onionskins(
else {
/* don't draw - disabled */
}
-
}
/* draw interpolate strokes (used only while operator is running) */
@@ -1376,29 +1360,27 @@ void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type)
/* loop over gpencil data layers, drawing them */
static void gp_draw_data_layers(
- bGPDbrush *brush, float alpha, bGPdata *gpd,
+ const bGPDbrush *brush, float alpha, bGPdata *gpd,
int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
- bGPDlayer *gpl;
float diff_mat[4][4];
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- bGPDframe *gpf;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* calculate parent position */
ED_gpencil_parent_location(gpl, diff_mat);
- bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? true : false;
+ bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG);
short lthick = brush->thickness + gpl->thickness;
-
+
/* don't draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE)
continue;
-
+
/* get frame to draw */
- gpf = BKE_gpencil_layer_getframe(gpl, cfra, 0);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra, 0);
if (gpf == NULL)
continue;
-
+
/* set basic stroke thickness */
glLineWidth(lthick);
@@ -1410,10 +1392,10 @@ static void gp_draw_data_layers(
if (condition) dflag |= (draw_flag_value); \
else dflag &= ~(draw_flag_value); \
} (void)0
-
+
/* xray... */
GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_NO_XRAY), GP_DRAWDATA_NO_XRAY);
-
+
/* volumetric strokes... */
GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_VOLUMETRIC), GP_DRAWDATA_VOLUMETRIC);
@@ -1437,11 +1419,11 @@ static void gp_draw_data_layers(
*/
gp_draw_onionskins(gpd, gpl, gpf, offsx, offsy, winx, winy, cfra, dflag, debug, diff_mat);
}
-
+
/* draw the strokes already in active frame */
gp_draw_strokes(gpd, gpf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness,
gpl->opacity, gpl->tintcolor, false, false, diff_mat);
-
+
/* Draw verts of selected strokes
* - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
* - locked layers can't be edited, so there's no point showing these verts
@@ -1456,16 +1438,13 @@ static void gp_draw_data_layers(
{
gp_draw_strokes_edit(gpd, gpf, offsx, offsy, winx, winy, dflag, gpl->flag, diff_mat, alpha);
}
-
+
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke buffer is currently stored in gp-data)
*/
if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
(gpf->flag & GP_FRAME_PAINT))
{
- /* Set color for drawing buffer stroke - since this may not be set yet */
- // glColor4fv(gpl->color);
-
/* Buffer stroke needs to be drawn with a different linestyle
* to help differentiate them from normal strokes.
*
@@ -1474,89 +1453,84 @@ static void gp_draw_data_layers(
*/
if (gpd->sflag & PC_COLOR_VOLUMETRIC) {
gp_draw_stroke_volumetric_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick,
- dflag, gpd->sbuffer_sflag, gpd->scolor);
+ dflag, gpd->scolor);
}
else {
- gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor);
+ gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor, gpd->sfill);
}
}
}
}
/* draw a short status message in the top-right corner */
-static void gp_draw_status_text(bGPdata *gpd, ARegion *ar)
+static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar)
{
rcti rect;
-
+
/* Cannot draw any status text when drawing OpenGL Renders */
if (G.f & G_RENDER_OGL)
return;
-
+
/* Get bounds of region - Necessary to avoid problems with region overlap */
ED_region_visible_rect(ar, &rect);
-
+
/* for now, this should only be used to indicate when we are in stroke editmode */
if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
const char *printable = IFACE_("GPencil Stroke Editing");
float printable_size[2];
- int xco, yco;
-
- BLF_width_and_height_default(printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
-
- xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
- yco = (rect.ymax - U.widget_unit);
+
+ int font_id = BLF_default();
+
+ BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
+ int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
+ int yco = (rect.ymax - U.widget_unit);
+
/* text label */
- UI_ThemeColor(TH_TEXT_HI);
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
#ifdef WITH_INTERNATIONAL
BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
#else
BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
#endif
-
+
/* grease pencil icon... */
// XXX: is this too intrusive?
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
xco -= U.widget_unit;
yco -= (int)printable_size[1] / 2;
UI_icon_draw(xco, yco, ICON_GREASEPENCIL);
-
+
glDisable(GL_BLEND);
}
}
/* draw grease-pencil datablock */
static void gp_draw_data(
- bGPDbrush *brush, float alpha, bGPdata *gpd,
+ const bGPDbrush *brush, float alpha, bGPdata *gpd,
int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
- /* reset line drawing style (in case previous user didn't reset) */
- setlinestyle(0);
-
/* turn on smooth lines (i.e. anti-aliasing) */
glEnable(GL_LINE_SMOOTH);
-
+
/* XXX: turn on some way of ensuring that the polygon edges get smoothed
* GL_POLYGON_SMOOTH is nasty and shouldn't be used, as it ends up
* creating internal white rays due to the ways it accumulates stuff
*/
-
+
/* turn on alpha-blending */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
/* draw! */
gp_draw_data_layers(brush, alpha, gpd, offsx, offsy, winx, winy, cfra, dflag);
-
+
/* turn off alpha blending, then smooth lines */
glDisable(GL_BLEND); // alpha blending
glDisable(GL_LINE_SMOOTH); // smooth lines
-
- /* restore initial gl conditions */
- glColor4f(0, 0, 0, 1);
}
/* if we have strokes for scenes (3d view)/clips (movie clip editor)
@@ -1591,7 +1565,7 @@ static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, i
}
}
}
-
+
/* scene/clip data has already been drawn, only object/track data is drawn here
* if gpd_source == gpd, we don't have any object/track data and we can skip */
if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) {
@@ -1617,28 +1591,27 @@ void ED_gpencil_draw_2dimage(const bContext *C)
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
- bGPdata *gpd;
+
int offsx, offsy, sizex, sizey;
int dflag = GP_DRAWDATA_NOSTATUS;
-
- gpd = ED_gpencil_data_get_active(C); // XXX
+
+ bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
if (gpd == NULL) return;
-
+
/* calculate rect */
switch (sa->spacetype) {
case SPACE_IMAGE: /* image */
case SPACE_CLIP: /* clip */
{
-
/* just draw using standard scaling (settings here are currently ignored anyways) */
/* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
offsx = 0;
offsy = 0;
sizex = ar->winx;
sizey = ar->winy;
-
+
wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax);
-
+
dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK;
break;
}
@@ -1649,7 +1622,7 @@ void ED_gpencil_draw_2dimage(const bContext *C)
offsy = 0;
sizex = ar->winx;
sizey = ar->winy;
-
+
/* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated
* and everything moved to standard View2d
*/
@@ -1661,77 +1634,74 @@ void ED_gpencil_draw_2dimage(const bContext *C)
offsy = 0;
sizex = ar->winx;
sizey = ar->winy;
-
+
dflag |= GP_DRAWDATA_ONLYI2D;
break;
}
-
+
if (ED_screen_animation_playing(wm)) {
/* don't show onionskins during animation playback/scrub (i.e. it obscures the poses)
* OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
*/
dflag |= GP_DRAWDATA_NO_ONIONS;
}
-
-
+
/* draw it! */
gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype);
}
/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
- * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes,
- * second time with onlyv2d=0 for screen-aligned strokes */
+ * Note: this gets called twice - first time with onlyv2d=true to draw 'canvas' strokes,
+ * second time with onlyv2d=false for screen-aligned strokes */
void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d)
{
wmWindowManager *wm = CTX_wm_manager(C);
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
- bGPdata *gpd;
int dflag = 0;
/* check that we have grease-pencil stuff to draw */
if (sa == NULL) return;
- gpd = ED_gpencil_data_get_active(C); // XXX
+ bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
if (gpd == NULL) return;
-
+
/* special hack for Image Editor */
/* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP))
dflag |= GP_DRAWDATA_IEDITHACK;
-
+
/* draw it! */
if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS);
if (ED_screen_animation_playing(wm)) dflag |= GP_DRAWDATA_NO_ONIONS;
-
+
gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype);
-
+
/* draw status text (if in screen/pixel-space) */
- if (onlyv2d == false) {
+ if (!onlyv2d) {
gp_draw_status_text(gpd, ar);
}
}
/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
- * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes,
- * second time with only3d=0 for screen-aligned strokes */
+ * Note: this gets called twice - first time with only3d=true to draw 3d-strokes,
+ * second time with only3d=false for screen-aligned strokes */
void ED_gpencil_draw_view3d(wmWindowManager *wm, Scene *scene, View3D *v3d, ARegion *ar, bool only3d)
{
- bGPdata *gpd;
int dflag = 0;
RegionView3D *rv3d = ar->regiondata;
int offsx, offsy, winx, winy;
-
+
/* check that we have grease-pencil stuff to draw */
- gpd = ED_gpencil_data_get_active_v3d(scene, v3d);
+ bGPdata *gpd = ED_gpencil_data_get_active_v3d(scene, v3d);
if (gpd == NULL) return;
-
+
/* when rendering to the offscreen buffer we don't want to
* deal with the camera border, otherwise map the coords to the camera border. */
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
rctf rectf;
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, true); /* no shift */
-
+
offsx = iroundf(rectf.xmin);
offsy = iroundf(rectf.ymin);
winx = iroundf(rectf.xmax - rectf.xmin);
@@ -1743,7 +1713,7 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm, Scene *scene, View3D *v3d, AReg
winx = ar->winx;
winy = ar->winy;
}
-
+
/* set flags */
if (only3d) {
/* 3D strokes/3D space:
@@ -1752,28 +1722,27 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm, Scene *scene, View3D *v3d, AReg
*/
dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
}
-
+
if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
/* don't draw status text when "only render" flag is set */
dflag |= GP_DRAWDATA_NOSTATUS;
}
-
+
if ((wm == NULL) || ED_screen_animation_playing(wm)) {
/* don't show onionskins during animation playback/scrub (i.e. it obscures the poses)
* OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
*/
dflag |= GP_DRAWDATA_NO_ONIONS;
}
-
+
/* draw it! */
- gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
-
+ gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
}
void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype)
{
int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D;
-
+
gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype);
}
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 8ddf3a22517..c2807f72fbb 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -75,8 +75,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "gpencil_intern.h"
@@ -958,28 +958,28 @@ static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
{
GP_EditBrush_Data *brush = gpsculpt_get_brush(CTX_data_scene(C));
-
+
if (brush) {
- glPushMatrix();
-
- glTranslatef((float)x, (float)y, 0.0f);
-
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
-
+
/* Inner Ring: Light color for action of the brush */
/* TODO: toggle between add and remove? */
- glColor4ub(255, 255, 255, 200);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, brush->size, 40);
-
+ immUniformColor4ub(255, 255, 255, 200);
+ imm_draw_circle_wire(pos, x, y, brush->size, 40);
+
/* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */
- glColor3ub(30, 30, 30);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, brush->size + 1, 40);
-
+ immUniformColor3ub(30, 30, 30);
+ imm_draw_circle_wire(pos, x, y, brush->size + 1, 40);
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
-
- glPopMatrix();
}
}
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index d0f68c4b8f3..8c98d570096 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -56,12 +56,14 @@
#include "DNA_view3d_types.h"
#include "DNA_gpencil_types.h"
+#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -1121,14 +1123,15 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
const bool norm_weights, const float rad_fac, const bool link_strokes, tGpTimingData *gtd)
{
struct Main *bmain = CTX_data_main(C);
- View3D *v3d = CTX_wm_view3d(C); /* may be NULL */
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ SceneCollection *sc = CTX_data_scene_collection(C);
bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
bGPDstroke *gps, *prev_gps = NULL;
Object *ob;
Curve *cu;
Nurb *nu = NULL;
- Base *base_orig = BASACT, *base_new = NULL;
+ Base *base_new = NULL;
float minmax_weights[2] = {1.0f, 0.0f};
/* camera framing */
@@ -1152,7 +1155,8 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
*/
ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info);
cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE);
- base_new = BKE_scene_base_add(scene, ob);
+ BKE_collection_object_add(scene, sc, ob);
+ base_new = BKE_scene_layer_base_find(sl, ob);
cu->flag |= CU_3D;
@@ -1216,8 +1220,8 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
}
/* set the layer and select */
- base_new->lay = ob->lay = base_orig ? base_orig->lay : BKE_screen_view3d_layer_active(v3d, scene);
- base_new->flag = ob->flag = base_new->flag | SELECT;
+ base_new->flag |= SELECT;
+ BKE_scene_object_base_flag_sync_from_base(base_new);
}
/* --- */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 2df4b2cae54..b4cfc1a8d87 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -2010,8 +2010,9 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* init autodist for geometry projection */
if (mode == GP_REPROJECT_SURFACE) {
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar);
- ED_view3d_autodist_init(scene, gsc.ar, CTX_wm_view3d(C), 0);
+ ED_view3d_autodist_init(graph, gsc.ar, CTX_wm_view3d(C), 0);
}
// TODO: For deforming geometry workflow, create new frames?
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 5eacbf6f807..eb37c3fe629 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -69,9 +69,11 @@
#include "ED_view3d.h"
#include "ED_clip.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -113,6 +115,7 @@ typedef enum eGPencil_PaintFlags {
*/
typedef struct tGPsdata {
Scene *scene; /* current scene from context */
+ struct Depsgraph *graph;
wmWindow *win; /* window where painting originated */
ScrArea *sa; /* area where painting originated */
@@ -637,7 +640,8 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
View3D *v3d = p->sa->spacedata.first;
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(
+ p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
/* convert screen-coordinates to appropriate coordinates (and store them) */
@@ -1237,9 +1241,8 @@ static void gp_stroke_doeraser(tGPsdata *p)
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
View3D *v3d = p->sa->spacedata.first;
-
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, 0);
+ ED_view3d_autodist_init(p->graph, p->ar, v3d, 0);
}
}
@@ -1393,6 +1396,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
/* pass on current scene and window */
p->scene = CTX_data_scene(C);
+ p->graph = CTX_data_depsgraph(C);
p->win = CTX_wm_window(C);
unit_m4(p->imat);
@@ -1547,6 +1551,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
bGPDpalettecolor *palcolor = p->palettecolor;
bGPdata *pdata = p->gpd;
copy_v4_v4(pdata->scolor, palcolor->color);
+ copy_v4_v4(pdata->sfill, palcolor->fill);
pdata->sflag = palcolor->flag;
/* lock axis */
p->lock_axis = ts->gp_sculpt.lock_axis;
@@ -1804,7 +1809,7 @@ static void gp_paint_strokeend(tGPsdata *p)
/* need to restore the original projection settings before packing up */
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
/* check if doing eraser or not */
@@ -1842,28 +1847,41 @@ static void gp_paint_cleanup(tGPsdata *p)
static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
{
tGPsdata *p = (tGPsdata *)p_ptr;
-
+
if (p->paintmode == GP_PAINTMODE_ERASER) {
- glPushMatrix();
-
- glTranslatef((float)x, (float)y, 0.0f);
-
+ VertexFormat *format = immVertexFormat();
+ const uint shdr_pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
-
- glColor4ub(255, 100, 100, 20);
- glutil_draw_filled_arc(0.0, M_PI * 2.0, p->radius, 40);
-
- setlinestyle(6);
-
- glColor4ub(255, 100, 100, 200);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, p->radius, 40);
-
- setlinestyle(0);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ immUniformColor4ub(255, 100, 100, 20);
+ imm_draw_circle_fill(shdr_pos, x, y, p->radius, 40);
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f);
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniform1f("dash_width", 12.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ imm_draw_circle_wire(shdr_pos, x, y, p->radius,
+ /* XXX Dashed shader gives bad results with sets of small segments currently,
+ * temp hack around the issue. :( */
+ max_ii(8, p->radius / 2)); /* was fixed 40 */
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
-
- glPopMatrix();
}
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 2b662d04f03..05b45a2f2eb 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -204,7 +204,7 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C)
// XXX: this should be removed... We really shouldn't duplicate logic like this!
bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d)
{
- Base *base = scene->basact;
+ BaseLegacy *base = scene->basact;
bGPdata *gpd = NULL;
/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
* to be consistent with ED_gpencil_data_get_active's behavior.
@@ -521,6 +521,7 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
if (sa->spacetype == SPACE_VIEW3D) {
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
View3D *v3d = (View3D *)CTX_wm_space_data(C);
RegionView3D *rv3d = ar->regiondata;
@@ -528,7 +529,7 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
view3d_operator_needs_opengl(C);
view3d_region_operator_needs_opengl(win, ar);
- ED_view3d_autodist_init(scene, ar, v3d, 0);
+ ED_view3d_autodist_init(graph, ar, v3d, 0);
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
@@ -868,8 +869,8 @@ bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf)
ptc = &gps->points[after];
/* the optimal value is the corresponding to the interpolation of the pressure
- * at the distance of point b
- */
+ * at the distance of point b
+ */
float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
float optimal = (1.0f - fac) * pta->pressure + fac * ptc->pressure;
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index e264d9e16a3..f91e7d42bca 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -36,45 +36,6 @@
#include "GPU_glew.h"
#include "BLI_utildefines.h"
-/*
- * these should be phased out. cpack should be replaced in
- * code with calls to glColor3ub. - zr
- */
-/*
- *
- * This define converts a numerical value to the equivalent 24-bit
- * color, while not being endian-sensitive. On little-endians, this
- * is the same as doing a 'naive' indexing, on big-endian, it is not!
- * */
-void cpack(unsigned int x);
-
-#ifdef WITH_GL_PROFILE_COMPAT
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
-# define glMultMatrixf(x) \
- glMultMatrixf(_Generic((x), \
- float *: (float *)(x), \
- float [16]: (float *)(x), \
- float (*)[4]: (float *)(x), \
- float [4][4]: (float *)(x), \
- const float *: (float *)(x), \
- const float [16]: (float *)(x), \
- const float (*)[4]: (float *)(x), \
- const float [4][4]: (float *)(x)) \
-)
-# define glLoadMatrixf(x) \
- glLoadMatrixf(_Generic((x), \
- float *: (float *)(x), \
- float [16]: (float *)(x), \
- float (*)[4]: (float *)(x), \
- float [4][4]: (float *)(x)) \
-)
-#else
-# define glMultMatrixf(x) glMultMatrixf((float *)(x))
-# define glLoadMatrixf(x) glLoadMatrixf((float *)(x))
-#endif /* C11 */
-#endif /* WITH_GL_PROFILE_COMPAT */
-
-
/* hacking pointsize and linewidth */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
# define glPointSize(f) glPointSize(U.pixelsize * _Generic((f), double: (float)(f), default: (f)))
@@ -86,19 +47,5 @@ void cpack(unsigned int x);
#define GLA_PIXEL_OFS 0.375f
-
-BLI_INLINE void glTranslate3iv(const int vec[3]) { glTranslatef(UNPACK3_EX((const float), vec, )); }
-BLI_INLINE void glTranslate2iv(const int vec[2]) { glTranslatef(UNPACK2_EX((const float), vec, ), 0.0f); }
-BLI_INLINE void glTranslate3fv(const float vec[3]) { glTranslatef(UNPACK3(vec)); }
-BLI_INLINE void glTranslate2fv(const float vec[2]) { glTranslatef(UNPACK2(vec), 0.0f); }
-
-BLI_INLINE void glScale3iv(const int vec[3]) { glTranslatef(UNPACK3_EX((const float), vec, )); }
-BLI_INLINE void glScale2iv(const int vec[2]) { glTranslatef(UNPACK2_EX((const float), vec, ), 0.0f); }
-BLI_INLINE void glScale3fv(const float vec[3]) { glScalef(UNPACK3(vec)); }
-BLI_INLINE void glScale2fv(const float vec[2]) { glScalef(UNPACK2(vec), 0.0); }
-
-/* v2 versions don't make much sense for rotation */
-BLI_INLINE void glRotate3fv(const float angle, const float vec[3]) { glRotatef(angle, UNPACK3(vec)); }
-
#endif /* #ifdef __BIF_GL_H__ */
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index d3d2c465d46..3184ebee4d9 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -38,56 +38,14 @@ struct bContext;
struct ColorManagedViewSettings;
struct ColorManagedDisplaySettings;
-void fdrawbezier(float vec[4][3]);
-void fdrawline(float x1, float y1, float x2, float y2);
-void fdrawbox(float x1, float y1, float x2, float y2);
-void sdrawline(int x1, int y1, int x2, int y2);
-#if 0
-void sdrawtri(int x1, int y1, int x2, int y2);
-void sdrawtrifill(int x1, int y1, int x2, int y2);
-#endif
-void sdrawbox(int x1, int y1, int x2, int y2);
-
-void sdrawXORline(int x0, int y0, int x1, int y1);
-void sdrawXORline4(int nr, int x0, int y0, int x1, int y1);
-
-void fdrawXORellipse(float xofs, float yofs, float hw, float hh);
-void fdrawXORcirc(float xofs, float yofs, float rad);
-
-void fdrawcheckerboard(float x1, float y1, float x2, float y2);
-
-/* OpenGL stipple defines */
-extern const unsigned char stipple_halftone[128];
-extern const unsigned char stipple_quarttone[128];
-extern const unsigned char stipple_diag_stripes_pos[128];
-extern const unsigned char stipple_diag_stripes_neg[128];
-extern const unsigned char stipple_checker_8px[128];
-
-/**
- * Draw a lined (non-looping) arc with the given
- * \a radius, starting at angle \a start and arcing
- * through \a angle. The arc is centered at the origin
- * and drawn in the XY plane.
+/* A few functions defined here are being DEPRECATED for Blender 2.8
*
- * \param start The initial angle (in radians).
- * \param angle The length of the arc (in radians).
- * \param radius The arc radius.
- * \param nsegments The number of segments to use in drawing the arc.
- */
-void glutil_draw_lined_arc(float start, float angle, float radius, int nsegments);
-
-/**
- * Draw a filled arc with the given \a radius,
- * starting at angle \a start and arcing through
- * \a angle. The arc is centered at the origin
- * and drawn in the XY plane.
+ * Do not use them in new code, and you are encouraged to
+ * convert existing code to draw without these.
*
- * \param start The initial angle (in radians).
- * \param angle The length of the arc (in radians).
- * \param radius The arc radius.
- * \param nsegments The number of segments to use in drawing the arc.
+ * These will be deleted before we ship 2.8!
+ * - merwin
*/
-void glutil_draw_filled_arc(float start, float angle, float radius, int nsegments);
/**
* Returns a float value as obtained by glGetFloatv.
@@ -109,58 +67,46 @@ int glaGetOneInt(int param);
*/
void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y);
-/**
- * Functions like a limited glDrawPixels, except ensures that
- * the image is displayed onscreen even if the \a x and \a y
- * coordinates for would be clipped. The routine respects the
- * glPixelZoom values, pixel unpacking parameters are _not_
- * respected.
- *
- * \attention This routine makes many assumptions: the rect data
- * is expected to be in RGBA unsigned byte format, the coordinate
- * (GLA_PIXEL_OFS, GLA_PIXEL_OFS) is assumed to be within the view frustum,
- * and the modelview and projection matrices are assumed to define a
- * 1-to-1 mapping to screen space.
- * \attention Furthermore, in the case of zoomed or unpixel aligned
- * images extending outside the view frustum, but still within the
- * window, some portion of the image may be visible left and/or
- * below of the given \a x and \a y coordinates. It is recommended
- * to use the glScissor functionality if images are to be drawn
- * with an inset view matrix.
- */
-void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect);
+typedef struct IMMDrawPixelsTexState {
+ struct GPUShader *shader;
+ unsigned int pos;
+ unsigned int texco;
+ bool do_shader_unbind;
+} IMMDrawPixelsTexState;
+
+/* To be used before calling immDrawPixelsTex
+ * Default shader is GPU_SHADER_2D_IMAGE_COLOR
+ * Returns a shader to be able to set uniforms */
+IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin);
/**
- * glaDrawPixelsTex - Functions like a limited glDrawPixels, but actually draws the
+ * immDrawPixelsTex - Functions like a limited glDrawPixels, but actually draws the
* image using textures, which can be tremendously faster on low-end
* cards, and also avoids problems with the raster position being
- * clipped when offscreen. The routine respects the glPixelZoom values,
- * pixel unpacking parameters are _not_ respected.
+ * clipped when offscreen. Pixel unpacking parameters and
+ * the glPixelZoom values are _not_ respected.
+ *
+ * \attention Use immDrawPixelsTexSetup before calling this function.
*
* \attention This routine makes many assumptions: the rect data
* is expected to be in RGBA byte or float format, and the
* modelview and projection matrices are assumed to define a
* 1-to-1 mapping to screen space.
*/
-
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
-void glaDrawPixelsTex_clipping(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect,
- float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y);
-
-/**
- * glaDrawPixelsAuto - Switches between texture or pixel drawing using UserDef.
- * only RGBA
- * needs glaDefine2DArea to be set.
- */
-void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
-void glaDrawPixelsAuto_clipping(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect,
- float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y);
-
-
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY);
-void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY,
- float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y);
-
+void immDrawPixelsTex(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect,
+ float xzoom, float yzoom, float color[4]);
+void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect,
+ float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y,
+ float xzoom, float yzoom, float color[4]);
+void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY,
+ float xzoom, float yzoom, float color[4]);
+void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY,
+ float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y,
+ float xzoom, float yzoom, float color[4]);
/* 2D Drawing Assistance */
/** Define a 2D area (viewport, scissor, matrices) for OpenGL rendering.
@@ -176,12 +122,13 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h, int
*/
void glaDefine2DArea(struct rcti *screen_rect);
-typedef struct gla2DDrawInfo gla2DDrawInfo;
+/* TODO(merwin): put the following 2D code to use, or build new 2D code inspired & informd by it */
+
+#if 0 /* UNUSED */
-/* UNUSED */
-#if 0
+typedef struct gla2DDrawInfo gla2DDrawInfo;
-gla2DDrawInfo *glaBegin2DDraw(struct rcti *screen_rect, struct rctf *world_rect);
+gla2DDrawInfo *glaBegin2DDraw(struct rcti *screen_rect, struct rctf *world_rect);
void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x, int *r_sc_y);
void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int r_screen[2]);
@@ -190,7 +137,8 @@ void glaEnd2DDraw(gla2DDrawInfo *di);
/** Adjust the transformation mapping of a 2d area */
void gla2DGetMap(gla2DDrawInfo *di, struct rctf *rect);
void gla2DSetMap(gla2DDrawInfo *di, struct rctf *rect);
-#endif
+
+#endif /* UNUSED */
void set_inverted_drawing(int enable);
void setlinestyle(int nr);
@@ -198,37 +146,32 @@ void setlinestyle(int nr);
/* own working polygon offset */
void bglPolygonOffset(float viewdist, float dist);
-/* For caching opengl matrices (gluProject/gluUnProject) */
-typedef struct bglMats {
- double modelview[16];
- double projection[16];
- int viewport[4];
-} bglMats;
-void bgl_get_mats(bglMats *mats);
-
/* **** Color management helper functions for GLSL display/transform ***** */
/* Draw imbuf on a screen, preferably using GLSL display transform */
void glaDrawImBuf_glsl(struct ImBuf *ibuf, float x, float y, int zoomfilter,
struct ColorManagedViewSettings *view_settings,
- struct ColorManagedDisplaySettings *display_settings);
+ struct ColorManagedDisplaySettings *display_settings,
+ float zoom_x, float zoom_y);
void glaDrawImBuf_glsl_clipping(struct ImBuf *ibuf, float x, float y, int zoomfilter,
struct ColorManagedViewSettings *view_settings,
struct ColorManagedDisplaySettings *display_settings,
float clip_min_x, float clip_min_y,
- float clip_max_x, float clip_max_y);
+ float clip_max_x, float clip_max_y,
+ float zoom_x, float zoom_y);
/* Draw imbuf on a screen, preferably using GLSL display transform */
-void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter);
+void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter,
+ float zoom_x, float zoom_y);
void glaDrawImBuf_glsl_ctx_clipping(const struct bContext *C,
struct ImBuf *ibuf,
float x, float y,
int zoomfilter,
float clip_min_x, float clip_min_y,
- float clip_max_x, float clip_max_y);
+ float clip_max_x, float clip_max_y,
+ float zoom_x, float zoom_y);
-void glaDrawBorderCorners(const struct rcti *border, float zoomx, float zoomy);
+void immDrawBorderCorners(unsigned int pos, const struct rcti *border, float zoomx, float zoomy);
#endif /* __BIF_GLUTIL_H__ */
-
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 4a4ab832b28..a65c6eec6ae 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -82,6 +82,7 @@ typedef struct bAnimContext {
struct bDopeSheet *ads; /* dopesheet data for editor (or which is being used) */
struct Scene *scene; /* active scene */
+ struct SceneLayer *scene_layer; /* active scene layer */
struct Object *obact; /* active object */
ListBase *markers; /* active set of markers */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 6b8943421bd..7866bed8666 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -35,7 +35,7 @@ extern "C" {
#endif
struct bArmature;
-struct Base;
+struct BaseLegacy;
struct bContext;
struct Bone;
struct bPoseChannel;
@@ -44,8 +44,10 @@ struct ListBase;
struct MeshDeformModifierData;
struct DerivedMesh;
struct Object;
+struct Base;
struct ReportList;
struct Scene;
+struct SceneLayer;
struct ViewContext;
struct wmKeyConfig;
struct wmOperator;
@@ -82,6 +84,12 @@ typedef struct EditBone {
short segments;
+ /* Used for display */
+ float disp_mat[4][4]; /* in Armature space, rest pos matrix */
+ float disp_tail_mat[4][4]; /* in Armature space, rest pos matrix */
+ /* 32 == MAX_BBONE_SUBDIV */
+ float disp_bbone_mat[32][4][4]; /* in Armature space, rest pos matrix */
+
/* Used to store temporary data */
union {
struct EditBone *ebone;
@@ -131,7 +139,7 @@ void ED_armature_deselect_all(struct Object *obedit);
void ED_armature_deselect_all_visible(struct Object *obedit);
bool ED_do_pose_selectbuffer(
- struct Scene *scene, struct Base *base, const unsigned int *buffer, short hits,
+ struct Scene *scene, struct SceneLayer *sl, struct Base *base, const unsigned int *buffer, short hits,
bool extend, bool deselect, bool toggle, bool do_nearest);
bool ED_armature_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
int join_armature_exec(struct bContext *C, struct wmOperator *op);
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 9de550a20ce..00e58785373 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -39,6 +39,7 @@ struct ToolSettings;
struct wmWindowManager;
struct ARegion;
struct Scene;
+struct SceneLayer;
/* image_edit.c, exported for transform */
struct Image *ED_space_image(struct SpaceImage *sima);
@@ -74,7 +75,7 @@ bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit);
bool ED_space_image_paint_curve(const struct bContext *C);
-bool ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima);
+bool ED_space_image_check_show_maskedit(struct SceneLayer *sl, struct SpaceImage *sima);
int ED_space_image_maskedit_poll(struct bContext *C);
int ED_space_image_maskedit_mask_poll(struct bContext *C);
diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h
index 6970abaa633..fe570fef83d 100644
--- a/source/blender/editors/include/ED_info.h
+++ b/source/blender/editors/include/ED_info.h
@@ -28,7 +28,7 @@
#define __ED_INFO_H__
/* info_stats.c */
-void ED_info_stats_clear(struct Scene *scene);
-const char *ED_info_stats_string(struct Scene *scene);
+void ED_info_stats_clear(struct SceneLayer *sl);
+const char *ED_info_stats_string(struct Scene *scene, struct SceneLayer *sl);
#endif /* __ED_INFO_H__ */
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index c478a8b17e5..8eef016a846 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -108,8 +108,10 @@ typedef enum eKeyframeShapeDrawOpts {
KEYFRAME_SHAPE_BOTH
} eKeyframeShapeDrawOpts;
-/* draw simple diamond-shape keyframe (with OpenGL) */
-void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, short key_type, short mode, float alpha);
+/* draw simple diamond-shape keyframe */
+/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, immBegin(PRIM_POINTS, n), then call this n times */
+void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha,
+ unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id);
/* ******************************* Methods ****************************** */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index de798b1fce2..0ee60471357 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -113,8 +113,8 @@ struct UvElementMap *BM_uv_element_map_create(
void BM_uv_element_map_free(struct UvElementMap *vmap);
struct UvElement *BM_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l);
-bool EDBM_mtexpoly_check(struct BMEditMesh *em);
-struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace **r_act_efa, const bool sloppy, const bool selected);
+bool EDBM_uv_check(struct BMEditMesh *em);
+struct BMFace *EDBM_uv_active_face_get(struct BMEditMesh *em, const bool sloppy, const bool selected);
void BM_uv_vert_map_free(struct UvVertMap *vmap);
struct UvMapVert *BM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v);
@@ -259,7 +259,6 @@ void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGrou
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum);
void ED_vgroup_vert_active_mirror(struct Object *ob, int def_nr);
-
/* mesh_data.c */
// void ED_mesh_geometry_add(struct Mesh *mesh, struct ReportList *reports, int verts, int edges, int faces);
void ED_mesh_polys_add(struct Mesh *mesh, struct ReportList *reports, int count);
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index e3c382382a9..20363c69fa0 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -75,7 +75,7 @@ void ED_init_custom_node_socket_type(struct bNodeSocketType *stype);
void ED_init_standard_node_socket_type(struct bNodeSocketType *stype);
void ED_init_node_socket_type_virtual(struct bNodeSocketType *stype);
void ED_node_sample_set(const float col[4]);
-void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, NodeBorder border);
+void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos);
/* node_draw.c */
void ED_node_tree_update(const struct bContext *C);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 04ff5692717..9e5d55dd031 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -35,14 +35,17 @@
extern "C" {
#endif
-struct Base;
+struct bFaceMap;
+struct BaseLegacy;
struct EnumPropertyItem;
struct ID;
struct Main;
struct ModifierData;
struct Object;
+struct Base;
struct ReportList;
struct Scene;
+struct SceneLayer;
struct bConstraint;
struct bContext;
struct bPoseChannel;
@@ -89,7 +92,6 @@ bool ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct
struct Object *par, int partype, const bool xmirror, const bool keep_transform,
const int vert_par[3]);
void ED_object_parent_clear(struct Object *ob, const int type);
-struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob);
void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
@@ -98,14 +100,20 @@ void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMa
const bool do_connected);
/* send your own notifier for select! */
-void ED_base_object_select(struct Base *base, short mode);
+void ED_base_object_select(struct BaseLegacy *base, short mode);
/* includes notifier */
-void ED_base_object_activate(struct bContext *C, struct Base *base);
+void ED_base_object_activate(struct bContext *C, struct BaseLegacy *base);
+
+void ED_object_base_select(struct Base *base, short mode);
+void ED_object_base_activate(struct bContext *C, struct Base *base);
-void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Base *base);
+void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Object *ob);
+
+void ED_base_object_sync_from_base(struct BaseLegacy *base, struct Object *ob);
+void ED_base_object_sync_from_object(struct BaseLegacy *base, struct Object *ob);
/* single object duplicate, if (dupflag == 0), fully linked, else it uses the flags given */
-struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, struct Base *base, int dupflag);
+struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, struct Base *base, int dupflag);
void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr);
@@ -191,7 +199,7 @@ void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
- struct Object *ob, struct ModifierData *md);
+ struct SceneLayer *sl, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene,
struct Object *ob, struct ModifierData *md, int mode);
int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
@@ -214,6 +222,10 @@ struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object);
+/* object_facemap_ops.c */
+void ED_object_facemap_face_add(struct Object *ob, struct bFaceMap *fmap, int facenum);
+void ED_object_facemap_face_remove(struct Object *ob, struct bFaceMap *fmap, int facenum);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 6cb8c0cfb19..41c746aa421 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -38,21 +38,22 @@ struct ParticleEditSettings;
struct rcti;
struct PTCacheEdit;
struct Scene;
+struct SceneLayer;
/* particle edit mode */
void PE_free_ptcache_edit(struct PTCacheEdit *edit);
int PE_start_edit(struct PTCacheEdit *edit);
/* access */
-struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob);
+struct PTCacheEdit *PE_get_current(struct Scene *scene, struct SceneLayer *sl, struct Object *ob);
struct PTCacheEdit *PE_create_current(struct Scene *scene, struct Object *ob);
void PE_current_changed(struct Scene *scene, struct Object *ob);
-int PE_minmax(struct Scene *scene, float min[3], float max[3]);
+int PE_minmax(struct Scene *scene, struct SceneLayer *sl, float min[3], float max[3]);
struct ParticleEditSettings *PE_settings(struct Scene *scene);
/* update calls */
void PE_hide_keys_time(struct Scene *scene, struct PTCacheEdit *edit, float cfra);
-void PE_update_object(struct Scene *scene, struct Object *ob, int useflag);
+void PE_update_object(struct Scene *scene, struct SceneLayer *sl, struct Object *ob, int useflag);
/* selection tools */
int PE_mouse_particles(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
@@ -62,13 +63,13 @@ int PE_lasso_select(struct bContext *C, const int mcords[][2], const short moves
void PE_deselect_all_visible(struct PTCacheEdit *edit);
/* undo */
-void PE_undo_push(struct Scene *scene, const char *str);
-void PE_undo_step(struct Scene *scene, int step);
-void PE_undo(struct Scene *scene);
-void PE_redo(struct Scene *scene);
-bool PE_undo_is_valid(struct Scene *scene);
-void PE_undo_number(struct Scene *scene, int nr);
-const char *PE_undo_get_name(struct Scene *scene, int nr, bool *r_active);
+void PE_undo_push(struct Scene *scene, struct SceneLayer *sl, const char *str);
+void PE_undo_step(struct Scene *scene, struct SceneLayer *sl, int step);
+void PE_undo(struct Scene *scene, struct SceneLayer *sl);
+void PE_redo(struct Scene *scene, struct SceneLayer *sl);
+bool PE_undo_is_valid(struct Scene *scene, struct SceneLayer *sl);
+void PE_undo_number(struct Scene *scene, struct SceneLayer *sl, int nr);
+const char *PE_undo_get_name(struct Scene *scene, struct SceneLayer *sl, int nr, bool *r_active);
#endif /* __ED_PARTICLE_H__ */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index ec09add56b8..1208b1f31b6 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -36,6 +36,8 @@
#include "DNA_view2d_types.h"
#include "DNA_view3d_types.h"
+#include "BLI_compiler_attrs.h"
+
struct wmWindowManager;
struct wmWindow;
struct wmNotifier;
@@ -47,9 +49,12 @@ struct bScreen;
struct ARegion;
struct uiBlock;
struct rcti;
+struct Main;
/* regions */
-void ED_region_do_listen(struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar, struct wmNotifier *note);
+void ED_region_do_listen(
+ struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar,
+ struct wmNotifier *note, const Scene *scene);
void ED_region_do_draw(struct bContext *C, struct ARegion *ar);
void ED_region_exit(struct bContext *C, struct ARegion *ar);
void ED_region_pixelspace(struct ARegion *ar);
@@ -70,6 +75,7 @@ void ED_region_header(const struct bContext *C, struct ARegion *ar);
void ED_region_cursor_set(struct wmWindow *win, struct ScrArea *sa, struct ARegion *ar);
void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar);
void ED_region_info_draw(struct ARegion *ar, const char *text, float fill_color[4], const bool full_redraw);
+void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float fill_color[4], const bool full_redraw);
void ED_region_image_metadata_draw(int x, int y, struct ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy);
void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
float ED_region_blend_factor(struct ARegion *ar);
@@ -84,7 +90,7 @@ int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *bl
void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa);
void ED_area_exit(struct bContext *C, struct ScrArea *sa);
int ED_screen_area_active(const struct bContext *C);
-void ED_area_do_listen(struct bScreen *sc, ScrArea *sa, struct wmNotifier *note);
+void ED_area_do_listen(struct bScreen *sc, ScrArea *sa, struct wmNotifier *note, const Scene *scene);
void ED_area_tag_redraw(ScrArea *sa);
void ED_area_tag_redraw_regiontype(ScrArea *sa, int type);
void ED_area_tag_refresh(ScrArea *sa);
@@ -118,6 +124,7 @@ void ED_screen_full_restore(struct bContext *C, ScrArea *sa);
struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa, const short state);
void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
bool ED_screen_stereo3d_required(struct bScreen *screen);
+void ED_screen_preview_render(const struct bScreen *screen, int size_x, int size_y, unsigned int *r_rect) ATTR_NONNULL();
/* anim */
void ED_update_for_newframe(struct Main *bmain, struct Scene *scene, int mute);
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index 6daaac5bb42..a81d63d9f25 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -39,8 +39,7 @@ struct rcti;
/* sculpt.c */
void ED_operatortypes_sculpt(void);
-void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar,
- struct RegionView3D *rv3d, struct Object *ob);
+void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar, struct Object *ob);
int ED_sculpt_mask_box_select(struct bContext *C, struct ViewContext *vc, const struct rcti *rect, bool select, bool extend);
#endif /* __ED_SCULPT_H__ */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index ebd2a3dcb7a..376ae8ca567 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -109,9 +109,11 @@ enum TfmMode {
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
struct TransInfo;
-struct Base;
+struct BaseLegacy;
struct Scene;
struct Object;
+struct wmManipulatorGroup;
+struct wmManipulatorGroupType;
struct wmOperator;
/* UNUSED */
@@ -152,10 +154,17 @@ int BIF_countTransformOrientation(const struct bContext *C);
void Transform_Properties(struct wmOperatorType *ot, int flags);
-/* view3d manipulators */
+/* transform manipulators */
+
+void TRANSFORM_WGT_manipulator(struct wmManipulatorGroupType *wgt);
+
+void TRANSFORM_WGT_object(struct wmManipulatorGroupType *wgt);
+
+bool WIDGETGROUP_manipulator2d_poll(const struct bContext *C, struct wmManipulatorGroupType *wgrouptype);
+void WIDGETGROUP_manipulator2d_init(const struct bContext *C, struct wmManipulatorGroup *wgroup);
+void WIDGETGROUP_manipulator2d_refresh(const struct bContext *C, struct wmManipulatorGroup *wgroup);
+void WIDGETGROUP_manipulator2d_draw_prepare(const struct bContext *C, struct wmManipulatorGroup *wgroup);
-int BIF_do_manipulator(struct bContext *C, const struct wmEvent *event, struct wmOperator *op);
-void BIF_draw_manipulator(const struct bContext *C);
/* Snapping */
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 6eaae49912c..010f7929e90 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -31,6 +31,7 @@ struct BMFace;
struct ListBase;
struct Scene;
+struct SceneLayer;
struct Main;
struct Object;
struct ARegion;
@@ -67,9 +68,9 @@ struct SnapObjectParams {
typedef struct SnapObjectContext SnapObjectContext;
SnapObjectContext *ED_transform_snap_object_context_create(
- struct Main *bmain, struct Scene *scene, int flag);
+ struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, int flag);
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- struct Main *bmain, struct Scene *scene, int flag,
+ struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, int flag,
/* extra args for view3d */
const struct ARegion *ar, const struct View3D *v3d);
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 535683823bf..cba2a440959 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -35,12 +35,13 @@ struct BMesh;
struct BMEditMesh;
struct BMFace;
struct BMLoop;
+struct Depsgraph;
struct Image;
struct ImageUser;
-struct MTexPoly;
struct Main;
struct Object;
struct Scene;
+struct SceneLayer;
struct SpaceImage;
struct bNode;
struct wmKeyConfig;
@@ -60,7 +61,7 @@ void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int ma
bool ED_uvedit_test(struct Object *obedit);
/* visibility and selection */
-bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa, struct MTexPoly *tf);
+bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa);
bool uvedit_face_select_test(struct Scene *scene, struct BMFace *efa,
const int cd_loop_uv_offset);
bool uvedit_edge_select_test(struct Scene *scene, struct BMLoop *l,
@@ -109,7 +110,7 @@ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel)
/* uvedit_draw.c */
void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]);
-void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact);
+void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct SceneLayer *sl, struct Object *obedit, struct Object *obact, struct Depsgraph *depsgraph);
/* uvedit_buttons.c */
void ED_uvedit_buttons_register(struct ARegionType *art);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index d5c301d98d6..02243738d6c 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -37,9 +37,10 @@ struct BMEdge;
struct BMFace;
struct BMVert;
struct BPoint;
-struct Base;
+struct BaseLegacy;
struct BezTriple;
struct BoundBox;
+struct Depsgraph;
struct EditBone;
struct ImBuf;
struct MVert;
@@ -50,13 +51,13 @@ struct Object;
struct RV3DMatrixStore;
struct RegionView3D;
struct Scene;
+struct SceneLayer;
struct ScrArea;
struct View3D;
struct ViewContext;
struct bContext;
struct bPoseChannel;
struct bScreen;
-struct bglMats;
struct rctf;
struct rcti;
struct wmOperator;
@@ -70,7 +71,9 @@ enum eGPUFXFlags;
/* for derivedmesh drawing callbacks, for view3d_select, .... */
typedef struct ViewContext {
+ struct Depsgraph *depsgraph;
struct Scene *scene;
+ struct SceneLayer *scene_layer;
struct Object *obact;
struct Object *obedit;
struct ARegion *ar;
@@ -188,7 +191,7 @@ void pose_foreachScreenBone(
void ED_view3d_project_float_v2_m4(const struct ARegion *ar, const float co[3], float r_co[2], float mat[4][4]);
void ED_view3d_project_float_v3_m4(const struct ARegion *ar, const float co[3], float r_co[3], float mat[4][4]);
-eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base);
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct BaseLegacy *base);
/* *** short *** */
eV3DProjStatus ED_view3d_project_short_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
@@ -232,7 +235,9 @@ bool ED_view3d_win_to_segment(const struct ARegion *ar, struct View3D *v3d, cons
float r_ray_start[3], float r_ray_end[3], const bool do_clip);
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
void ED_view3d_ob_project_mat_get_from_obmat(const struct RegionView3D *rv3d, float obmat[4][4], float pmat[4][4]);
-void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
+
+void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3]);
+bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3]);
/* end */
@@ -261,7 +266,8 @@ bool ED_view3d_calc_render_border(struct Scene *scene, struct View3D *v3d,
struct ARegion *ar, struct rcti *rect);
void ED_view3d_clipping_calc_from_boundbox(float clip[6][4], const struct BoundBox *clipbb, const bool is_flip);
-void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
+void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4],
+ const struct ARegion *ar, const struct Object *ob, const struct rcti *rect);
void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
bool ED_view3d_clipping_test(const struct RegionView3D *rv3d, const float co[3], const bool is_local);
void ED_view3d_clipping_set(struct RegionView3D *rv3d);
@@ -277,7 +283,7 @@ float ED_view3d_radius_to_dist(
const char persp, const bool use_aspect,
const float radius);
-void drawcircball(int mode, const float cent[3], float rad, const float tmat[4][4]);
+void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos);
/* backbuffer select and draw support */
void ED_view3d_backbuf_validate(struct ViewContext *vc);
@@ -289,12 +295,12 @@ int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float
unsigned int ED_view3d_backbuf_sample(struct ViewContext *vc, int x, int y);
bool ED_view3d_autodist(
- struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
+ struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d,
const int mval[2], float mouse_worldloc[3],
const bool alphaoverride, const float fallback_depth_pt[3]);
/* only draw so ED_view3d_autodist_simple can be called many times after */
-void ED_view3d_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, int mode);
+void ED_view3d_autodist_init(struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, int mode);
bool ED_view3d_autodist_simple(struct ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth);
bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth);
bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth);
@@ -325,7 +331,6 @@ void view3d_set_viewcontext(struct bContext *C, struct ViewContext *vc);
void view3d_operator_needs_opengl(const struct bContext *C);
void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
void view3d_opengl_read_pixels(struct ARegion *ar, int x, int y, int w, int h, int format, int type, void *data);
-void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats);
/* XXX should move to BLI_math */
bool edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]);
@@ -350,7 +355,7 @@ struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
bool ED_view3d_context_activate(struct bContext *C);
-void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
+void ED_view3d_draw_offscreen_init(struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d);
void ED_view3d_draw_offscreen(
struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
@@ -361,17 +366,17 @@ void ED_view3d_draw_setup_view(
float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(
- struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey,
+ struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey,
unsigned int flag, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
- struct Scene *scene, struct Object *camera, int width, int height,
+ struct Scene *scene, struct SceneLayer *sl, struct Object *camera, int width, int height,
unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
-struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
+struct BaseLegacy *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
void ED_view3d_update_viewmat(
struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 252c199d46c..b3c95aa0712 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -255,6 +255,7 @@ typedef enum {
UI_BTYPE_CHECKBOX = (13 << 9), /* similar to toggle, display a 'tick' */
UI_BTYPE_CHECKBOX_N = (14 << 9),
UI_BTYPE_COLOR = (15 << 9),
+ UI_BTYPE_TAB = (16 << 9),
UI_BTYPE_SCROLL = (18 << 9),
UI_BTYPE_BLOCK = (19 << 9),
UI_BTYPE_LABEL = (20 << 9),
@@ -307,18 +308,22 @@ typedef enum {
* Functions to draw various shapes, taking theme settings into account.
* Used for code that draws its own UI style elements. */
-void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad);
void UI_draw_roundbox_corner_set(int type);
+void UI_draw_roundbox_aa(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4]);
+void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4]);
+void UI_draw_roundbox_3ubAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const unsigned char col[3], unsigned char alpha);
+void UI_draw_roundbox_3fvAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[3], float alpha);
+void UI_draw_roundbox_shade_x(bool filled, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown, const float col[4]);
+
+#if 0 /* unused */
int UI_draw_roundbox_corner_get(void);
-void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad);
+void UI_draw_roundbox_shade_y(bool filled, float minx, float miny, float maxx, float maxy, float rad, float shadeleft, float shaderight, const float col[4]);
+#endif
+
void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
-void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad);
-void UI_draw_roundbox_shade_x(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
-void UI_draw_roundbox_shade_y(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight);
-void UI_draw_text_underline(int pos_x, int pos_y, int len, int height);
+void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4]);
-void UI_draw_safe_areas(
- float x1, float x2, float y1, float y2,
+void UI_draw_safe_areas(uint pos, float x1, float x2, float y1, float y2,
const float title_aspect[2], const float action_aspect[2]);
/* state for scrolldrawing */
@@ -786,7 +791,6 @@ void UI_popup_handlers_remove_all(struct bContext *C, struct ListBase *handlers)
void UI_init(void);
void UI_init_userdef(void);
void UI_reinit_font(void);
-void UI_reinit_gl_state(void);
void UI_exit(void);
/* Layout
@@ -851,9 +855,6 @@ enum {
UI_CNR_ALL = (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)
};
-/* not apart of the corner flags but mixed in some functions */
-#define UI_RB_ALPHA (UI_CNR_ALL + 1)
-
uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, struct uiStyle *style);
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout);
void UI_block_layout_resolve(uiBlock *block, int *x, int *y);
@@ -911,6 +912,17 @@ void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA
const char *newop, const char *openop, const char *unlinkop, int rows, int cols);
void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
const char *proptypename, const char *text);
+void uiTemplateSearch(
+ uiLayout *layout, struct bContext *C,
+ struct PointerRNA *ptr, const char *propname,
+ struct PointerRNA *searchptr, const char *searchpropname,
+ const char *newop, const char *unlinkop);
+void uiTemplateSearchPreview(
+ uiLayout *layout, struct bContext *C,
+ struct PointerRNA *ptr, const char *propname,
+ struct PointerRNA *searchptr, const char *searchpropname,
+ const char *newop, const char *unlinkop,
+ const int rows, const int cols);
void uiTemplatePathBuilder(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
struct PointerRNA *root_ptr, const char *text);
uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
@@ -944,6 +956,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C);
void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
+void uiTemplateOverrideProperty(uiLayout *layout, struct PointerRNA *collection_props_ptr, struct PointerRNA *scene_props_ptr, const char *name, const char *custom_template);
void uiTemplateComponentMenu(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name);
void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float *color);
void uiTemplateCacheFile(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname);
@@ -1041,20 +1054,22 @@ void UI_context_active_but_prop_get_templateID(
/* Styled text draw */
void UI_fontstyle_set(const struct uiFontStyle *fs);
-void UI_fontstyle_draw_ex(
- const struct uiFontStyle *fs, const struct rcti *rect, const char *str,
- size_t len, float *r_xofs, float *r_yofs);
-void UI_fontstyle_draw(const struct uiFontStyle *fs, const struct rcti *rect, const char *str);
-void UI_fontstyle_draw_rotated(const struct uiFontStyle *fs, const struct rcti *rect, const char *str);
-void UI_fontstyle_draw_simple(const struct uiFontStyle *fs, float x, float y, const char *str);
+void UI_fontstyle_draw_ex(const struct uiFontStyle *fs, const struct rcti *rect, const char *str,
+ const unsigned char col[4], size_t len, float *r_xofs, float *r_yofs);
+void UI_fontstyle_draw(const struct uiFontStyle *fs, const struct rcti *rect, const char *str,
+ const unsigned char col[4]);
+void UI_fontstyle_draw_rotated(const struct uiFontStyle *fs, const struct rcti *rect, const char *str,
+ const unsigned char col[4]);
+void UI_fontstyle_draw_simple(const struct uiFontStyle *fs, float x, float y, const char *str,
+ const unsigned char col[4]);
void UI_fontstyle_draw_simple_backdrop(
const struct uiFontStyle *fs, float x, float y, const char *str,
- const unsigned char fg[4], const unsigned char bg[4]);
+ const float col_fg[4], const float col_bg[4]);
int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str);
int UI_fontstyle_height_max(const struct uiFontStyle *fs);
-void UI_draw_icon_tri(float x, float y, char dir);
+void UI_draw_icon_tri(float x, float y, char dir, const float[4]);
struct uiStyle *UI_style_get(void); /* use for fonts etc */
struct uiStyle *UI_style_get_dpi(void); /* DPI scaled settings for drawing */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 945ac1b6db9..cee68ed361c 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -66,6 +66,7 @@ void UI_id_icon_render(
int UI_preview_render_size(enum eIconSizes size);
void UI_icon_draw(float x, float y, int icon_id);
+void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha);
void UI_icon_draw_preview(float x, float y, int icon_id);
void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect);
void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, float alpha, int size);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index f8a5f30a596..ac657a4ac73 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -320,13 +320,13 @@ struct bThemeState {
void UI_ThemeColor(int colorid);
// sets the color plus alpha
-void UI_ThemeColor4(int colorid);
+void UI_ThemeColor4(int colorid);
// sets color plus offset for shade
-void UI_ThemeColorShade(int colorid, int offset);
+void UI_ThemeColorShade(int colorid, int offset);
// sets color plus offset for alpha
-void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset);
+void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset);
// sets color, which is blend between two theme colors
void UI_ThemeColorBlend(int colorid1, int colorid2, float fac);
@@ -344,14 +344,27 @@ int UI_GetThemeValueType(int colorid, int spacetype);
// get three color values, scaled to 0.0-1.0 range
void UI_GetThemeColor3fv(int colorid, float col[3]);
void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned char col[3]);
+void UI_GetThemeColorBlend3f(int colorid1, int colorid2, float fac, float r_col[3]);
// get the color, range 0.0-1.0, complete with shading offset
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]);
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3]);
+void UI_GetThemeColorShade4ubv(int colorid, int offset, unsigned char col[4]);
+
+// get three color values, range 0-255, complete with shading offset for the RGB components and blending
+void UI_GetThemeColorBlendShade3ubv(int colorid1, int colorid2, float fac, int offset, unsigned char col[3]);
// get four color values, scaled to 0.0-1.0 range
void UI_GetThemeColor4fv(int colorid, float col[4]);
// get four color values, range 0.0-1.0, complete with shading offset for the RGB components
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4]);
+void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4]);
+
+// get four colour values ranged between 0 and 255; includes the alpha channel
+void UI_GetThemeColorShadeAlpha4ubv(int colorid, int coloffset, int alphaoffset, unsigned char col[4]);
+
+// get four color values, range 0.0-1.0, complete with shading offset for the RGB components and blending
+void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int offset, float col[3]);
+void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4]);
// get the 3 or 4 byte values
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3]);
@@ -369,6 +382,10 @@ void UI_GetColorPtrShade3ubv(const unsigned char cp1[3], unsigned char col[3]
// get a 3 byte color, blended and shaded between two other char color pointers
void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3], float fac, int offset);
+// sets the font color
+// (for anything fancy use UI_GetThemeColor[Fancy] then BLF_color)
+void UI_FontThemeColor(int fontid, int colorid);
+
// clear the openGL ClearColor using the input colorid
void UI_ThemeClearColor(int colorid);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 7180e18ab92..562a2f6e32c 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -56,7 +56,7 @@
#include "BKE_screen.h"
#include "BKE_idprop.h"
-#include "BIF_gl.h"
+#include "GPU_matrix.h"
#include "BLF_api.h"
#include "BLT_translation.h"
@@ -499,6 +499,7 @@ static int ui_but_calc_float_precision(uiBut *but, double value)
static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines, int dashInactiveLines)
{
rcti rect;
+ float color[4] = {1.0f};
if (line->from == NULL || line->to == NULL) return;
@@ -508,15 +509,15 @@ static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines, int das
rect.ymax = BLI_rctf_cent_y(&line->to->rect);
if (dashInactiveLines)
- UI_ThemeColor(TH_GRID);
+ UI_GetThemeColor4fv(TH_GRID, color);
else if (line->flag & UI_SELECT)
- glColor3ub(100, 100, 100);
+ rgba_float_args_set_ch(color, 100, 100, 100, 255);
else if (highlightActiveLines && ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE)))
- UI_ThemeColor(TH_TEXT_HI);
+ UI_GetThemeColor4fv(TH_TEXT_HI, color);
else
- glColor3ub(0, 0, 0);
+ rgba_float_args_set_ch(color, 0, 0, 0, 255);
- ui_draw_link_bezier(&rect);
+ ui_draw_link_bezier(&rect, color);
}
static void ui_draw_links(uiBlock *block)
@@ -1376,11 +1377,9 @@ void UI_block_draw(const bContext *C, uiBlock *block)
ui_but_to_pixelrect(&rect, ar, block, NULL);
/* pixel space for AA widgets */
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
+ gpuPushProjectionMatrix();
+ gpuPushMatrix();
+ gpuLoadIdentity();
wmOrtho2_region_pixelspace(ar);
@@ -1405,10 +1404,8 @@ void UI_block_draw(const bContext *C, uiBlock *block)
}
/* restore matrix */
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
if (multisample_enabled)
glEnable(GL_MULTISAMPLE);
@@ -1462,6 +1459,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
break;
case UI_BTYPE_ROW:
case UI_BTYPE_LISTROW:
+ case UI_BTYPE_TAB:
UI_GET_BUT_VALUE_INIT(but, *value);
/* support for rna enum buts */
if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
@@ -2375,7 +2373,7 @@ static void ui_but_string_free_internal(uiBut *but)
bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ if (but->rnaprop && but->rnapoin.data && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
PropertyType type;
@@ -2422,8 +2420,15 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
}
else if (but->type == UI_BTYPE_TEXT) {
/* string */
- if (ui_but_is_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax);
- else BLI_strncpy(but->poin, str, but->hardmax);
+ if (!but->poin || (str[0] == '\0')) {
+ str = "";
+ }
+ else if (ui_but_is_utf8(but)) {
+ BLI_strncpy_utf8(but->poin, str, but->hardmax);
+ }
+ else {
+ BLI_strncpy(but->poin, str, but->hardmax);
+ }
return true;
}
@@ -2629,6 +2634,10 @@ static void ui_but_free(const bContext *C, uiBut *but)
MEM_freeN(but->tip_argN);
}
+ if (!but->editstr && but->free_search_arg) {
+ MEM_SAFE_FREE(but->search_arg);
+ }
+
if (but->active) {
/* XXX solve later, buttons should be free-able without context ideally,
* however they may have open tooltips or popup windows, which need to
@@ -3501,7 +3510,7 @@ static uiBut *ui_def_but_rna(
}
const char *info;
- if (!RNA_property_editable_info(&but->rnapoin, prop, &info)) {
+ if (but->rnapoin.data && !RNA_property_editable_info(&but->rnapoin, prop, &info)) {
ui_def_but_rna__disable(but, info);
}
@@ -4400,7 +4409,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
for (item = item_array; item->identifier; item++) {
/* note: need to give the index rather than the identifier because the enum can be freed */
if (BLI_strcasestr(item->name, str)) {
- if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), 0))
+ if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), item->icon))
break;
}
}
@@ -4524,7 +4533,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
tmp = BLI_strdup(RNA_property_identifier(but->rnaprop));
}
else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) {
- if (but->rnaprop)
+ if (but->rnaprop && but->rnapoin.data)
tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type));
else if (but->optype)
tmp = BLI_strdup(but->optype->idname);
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 500744c366d..9aeb685a907 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -110,9 +110,9 @@ enum {
bool ui_but_can_align(const uiBut *but)
{
- return (
- !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE) &&
- (BLI_rctf_size_x(&but->rect) > 0.0f) && (BLI_rctf_size_y(&but->rect) > 0.0f));
+ const bool btype_can_align = !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N,
+ UI_BTYPE_TAB, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE);
+ return (btype_can_align && (BLI_rctf_size_x(&but->rect) > 0.0f) && (BLI_rctf_size_y(&but->rect) > 0.0f));
}
/**
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 01ea1e953fa..3553b5f4d4b 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -50,13 +50,14 @@
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BLF_api.h"
-#include "GPU_draw.h"
-#include "GPU_basic_shader.h"
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "UI_interface.h"
@@ -71,336 +72,462 @@ void UI_draw_roundbox_corner_set(int type)
* if this is undone, it's not that big a deal, only makes curves edges
* square for the */
roundboxtype = type;
-
}
+#if 0 /* unused */
int UI_draw_roundbox_corner_get(void)
{
return roundboxtype;
}
+#endif
+
+void UI_draw_roundbox_3ubAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const unsigned char col[3], unsigned char alpha)
+{
+ float colv[4];
+ colv[0] = ((float)col[0]) / 255;
+ colv[1] = ((float)col[1]) / 255;
+ colv[2] = ((float)col[2]) / 255;
+ colv[3] = ((float)alpha) / 255;
+ UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
+}
+
+void UI_draw_roundbox_3fvAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[3], float alpha)
+{
+ float colv[4];
+ colv[0] = col[0];
+ colv[1] = col[1];
+ colv[2] = col[2];
+ colv[3] = alpha;
+ UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
+}
-void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad)
+void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4])
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
int a;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
/* mult */
for (a = 0; a < 7; a++) {
mul_v2_fl(vec[a], rad);
}
- glBegin(mode);
+ unsigned int vert_ct = 0;
+ vert_ct += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
+ vert_ct += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
+ vert_ct += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
+ vert_ct += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(col);
+ immBegin(filled ? PRIM_TRIANGLE_FAN : PRIM_LINE_LOOP, vert_ct);
/* start with corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- glVertex2f(maxx - rad, miny);
+ immVertex2f(pos, maxx - rad, miny);
for (a = 0; a < 7; a++) {
- glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
}
- glVertex2f(maxx, miny + rad);
+ immVertex2f(pos, maxx, miny + rad);
}
else {
- glVertex2f(maxx, miny);
+ immVertex2f(pos, maxx, miny);
}
/* corner right-top */
if (roundboxtype & UI_CNR_TOP_RIGHT) {
- glVertex2f(maxx, maxy - rad);
+ immVertex2f(pos, maxx, maxy - rad);
for (a = 0; a < 7; a++) {
- glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
}
- glVertex2f(maxx - rad, maxy);
+ immVertex2f(pos, maxx - rad, maxy);
}
else {
- glVertex2f(maxx, maxy);
+ immVertex2f(pos, maxx, maxy);
}
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
- glVertex2f(minx + rad, maxy);
+ immVertex2f(pos, minx + rad, maxy);
for (a = 0; a < 7; a++) {
- glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
}
- glVertex2f(minx, maxy - rad);
+ immVertex2f(pos, minx, maxy - rad);
}
else {
- glVertex2f(minx, maxy);
+ immVertex2f(pos, minx, maxy);
}
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- glVertex2f(minx, miny + rad);
+ immVertex2f(pos, minx, miny + rad);
for (a = 0; a < 7; a++) {
- glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
}
- glVertex2f(minx + rad, miny);
+ immVertex2f(pos, minx + rad, miny);
}
else {
- glVertex2f(minx, miny);
+ immVertex2f(pos, minx, miny);
}
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
-static void round_box_shade_col(const float col1[3], float const col2[3], const float fac)
+static void round_box_shade_col(unsigned attrib, const float col1[3], float const col2[3], const float fac)
{
- float col[3] = {
+ float col[4] = {
fac * col1[0] + (1.0f - fac) * col2[0],
fac * col1[1] + (1.0f - fac) * col2[1],
- fac * col1[2] + (1.0f - fac) * col2[2]
+ fac * col1[2] + (1.0f - fac) * col2[2],
+ 1.0f
};
- glColor3fv(col);
+ immAttrib4fv(attrib, col);
}
/* linear horizontal shade within button or in outline */
/* view2d scrollers use it */
void UI_draw_roundbox_shade_x(
- int mode, float minx, float miny, float maxx, float maxy,
- float rad, float shadetop, float shadedown)
+ bool filled, float minx, float miny, float maxx, float maxy,
+ float rad, float shadetop, float shadedown, const float col[4])
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
const float div = maxy - miny;
const float idiv = 1.0f / div;
- float coltop[3], coldown[3], color[4];
+ float coltop[3], coldown[3];
+ int vert_count = 0;
int a;
-
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
/* mult */
for (a = 0; a < 7; a++) {
mul_v2_fl(vec[a], rad);
}
- /* get current color, needs to be outside of glBegin/End */
- glGetFloatv(GL_CURRENT_COLOR, color);
/* 'shade' defines strength of shading */
- coltop[0] = min_ff(1.0f, color[0] + shadetop);
- coltop[1] = min_ff(1.0f, color[1] + shadetop);
- coltop[2] = min_ff(1.0f, color[2] + shadetop);
- coldown[0] = max_ff(0.0f, color[0] + shadedown);
- coldown[1] = max_ff(0.0f, color[1] + shadedown);
- coldown[2] = max_ff(0.0f, color[2] + shadedown);
+ coltop[0] = min_ff(1.0f, col[0] + shadetop);
+ coltop[1] = min_ff(1.0f, col[1] + shadetop);
+ coltop[2] = min_ff(1.0f, col[2] + shadetop);
+ coldown[0] = max_ff(0.0f, col[0] + shadedown);
+ coldown[1] = max_ff(0.0f, col[1] + shadedown);
+ coldown[2] = max_ff(0.0f, col[2] + shadedown);
- glBegin(mode);
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
+
+ immBegin(filled ? PRIM_TRIANGLE_FAN : PRIM_LINE_LOOP, vert_count);
/* start with corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- round_box_shade_col(coltop, coldown, 0.0);
- glVertex2f(maxx - rad, miny);
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, maxx - rad, miny);
for (a = 0; a < 7; a++) {
- round_box_shade_col(coltop, coldown, vec[a][1] * idiv);
- glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
+ round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv);
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
}
- round_box_shade_col(coltop, coldown, rad * idiv);
- glVertex2f(maxx, miny + rad);
+ round_box_shade_col(color, coltop, coldown, rad * idiv);
+ immVertex2f(pos, maxx, miny + rad);
}
else {
- round_box_shade_col(coltop, coldown, 0.0);
- glVertex2f(maxx, miny);
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, maxx, miny);
}
/* corner right-top */
if (roundboxtype & UI_CNR_TOP_RIGHT) {
- round_box_shade_col(coltop, coldown, (div - rad) * idiv);
- glVertex2f(maxx, maxy - rad);
+ round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
+ immVertex2f(pos, maxx, maxy - rad);
for (a = 0; a < 7; a++) {
- round_box_shade_col(coltop, coldown, (div - rad + vec[a][1]) * idiv);
- glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
+ round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv);
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
}
- round_box_shade_col(coltop, coldown, 1.0);
- glVertex2f(maxx - rad, maxy);
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, maxx - rad, maxy);
}
else {
- round_box_shade_col(coltop, coldown, 1.0);
- glVertex2f(maxx, maxy);
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, maxx, maxy);
}
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
- round_box_shade_col(coltop, coldown, 1.0);
- glVertex2f(minx + rad, maxy);
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, minx + rad, maxy);
for (a = 0; a < 7; a++) {
- round_box_shade_col(coltop, coldown, (div - vec[a][1]) * idiv);
- glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
+ round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv);
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
}
- round_box_shade_col(coltop, coldown, (div - rad) * idiv);
- glVertex2f(minx, maxy - rad);
+ round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
+ immVertex2f(pos, minx, maxy - rad);
}
else {
- round_box_shade_col(coltop, coldown, 1.0);
- glVertex2f(minx, maxy);
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, minx, maxy);
}
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- round_box_shade_col(coltop, coldown, rad * idiv);
- glVertex2f(minx, miny + rad);
+ round_box_shade_col(color, coltop, coldown, rad * idiv);
+ immVertex2f(pos, minx, miny + rad);
for (a = 0; a < 7; a++) {
- round_box_shade_col(coltop, coldown, (rad - vec[a][1]) * idiv);
- glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
+ round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv);
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
}
- round_box_shade_col(coltop, coldown, 0.0);
- glVertex2f(minx + rad, miny);
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, minx + rad, miny);
}
else {
- round_box_shade_col(coltop, coldown, 0.0);
- glVertex2f(minx, miny);
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, minx, miny);
}
-
- glEnd();
+
+ immEnd();
+ immUnbindProgram();
}
+#if 0 /* unused */
/* linear vertical shade within button or in outline */
/* view2d scrollers use it */
void UI_draw_roundbox_shade_y(
- int mode, float minx, float miny, float maxx, float maxy,
- float rad, float shadeLeft, float shadeRight)
+ bool filled, float minx, float miny, float maxx, float maxy,
+ float rad, float shadeleft, float shaderight, const float col[4])
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
const float div = maxx - minx;
const float idiv = 1.0f / div;
- float colLeft[3], colRight[3], color[4];
+ float colLeft[3], colRight[3];
+ int vert_count = 0;
int a;
/* mult */
for (a = 0; a < 7; a++) {
mul_v2_fl(vec[a], rad);
}
- /* get current color, needs to be outside of glBegin/End */
- glGetFloatv(GL_CURRENT_COLOR, color);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
/* 'shade' defines strength of shading */
- colLeft[0] = min_ff(1.0f, color[0] + shadeLeft);
- colLeft[1] = min_ff(1.0f, color[1] + shadeLeft);
- colLeft[2] = min_ff(1.0f, color[2] + shadeLeft);
- colRight[0] = max_ff(0.0f, color[0] + shadeRight);
- colRight[1] = max_ff(0.0f, color[1] + shadeRight);
- colRight[2] = max_ff(0.0f, color[2] + shadeRight);
+ colLeft[0] = min_ff(1.0f, col[0] + shadeleft);
+ colLeft[1] = min_ff(1.0f, col[1] + shadeleft);
+ colLeft[2] = min_ff(1.0f, col[2] + shadeleft);
+ colRight[0] = max_ff(0.0f, col[0] + shaderight);
+ colRight[1] = max_ff(0.0f, col[1] + shaderight);
+ colRight[2] = max_ff(0.0f, col[2] + shaderight);
+
- glBegin(mode);
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
+
+ immBegin(filled ? PRIM_TRIANGLE_FAN : PRIM_LINE_LOOP, vert_count);
/* start with corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- round_box_shade_col(colLeft, colRight, 0.0);
- glVertex2f(maxx - rad, miny);
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx - rad, miny);
for (a = 0; a < 7; a++) {
- round_box_shade_col(colLeft, colRight, vec[a][0] * idiv);
- glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
+ round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv);
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
}
- round_box_shade_col(colLeft, colRight, rad * idiv);
- glVertex2f(maxx, miny + rad);
+ round_box_shade_col(color, colLeft, colRight, rad * idiv);
+ immVertex2f(pos, maxx, miny + rad);
}
else {
- round_box_shade_col(colLeft, colRight, 0.0);
- glVertex2f(maxx, miny);
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx, miny);
}
/* corner right-top */
if (roundboxtype & UI_CNR_TOP_RIGHT) {
- round_box_shade_col(colLeft, colRight, 0.0);
- glVertex2f(maxx, maxy - rad);
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx, maxy - rad);
for (a = 0; a < 7; a++) {
- round_box_shade_col(colLeft, colRight, (div - rad - vec[a][0]) * idiv);
- glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
+ round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv);
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
}
- round_box_shade_col(colLeft, colRight, (div - rad) * idiv);
- glVertex2f(maxx - rad, maxy);
+ round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
+ immVertex2f(pos, maxx - rad, maxy);
}
else {
- round_box_shade_col(colLeft, colRight, 0.0);
- glVertex2f(maxx, maxy);
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx, maxy);
}
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
- round_box_shade_col(colLeft, colRight, (div - rad) * idiv);
- glVertex2f(minx + rad, maxy);
+ round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
+ immVertex2f(pos, minx + rad, maxy);
for (a = 0; a < 7; a++) {
- round_box_shade_col(colLeft, colRight, (div - rad + vec[a][0]) * idiv);
- glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
+ round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv);
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
}
- round_box_shade_col(colLeft, colRight, 1.0);
- glVertex2f(minx, maxy - rad);
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, maxy - rad);
}
else {
- round_box_shade_col(colLeft, colRight, 1.0);
- glVertex2f(minx, maxy);
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, maxy);
}
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- round_box_shade_col(colLeft, colRight, 1.0);
- glVertex2f(minx, miny + rad);
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, miny + rad);
for (a = 0; a < 7; a++) {
- round_box_shade_col(colLeft, colRight, (vec[a][0]) * idiv);
- glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
+ round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv);
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
}
- round_box_shade_col(colLeft, colRight, 1.0);
- glVertex2f(minx + rad, miny);
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx + rad, miny);
}
else {
- round_box_shade_col(colLeft, colRight, 1.0);
- glVertex2f(minx, miny);
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, miny);
}
-
- glEnd();
+
+ immEnd();
+ immUnbindProgram();
}
+#endif /* unused */
-/* plain antialiased unfilled rectangle */
-void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad)
+void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
{
- float color[4];
-
- if (roundboxtype & UI_RB_ALPHA) {
- glGetFloatv(GL_CURRENT_COLOR, color);
- color[3] = 0.5;
- glColor4fv(color);
- glEnable(GL_BLEND);
- }
-
- /* set antialias line */
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
+ int ofs_y = 4 * U.pixelsize;
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
-}
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
-/* (old, used in outliner) plain antialiased filled box */
-void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad)
-{
- ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA);
+ immRecti(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
+ immUnbindProgram();
}
-void UI_draw_text_underline(int pos_x, int pos_y, int len, int height)
+/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
+
+/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
+void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3])
{
- int ofs_y = 4 * U.pixelsize;
- glRecti(pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
-}
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ /* add a 1px offset, looks nicer */
+ const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
+ const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
+ int a;
+ float vec[4][2] = {
+ {0.195, 0.02},
+ {0.55, 0.169},
+ {0.831, 0.45},
+ {0.98, 0.805},
+ };
-/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
+
+ /* mult */
+ for (a = 0; a < 4; a++) {
+ mul_v2_fl(vec[a], rad);
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ immBeginAtMost(PRIM_LINE_STRIP, 25);
+
+ immAttrib3ubv(col, highlight);
+
+ /* start with corner left-top */
+ if (roundboxtype & UI_CNR_TOP_LEFT) {
+ immVertex2f(pos, minx, maxy - rad);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
+ }
+ immVertex2f(pos, minx + rad, maxy);
+ }
+ else {
+ immVertex2f(pos, minx, maxy);
+ }
+
+ /* corner right-top */
+ if (roundboxtype & UI_CNR_TOP_RIGHT) {
+ immVertex2f(pos, maxx - rad, maxy);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
+ }
+ immVertex2f(pos, maxx, maxy - rad);
+ }
+ else {
+ immVertex2f(pos, maxx, maxy);
+ }
+
+ immAttrib3ubv(col, highlight_fade);
+
+ /* corner right-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
+ immVertex2f(pos, maxx, miny + rad);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
+ }
+ immVertex2f(pos, maxx - rad, miny);
+ }
+ else {
+ immVertex2f(pos, maxx, miny);
+ }
+
+ /* corner left-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
+ immVertex2f(pos, minx + rad, miny);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
+ }
+ immVertex2f(pos, minx, miny + rad);
+ }
+ else {
+ immVertex2f(pos, minx, miny);
+ }
+
+ immAttrib3ubv(col, highlight);
+
+ /* back to corner left-top */
+ immVertex2f(pos, minx, roundboxtype & UI_CNR_TOP_LEFT ? maxy - rad : maxy);
+
+ immEnd();
+ immUnbindProgram();
+}
void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect)
{
@@ -411,15 +538,15 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
ImBuf *ibuf = (ImBuf *)but->poin;
if (!ibuf) return;
+
+ float facx = 1.0f;
+ float facy = 1.0f;
int w = BLI_rcti_size_x(rect);
int h = BLI_rcti_size_y(rect);
/* scissor doesn't seem to be doing the right thing...? */
#if 0
- //glColor4f(1.0, 0.f, 0.f, 1.f);
- //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax)
-
/* prevent drawing outside widget area */
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
@@ -427,16 +554,15 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
#endif
glEnable(GL_BLEND);
- glColor4f(0.0, 0.0, 0.0, 0.0);
if (w != ibuf->x || h != ibuf->y) {
- float facx = (float)w / (float)ibuf->x;
- float facy = (float)h / (float)ibuf->y;
- glPixelZoom(facx, facy);
+ facx = (float)w / (float)ibuf->x;
+ facy = (float)h / (float)ibuf->y;
}
- glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect);
-
- glPixelZoom(1.0f, 1.0f);
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, (float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect,
+ facx, facy, NULL);
glDisable(GL_BLEND);
@@ -451,43 +577,34 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
/**
* Draw title and text safe areas.
*
- * The first 4 parameters are the offsets for the view, not the zones.
+ * \Note This functionn is to be used with the 2D dashed shader enabled.
+ *
+ * \param pos is a PRIM_FLOAT, 2, KEEP_FLOAT vertex attrib
+ * \param line_origin is a PRIM_FLOAT, 2, KEEP_FLOAT vertex attrib
+ *
+ * The next 4 parameters are the offsets for the view, not the zones.
*/
void UI_draw_safe_areas(
- float x1, float x2, float y1, float y2,
+ uint pos, float x1, float x2, float y1, float y2,
const float title_aspect[2], const float action_aspect[2])
{
const float size_x_half = (x2 - x1) * 0.5f;
const float size_y_half = (y2 - y1) * 0.5f;
const float *safe_areas[] = {title_aspect, action_aspect};
- int safe_len = ARRAY_SIZE(safe_areas);
- bool is_first = true;
+ const int safe_len = ARRAY_SIZE(safe_areas);
for (int i = 0; i < safe_len; i++) {
if (safe_areas[i][0] || safe_areas[i][1]) {
- float margin_x, margin_y;
- float minx, miny, maxx, maxy;
+ float margin_x = safe_areas[i][0] * size_x_half;
+ float margin_y = safe_areas[i][1] * size_y_half;
- if (is_first) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
- is_first = false;
- }
+ float minx = x1 + margin_x;
+ float miny = y1 + margin_y;
+ float maxx = x2 - margin_x;
+ float maxy = y2 - margin_y;
- margin_x = safe_areas[i][0] * size_x_half;
- margin_y = safe_areas[i][1] * size_y_half;
-
- minx = x1 + margin_x;
- miny = y1 + margin_y;
- maxx = x2 - margin_x;
- maxy = y2 - margin_y;
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(maxx, miny);
- glVertex2f(maxx, maxy);
- glVertex2f(minx, maxy);
- glVertex2f(minx, miny);
- glEnd();
+ imm_draw_line_box(pos, minx, miny, maxx, maxy);
}
}
}
@@ -501,52 +618,60 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* outline */
- glColor4f(0.f, 0.f, 0.f, 0.5f);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
+ UI_draw_roundbox_4fv(false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color);
}
static void histogram_draw_one(
float r, float g, float b, float alpha,
- float x, float y, float w, float h, const float *data, int res, const bool is_line)
+ float x, float y, float w, float h, const float *data, int res, const bool is_line,
+ unsigned int pos_attrib)
{
+ float color[4] = {r, g, b, alpha};
+
+ /* that can happen */
+ if (res == 0)
+ return;
+
glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- glColor4f(r, g, b, alpha);
+
+ immUniformColor4fv(color);
if (is_line) {
/* curve outline */
glLineWidth(1.5);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, res);
for (int i = 0; i < res; i++) {
float x2 = x + i * (w / (float)res);
- glVertex2f(x2, y + (data[i] * h));
+ immVertex2f(pos_attrib, x2, y + (data[i] * h));
}
- glEnd();
+ immEnd();
}
else {
/* under the curve */
- glBegin(GL_TRIANGLE_STRIP);
- glVertex2f(x, y);
- glVertex2f(x, y + (data[0] * h));
+ immBegin(PRIM_TRIANGLE_STRIP, res * 2);
+ immVertex2f(pos_attrib, x, y);
+ immVertex2f(pos_attrib, x, y + (data[0] * h));
for (int i = 1; i < res; i++) {
float x2 = x + i * (w / (float)res);
- glVertex2f(x2, y + (data[i] * h));
- glVertex2f(x2, y);
+ immVertex2f(pos_attrib, x2, y + (data[i] * h));
+ immVertex2f(pos_attrib, x2, y);
}
- glEnd();
+ immEnd();
/* curve outline */
- glColor4f(0.f, 0.f, 0.f, 0.25f);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, res);
for (int i = 0; i < res; i++) {
float x2 = x + i * (w / (float)res);
- glVertex2f(x2, y + (data[i] * h));
+ immVertex2f(pos_attrib, x2, y + (data[i] * h));
}
- glEnd();
+ immEnd();
}
glDisable(GL_LINE_SMOOTH);
@@ -559,7 +684,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
Histogram *hist = (Histogram *)but->poin;
int res = hist->x_resolution;
const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
-
+
rctf rect = {
.xmin = (float)recti->xmin + 1,
.xmax = (float)recti->xmax - 1,
@@ -573,9 +698,10 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- UI_ThemeColor4(TH_PREVIEW_BACK);
+ float color[4];
+ UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
/* need scissor test, histogram can draw outside of boundary */
GLint scissor[4];
@@ -585,34 +711,48 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
- glColor4f(1.f, 1.f, 1.f, 0.08f);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
/* draw grid lines here */
for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES;
/* so we can tell the 1.0 color point */
if (i == HISTOGRAM_TOT_GRID_LINES) {
- glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
}
- fdrawline(rect.xmin, rect.ymin + fac * h, rect.xmax, rect.ymin + fac * h);
- fdrawline(rect.xmin + fac * w, rect.ymin, rect.xmin + fac * w, rect.ymax);
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
+ immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
+
+ immVertex2f(pos, rect.xmin + fac * w, rect.ymin);
+ immVertex2f(pos, rect.xmin + fac * w, rect.ymax);
+
+ immEnd();
}
-
+
if (hist->mode == HISTO_MODE_LUMA) {
- histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line);
+ histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos);
}
else if (hist->mode == HISTO_MODE_ALPHA) {
- histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line);
+ histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos);
}
else {
if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R)
- histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line);
+ histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G)
- histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line);
+ histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B)
- histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line);
+ histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
}
+
+ immUnbindProgram();
/* outline */
draw_scope_end(&rect, scissor);
@@ -620,6 +760,25 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
#undef HISTOGRAM_TOT_GRID_LINES
+static void waveform_draw_one(float *waveform, int nbr, const float col[3])
+{
+ VertexFormat format = {0};
+ unsigned int pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, nbr);
+
+ VertexBuffer_fill_attrib(vbo, pos_id, waveform);
+
+ /* TODO store the Batch inside the scope */
+ Batch *batch = Batch_create(PRIM_POINTS, vbo, NULL);
+ Batch_set_builtin_program(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ Batch_Uniform4f(batch, "color", col[0], col[1], col[2], 1.0f);
+ Batch_draw(batch);
+
+ Batch_discard_all(batch);
+}
+
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
{
Scopes *scopes = (Scopes *)but->poin;
@@ -642,7 +801,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
scopes->wavefrm_yfac = 0.98f;
float w = BLI_rctf_size_x(&rect) - 7;
float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
- float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) / 2.0f;
+ float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
float w3 = w / 3.0f;
/* log scale for alpha */
@@ -660,9 +819,10 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- UI_ThemeColor4(TH_PREVIEW_BACK);
+ float color[4];
+ UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
/* need scissor test, waveform can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
@@ -671,94 +831,119 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
- glColor4f(1.f, 1.f, 1.f, 0.08f);
- /* draw grid lines here */
+ /* draw scale numbers first before binding any shader */
for (int i = 0; i < 6; i++) {
char str[4];
BLI_snprintf(str, sizeof(str), "%-3d", i * 20);
str[3] = '\0';
- fdrawline(rect.xmin + 22, yofs + (i / 5.f) * h, rect.xmax + 1, yofs + (i / 5.f) * h);
- BLF_draw_default(rect.xmin + 1, yofs - 5 + (i / 5.f) * h, 0, str, sizeof(str) - 1);
- /* in the loop because blf_draw reset it */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
+ BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
+
+ /* draw grid lines here */
+ immBegin(PRIM_LINES, 12);
+
+ for (int i = 0; i < 6; i++) {
+ immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
+ immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
}
+
+ immEnd();
+
/* 3 vertical separation */
if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
+ immBegin(PRIM_LINES, 4);
+
for (int i = 1; i < 3; i++) {
- fdrawline(rect.xmin + i * w3, rect.ymin, rect.xmin + i * w3, rect.ymax);
+ immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
+ immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
}
+
+ immEnd();
}
/* separate min max zone on the right */
- fdrawline(rect.xmin + w, rect.ymin, rect.xmin + w, rect.ymax);
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmin + w, rect.ymin);
+ immVertex2f(pos, rect.xmin + w, rect.ymax);
+ immEnd();
+
/* 16-235-240 level in case of ITU-R BT601/709 */
- glColor4f(1.f, 0.4f, 0.f, 0.2f);
+ immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) {
- fdrawline(rect.xmin + 22, yofs + h * 16.0f / 255.0f, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
- fdrawline(rect.xmin + 22, yofs + h * 235.0f / 255.0f, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
- fdrawline(rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
- fdrawline(rect.xmin + w3, yofs + h * 240.0f / 255.0f, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
+ immBegin(PRIM_LINES, 8);
+
+ immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
+
+ immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
+ immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
+
+ immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
+
+ immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
+
+ immEnd();
}
/* 7.5 IRE black point level for NTSC */
- if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA)
- fdrawline(rect.xmin, yofs + h * 0.075f, rect.xmax + 1, yofs + h * 0.075f);
+ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
+ immEnd();
+ }
if (scopes->ok && scopes->waveform_1 != NULL) {
-
- /* LUMA (1 channel) */
glBlendFunc(GL_ONE, GL_ONE);
- glColor3f(alpha, alpha, alpha);
glPointSize(1.0);
+ /* LUMA (1 channel) */
if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
+ float col[3] = {alpha, alpha, alpha};
- glBlendFunc(GL_ONE, GL_ONE);
-
- glPushMatrix();
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glTranslatef(rect.xmin, yofs, 0.f);
- glScalef(w, h, 0.f);
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+ gpuPushMatrix();
+ gpuTranslate2f(rect.xmin, yofs);
+ gpuScale2f(w, h);
- glDisableClientState(GL_VERTEX_ARRAY);
- glPopMatrix();
+ waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
+
+ gpuPopMatrix();
/* min max */
- glColor3f(0.5f, 0.5f, 0.5f);
+ immUniformColor3f(0.5f, 0.5f, 0.5f);
min = yofs + scopes->minmax[0][0] * h;
max = yofs + scopes->minmax[0][1] * h;
CLAMP(min, rect.ymin, rect.ymax);
CLAMP(max, rect.ymin, rect.ymax);
- fdrawline(rect.xmax - 3, min, rect.xmax - 3, max);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmax - 3, min);
+ immVertex2f(pos, rect.xmax - 3, max);
+ immEnd();
}
/* RGB (3 channel) */
else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
- glBlendFunc(GL_ONE, GL_ONE);
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glPushMatrix();
+ gpuPushMatrix();
+ gpuTranslate2f(rect.xmin, yofs);
+ gpuScale2f(w, h);
- glTranslatef(rect.xmin, yofs, 0.f);
- glScalef(w, h, 0.f);
+ waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
+ waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
+ waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
- glColor3fv( colors_alpha[0] );
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
-
- glColor3fv( colors_alpha[1] );
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
-
- glColor3fv( colors_alpha[2] );
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glPopMatrix();
+ gpuPopMatrix();
}
/* PARADE / YCC (3 channels) */
else if (ELEM(scopes->wavefrm_mode,
@@ -770,49 +955,47 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
{
int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
- glBlendFunc(GL_ONE, GL_ONE);
-
- glPushMatrix();
- glEnableClientState(GL_VERTEX_ARRAY);
+ gpuPushMatrix();
+ gpuTranslate2f(rect.xmin, yofs);
+ gpuScale2f(w3, h);
- glTranslatef(rect.xmin, yofs, 0.f);
- glScalef(w3, h, 0.f);
+ waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
- glColor3fv((rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+ gpuTranslate2f(1.0f, 0.0f);
+ waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
- glTranslatef(1.f, 0.f, 0.f);
- glColor3fv((rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+ gpuTranslate2f(1.0f, 0.0f);
+ waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
- glTranslatef(1.f, 0.f, 0.f);
- glColor3fv((rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
- glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glPopMatrix();
+ gpuPopMatrix();
}
+
/* min max */
if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA ) {
for (int c = 0; c < 3; c++) {
if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB_PARADE, SCOPES_WAVEFRM_RGB))
- glColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
+ immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
else
- glColor3f(colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
+ immUniformColor3f(colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
min = yofs + scopes->minmax[c][0] * h;
max = yofs + scopes->minmax[c][1] * h;
CLAMP(min, rect.ymin, rect.ymax);
CLAMP(max, rect.ymin, rect.ymax);
- fdrawline(rect.xmin + w + 2 + c * 2, min, rect.xmin + w + 2 + c * 2, max);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
+ immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
+ immEnd();
}
}
}
-
+
+ immUnbindProgram();
+
/* outline */
draw_scope_end(&rect, scissor);
+
+ glDisable(GL_BLEND);
}
static float polar_to_x(float center, float diam, float ampli, float angle)
@@ -825,10 +1008,10 @@ static float polar_to_y(float center, float diam, float ampli, float angle)
return center + diam * ampli * sinf(angle);
}
-static void vectorscope_draw_target(float centerx, float centery, float diam, const float colf[3])
+static void vectorscope_draw_target(unsigned int pos, float centerx, float centery, float diam, const float colf[3])
{
float y, u, v;
- float tangle = 0.f, tampli;
+ float tangle = 0.0f, tampli;
float dangle, dampli, dangle2, dampli2;
rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v);
@@ -840,41 +1023,41 @@ static void vectorscope_draw_target(float centerx, float centery, float diam, co
tampli = sqrtf(u * u + v * v);
/* small target vary by 2.5 degree and 2.5 IRE unit */
- glColor4f(1.0f, 1.0f, 1.0, 0.12f);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
dangle = DEG2RADF(2.5f);
dampli = 2.5f / 200.0f;
- glBegin(GL_LINE_LOOP);
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
- glEnd();
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
+ immEnd();
/* big target vary by 10 degree and 20% amplitude */
- glColor4f(1.0f, 1.0f, 1.0, 0.12f);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
dangle = DEG2RADF(10.0f);
dampli = 0.2f * tampli;
dangle2 = DEG2RADF(5.0f);
dampli2 = 0.5f * dampli;
- glBegin(GL_LINE_STRIP);
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2));
- glEnd();
- glBegin(GL_LINE_STRIP);
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2));
- glEnd();
- glBegin(GL_LINE_STRIP);
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2));
- glEnd();
- glBegin(GL_LINE_STRIP);
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
- glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2));
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2));
+ immEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2));
+ immEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2));
+ immEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
+ immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2));
+ immEnd();
}
void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
@@ -895,8 +1078,8 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
float w = BLI_rctf_size_x(&rect);
float h = BLI_rctf_size_y(&rect);
- float centerx = rect.xmin + w / 2;
- float centery = rect.ymin + h / 2;
+ float centerx = rect.xmin + w * 0.5f;
+ float centery = rect.ymin + h * 0.5f;
float diam = (w < h) ? w : h;
float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
@@ -904,9 +1087,10 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- UI_ThemeColor4(TH_PREVIEW_BACK);
+ float color[4];
+ UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
/* need scissor test, hvectorscope can draw outside of boundary */
GLint scissor[4];
@@ -916,93 +1100,109 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
- glColor4f(1.f, 1.f, 1.f, 0.08f);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
/* draw grid elements */
/* cross */
- fdrawline(centerx - (diam / 2) - 5, centery, centerx + (diam / 2) + 5, centery);
- fdrawline(centerx, centery - (diam / 2) - 5, centerx, centery + (diam / 2) + 5);
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
+ immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
+
+ immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
+ immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
+
+ immEnd();
+
/* circles */
for (int j = 0; j < 5; j++) {
- glBegin(GL_LINE_LOOP);
const int increment = 15;
+ immBegin(PRIM_LINE_LOOP, (int)(360 / increment));
for (int i = 0; i <= 360 - increment; i += increment) {
const float a = DEG2RADF((float)i);
- const float r = (j + 1) / 10.0f;
- glVertex2f(polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
+ const float r = (j + 1) * 0.1f;
+ immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
}
- glEnd();
+ immEnd();
}
/* skin tone line */
- glColor4f(1.f, 0.4f, 0.f, 0.2f);
- fdrawline(polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5, skin_rad),
- polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1, skin_rad));
+ immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
+ immVertex2f(pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
+ immEnd();
+
/* saturation points */
for (int i = 0; i < 6; i++)
- vectorscope_draw_target(centerx, centery, diam, colors[i]);
+ vectorscope_draw_target(pos, centerx, centery, diam, colors[i]);
if (scopes->ok && scopes->vecscope != NULL) {
/* pixel point cloud */
+ float col[3] = {alpha, alpha, alpha};
+
glBlendFunc(GL_ONE, GL_ONE);
- glColor3f(alpha, alpha, alpha);
+ glPointSize(1.0);
- glPushMatrix();
- glEnableClientState(GL_VERTEX_ARRAY);
+ gpuPushMatrix();
+ gpuTranslate2f(centerx, centery);
+ gpuScaleUniform(diam);
- glTranslatef(centerx, centery, 0.f);
- glScalef(diam, diam, 0.f);
+ waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
- glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope);
- glPointSize(1.0);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glPopMatrix();
+ gpuPopMatrix();
}
+ immUnbindProgram();
+
/* outline */
draw_scope_end(&rect, scissor);
glDisable(GL_BLEND);
}
-static void ui_draw_colorband_handle_tri_hlight(float x1, float y1, float halfwidth, float height)
+static void ui_draw_colorband_handle_tri_hlight(unsigned int pos, float x1, float y1, float halfwidth, float height)
{
glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINE_STRIP);
- glVertex2f(x1 + halfwidth, y1);
- glVertex2f(x1, y1 + height);
- glVertex2f(x1 - halfwidth, y1);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, x1 + halfwidth, y1);
+ immVertex2f(pos, x1, y1 + height);
+ immVertex2f(pos, x1 - halfwidth, y1);
+ immEnd();
glDisable(GL_LINE_SMOOTH);
}
-static void ui_draw_colorband_handle_tri(float x1, float y1, float halfwidth, float height, bool fill)
+static void ui_draw_colorband_handle_tri(unsigned int pos, float x1, float y1, float halfwidth, float height, bool fill)
{
glEnable(fill ? GL_POLYGON_SMOOTH : GL_LINE_SMOOTH);
- glBegin(fill ? GL_TRIANGLES : GL_LINE_LOOP);
- glVertex2f(x1 + halfwidth, y1);
- glVertex2f(x1, y1 + height);
- glVertex2f(x1 - halfwidth, y1);
- glEnd();
+ immBegin(fill ? PRIM_TRIANGLES : PRIM_LINE_LOOP, 3);
+ immVertex2f(pos, x1 + halfwidth, y1);
+ immVertex2f(pos, x1, y1 + height);
+ immVertex2f(pos, x1 - halfwidth, y1);
+ immEnd();
glDisable(fill ? GL_POLYGON_SMOOTH : GL_LINE_SMOOTH);
}
-static void ui_draw_colorband_handle_box(float x1, float y1, float x2, float y2, bool fill)
+static void ui_draw_colorband_handle_box(unsigned int pos, float x1, float y1, float x2, float y2, bool fill)
{
- glBegin(fill ? GL_QUADS : GL_LINE_LOOP);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
- glEnd();
+ immBegin(fill ? PRIM_TRIANGLE_FAN : PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2, y1);
+ immEnd();
}
static void ui_draw_colorband_handle(
- const rcti *rect, float x,
+ uint shdr_pos, const rcti *rect, float x,
const float rgb[3], struct ColorManagedDisplay *display,
bool active)
{
@@ -1021,18 +1221,26 @@ static void ui_draw_colorband_handle(
y1 = floorf(y1 + 0.5f);
if (active || half_width < min_width) {
- glBegin(GL_LINES);
- glColor3ub(0, 0, 0);
- glVertex2f(x, y1);
- glVertex2f(x, y2);
- glEnd();
- setlinestyle(active ? 2 : 1);
- glBegin(GL_LINES);
- glColor3ub(200, 200, 200);
- glVertex2f(x, y1);
- glVertex2f(x, y2);
- glEnd();
- setlinestyle(0);
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", active ? 4.0f : 2.0f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(shdr_pos, x, y1);
+ immVertex2f(shdr_pos, x, y2);
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* hide handles when zoomed out too far */
if (half_width < min_width) {
@@ -1043,45 +1251,46 @@ static void ui_draw_colorband_handle(
/* shift handle down */
y1 -= half_width;
- glColor3ub(0, 0, 0);
- ui_draw_colorband_handle_box(x - half_width, y1 - 1, x + half_width, y1 + height, false);
+ immUniformColor3ub(0, 0, 0);
+ ui_draw_colorband_handle_box(shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false);
/* draw all triangles blended */
glEnable(GL_BLEND);
- ui_draw_colorband_handle_tri(x, y1 + height, half_width, half_width, true);
+ ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
if (active)
- glColor3ub(196, 196, 196);
+ immUniformColor3ub(196, 196, 196);
else
- glColor3ub(96, 96, 96);
- ui_draw_colorband_handle_tri(x, y1 + height, half_width, half_width, true);
+ immUniformColor3ub(96, 96, 96);
+ ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
if (active)
- glColor3ub(255, 255, 255);
+ immUniformColor3ub(255, 255, 255);
else
- glColor3ub(128, 128, 128);
- ui_draw_colorband_handle_tri_hlight(x, y1 + height - 1, (half_width - 1), (half_width - 1));
+ immUniformColor3ub(128, 128, 128);
+ ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height - 1, (half_width - 1), (half_width - 1));
- glColor3ub(0, 0, 0);
- ui_draw_colorband_handle_tri_hlight(x, y1 + height, half_width, half_width);
+ immUniformColor3ub(0, 0, 0);
+ ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width);
glDisable(GL_BLEND);
- glColor3ub(128, 128, 128);
- ui_draw_colorband_handle_box(x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true);
+ immUniformColor3ub(128, 128, 128);
+ ui_draw_colorband_handle_box(shdr_pos, x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true);
if (display) {
IMB_colormanagement_scene_linear_to_display_v3(colf, display);
}
- glColor3fv(colf);
- ui_draw_colorband_handle_box(x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true);
+ immUniformColor3fv(colf);
+ ui_draw_colorband_handle_box(shdr_pos, x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true);
}
void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect)
{
struct ColorManagedDisplay *display = NULL;
+ unsigned int position, color;
ColorBand *coba = (ColorBand *)(but->editcoba ? but->editcoba : but->poin);
if (coba == NULL) return;
@@ -1092,20 +1301,25 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
float x1 = rect->xmin;
float sizex = rect->xmax - x1;
float sizey = BLI_rcti_size_y(rect);
- float sizey_solid = sizey / 4;
+ float sizey_solid = sizey * 0.25f;
float y1 = rect->ymin;
- /* Drawing the checkerboard.
- * This could be optimized with a single checkerboard shader,
- * instead of drawing twice and using stippling the second time. */
- /* layer: background, to show tranparency */
- glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255);
- glRectf(x1, y1, x1 + sizex, rect->ymax);
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_CHECKER_8PX);
- glRectf(x1, y1, x1 + sizex, rect->ymax);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ VertexFormat *format = immVertexFormat();
+ position = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
+
+ /* Drawing the checkerboard. */
+ immUniform4f("color1", UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, 1.0f);
+ immUniform4f("color2", UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 1.0f);
+ immUniform1i("size", 8);
+ immRectf(position, x1, y1, x1 + sizex, rect->ymax);
+ immUnbindProgram();
+
+ /* New format */
+ format = immVertexFormat();
+ position = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ color = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
/* layer: color ramp */
glEnable(GL_BLEND);
@@ -1118,7 +1332,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[1] = y1 + sizey_solid;
v2[1] = rect->ymax;
- glBegin(GL_TRIANGLE_STRIP);
+ immBegin(PRIM_TRIANGLE_STRIP, (sizex + 1) * 2);
for (int a = 0; a <= sizex; a++) {
float pos = ((float)a) / sizex;
do_colorband(coba, pos, colf);
@@ -1127,17 +1341,17 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[0] = v2[0] = x1 + a;
- glColor4fv(colf);
- glVertex2fv(v1);
- glVertex2fv(v2);
+ immAttrib4fv(color, colf);
+ immVertex2fv(position, v1);
+ immVertex2fv(position, v2);
}
- glEnd();
+ immEnd();
/* layer: color ramp without alpha for reference when manipulating ramp properties */
v1[1] = y1;
v2[1] = y1 + sizey_solid;
- glBegin(GL_TRIANGLE_STRIP);
+ immBegin(PRIM_TRIANGLE_STRIP, (sizex + 1) * 2);
for (int a = 0; a <= sizex; a++) {
float pos = ((float)a) / sizex;
do_colorband(coba, pos, colf);
@@ -1146,31 +1360,48 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[0] = v2[0] = x1 + a;
- glColor4f(colf[0], colf[1], colf[2], 1.0f);
- glVertex2fv(v1);
- glVertex2fv(v2);
+ immAttrib4f(color, colf[0], colf[1], colf[2], 1.0f);
+ immVertex2fv(position, v1);
+ immVertex2fv(position, v2);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
glDisable(GL_BLEND);
+ /* New format */
+ format = immVertexFormat();
+ position = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* layer: box outline */
- glColor4f(0.0, 0.0, 0.0, 1.0);
- fdrawbox(x1, y1, x1 + sizex, rect->ymax);
-
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ imm_draw_line_box(position, x1, y1, x1 + sizex, rect->ymax);
+
/* layer: box outline */
glEnable(GL_BLEND);
- glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
- fdrawline(x1, y1, x1 + sizex, y1);
- glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
- fdrawline(x1, y1 - 1, x1 + sizex, y1 - 1);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(position, x1, y1);
+ immVertex2f(position, x1 + sizex, y1);
+ immEnd();
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(position, x1, y1 - 1);
+ immVertex2f(position, x1 + sizex, y1 - 1);
+ immEnd();
+
glDisable(GL_BLEND);
/* layer: draw handles */
for (int a = 0; a < coba->tot; a++, cbd++) {
if (a != coba->cur) {
float pos = x1 + cbd->pos * (sizex - 1) + 1;
- ui_draw_colorband_handle(rect, pos, &cbd->r, display, false);
+ ui_draw_colorband_handle(position, rect, pos, &cbd->r, display, false);
}
}
@@ -1178,117 +1409,100 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
if (coba->tot != 0) {
cbd = &coba->data[coba->cur];
float pos = x1 + cbd->pos * (sizex - 1) + 1;
- ui_draw_colorband_handle(rect, pos, &cbd->r, display, true);
+ ui_draw_colorband_handle(position, rect, pos, &cbd->r, display, true);
}
+
+ immUnbindProgram();
}
void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
{
- static GLuint displist = 0;
+ /* sphere color */
float diffuse[3] = {1.0f, 1.0f, 1.0f};
+ float light[3];
float size;
/* backdrop */
- glColor3ubv((unsigned char *)wcol->inner);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f);
+ UI_draw_roundbox_3ubAlpha(true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, (unsigned char *)wcol->inner, 255);
- /* sphere color */
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
/* setup lights */
- GPULightData light = {0};
- light.type = GPU_LIGHT_SUN;
- copy_v3_v3(light.diffuse, diffuse);
- zero_v3(light.specular);
- ui_but_v3_get(but, light.direction);
-
- GPU_basic_shader_light_set(0, &light);
- for (int a = 1; a < 8; a++)
- GPU_basic_shader_light_set(a, NULL);
-
- /* setup shader */
- GPU_basic_shader_colors(diffuse, NULL, 0, 1.0f);
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING);
+ ui_but_v3_get(but, light);
/* transform to button */
- glPushMatrix();
- glTranslatef(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect), 0.0f);
+ gpuPushMatrix();
if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect))
- size = BLI_rcti_size_x(rect) / 200.f;
+ size = 0.5f * BLI_rcti_size_x(rect);
else
- size = BLI_rcti_size_y(rect) / 200.f;
-
- glScalef(size, size, MIN2(size, 1.0f));
+ size = 0.5f * BLI_rcti_size_y(rect);
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
- GPU_basic_shader_bind(GPU_basic_shader_bound_options());
- gluSphere(qobj, 100.0, 32, 24);
- gluDeleteQuadric(qobj);
-
- glEndList();
- }
+ gpuTranslate2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect));
+ gpuScaleUniform(size);
- glCallList(displist);
+ Batch *sphere = Batch_get_sphere(2);
+ Batch_set_builtin_program(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
+ Batch_Uniform3fv(sphere, "light", light);
+ Batch_draw(sphere);
/* restore */
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- GPU_default_lights();
glDisable(GL_CULL_FACE);
/* AA circle */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ubv((unsigned char *)wcol->inner);
+
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glColor3ubv((unsigned char *)wcol->inner);
- glutil_draw_lined_arc(0.0f, M_PI * 2.0, 100.0f, 32);
+ imm_draw_circle_wire(pos, 0.0f, 0.0f, 1.0f, 32);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
/* matrix after circle */
- glPopMatrix();
+ gpuPopMatrix();
- /* We disabled all blender lights above, so restore them here. */
- GPU_default_lights();
+ immUnbindProgram();
}
-static void ui_draw_but_curve_grid(const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step)
+static void ui_draw_but_curve_grid(unsigned int pos, const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step)
{
- glBegin(GL_LINES);
float dx = step * zoomx;
float fx = rect->xmin + zoomx * (-offsx);
if (fx > rect->xmin) fx -= dx * (floorf(fx - rect->xmin));
- while (fx < rect->xmax) {
- glVertex2f(fx, rect->ymin);
- glVertex2f(fx, rect->ymax);
- fx += dx;
- }
float dy = step * zoomy;
float fy = rect->ymin + zoomy * (-offsy);
if (fy > rect->ymin) fy -= dy * (floorf(fy - rect->ymin));
+
+ float line_count = floorf((rect->xmax - fx) / dx) + 1.0f +
+ floorf((rect->ymax - fy) / dy) + 1.0f;
+
+ immBegin(PRIM_LINES, (int)line_count * 2);
+ while (fx < rect->xmax) {
+ immVertex2f(pos, fx, rect->ymin);
+ immVertex2f(pos, fx, rect->ymax);
+ fx += dx;
+ }
while (fy < rect->ymax) {
- glVertex2f(rect->xmin, fy);
- glVertex2f(rect->xmax, fy);
+ immVertex2f(pos, rect->xmin, fy);
+ immVertex2f(pos, rect->xmax, fy);
fy += dy;
}
- glEnd();
+ immEnd();
}
static void gl_shaded_color(unsigned char *col, int shade)
{
- glColor3ub(col[0] - shade > 0 ? col[0] - shade : 0,
- col[1] - shade > 0 ? col[1] - shade : 0,
- col[2] - shade > 0 ? col[2] - shade : 0);
+ immUniformColor3ub(col[0] - shade > 0 ? col[0] - shade : 0,
+ col[1] - shade > 0 ? col[1] - shade : 0,
+ col[2] - shade > 0 ? col[2] - shade : 0);
}
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti *rect)
@@ -1324,10 +1538,8 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&cumap->curr);
float offsx = cumap->curr.xmin - (1.0f / zoomx);
float offsy = cumap->curr.ymin - (1.0f / zoomy);
-
- glLineWidth(1.0f);
- /* backdrop */
+ /* Do this first to not mess imm context */
if (but->a1 == UI_GRAD_H) {
/* magic trigger for curve backgrounds */
float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
@@ -1340,96 +1552,105 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
};
ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f);
+ }
+ glLineWidth(1.0f);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* backdrop */
+ if (but->a1 == UI_GRAD_H) {
/* grid, hsv uses different grid */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(0, 0, 0, 48);
- ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
+ immUniformColor4ub(0, 0, 0, 48);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
glDisable(GL_BLEND);
}
else {
if (cumap->flag & CUMA_DO_CLIP) {
gl_shaded_color((unsigned char *)wcol->inner, -20);
- glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- glColor3ubv((unsigned char *)wcol->inner);
- glRectf(rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
- rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
- rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
- rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformColor3ubv((unsigned char *)wcol->inner);
+ immRectf(pos, rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
+ rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
+ rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
+ rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
}
else {
- glColor3ubv((unsigned char *)wcol->inner);
- glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformColor3ubv((unsigned char *)wcol->inner);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
}
/* grid, every 0.25 step */
gl_shaded_color((unsigned char *)wcol->inner, -16);
- ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
/* grid, every 1.0 step */
gl_shaded_color((unsigned char *)wcol->inner, -24);
- ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
/* axes */
gl_shaded_color((unsigned char *)wcol->inner, -50);
- glBegin(GL_LINES);
- glVertex2f(rect->xmin, rect->ymin + zoomy * (-offsy));
- glVertex2f(rect->xmax, rect->ymin + zoomy * (-offsy));
- glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymin);
- glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymax);
- glEnd();
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
+ immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
+ immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax);
+ immEnd();
}
/* cfra option */
/* XXX 2.48 */
#if 0
if (cumap->flag & CUMA_DRAW_CFRA) {
- glColor3ub(0x60, 0xc0, 0x40);
- glBegin(GL_LINES);
- glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
- glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
- glEnd();
+ immUniformColor3ub(0x60, 0xc0, 0x40);
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
+ immEnd();
}
#endif
/* sample option */
if (cumap->flag & CUMA_DRAW_SAMPLE) {
- glBegin(GL_LINES); /* will draw one of the following 3 lines */
+ immBegin(PRIM_LINES, 2); /* will draw one of the following 3 lines */
if (but->a1 == UI_GRAD_H) {
float tsample[3];
float hsv[3];
linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
rgb_to_hsv_v(tsample, hsv);
- glColor3ub(240, 240, 240);
+ immUniformColor3ub(240, 240, 240);
- glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
- glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
+ immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
}
else if (cumap->cur == 3) {
float lum = IMB_colormanagement_get_luminance(cumap->sample);
- glColor3ub(240, 240, 240);
+ immUniformColor3ub(240, 240, 240);
- glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymin);
- glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymax);
+ immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
}
else {
if (cumap->cur == 0)
- glColor3ub(240, 100, 100);
+ immUniformColor3ub(240, 100, 100);
else if (cumap->cur == 1)
- glColor3ub(100, 240, 100);
+ immUniformColor3ub(100, 240, 100);
else
- glColor3ub(100, 100, 240);
+ immUniformColor3ub(100, 100, 240);
- glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
- glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
}
- glEnd();
+ immEnd();
}
/* the curve */
- glColor3ubv((unsigned char *)wcol->item);
+ immUniformColor3ubv((unsigned char *)wcol->item);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, (CM_TABLE+1) + 2);
if (cuma->table == NULL)
curvemapping_changed(cumap, false);
@@ -1438,52 +1659,67 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
/* first point */
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
- glVertex2f(rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy));
+ immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy));
}
else {
float fx = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
float fy = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
- glVertex2f(fx, fy);
+ immVertex2f(pos, fx, fy);
}
for (int a = 0; a <= CM_TABLE; a++) {
float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
- glVertex2f(fx, fy);
+ immVertex2f(pos, fx, fy);
}
/* last point */
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
- glVertex2f(rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy));
+ immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy));
}
else {
float fx = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
float fy = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
- glVertex2f(fx, fy);
+ immVertex2f(pos, fx, fy);
}
- glEnd();
+ immEnd();
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
+ immUnbindProgram();
/* the points, use aspect to make them visible on edges */
+ format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
cmp = cuma->curve;
glPointSize(3.0f);
- glBegin(GL_POINTS);
+ immBegin(PRIM_POINTS, cuma->totpoint);
for (int a = 0; a < cuma->totpoint; a++) {
+ float color[4];
if (cmp[a].flag & CUMA_SELECT)
- UI_ThemeColor(TH_TEXT_HI);
+ UI_GetThemeColor4fv(TH_TEXT_HI, color);
else
- UI_ThemeColor(TH_TEXT);
+ UI_GetThemeColor4fv(TH_TEXT, color);
float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
- glVertex2f(fx, fy);
+ immAttrib4fv(col, color);
+ immVertex2f(pos, fx, fy);
}
- glEnd();
+ immEnd();
+ immUnbindProgram();
/* restore scissortest */
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
/* outline */
- glColor3ubv((unsigned char *)wcol->outline);
- fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv((unsigned char *)wcol->outline);
+ imm_draw_line_box(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ immUnbindProgram();
}
void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
@@ -1513,9 +1749,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
(rect.ymax + 1) - (rect.ymin - 1));
if (scopes->track_disabled) {
- glColor4f(0.7f, 0.3f, 0.3f, 0.3f);
+ float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
ok = true;
}
@@ -1542,62 +1778,72 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
}
if (!ok && scopes->track_preview) {
- glPushMatrix();
+ gpuPushMatrix();
/* draw content of pattern area */
glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]);
if (width > 0 && height > 0) {
ImBuf *drawibuf = scopes->track_preview;
+ float col_sel[4], col_outline[4];
if (scopes->use_track_mask) {
- glColor4f(0.0f, 0.0f, 0.0f, 0.3f);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
}
- glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y,
- drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, drawibuf->rect, 1.0f, 1.0f, NULL);
/* draw cross for pixel position */
- glTranslatef(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1], 0.f);
+ gpuTranslate2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
glScissor(ar->winrct.xmin + rect.xmin,
ar->winrct.ymin + rect.ymin,
BLI_rctf_size_x(&rect),
BLI_rctf_size_y(&rect));
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE);
-
- for (int a = 0; a < 2; a++) {
- if (a == 1) {
- GPU_basic_shader_bind_enable(GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
- UI_ThemeColor(TH_SEL_MARKER);
- }
- else {
- UI_ThemeColor(TH_MARKER_OUTLINE);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel);
+ UI_GetThemeColor4fv(TH_MARKER_OUTLINE, col_outline);
+
+ /* Do stipple cross with geometry */
+ immBegin(PRIM_LINES, 7*2*2);
+ float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
+ for (int axe = 0; axe < 2; ++axe) {
+ for (int i = 0; i < 7; ++i) {
+ float x1 = pos_sel[i] * (1 - axe);
+ float y1 = pos_sel[i] * axe;
+ float x2 = pos_sel[i+1] * (1 - axe);
+ float y2 = pos_sel[i+1] * axe;
+
+ if (i % 2 == 1)
+ immAttrib4fv(col, col_sel);
+ else
+ immAttrib4fv(col, col_outline);
+
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
}
-
- glBegin(GL_LINES);
- glVertex2f(-10.0f, 0.0f);
- glVertex2f(10.0f, 0.0f);
- glVertex2f(0.0f, -10.0f);
- glVertex2f(0.0f, 10.0f);
- glEnd();
}
+ immEnd();
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ immUnbindProgram();
}
- glPopMatrix();
+ gpuPopMatrix();
ok = true;
}
if (!ok) {
- glColor4f(0.f, 0.f, 0.f, 0.3f);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
}
/* outline */
@@ -1643,26 +1889,31 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
BLI_rcti_size_x(&scissor_new),
BLI_rcti_size_y(&scissor_new));
- glColor4ubv(but->col);
-
float x = 0.5f * (recti->xmin + recti->xmax);
float y = 0.5f * (recti->ymin + recti->ymax);
-
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv(but->col);
+
glEnable(GL_BLEND);
- glBegin(GL_POLYGON);
+ immBegin(PRIM_TRIANGLE_FAN, 16);
for (int a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
+ immVertex2f(pos, x + size * si[a], y + size * co[a]);
+ immEnd();
- glColor4ub(0, 0, 0, 150);
+ immUniformColor4ub(0, 0, 0, 150);
glLineWidth(1);
glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINE_LOOP);
+ immBegin(PRIM_LINE_LOOP, 16);
for (int a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
+ immVertex2f(pos, x + size * si[a], y + size * co[a]);
+ immEnd();
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
+
+ immUnbindProgram();
/* restore scissortest */
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
@@ -1670,47 +1921,91 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
/* ****************************************************** */
+/* TODO: high quality UI drop shadows using GLSL shader and single draw call
+ * would replace / modify the following 3 functions - merwin
+ */
-static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
+static void ui_shadowbox(unsigned pos, unsigned color, float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
{
+ /* v1-_
+ * | -_v2
+ * | |
+ * | |
+ * | |
+ * v7_______v3____v4
+ * \ | /
+ * \ | _v5
+ * v8______v6_-
+ */
+ const float v1[2] = {maxx, maxy - 0.3f * shadsize};
+ const float v2[2] = {maxx + shadsize, maxy - 0.75f * shadsize};
+ const float v3[2] = {maxx, miny};
+ const float v4[2] = {maxx + shadsize, miny};
+
+ const float v5[2] = {maxx + 0.7f * shadsize, miny - 0.7f * shadsize};
+
+ const float v6[2] = {maxx, miny - shadsize};
+ const float v7[2] = {minx + 0.3f * shadsize, miny};
+ const float v8[2] = {minx + 0.5f * shadsize, miny - shadsize};
+
/* right quad */
- glColor4ub(0, 0, 0, alpha);
- glVertex2f(maxx, miny);
- glVertex2f(maxx, maxy - 0.3f * shadsize);
- glColor4ub(0, 0, 0, 0);
- glVertex2f(maxx + shadsize, maxy - 0.75f * shadsize);
- glVertex2f(maxx + shadsize, miny);
-
+ immAttrib4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v3);
+ immVertex2fv(pos, v1);
+ immAttrib4ub(color, 0, 0, 0, 0);
+ immVertex2fv(pos, v2);
+
+ immVertex2fv(pos, v2);
+ immVertex2fv(pos, v4);
+ immAttrib4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v3);
+
/* corner shape */
- glColor4ub(0, 0, 0, alpha);
- glVertex2f(maxx, miny);
- glColor4ub(0, 0, 0, 0);
- glVertex2f(maxx + shadsize, miny);
- glVertex2f(maxx + 0.7f * shadsize, miny - 0.7f * shadsize);
- glVertex2f(maxx, miny - shadsize);
-
+ /* immAttrib4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */
+ immVertex2fv(pos, v3);
+ immAttrib4ub(color, 0, 0, 0, 0);
+ immVertex2fv(pos, v4);
+ immVertex2fv(pos, v5);
+
+ immVertex2fv(pos, v5);
+ immVertex2fv(pos, v6);
+ immAttrib4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v3);
+
/* bottom quad */
- glColor4ub(0, 0, 0, alpha);
- glVertex2f(minx + 0.3f * shadsize, miny);
- glVertex2f(maxx, miny);
- glColor4ub(0, 0, 0, 0);
- glVertex2f(maxx, miny - shadsize);
- glVertex2f(minx + 0.5f * shadsize, miny - shadsize);
+ /* immAttrib4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */
+ immVertex2fv(pos, v3);
+ immAttrib4ub(color, 0, 0, 0, 0);
+ immVertex2fv(pos, v6);
+ immVertex2fv(pos, v8);
+
+ immVertex2fv(pos, v8);
+ immAttrib4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v7);
+ immVertex2fv(pos, v3);
}
void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
{
glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ immBegin(PRIM_TRIANGLES, 54);
/* accumulated outline boxes to make shade not linear, is more pleasant */
- ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
- ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
- ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
-
- glEnd();
+ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
+ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
+ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
+ immEnd();
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
@@ -1719,8 +2014,8 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha
{
float rad;
- if (radius > (BLI_rctf_size_y(rct) - 10.0f) / 2.0f)
- rad = (BLI_rctf_size_y(rct) - 10.0f) / 2.0f;
+ if (radius > (BLI_rctf_size_y(rct) - 10.0f) * 0.5f)
+ rad = (BLI_rctf_size_y(rct) - 10.0f) * 0.5f;
else
rad = radius;
@@ -1741,29 +2036,16 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha
float calpha = dalpha;
for (; i--; a -= aspect) {
/* alpha ranges from 2 to 20 or so */
- glColor4f(0.0f, 0.0f, 0.0f, calpha);
+ float color[4] = {0.0f, 0.0f, 0.0f, calpha};
+ UI_draw_roundbox_4fv(true, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a, color);
calpha += dalpha;
-
- UI_draw_roundbox_gl_mode(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a);
}
/* outline emphasis */
glEnable(GL_LINE_SMOOTH);
- glColor4ub(0, 0, 0, 100);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
+ UI_draw_roundbox_4fv(false, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f, color);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
-
-/**
- * Reset GL state (keep minimal).
- *
- * \note Blender's internal code doesn't assume these are reset,
- * but external callbacks may depend on their state.
- */
-void UI_reinit_gl_state(void)
-{
- glLineWidth(1.0f);
- glPointSize(1.0f);
-}
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index eab609ebe84..bad47512d12 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -139,8 +139,8 @@ static void eyedropper_draw_cursor_text(const struct bContext *C, ARegion *ar, c
wmWindow *win = CTX_wm_window(C);
int x = win->eventstate->x;
int y = win->eventstate->y;
- const unsigned char fg[4] = {255, 255, 255, 255};
- const unsigned char bg[4] = {0, 0, 0, 50};
+ const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
if ((name[0] == '\0') ||
@@ -154,7 +154,7 @@ static void eyedropper_draw_cursor_text(const struct bContext *C, ARegion *ar, c
y += U.widget_unit;
- UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, fg, bg);
+ UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
}
@@ -601,7 +601,7 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
const int mval[2] = {
mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- Base *base;
+ BaseLegacy *base;
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
@@ -902,6 +902,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
if (sa->spacetype == SPACE_VIEW3D) {
ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
if (ar) {
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
/* weak, we could pass in some reference point */
@@ -919,7 +920,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, mval, co, true, NULL)) {
+ if (ED_view3d_autodist(graph, ar, v3d, mval, co, true, NULL)) {
const float mval_center_fl[2] = {
(float)ar->winx / 2,
(float)ar->winy / 2};
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a3f0e29065d..59064ec332e 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -186,7 +186,6 @@ typedef struct uiSelectContextStore {
uiSelectContextElem *elems;
int elems_len;
bool do_free;
- bool is_enabled;
/* When set, simply copy values (don't apply difference).
* Rules are:
* - dragging numbers uses delta.
@@ -202,7 +201,9 @@ static void ui_selectcontext_apply(
bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data,
const double value, const double value_orig);
+#if 0
#define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
+#endif
/** just show a tinted color so users know its activated */
#define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
@@ -1179,14 +1180,11 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
ui_but_execute_begin(C, ar, but, &active_back);
#ifdef USE_ALLSELECT
- if (data->select_others.is_enabled) {
- /* init once! */
- if (mbut_state->select_others.elems_len == 0) {
- ui_selectcontext_begin(C, but, &mbut_state->select_others);
- }
- if (mbut_state->select_others.elems_len == 0) {
- mbut_state->select_others.elems_len = -1;
- }
+ if (mbut_state->select_others.elems_len == 0) {
+ ui_selectcontext_begin(C, but, &mbut_state->select_others);
+ }
+ if (mbut_state->select_others.elems_len == 0) {
+ mbut_state->select_others.elems_len = -1;
}
/* needed so we apply the right deltas */
@@ -2074,12 +2072,7 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
else
# endif
if (data->select_others.elems_len == 0) {
- wmWindow *win = CTX_wm_window(C);
- /* may have been enabled before activating */
- if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) {
- ui_selectcontext_begin(C, but, &data->select_others);
- data->select_others.is_enabled = true;
- }
+ ui_selectcontext_begin(C, but, &data->select_others);
}
if (data->select_others.elems_len == 0) {
/* dont check again */
@@ -2120,6 +2113,7 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
break;
case UI_BTYPE_ROW:
case UI_BTYPE_LISTROW:
+ case UI_BTYPE_TAB:
ui_apply_but_ROW(C, block, but, data);
break;
case UI_BTYPE_SCROLL:
@@ -3080,11 +3074,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
#ifdef USE_ALLSELECT
if (is_num_but) {
- if (IS_ALLSELECT_EVENT(win->eventstate)) {
- data->select_others.is_enabled = true;
- data->select_others.is_copy = true;
-
- }
+ data->select_others.is_copy = true;
}
#endif
@@ -3169,6 +3159,9 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
ui_searchbox_free(C, data->searchbox);
data->searchbox = NULL;
+ if (but->free_search_arg) {
+ MEM_SAFE_FREE(but->search_arg);
+ }
}
but->editstr = NULL;
@@ -3684,15 +3677,6 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
data->menu->popup = but->block->handle->popup;
}
-#ifdef USE_ALLSELECT
- {
- wmWindow *win = CTX_wm_window(C);
- if (IS_ALLSELECT_EVENT(win->eventstate)) {
- data->select_others.is_enabled = true;
- }
- }
-#endif
-
/* this makes adjacent blocks auto open from now on */
//if (but->block->auto_open == 0) but->block->auto_open = 1;
}
@@ -3874,6 +3858,18 @@ static int ui_do_but_KEYEVT(
return WM_UI_HANDLER_CONTINUE;
}
+static int ui_do_but_TAB(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2])
{
int x = mouse_xy[0], y = mouse_xy[1];
@@ -5218,7 +5214,8 @@ static int ui_do_but_COLOR(
if (!event->ctrl) {
float color[3];
Scene *scene = CTX_data_scene(C);
- Paint *paint = BKE_paint_get_active(scene);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Paint *paint = BKE_paint_get_active(scene, sl);
Brush *brush = BKE_paint_brush(paint);
if (brush->flag & BRUSH_USE_GRADIENT) {
@@ -6126,6 +6123,7 @@ static int ui_do_but_CURVE(
int mx, my, a;
bool changed = false;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
mx = event->x;
my = event->y;
@@ -6254,7 +6252,7 @@ static int ui_do_but_CURVE(
}
else {
curvemapping_changed(cumap, true); /* remove doubles */
- BKE_paint_invalidate_cursor_overlay(scene, cumap);
+ BKE_paint_invalidate_cursor_overlay(scene, sl, cumap);
}
}
@@ -7133,6 +7131,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_HOTKEY_EVENT:
retval = ui_do_but_HOTKEYEVT(C, but, data, event);
break;
+ case UI_BTYPE_TAB:
+ retval = ui_do_but_TAB(C, but, data, event);
+ break;
case UI_BTYPE_BUT_TOGGLE:
case UI_BTYPE_TOGGLE:
case UI_BTYPE_ICON_TOGGLE:
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 65b12fcd64e..88d92906040 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -33,8 +33,8 @@
#include "MEM_guardedalloc.h"
-#include "GPU_extensions.h"
-#include "GPU_basic_shader.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -59,7 +59,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_thumbs.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "ED_datafiles.h"
@@ -224,13 +223,17 @@ static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float
viconutil_set_point(pts[1], cx - d2, cy - d);
viconutil_set_point(pts[2], cx + d2, cy);
- glColor4f(0.2f, 0.2f, 0.2f, alpha);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.2f, 0.2f, 0.2f, alpha);
- glBegin(GL_TRIANGLES);
- glVertex2iv(pts[0]);
- glVertex2iv(pts[1]);
- glVertex2iv(pts[2]);
- glEnd();
+ immBegin(PRIM_TRIANGLES, 3);
+ immVertex2iv(pos, pts[0]);
+ immVertex2iv(pos, pts[1]);
+ immVertex2iv(pos, pts[2]);
+ immEnd();
+
+ immUnbindProgram();
}
static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, short key_type)
@@ -239,7 +242,6 @@ static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha,
* (since we're doing this offscreen, free from any particular space_id)
*/
struct bThemeState theme_state;
- int xco, yco;
UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_ACTION, RGN_TYPE_WINDOW);
@@ -248,16 +250,30 @@ static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha,
* while the draw_keyframe_shape() function needs the midpoint for
* the keyframe
*/
- xco = x + w / 2;
- yco = y + h / 2;
-
+ int xco = x + w / 2;
+ int yco = y + h / 2;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int size_id = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color_id = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ unsigned int outline_color_id = VertexFormat_add_attrib(format, "outlineColor", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, 1);
+
/* draw keyframe
- * - xscale: 1.0 (since there's no timeline scaling to compensate for)
- * - yscale: 0.3 * h (found out experimentally... dunno why!)
+ * - size: 0.6 * h (found out experimentally... dunno why!)
* - sel: true (so that "keyframe" state shows the iconic yellow icon)
*/
- draw_keyframe_shape(xco, yco, 1.0f, 0.3f * h, true, key_type, KEYFRAME_SHAPE_BOTH, alpha);
-
+ draw_keyframe_shape(xco, yco, 0.6f * h, true, key_type, KEYFRAME_SHAPE_BOTH, alpha,
+ pos_id, size_id, color_id, outline_color_id);
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
+
UI_Theme_Restore(&theme_state);
}
@@ -290,7 +306,7 @@ static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNU
{
bTheme *btheme = UI_GetTheme();
ThemeWireColor *cs = &btheme->tarm[index];
-
+
/* Draw three bands of color: One per color
* x-----a-----b-----c
* | N | S | A |
@@ -299,19 +315,24 @@ static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNU
const int a = x + w / 3;
const int b = x + w / 3 * 2;
const int c = x + w;
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* XXX: Include alpha into this... */
/* normal */
- glColor3ubv((unsigned char *)cs->solid);
- glRecti(x, y, a, y + h);
-
+ immUniformColor3ubv((unsigned char *)cs->solid);
+ immRecti(pos, x, y, a, y + h);
+
/* selected */
- glColor3ubv((unsigned char *)cs->select);
- glRecti(a, y, b, y + h);
-
+ immUniformColor3ubv((unsigned char *)cs->select);
+ immRecti(pos, a, y, b, y + h);
+
/* active */
- glColor3ubv((unsigned char *)cs->active);
- glRecti(b, y, c, y + h);
+ immUniformColor3ubv((unsigned char *)cs->active);
+ immRecti(pos, b, y, c, y + h);
+
+ immUnbindProgram();
}
#define DEF_VICON_COLORSET_DRAW_NTH(prefix, index) \
@@ -504,8 +525,12 @@ static void init_internal_icons(void)
icongltex.id = 0;
}
+#if 0 /* should be a compile-time check (if needed at all) */
/* we only use a texture for cards with non-power of two */
if (GPU_full_non_power_of_two_support()) {
+#else
+ {
+#endif
glGenTextures(1, &icongltex.id);
if (icongltex.id) {
@@ -533,11 +558,6 @@ static void init_internal_icons(void)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
-
- if (glGetError() == GL_OUT_OF_MEMORY) {
- glDeleteTextures(1, &icongltex.id);
- icongltex.id = 0;
- }
}
}
}
@@ -851,12 +871,15 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi
{
ID *id = (icon->type != 0) ? icon->obj : NULL;
PreviewImage *prv = id ? BKE_previewimg_id_ensure(id) : icon->obj;
+ /* Using jobs for screen previews crashes due to offscreen rendering.
+ * XXX would be nicer if PreviewImage could store if it supports jobs */
+ const bool use_jobs = !id || (GS(id->name) != ID_SCR);
if (prv) {
const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON;
if (id || (prv->tag & PRV_TAG_DEFFERED) != 0) {
- ui_id_preview_image_render_size(C, NULL, id, prv, size, true);
+ ui_id_preview_image_render_size(C, NULL, id, prv, size, use_jobs);
}
}
break;
@@ -936,7 +959,7 @@ PreviewImage *UI_icon_to_preview(int icon_id)
}
static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), int rw, int rh,
- unsigned int *rect, float alpha, const float rgb[3], const bool is_preview)
+ unsigned int *rect, float alpha, const float rgb[3], const bool UNUSED(is_preview))
{
ImBuf *ima = NULL;
int draw_w = w;
@@ -950,15 +973,13 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
BLI_assert(!"invalid icon size");
return;
}
-
/* modulate color */
- if (alpha != 1.0f)
- glPixelTransferf(GL_ALPHA_SCALE, alpha);
+ float col[4] = {1.0f, 1.0f, 1.0f, alpha};
if (rgb) {
- glPixelTransferf(GL_RED_SCALE, rgb[0]);
- glPixelTransferf(GL_GREEN_SCALE, rgb[1]);
- glPixelTransferf(GL_BLUE_SCALE, rgb[2]);
+ col[0] = rgb[0];
+ col[1] = rgb[1];
+ col[2] = rgb[2];
}
/* rect contains image in 'rendersize', we only scale if needed */
@@ -984,31 +1005,12 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
}
/* draw */
- if (is_preview) {
- glaDrawPixelsSafe(draw_x, draw_y, draw_w, draw_h, draw_w, GL_RGBA, GL_UNSIGNED_BYTE, rect);
- }
- else {
- int bound_options;
- GPU_BASIC_SHADER_DISABLE_AND_STORE(bound_options);
-
- glRasterPos2f(draw_x, draw_y);
- glDrawPixels(draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
-
- GPU_BASIC_SHADER_ENABLE_AND_RESTORE(bound_options);
- }
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, draw_x, draw_y, draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect,
+ 1.0f, 1.0f, col);
if (ima)
IMB_freeImBuf(ima);
-
- /* restore color */
- if (alpha != 0.0f)
- glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
-
- if (rgb) {
- glPixelTransferf(GL_RED_SCALE, 1.0f);
- glPixelTransferf(GL_GREEN_SCALE, 1.0f);
- glPixelTransferf(GL_BLUE_SCALE, 1.0f);
- }
}
static void icon_draw_texture(
@@ -1017,38 +1019,39 @@ static void icon_draw_texture(
{
float x1, x2, y1, y2;
- if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha);
- else glColor4f(alpha, alpha, alpha, alpha);
-
x1 = ix * icongltex.invw;
x2 = (ix + ih) * icongltex.invw;
y1 = iy * icongltex.invh;
y2 = (iy + ih) * icongltex.invh;
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
- /* sharper downscaling, has no effect when scale matches with a mip level */
- glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -0.5f);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
+ if (rgb) immUniformColor3fvAlpha(rgb, alpha);
+ else immUniformColor4f(alpha, alpha, alpha, alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(x1, y1);
- glVertex2f(x, y);
+ immUniform1i("image", 0);
- glTexCoord2f(x2, y1);
- glVertex2f(x + w, y);
+ immBegin(PRIM_TRIANGLE_STRIP, 4);
+ immAttrib2f(texCoord, x1, y2);
+ immVertex2f(pos, x, y + h);
- glTexCoord2f(x2, y2);
- glVertex2f(x + w, y + h);
+ immAttrib2f(texCoord, x1, y1);
+ immVertex2f(pos, x, y);
- glTexCoord2f(x1, y2);
- glVertex2f(x, y + h);
- glEnd();
+ immAttrib2f(texCoord, x2, y2);
+ immVertex2f(pos, x + w, y + h);
- glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0f);
+ immAttrib2f(texCoord, x2, y1);
+ immVertex2f(pos, x + w, y);
+ immEnd();
+
+ immUnbindProgram();
glBindTexture(GL_TEXTURE_2D, 0);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
}
/* Drawing size for preview images */
@@ -1162,7 +1165,7 @@ void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big,
}
}
-static void ui_id_brush_render(const bContext *C, ID *id)
+static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs)
{
PreviewImage *pi = BKE_previewimg_id_ensure(id);
enum eIconSizes i;
@@ -1174,7 +1177,7 @@ static void ui_id_brush_render(const bContext *C, ID *id)
/* check if rect needs to be created; changed
* only set by dynamic icons */
if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
- icon_set_image(C, NULL, id, pi, i, true);
+ icon_set_image(C, NULL, id, pi, i, use_jobs);
pi->flag[i] &= ~PRV_CHANGED;
}
}
@@ -1187,7 +1190,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
if (br->flag & BRUSH_CUSTOM_ICON) {
BKE_icon_id_ensure(id);
- ui_id_brush_render(C, id);
+ ui_id_icon_render(C, id, true);
}
else {
Object *ob = CTX_data_active_object(C);
@@ -1234,6 +1237,15 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
return id->icon_id;
}
+static int ui_id_screen_get_icon(const bContext *C, ID *id)
+{
+ BKE_icon_id_ensure(id);
+ /* Don't use jobs here, offscreen rendering doesn't like this and crashes. */
+ ui_id_icon_render(C, id, false);
+
+ return id->icon_id;
+}
+
int ui_id_icon_get(const bContext *C, ID *id, const bool big)
{
int iconid = 0;
@@ -1252,6 +1264,9 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big)
/* checks if not exists, or changed */
UI_id_icon_render(C, NULL, id, big, true);
break;
+ case ID_SCR:
+ iconid = ui_id_screen_get_icon(C, id);
+ break;
default:
break;
}
@@ -1388,6 +1403,11 @@ void UI_icon_draw(float x, float y, int icon_id)
UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f);
}
+void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
+{
+ UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, alpha);
+}
+
void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
{
icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, ICON_SIZE_ICON, size, true, false);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 067279777ba..ace3bb5b4f8 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -72,6 +72,7 @@ typedef enum {
UI_WTYPE_NUMBER,
UI_WTYPE_SLIDER,
UI_WTYPE_EXEC,
+ UI_WTYPE_TAB,
UI_WTYPE_TOOLTIP,
/* strings */
@@ -258,6 +259,7 @@ struct uiBut {
uiButSearchCreateFunc search_create_func;
uiButSearchFunc search_func;
+ bool free_search_arg;
void *search_arg;
uiButHandleRenameFunc rename_func;
@@ -277,7 +279,7 @@ struct uiBut {
BIFIconID icon;
char dt; /* drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */
signed char pie_dir; /* direction in a pie menu, used for collision detection (RadialDirection) */
- char changed; /* could be made into a single flag */
+ bool changed; /* could be made into a single flag */
unsigned char unit_type; /* so buttons can support unit systems which are not RNA */
short modifier_key;
short iconadd;
@@ -640,6 +642,8 @@ extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, floa
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha);
+
+void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3]);
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
@@ -682,15 +686,16 @@ struct wmIMEData *ui_but_ime_data_get(uiBut *but);
#endif
/* interface_widgets.c */
-void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha);
+void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3, const float color[4]);
+void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy,
+ float rad, bool use_alpha, const float color[4]);
void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
void ui_draw_pie_center(uiBlock *block);
uiWidgetColors *ui_tooltip_get_theme(void);
void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock *block, rcti *rect);
void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect);
bool ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol);
-void ui_draw_link_bezier(const rcti *rect);
+void ui_draw_link_bezier(const rcti *rect, const float color[4]);
extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
/* theme color init */
@@ -744,4 +749,20 @@ void UI_OT_eyedropper_id(struct wmOperatorType *ot);
void UI_OT_eyedropper_depth(struct wmOperatorType *ot);
void UI_OT_eyedropper_driver(struct wmOperatorType *ot);
+/* interface_util.c */
+
+/**
+ * For use with #ui_rna_collection_search_cb.
+ */
+typedef struct uiRNACollectionSearch {
+ PointerRNA target_ptr;
+ PropertyRNA *target_prop;
+
+ PointerRNA search_ptr;
+ PropertyRNA *search_prop;
+
+ bool *but_changed; /* pointer to uiBut.changed */
+} uiRNACollectionSearch;
+void ui_rna_collection_search_cb(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
+
#endif /* __INTERFACE_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 30a2094fee7..5462043c961 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1574,95 +1574,6 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
/* Pointer RNA button with search */
-typedef struct CollItemSearch {
- struct CollItemSearch *next, *prev;
- char *name;
- int index;
- int iconid;
-} CollItemSearch;
-
-static int sort_search_items_list(const void *a, const void *b)
-{
- const CollItemSearch *cis1 = a;
- const CollItemSearch *cis2 = b;
-
- if (BLI_strcasecmp(cis1->name, cis2->name) > 0)
- return 1;
- else
- return 0;
-}
-
-static void rna_search_cb(const struct bContext *C, void *arg_but, const char *str, uiSearchItems *items)
-{
- uiBut *but = arg_but;
- char *name;
- int i = 0, iconid = 0, flag = RNA_property_flag(but->rnaprop);
- ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
- CollItemSearch *cis;
- const bool skip_filter = !but->changed;
-
- /* build a temporary list of relevant items first */
- RNA_PROP_BEGIN (&but->rnasearchpoin, itemptr, but->rnasearchprop)
- {
- if (flag & PROP_ID_SELF_CHECK)
- if (itemptr.data == but->rnapoin.id.data)
- continue;
-
- /* use filter */
- if (RNA_property_type(but->rnaprop) == PROP_POINTER) {
- if (RNA_property_pointer_poll(&but->rnapoin, but->rnaprop, &itemptr) == 0)
- continue;
- }
-
- if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
- ID *id = itemptr.data;
- char name_ui[MAX_ID_NAME];
-
-#if 0 /* this name is used for a string comparison and can't be modified, TODO */
- /* if ever enabled, make name_ui be MAX_ID_NAME+1 */
- BKE_id_ui_prefix(name_ui, id);
-#else
- BLI_strncpy(name_ui, id->name + 2, sizeof(name_ui));
-#endif
- name = BLI_strdup(name_ui);
- iconid = ui_id_icon_get(C, id, false);
- }
- else {
- name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
- iconid = 0;
- }
-
- if (name) {
- if (skip_filter || BLI_strcasestr(name, str)) {
- cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
- cis->name = MEM_dupallocN(name);
- cis->index = i;
- cis->iconid = iconid;
- BLI_addtail(items_list, cis);
- }
- MEM_freeN(name);
- }
-
- i++;
- }
- RNA_PROP_END;
-
- BLI_listbase_sort(items_list, sort_search_items_list);
-
- /* add search items from temporary list */
- for (cis = items_list->first; cis; cis = cis->next) {
- if (false == UI_search_item_add(items, cis->name, SET_INT_IN_POINTER(cis->index), cis->iconid)) {
- break;
- }
- }
-
- for (cis = items_list->first; cis; cis = cis->next) {
- MEM_freeN(cis->name);
- }
- BLI_freelistN(items_list);
- MEM_freeN(items_list);
-}
-
static void search_id_collection(StructRNA *ptype, PointerRNA *ptr, PropertyRNA **prop)
{
StructRNA *srna;
@@ -1703,6 +1614,8 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
/* turn button into search button */
if (searchprop) {
+ uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__);
+
but->type = UI_BTYPE_SEARCH_MENU;
but->hardmax = MAX2(but->hardmax, 256.0f);
but->rnasearchpoin = *searchptr;
@@ -1712,13 +1625,22 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
but->flag |= UI_BUT_VALUE_CLEAR;
}
+ coll_search->target_ptr = *ptr;
+ coll_search->target_prop = prop;
+ coll_search->search_ptr = *searchptr;
+ coll_search->search_prop = searchprop;
+ coll_search->but_changed = &but->changed;
+
if (RNA_property_type(prop) == PROP_ENUM) {
/* XXX, this will have a menu string,
* but in this case we just want the text */
but->str[0] = 0;
}
- UI_but_func_search_set(but, ui_searchbox_create_generic, rna_search_cb, but, NULL, NULL);
+ UI_but_func_search_set(
+ but, ui_searchbox_create_generic, ui_rna_collection_search_cb,
+ coll_search, NULL, NULL);
+ but->free_search_arg = true;
}
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index fb95cdf389b..09388ff1a18 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -42,6 +42,9 @@
#include "BLT_lang.h"
#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_idprop.h"
+#include "BKE_layer.h"
#include "BKE_screen.h"
#include "BKE_global.h"
#include "BKE_node.h"
@@ -50,6 +53,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_types.h"
#include "UI_interface.h"
@@ -328,6 +332,125 @@ static void UI_OT_unset_property_button(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
+/* Use/Unuse Property Button Operator ------------------------ */
+
+static int use_property_button_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ PointerRNA ptr, scene_props_ptr;
+ PropertyRNA *prop;
+ IDProperty *props;
+
+ uiBut *but = UI_context_active_but_get(C);
+
+ prop = but->rnaprop;
+ ptr = but->rnapoin;
+ props = (IDProperty *)ptr.data;
+ /* XXX Using existing data struct to pass another RNAPointer */
+ scene_props_ptr = but->rnasearchpoin;
+
+ const char *identifier = RNA_property_identifier(prop);
+ if (IDP_GetPropertyFromGroup(props, identifier)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ int array_len = RNA_property_array_length(&scene_props_ptr, prop);
+ bool is_array = array_len != 0;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ {
+ if (is_array) {
+ float values[RNA_MAX_ARRAY_LENGTH];
+ RNA_property_float_get_array(&scene_props_ptr, prop, values);
+ BKE_collection_engine_property_add_float_array(props, identifier, values, array_len);
+ }
+ else {
+ float value = RNA_property_float_get(&scene_props_ptr, prop);
+ BKE_collection_engine_property_add_float(props, identifier, value);
+ }
+ break;
+ }
+ case PROP_ENUM:
+ {
+ int value = RNA_enum_get(&scene_props_ptr, identifier);
+ BKE_collection_engine_property_add_int(props, identifier, value);
+ break;
+ }
+ case PROP_INT:
+ {
+ int value = RNA_int_get(&scene_props_ptr, identifier);
+ BKE_collection_engine_property_add_int(props, identifier, value);
+ break;
+ }
+ case PROP_BOOLEAN:
+ {
+ int value = RNA_boolean_get(&scene_props_ptr, identifier);
+ BKE_collection_engine_property_add_bool(props, identifier, value);
+ break;
+ }
+ case PROP_STRING:
+ case PROP_POINTER:
+ case PROP_COLLECTION:
+ default:
+ break;
+ }
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update((ID *)CTX_data_scene(C), 0);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UI_OT_use_property_button(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Use property";
+ ot->idname = "UI_OT_use_property_button";
+ ot->description = "Create a property";
+
+ /* callbacks */
+ ot->poll = ED_operator_regionactive;
+ ot->exec = use_property_button_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+}
+
+static int unuse_property_button_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ /* try to unset the nominated property */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ const char *identifier = RNA_property_identifier(prop);
+
+ IDProperty *props = (IDProperty *)ptr.data;
+ IDProperty *prop_to_remove = IDP_GetPropertyFromGroup(props, identifier);
+ IDP_FreeFromGroup(props, prop_to_remove);
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update((ID *)CTX_data_scene(C), 0);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UI_OT_unuse_property_button(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unuse property";
+ ot->idname = "UI_OT_unuse_property_button";
+ ot->description = "Remove a property";
+
+ /* callbacks */
+ ot->poll = ED_operator_regionactive;
+ ot->exec = unuse_property_button_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+}
+
/* Copy To Selected Operator ------------------------ */
bool UI_context_copy_to_selected_list(
@@ -1114,6 +1237,8 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_copy_python_command_button);
WM_operatortype_append(UI_OT_reset_default_button);
WM_operatortype_append(UI_OT_unset_property_button);
+ WM_operatortype_append(UI_OT_use_property_button);
+ WM_operatortype_append(UI_OT_unuse_property_button);
WM_operatortype_append(UI_OT_copy_to_selected_button);
WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */
WM_operatortype_append(UI_OT_drop_color);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index c131bcb8e14..d1b4c2cd8fb 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -50,9 +50,6 @@
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "BLF_api.h"
#include "WM_api.h"
@@ -65,6 +62,8 @@
#include "UI_interface_icons.h"
#include "UI_resources.h"
+#include "GPU_immediate.h"
+
#include "interface_intern.h"
/*********************** defines and structs ************************/
@@ -393,54 +392,42 @@ static void ui_offset_panel_block(uiBlock *block)
/**************************** drawing *******************************/
-/* extern used by previewrender */
-#if 0 /*UNUSED 2.5*/
-static void uiPanelPush(uiBlock *block)
-{
- glPushMatrix();
-
- if (block->panel)
- glTranslatef((float)block->panel->ofsx, (float)block->panel->ofsy, 0.0);
-}
-
-static void uiPanelPop(uiBlock *UNUSED(block))
-{
- glPopMatrix();
-}
-#endif
-
/* triangle 'icon' for panel header */
-void UI_draw_icon_tri(float x, float y, char dir)
+void UI_draw_icon_tri(float x, float y, char dir, const float color[4])
{
float f3 = 0.15 * U.widget_unit;
float f5 = 0.25 * U.widget_unit;
float f7 = 0.35 * U.widget_unit;
if (dir == 'h') {
- ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y);
+ ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color);
}
else if (dir == 't') {
- ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3);
+ ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3, color);
}
else { /* 'v' = vertical, down */
- ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7);
+ ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7, color);
}
}
/* triangle 'icon' inside rect */
static void ui_draw_tria_rect(const rctf *rect, char dir)
{
+ float color[4];
+ UI_GetThemeColor3fv(TH_TITLE, color);
+ color[3] = 1.0f;
+
if (dir == 'h') {
float half = 0.5f * BLI_rctf_size_y(rect);
- ui_draw_anti_tria(rect->xmin, rect->ymin, rect->xmin, rect->ymax, rect->xmax, rect->ymin + half);
+ ui_draw_anti_tria(rect->xmin, rect->ymin, rect->xmin, rect->ymax, rect->xmax, rect->ymin + half, color);
}
else {
float half = 0.5f * BLI_rctf_size_x(rect);
- ui_draw_anti_tria(rect->xmin, rect->ymax, rect->xmax, rect->ymax, rect->xmin + half, rect->ymin);
+ ui_draw_anti_tria(rect->xmin, rect->ymax, rect->xmax, rect->ymax, rect->xmin + half, rect->ymin, color);
}
}
-static void ui_draw_anti_x(float x1, float y1, float x2, float y2)
+static void ui_draw_anti_x(unsigned int pos, float x1, float y1, float x2, float y2)
{
/* set antialias line */
@@ -448,9 +435,16 @@ static void ui_draw_anti_x(float x1, float y1, float x2, float y2)
glEnable(GL_BLEND);
glLineWidth(2.0);
-
- fdrawline(x1, y1, x2, y2);
- fdrawline(x1, y2, x2, y1);
+
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y1);
+
+ immEnd();
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -458,16 +452,16 @@ static void ui_draw_anti_x(float x1, float y1, float x2, float y2)
}
/* x 'icon' for panel header */
-static void ui_draw_x_icon(float x, float y)
+static void ui_draw_x_icon(unsigned int pos, float x, float y)
{
- ui_draw_anti_x(x, y, x + 9.375f, y + 9.375f);
+ ui_draw_anti_x(pos, x, y, x + 9.375f, y + 9.375f);
}
#define PNL_ICON UI_UNIT_X /* could be UI_UNIT_Y too */
-static void ui_draw_panel_scalewidget(const rcti *rect)
+static void ui_draw_panel_scalewidget(unsigned int pos, const rcti *rect)
{
float xmin, xmax, dx;
float ymin, ymax, dy;
@@ -481,16 +475,33 @@ static void ui_draw_panel_scalewidget(const rcti *rect)
dy = 0.5f * (ymax - ymin);
glEnable(GL_BLEND);
- glColor4ub(255, 255, 255, 50);
- fdrawline(xmin, ymin, xmax, ymax);
- fdrawline(xmin + dx, ymin, xmax, ymax - dy);
+ immUniformColor4ub(255, 255, 255, 50);
+
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, xmin, ymin);
+ immVertex2f(pos, xmax, ymax);
+
+ immVertex2f(pos, xmin + dx, ymin);
+ immVertex2f(pos, xmax, ymax - dy);
+
+ immEnd();
- glColor4ub(0, 0, 0, 50);
- fdrawline(xmin, ymin + 1, xmax, ymax + 1);
- fdrawline(xmin + dx, ymin + 1, xmax, ymax - dy + 1);
+ immUniformColor4ub(0, 0, 0, 50);
+
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, xmin, ymin + 1);
+ immVertex2f(pos, xmax, ymax + 1);
+
+ immVertex2f(pos, xmin + dx, ymin + 1);
+ immVertex2f(pos, xmax, ymax - dy + 1);
+
+ immEnd();
+
glDisable(GL_BLEND);
}
-static void ui_draw_panel_dragwidget(const rctf *rect)
+static void ui_draw_panel_dragwidget(unsigned int pos, const rctf *rect)
{
unsigned char col_back[3], col_high[3], col_dark[3];
const int col_tint = 84;
@@ -519,10 +530,10 @@ static void ui_draw_panel_dragwidget(const rctf *rect)
const int x_co = (x_min + x_ofs) + (i_x * (box_size + box_margin));
const int y_co = (y_min + y_ofs) + (i_y * (box_size + box_margin));
- glColor3ubv(col_dark);
- glRectf(x_co - box_size, y_co - px_zoom, x_co, (y_co + box_size) - px_zoom);
- glColor3ubv(col_high);
- glRectf(x_co - box_size, y_co, x_co, y_co + box_size);
+ immUniformColor3ubv(col_dark);
+ immRectf(pos, x_co - box_size, y_co - px_zoom, x_co, (y_co + box_size) - px_zoom);
+ immUniformColor3ubv(col_high);
+ immRectf(pos, x_co - box_size, y_co, x_co, y_co + box_size);
}
}
}
@@ -534,29 +545,30 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const r
rcti hrect;
int pnl_icons;
const char *activename = panel->drawname[0] ? panel->drawname : panel->panelname;
+ unsigned char col_title[4];
/* + 0.001f to avoid flirting with float inaccuracy */
if (panel->control & UI_PNL_CLOSE)
pnl_icons = (panel->labelofs + 2 * PNL_ICON + 5) / block->aspect + 0.001f;
else
pnl_icons = (panel->labelofs + PNL_ICON + 5) / block->aspect + 0.001f;
-
- /* active tab */
+
/* draw text label */
- UI_ThemeColor(TH_TITLE);
-
+ UI_GetThemeColor3ubv(TH_TITLE, col_title);
+ col_title[3] = 255;
+
hrect = *rect;
if (dir == 'h') {
hrect.xmin = rect->xmin + pnl_icons;
hrect.ymin += 2.0f / block->aspect;
- UI_fontstyle_draw(&style->paneltitle, &hrect, activename);
+ UI_fontstyle_draw(&style->paneltitle, &hrect, activename, col_title);
}
else {
/* ignore 'pnl_icons', otherwise the text gets offset horizontally
* + 0.001f to avoid flirting with float inaccuracy
*/
hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
- UI_fontstyle_draw_rotated(&style->paneltitle, &hrect, activename);
+ UI_fontstyle_draw_rotated(&style->paneltitle, &hrect, activename, col_title);
}
}
@@ -566,7 +578,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
Panel *panel = block->panel;
rcti headrect;
rctf itemrect;
- int ofsx;
+ float color[4];
const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false;
const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false;
@@ -579,6 +591,9 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
headrect.ymin = headrect.ymax;
headrect.ymax = headrect.ymin + floor(PNL_HEADER / block->aspect + 0.001f);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
{
float minx = rect->xmin;
float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax;
@@ -588,11 +603,18 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
if (UI_GetThemeValue(TH_PANEL_SHOW_HEADER)) {
/* draw with background color */
- UI_ThemeColor4(TH_PANEL_HEADER);
- glRectf(minx, headrect.ymin + 1, maxx, y);
+ immUniformThemeColor(TH_PANEL_HEADER);
+ immRectf(pos, minx, headrect.ymin + 1, maxx, y);
+
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, minx, y);
+ immVertex2f(pos, maxx, y);
+
+ immVertex2f(pos, minx, y);
+ immVertex2f(pos, maxx, y);
- fdrawline(minx, y, maxx, y);
- fdrawline(minx, y, maxx, y);
+ immEnd();
}
else if (!(panel->runtime_flag & PNL_FIRST)) {
/* draw embossed separator */
@@ -602,15 +624,26 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
maxx -= 5.0f / block->aspect;
}
- glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
- fdrawline(minx, y, maxx, y);
- glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
- fdrawline(minx, y - 1, maxx, y - 1);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, minx, y);
+ immVertex2f(pos, maxx, y);
+ immEnd();
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, minx, y - 1);
+ immVertex2f(pos, maxx, y - 1);
+ immEnd();
}
glDisable(GL_BLEND);
}
+ immUnbindProgram();
+
/* draw optional pin icon */
#ifdef USE_PIN_HIDDEN
@@ -626,9 +659,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
glDisable(GL_BLEND);
}
+
/* horizontal title */
if (is_closed_x == false) {
ui_draw_aligned_panel_header(style, block, &headrect, 'h');
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
/* itemrect smaller */
itemrect.xmax = headrect.xmax - 5.0f / block->aspect;
@@ -637,7 +672,9 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
itemrect.ymax = headrect.ymax;
BLI_rctf_scale(&itemrect, 0.7f);
- ui_draw_panel_dragwidget(&itemrect);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ ui_draw_panel_dragwidget(pos, &itemrect);
+ immUnbindProgram();
}
/* if the panel is minimized vertically:
@@ -649,6 +686,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
else if (is_closed_x) {
/* draw vertical title */
ui_draw_aligned_panel_header(style, block, &headrect, 'v');
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
}
/* an open panel */
else {
@@ -657,33 +695,37 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
if (panel->control & UI_PNL_SOLID) UI_draw_roundbox_corner_set(UI_CNR_ALL);
else UI_draw_roundbox_corner_set(UI_CNR_NONE);
- UI_ThemeColorShade(TH_BACK, -120);
- UI_draw_roundbox_unfilled(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8);
+ UI_GetThemeColorShade4fv(TH_BACK, -120, color);
+ UI_draw_roundbox_aa(false, 0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8, color);
}
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* panel backdrop */
if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
/* draw with background color */
glEnable(GL_BLEND);
- UI_ThemeColor4(TH_PANEL_BACK);
- glRecti(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformThemeColor(TH_PANEL_BACK);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
}
if (panel->control & UI_PNL_SCALE)
- ui_draw_panel_scalewidget(rect);
+ ui_draw_panel_scalewidget(pos, rect);
+
+ immUnbindProgram();
}
/* draw optional close icon */
- ofsx = 6;
if (panel->control & UI_PNL_CLOSE) {
- UI_ThemeColor(TH_TITLE);
- ui_draw_x_icon(rect->xmin + 2 + ofsx, rect->ymax + 2);
- ofsx = 22;
+ const int ofsx = 6;
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor3(TH_TITLE);
+ ui_draw_x_icon(pos, rect->xmin + 2 + ofsx, rect->ymax + 2);
+ immUnbindProgram();
}
/* draw collapse icon */
- UI_ThemeColor(TH_TITLE);
/* itemrect smaller */
itemrect.xmin = headrect.xmin + 5.0f / block->aspect;
@@ -699,8 +741,6 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
ui_draw_tria_rect(&itemrect, 'h');
else
ui_draw_tria_rect(&itemrect, 'v');
-
- (void)ofsx;
}
/************************** panel alignment *************************/
@@ -1513,12 +1553,13 @@ void UI_panel_category_clear_all(ARegion *ar)
BLI_freelistN(&ar->panels_category);
}
-/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
+/* based on UI_draw_roundbox, check on making a version which allows us to skip some sides */
static void ui_panel_category_draw_tab(
- int mode, float minx, float miny, float maxx, float maxy, float rad,
+ bool filled, float minx, float miny, float maxx, float maxy, float rad,
int roundboxtype,
- const bool use_highlight, const bool use_shadow,
- const unsigned char highlight_fade[3])
+ bool use_highlight, bool use_shadow,
+ const unsigned char highlight_fade[3],
+ const unsigned char col[3])
{
float vec[4][2] = {
{0.195, 0.02},
@@ -1527,74 +1568,96 @@ static void ui_panel_category_draw_tab(
{0.98, 0.805}};
int a;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
/* mult */
for (a = 0; a < 4; a++) {
mul_v2_fl(vec[a], rad);
}
- glBegin(mode);
+ unsigned int vert_ct = 0;
+ if (use_highlight) {
+ vert_ct += (roundboxtype & UI_CNR_TOP_RIGHT) ? 6 : 1;
+ vert_ct += (roundboxtype & UI_CNR_TOP_LEFT) ? 6 : 1;
+ }
+ if (use_highlight && !use_shadow) {
+ vert_ct++;
+ }
+ else {
+ vert_ct += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 6 : 1;
+ vert_ct += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 6 : 1;
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ immBegin(filled ? PRIM_TRIANGLE_FAN : PRIM_LINE_STRIP, vert_ct);
+
+ immAttrib3ubv(color, col);
/* start with corner right-top */
if (use_highlight) {
if (roundboxtype & UI_CNR_TOP_RIGHT) {
- glVertex2f(maxx, maxy - rad);
+ immVertex2f(pos, maxx, maxy - rad);
for (a = 0; a < 4; a++) {
- glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
}
- glVertex2f(maxx - rad, maxy);
+ immVertex2f(pos, maxx - rad, maxy);
}
else {
- glVertex2f(maxx, maxy);
+ immVertex2f(pos, maxx, maxy);
}
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
- glVertex2f(minx + rad, maxy);
+ immVertex2f(pos, minx + rad, maxy);
for (a = 0; a < 4; a++) {
- glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
}
- glVertex2f(minx, maxy - rad);
+ immVertex2f(pos, minx, maxy - rad);
}
else {
- glVertex2f(minx, maxy);
+ immVertex2f(pos, minx, maxy);
}
}
if (use_highlight && !use_shadow) {
if (highlight_fade) {
- glColor3ubv(highlight_fade);
+ immAttrib3ubv(color, highlight_fade);
}
- glVertex2f(minx, miny + rad);
- glEnd();
+ immVertex2f(pos, minx, miny + rad);
+ immEnd();
+ immUnbindProgram();
return;
}
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- glVertex2f(minx, miny + rad);
+ immVertex2f(pos, minx, miny + rad);
for (a = 0; a < 4; a++) {
- glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
}
- glVertex2f(minx + rad, miny);
+ immVertex2f(pos, minx + rad, miny);
}
else {
- glVertex2f(minx, miny);
+ immVertex2f(pos, minx, miny);
}
/* corner right-bottom */
-
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- glVertex2f(maxx - rad, miny);
+ immVertex2f(pos, maxx - rad, miny);
for (a = 0; a < 4; a++) {
- glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
}
- glVertex2f(maxx, miny + rad);
+ immVertex2f(pos, maxx, miny + rad);
}
else {
- glVertex2f(maxx, miny);
+ immVertex2f(pos, maxx, miny);
}
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
@@ -1717,21 +1780,26 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
/* begin drawing */
glEnable(GL_LINE_SMOOTH);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* draw the background */
if (is_alpha) {
glEnable(GL_BLEND);
- glColor4ubv(theme_col_tab_bg);
+ immUniformColor4ubv(theme_col_tab_bg);
}
else {
- glColor3ubv(theme_col_tab_bg);
+ immUniformColor3ubv(theme_col_tab_bg);
}
- glRecti(v2d->mask.xmin, v2d->mask.ymin, v2d->mask.xmin + category_tabs_width, v2d->mask.ymax);
+ immRecti(pos, v2d->mask.xmin, v2d->mask.ymin, v2d->mask.xmin + category_tabs_width, v2d->mask.ymax);
if (is_alpha) {
glDisable(GL_BLEND);
}
+ immUnbindProgram();
+
for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
const rcti *rct = &pc_dyn->rect;
const char *category_id = pc_dyn->idname;
@@ -1754,28 +1822,33 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
if (is_active)
#endif
{
- glColor3ubv(is_active ? theme_col_tab_active : theme_col_tab_inactive);
- ui_panel_category_draw_tab(GL_POLYGON, rct->xmin, rct->ymin, rct->xmax, rct->ymax,
- tab_curve_radius - px, roundboxtype, true, true, NULL);
+ ui_panel_category_draw_tab(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax,
+ tab_curve_radius - px, roundboxtype, true, true, NULL,
+ is_active ? theme_col_tab_active : theme_col_tab_inactive);
/* tab outline */
- glColor3ubv(theme_col_tab_outline);
- ui_panel_category_draw_tab(GL_LINE_STRIP, rct->xmin - px, rct->ymin - px, rct->xmax - px, rct->ymax + px,
- tab_curve_radius, roundboxtype, true, true, NULL);
+ ui_panel_category_draw_tab(false, rct->xmin - px, rct->ymin - px, rct->xmax - px, rct->ymax + px,
+ tab_curve_radius, roundboxtype, true, true, NULL, theme_col_tab_outline);
+
/* tab highlight (3d look) */
- glColor3ubv(is_active ? theme_col_tab_highlight : theme_col_tab_highlight_inactive);
- ui_panel_category_draw_tab(GL_LINE_STRIP, rct->xmin, rct->ymin, rct->xmax, rct->ymax,
+ ui_panel_category_draw_tab(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax,
tab_curve_radius, roundboxtype, true, false,
- is_active ? theme_col_back : theme_col_tab_inactive);
+ is_active ? theme_col_back : theme_col_tab_inactive,
+ is_active ? theme_col_tab_highlight : theme_col_tab_highlight_inactive);
}
/* tab blackline */
if (!is_active) {
- glColor3ubv(theme_col_tab_divider);
- glRecti(v2d->mask.xmin + category_tabs_width - px,
- rct->ymin - tab_v_pad,
- v2d->mask.xmin + category_tabs_width,
- rct->ymax + tab_v_pad);
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, v2d->mask.xmin + category_tabs_width - px,
+ rct->ymin - tab_v_pad,
+ v2d->mask.xmin + category_tabs_width,
+ rct->ymax + tab_v_pad);
+
+ immUnbindProgram();
}
if (do_scaletabs) {
@@ -1788,7 +1861,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
/* tab titles */
/* draw white shadow to give text more depth */
- glColor3ubv(theme_col_text);
+ BLF_color3ubv(fontid, theme_col_text);
/* main tab title */
BLF_draw(fontid, category_id_draw, category_draw_len);
@@ -1796,33 +1869,36 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
glDisable(GL_BLEND);
/* tab blackline remaining (last tab) */
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
if (pc_dyn->prev == NULL) {
- glColor3ubv(theme_col_tab_divider);
- glRecti(v2d->mask.xmin + category_tabs_width - px,
- rct->ymax + px,
- v2d->mask.xmin + category_tabs_width,
- v2d->mask.ymax);
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, v2d->mask.xmin + category_tabs_width - px,
+ rct->ymax + px,
+ v2d->mask.xmin + category_tabs_width,
+ v2d->mask.ymax);
}
if (pc_dyn->next == NULL) {
- glColor3ubv(theme_col_tab_divider);
- glRecti(v2d->mask.xmin + category_tabs_width - px,
- 0,
- v2d->mask.xmin + category_tabs_width,
- rct->ymin);
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, v2d->mask.xmin + category_tabs_width - px,
+ 0,
+ v2d->mask.xmin + category_tabs_width,
+ rct->ymin);
}
#ifdef USE_FLAT_INACTIVE
/* draw line between inactive tabs */
if (is_active == false && is_active_prev == false && pc_dyn->prev) {
- glColor3ubv(theme_col_tab_divider);
- glRecti(v2d->mask.xmin + (category_tabs_width / 5),
- rct->ymax + px,
- (v2d->mask.xmin + category_tabs_width) - (category_tabs_width / 5),
- rct->ymax + (px * 3));
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, v2d->mask.xmin + (category_tabs_width / 5),
+ rct->ymax + px,
+ (v2d->mask.xmin + category_tabs_width) - (category_tabs_width / 5),
+ rct->ymax + (px * 3));
}
is_active_prev = is_active;
#endif
+ immUnbindProgram();
/* not essential, but allows events to be handled right up until the region edge [#38171] */
pc_dyn->rect.xmin = v2d->mask.xmin;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 534bd4278ca..ed8c3a50875 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -194,6 +194,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
uiWidgetColors *theme = ui_tooltip_get_theme();
rcti bbox = data->bbox;
float tip_colors[UI_TIP_LC_MAX][3];
+ unsigned char drawcol[4] = {0, 0, 0, 255}; /* to store color in while drawing (alpha is always 255) */
float *main_color = tip_colors[UI_TIP_LC_MAIN]; /* the color from the theme */
float *value_color = tip_colors[UI_TIP_LC_VALUE];
@@ -260,9 +261,9 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
fstyle_header.shadowalpha = 1.0f;
fstyle_header.word_wrap = true;
+ rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_MAIN]);
UI_fontstyle_set(&fstyle_header);
- glColor3fv(tip_colors[UI_TIP_LC_MAIN]);
- UI_fontstyle_draw(&fstyle_header, &bbox, data->header);
+ UI_fontstyle_draw(&fstyle_header, &bbox, data->header, drawcol);
/* offset to the end of the last line */
xofs = data->line_geom[i].x_pos;
@@ -270,9 +271,9 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
bbox.xmin += xofs;
bbox.ymax -= yofs;
- glColor3fv(tip_colors[UI_TIP_LC_ACTIVE]);
+ rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]);
fstyle_header.shadow = 0;
- UI_fontstyle_draw(&fstyle_header, &bbox, data->active_info);
+ UI_fontstyle_draw(&fstyle_header, &bbox, data->active_info, drawcol);
/* undo offset */
bbox.xmin -= xofs;
@@ -280,14 +281,15 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
}
else if (data->format[i].style == UI_TIP_STYLE_MONO) {
uiFontStyle fstyle_mono = data->fstyle;
+
fstyle_mono.uifont_id = blf_mono_font;
fstyle_mono.word_wrap = true;
UI_fontstyle_set(&fstyle_mono);
/* XXX, needed because we dont have mono in 'U.uifonts' */
BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi);
- glColor3fv(tip_colors[data->format[i].color_id]);
- UI_fontstyle_draw(&fstyle_mono, &bbox, data->lines[i]);
+ rgb_float_to_uchar(drawcol, tip_colors[data->format[i].color_id]);
+ UI_fontstyle_draw(&fstyle_mono, &bbox, data->lines[i], drawcol);
}
else {
uiFontStyle fstyle_normal = data->fstyle;
@@ -296,8 +298,8 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
/* draw remaining data */
UI_fontstyle_set(&fstyle_normal);
- glColor3fv(tip_colors[data->format[i].color_id]);
- UI_fontstyle_draw(&fstyle_normal, &bbox, data->lines[i]);
+ rgb_float_to_uchar(drawcol, tip_colors[data->format[i].color_id]);
+ UI_fontstyle_draw(&fstyle_normal, &bbox, data->lines[i], drawcol);
}
bbox.ymax -= data->lineh * data->line_geom[i].lines;
@@ -1059,7 +1061,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
return match;
}
-static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
+static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *ar)
{
uiSearchboxData *data = ar->regiondata;
@@ -1077,6 +1079,9 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
if (data->preview) {
/* draw items */
for (a = 0; a < data->items.totitem; a++) {
+ /* ensure icon is up-to-date */
+ ui_icon_ensure_deferred(C, data->items.icons[a], data->preview);
+
ui_searchbox_butrect(&rect, data, a);
/* widget itself */
@@ -1696,7 +1701,7 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
* Use to refresh centered popups on screen resizing (for splash).
*/
static void ui_block_region_popup_window_listener(
- bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene))
{
switch (wmn->category) {
case NC_WINDOW:
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 8b41302b5bb..01456e2e122 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -149,7 +149,7 @@ static uiFont *uifont_to_blfont(int id)
void UI_fontstyle_draw_ex(
- const uiFontStyle *fs, const rcti *rect, const char *str,
+ const uiFontStyle *fs, const rcti *rect, const char *str, const unsigned char col[4],
size_t len, float *r_xofs, float *r_yofs)
{
int xofs = 0, yofs;
@@ -196,6 +196,7 @@ void UI_fontstyle_draw_ex(
/* clip is very strict, so we give it some space */
BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4);
BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f);
+ BLF_color4ubv(fs->uifont_id, col);
BLF_draw(fs->uifont_id, str, len);
@@ -205,17 +206,17 @@ void UI_fontstyle_draw_ex(
*r_yofs = yofs;
}
-void UI_fontstyle_draw(const uiFontStyle *fs, const rcti *rect, const char *str)
+void UI_fontstyle_draw(const uiFontStyle *fs, const rcti *rect, const char *str, const unsigned char col[4])
{
float xofs, yofs;
UI_fontstyle_draw_ex(
- fs, rect, str,
+ fs, rect, str, col,
BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs);
}
/* drawn same as above, but at 90 degree angle */
-void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const char *str)
+void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const char *str, const unsigned char col[4])
{
float height;
int xofs, yofs;
@@ -249,6 +250,7 @@ void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const ch
BLF_enable(fs->uifont_id, BLF_ROTATION);
BLF_rotation(fs->uifont_id, angle);
+ BLF_color4ubv(fs->uifont_id, col);
if (fs->shadow) {
BLF_enable(fs->uifont_id, BLF_SHADOW);
@@ -275,13 +277,14 @@ void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const ch
*
* For drawing on-screen labels.
*/
-void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const char *str)
+void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const char *str, const unsigned char col[4])
{
if (fs->kerning == 1)
BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
UI_fontstyle_set(fs);
BLF_position(fs->uifont_id, x, y, 0.0f);
+ BLF_color4ubv(fs->uifont_id, col);
BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
if (fs->kerning == 1)
@@ -293,7 +296,7 @@ void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const cha
*/
void UI_fontstyle_draw_simple_backdrop(
const uiFontStyle *fs, float x, float y, const char *str,
- const unsigned char fg[4], const unsigned char bg[4])
+ const float col_fg[4], const float col_bg[4])
{
if (fs->kerning == 1)
BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
@@ -307,21 +310,19 @@ void UI_fontstyle_draw_simple_backdrop(
const float margin = height / 4.0f;
/* backdrop */
- glColor4ubv(bg);
+ float color[4] = { col_bg[0], col_bg[1], col_bg[2], 0.5f };
- UI_draw_roundbox_corner_set(UI_CNR_ALL | UI_RB_ALPHA);
- UI_draw_roundbox(
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
x - margin,
(y + decent) - margin,
x + width + margin,
(y + decent) + height + margin,
- margin);
-
- glColor4ubv(fg);
+ margin, color);
}
-
BLF_position(fs->uifont_id, x, y, 0.0f);
+ BLF_color4fv(fs->uifont_id, col_fg);
BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
if (fs->kerning == 1)
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 131584dd405..266d8aacae3 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -58,6 +58,8 @@
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_idcode.h"
+#include "BKE_idprop.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
@@ -87,10 +89,126 @@
#include "PIL_time.h"
+/* defines for templateID/TemplateSearch */
+#define TEMPLATE_SEARCH_TEXTBUT_WIDTH (UI_UNIT_X * 6)
+#define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y
+
+
void UI_template_fix_linking(void)
{
}
+/**
+ * Add a block button for the search menu for templateID and templateSearch.
+ */
+static void template_add_button_search_menu(
+ const bContext *C, uiLayout *layout, uiBlock *block,
+ PointerRNA *ptr, PropertyRNA *prop,
+ uiBlockCreateFunc block_func, void *block_argN, const char * const tip,
+ const bool use_previews, const bool editable)
+{
+ PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
+ ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
+ const ID *idfrom = ptr->id.data;
+ const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
+ uiBut *but;
+
+ if (use_previews) {
+ ARegion *region = CTX_wm_region(C);
+ const bool use_big_size = (region->regiontype != RGN_TYPE_HEADER); /* silly check, could be more generic */
+ /* Ugly exception for screens here, drawing their preview in icon size looks ugly/useless */
+ const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
+ const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
+ const short height = UI_UNIT_Y * (use_big_size ? 6: 1);
+
+ but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
+ if (use_preview_icon) {
+ int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ }
+ else {
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
+ UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
+ }
+
+ if ((idfrom && idfrom->lib) || !editable)
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ if (use_big_size) {
+ uiLayoutRow(layout, true);
+ }
+ }
+ else {
+ but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
+ if (id) {
+ /* default dragging of icon for id browse buttons */
+ UI_but_drag_set_id(but, id);
+ }
+ UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
+
+ if ((idfrom && idfrom->lib) || !editable)
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+}
+
+static uiBlock *template_common_search_menu(
+ const bContext *C, ARegion *region,
+ uiButSearchFunc search_func, void *search_arg,
+ uiButHandleFunc handle_func, void *active_item,
+ const int preview_rows, const int preview_cols)
+{
+ static char search[256];
+ wmWindow *win = CTX_wm_window(C);
+ uiBlock *block;
+ uiBut *but;
+
+ /* clear initial search string, then all items show */
+ search[0] = 0;
+
+ block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
+
+ /* preview thumbnails */
+ if (preview_rows > 0 && preview_cols > 0) {
+ const int w = 4 * U.widget_unit * preview_cols;
+ const int h = 5 * U.widget_unit * preview_rows;
+
+ /* fake button, it holds space for search items */
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
+
+ but = uiDefSearchBut(
+ block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
+ preview_rows, preview_cols, "");
+ }
+ /* list view */
+ else {
+ const int searchbox_width = UI_searchbox_size_x();
+ const int searchbox_height = UI_searchbox_size_y();
+
+ /* fake button, it holds space for search items */
+ uiDefBut(
+ block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height,
+ NULL, 0, 0, 0, 0, NULL);
+ but = uiDefSearchBut(
+ block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0,
+ searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
+ }
+ UI_but_func_search_set(
+ but, ui_searchbox_create_generic, search_func,
+ search_arg, handle_func, active_item);
+
+
+ UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
+ UI_block_direction_set(block, UI_DIR_DOWN);
+
+ /* give search-field focus */
+ UI_but_focus_on_enter_event(win, but);
+ /* this type of search menu requires undo */
+ but->flag |= UI_BUT_UNDO;
+
+ return block;
+}
+
/********************** Header Template *************************/
void uiTemplateHeader(uiLayout *layout, bContext *C)
@@ -172,61 +290,16 @@ static void id_search_cb(const bContext *C, void *arg_template, const char *str,
/* ID Search browse menu, open */
static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
{
- static char search[256];
static TemplateID template;
- PointerRNA idptr;
- wmWindow *win = CTX_wm_window(C);
- uiBlock *block;
- uiBut *but;
-
- /* clear initial search string, then all items show */
- search[0] = 0;
+ PointerRNA active_item_ptr;
+
/* arg_litem is malloced, can be freed by parent button */
template = *((TemplateID *)arg_litem);
-
- /* get active id for showing first item */
- idptr = RNA_property_pointer_get(&template.ptr, template.prop);
+ active_item_ptr = RNA_property_pointer_get(&template.ptr, template.prop);
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
-
- /* preview thumbnails */
- if (template.prv_rows > 0 && template.prv_cols > 0) {
- int w = 4 * U.widget_unit * template.prv_cols;
- int h = 5 * U.widget_unit * template.prv_rows;
-
- /* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
-
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
- template.prv_rows, template.prv_cols, "");
- UI_but_func_search_set(
- but, ui_searchbox_create_generic, id_search_cb,
- &template, id_search_call_cb, idptr.data);
- }
- /* list view */
- else {
- const int searchbox_width = UI_searchbox_size_x();
- const int searchbox_height = UI_searchbox_size_y();
-
- /* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
- UI_but_func_search_set(
- but, ui_searchbox_create_generic, id_search_cb,
- &template, id_search_call_cb, idptr.data);
- }
-
-
- UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
- UI_block_direction_set(block, UI_DIR_DOWN);
-
- /* give search-field focus */
- UI_but_focus_on_enter_event(win, but);
- /* this type of search menu requires undo */
- but->flag |= UI_BUT_UNDO;
-
- return block;
+ return template_common_search_menu(
+ C, ar, id_search_cb, &template, id_search_call_cb, active_item_ptr.data,
+ template.prv_rows, template.prv_cols);
}
/************************ ID Template ***************************/
@@ -343,7 +416,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
}
}
-static const char *template_id_browse_tip(StructRNA *type)
+static const char *template_id_browse_tip(const StructRNA *type)
{
if (type) {
switch (RNA_type_to_ID_code(type)) {
@@ -404,6 +477,7 @@ static void template_ID(
// ListBase *lb; // UNUSED
ID *id, *idfrom;
const bool editable = RNA_property_editable(&template->ptr, template->prop);
+ const bool use_previews = template->preview = (flag & UI_ID_PREVIEWS) != 0;
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
id = idptr.data;
@@ -416,29 +490,11 @@ static void template_ID(
if (idptr.type)
type = idptr.type;
- if (flag & UI_ID_PREVIEWS) {
- template->preview = true;
-
- but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
- TIP_(template_id_browse_tip(type)));
- ui_def_but_icon(but, id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type),
- UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
-
- if ((idfrom && idfrom->lib) || !editable)
- UI_but_flag_enable(but, UI_BUT_DISABLED);
-
- uiLayoutRow(layout, true);
- }
- else if (flag & UI_ID_BROWSE) {
- but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
- TIP_(template_id_browse_tip(type)));
- ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
- /* default dragging of icon for id browse buttons */
- UI_but_drag_set_id(but, id);
- UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
-
- if ((idfrom && idfrom->lib) || !editable)
- UI_but_flag_enable(but, UI_BUT_DISABLED);
+ if (flag & UI_ID_BROWSE) {
+ template_add_button_search_menu(
+ C, layout, block, &template->ptr, template->prop,
+ id_search_menu, MEM_dupallocN(template), TIP_(template_id_browse_tip(type)),
+ use_previews, editable);
}
/* text button with name */
@@ -448,8 +504,9 @@ static void template_ID(
//text_idbutton(id, name);
name[0] = '\0';
- but = uiDefButR(block, UI_BTYPE_TEXT, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
- &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
+ but = uiDefButR(
+ block, UI_BTYPE_TEXT, 0, name, 0, 0, TEMPLATE_SEARCH_TEXTBUT_WIDTH, TEMPLATE_SEARCH_TEXTBUT_HEIGHT,
+ &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT);
@@ -735,6 +792,204 @@ void uiTemplateAnyID(
uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
}
+/********************* Search Template ********************/
+
+typedef struct TemplateSearch {
+ uiRNACollectionSearch search_data;
+
+ bool use_previews;
+ int preview_rows, preview_cols;
+} TemplateSearch;
+
+static void template_search_handle_cb(bContext *C, void *arg_template, void *item)
+{
+ TemplateSearch *template_search = arg_template;
+ uiRNACollectionSearch *coll_search = &template_search->search_data;
+ StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
+ PointerRNA item_ptr;
+
+ RNA_pointer_create(NULL, type, item, &item_ptr);
+ RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr);
+ RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
+}
+
+static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_template)
+{
+ static TemplateSearch template_search;
+ PointerRNA active_ptr;
+
+ /* arg_template is malloced, can be freed by parent button */
+ template_search = *((TemplateSearch *)arg_template);
+ active_ptr = RNA_property_pointer_get(&template_search.search_data.target_ptr,
+ template_search.search_data.target_prop);
+
+ return template_common_search_menu(
+ C, region, ui_rna_collection_search_cb, &template_search,
+ template_search_handle_cb, active_ptr.data,
+ template_search.preview_rows, template_search.preview_cols);
+}
+
+static void template_search_add_button_searchmenu(
+ const bContext *C, uiLayout *layout, uiBlock *block,
+ TemplateSearch *template_search, const bool editable)
+{
+ const char *ui_description = RNA_property_ui_description(template_search->search_data.target_prop);
+
+ template_add_button_search_menu(
+ C, layout, block,
+ &template_search->search_data.target_ptr, template_search->search_data.target_prop,
+ template_search_menu, MEM_dupallocN(template_search), ui_description,
+ template_search->use_previews, editable);
+}
+
+static void template_search_add_button_name(
+ uiBlock *block, PointerRNA *active_ptr, const StructRNA *type)
+{
+ uiDefAutoButR(
+ block, active_ptr, RNA_struct_name_property(type), 0, "", ICON_NONE,
+ 0, 0, TEMPLATE_SEARCH_TEXTBUT_WIDTH, TEMPLATE_SEARCH_TEXTBUT_HEIGHT);
+}
+
+static void template_search_add_button_operator(
+ uiBlock *block, const char * const operator_name,
+ const int opcontext, const int icon, const bool editable)
+{
+ if (!operator_name) {
+ return;
+ }
+
+ uiBut *but = uiDefIconButO(
+ block, UI_BTYPE_BUT, operator_name, opcontext, icon,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+
+ if (!editable) {
+ UI_but_drawflag_enable(but, UI_BUT_DISABLED);
+ }
+}
+
+static void template_search_buttons(
+ const bContext *C, uiLayout *layout, TemplateSearch *template_search,
+ const char *newop, const char *unlinkop)
+{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiRNACollectionSearch *search_data = &template_search->search_data;
+ StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
+ const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
+ PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr, search_data->target_prop);
+
+ if (active_ptr.type) {
+ /* can only get correct type when there is an active item */
+ type = active_ptr.type;
+ }
+
+ uiLayoutRow(layout, true);
+ UI_block_align_begin(block);
+
+ template_search_add_button_searchmenu(C, layout, block, template_search, editable);
+ template_search_add_button_name(block, &active_ptr, type);
+ template_search_add_button_operator(block, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, editable);
+ template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
+
+ UI_block_align_end(block);
+}
+
+static PropertyRNA *template_search_get_searchprop(
+ PointerRNA *targetptr, PropertyRNA *targetprop,
+ PointerRNA *searchptr, const char * const searchpropname)
+{
+ PropertyRNA *searchprop;
+
+ if (searchptr && !searchptr->data) {
+ searchptr = NULL;
+ }
+
+ if (!searchptr && !searchpropname) {
+ /* both NULL means we don't use a custom rna collection to search in */
+ }
+ else if (!searchptr && searchpropname) {
+ RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
+ }
+ else if (searchptr && !searchpropname) {
+ RNA_warning("searchptr defined (%s) but searchpropname is missing", RNA_struct_identifier(searchptr->type));
+ }
+ else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
+ RNA_warning("search collection property not found: %s.%s",
+ RNA_struct_identifier(searchptr->type), searchpropname);
+ }
+ else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
+ RNA_warning("search collection property is not a collection type: %s.%s",
+ RNA_struct_identifier(searchptr->type), searchpropname);
+ }
+ /* check if searchprop has same type as targetprop */
+ else if (RNA_property_pointer_type(searchptr, searchprop) != RNA_property_pointer_type(targetptr, targetprop)) {
+ RNA_warning("search collection items from %s.%s are not of type %s",
+ RNA_struct_identifier(searchptr->type), searchpropname,
+ RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
+ }
+ else {
+ return searchprop;
+ }
+
+ return NULL;
+}
+
+static TemplateSearch *template_search_setup(
+ PointerRNA *ptr, const char * const propname,
+ PointerRNA *searchptr, const char * const searchpropname)
+{
+ TemplateSearch *template_search;
+ PropertyRNA *prop, *searchprop;
+
+ prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return NULL;
+ }
+ searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
+
+ template_search = MEM_callocN(sizeof(*template_search), __func__);
+ template_search->search_data.target_ptr = *ptr;
+ template_search->search_data.target_prop = prop;
+ template_search->search_data.search_ptr = *searchptr;
+ template_search->search_data.search_prop = searchprop;
+
+ return template_search;
+}
+
+/**
+ * Search menu to pick an item from a collection.
+ * A version of uiTemplateID that works for non-ID types.
+ */
+void uiTemplateSearch(
+ uiLayout *layout, bContext *C,
+ PointerRNA *ptr, const char *propname,
+ PointerRNA *searchptr, const char *searchpropname,
+ const char *newop, const char *unlinkop)
+{
+ TemplateSearch *template_search = template_search_setup(ptr, propname, searchptr, searchpropname);
+ template_search_buttons(C, layout, template_search, newop, unlinkop);
+ MEM_freeN(template_search);
+}
+
+void uiTemplateSearchPreview(
+ uiLayout *layout, bContext *C,
+ PointerRNA *ptr, const char *propname,
+ PointerRNA *searchptr, const char *searchpropname,
+ const char *newop, const char *unlinkop,
+ const int rows, const int cols)
+{
+ TemplateSearch *template_search = template_search_setup(ptr, propname, searchptr, searchpropname);
+
+ template_search->use_previews = true;
+ template_search->preview_rows = rows;
+ template_search->preview_cols = cols;
+
+ template_search_buttons(C, layout, template_search, newop, unlinkop);
+
+ MEM_freeN(template_search);
+}
+
/********************* RNA Path Builder Template ********************/
/* ---------- */
@@ -3720,6 +3975,7 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
if (propptr.data) {
uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
+ WM_operator_properties_sanitize(&propptr, false);
template_keymap_item_properties(layout, NULL, &propptr);
/* attach callbacks to compensate for missing properties update,
@@ -3736,6 +3992,60 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
}
}
+/********************************* Overrides *************************************/
+
+void uiTemplateOverrideProperty(uiLayout *layout, struct PointerRNA *collection_props_ptr, struct PointerRNA *scene_props_ptr, const char *name, const char *custom_template)
+{
+ bool is_set = false;
+ uiLayout *row, *col;
+
+ PointerRNA *ptr;
+ PropertyRNA *prop;
+
+ IDProperty *collection_props = collection_props_ptr->data;
+
+ if (IDP_GetPropertyFromGroup(collection_props, name)) {
+ prop = RNA_struct_find_property(collection_props_ptr, name);
+ ptr = collection_props_ptr;
+ is_set = RNA_property_is_set(ptr, prop);
+ }
+ else {
+ /* property doesn't exist yet */
+ prop = RNA_struct_find_property(scene_props_ptr, name);
+ ptr = scene_props_ptr;
+ }
+
+ row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, false);
+
+ uiLayoutSetEnabled(col, is_set);
+
+ if (custom_template && STREQ(custom_template, "icon_view")) {
+ uiTemplateIconView(col, ptr, name, false, 5.0f);
+ }
+ else {
+ uiItemFullR(col, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
+ }
+
+ col = uiLayoutColumn(row, false);
+ uiBut *but;
+ uiBlock *block = uiLayoutGetBlock(col);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ if (is_set) {
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_unuse_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ }
+ else {
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_use_property_button", WM_OP_EXEC_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ /* XXX - Using existing data struct to pass another RNAPointer */
+ but->rnasearchpoin = *scene_props_ptr;
+ }
+
+ but->rnapoin = *collection_props_ptr;
+ but->rnaprop = prop;
+ UI_block_emboss_set(block, UI_EMBOSS);
+}
+
/********************************* Color management *************************************/
void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 636b7e4e9ce..f383719a747 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -215,6 +215,89 @@ int uiDefAutoButsRNA(
return tot;
}
+/* *** RNA collection search menu *** */
+
+typedef struct CollItemSearch {
+ struct CollItemSearch *next, *prev;
+ void *data;
+ char *name;
+ int index;
+ int iconid;
+} CollItemSearch;
+
+static int sort_search_items_list(const void *a, const void *b)
+{
+ const CollItemSearch *cis1 = a;
+ const CollItemSearch *cis2 = b;
+
+ if (BLI_strcasecmp(cis1->name, cis2->name) > 0)
+ return 1;
+ else
+ return 0;
+}
+
+void ui_rna_collection_search_cb(const struct bContext *C, void *arg, const char *str, uiSearchItems *items)
+{
+ uiRNACollectionSearch *data = arg;
+ char *name;
+ int i = 0, iconid = 0, flag = RNA_property_flag(data->target_prop);
+ ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
+ CollItemSearch *cis;
+ const bool skip_filter = !(data->but_changed && *data->but_changed);
+
+ /* build a temporary list of relevant items first */
+ RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop)
+ {
+
+ if (flag & PROP_ID_SELF_CHECK)
+ if (itemptr.data == data->target_ptr.id.data)
+ continue;
+
+ /* use filter */
+ if (RNA_property_type(data->target_prop) == PROP_POINTER) {
+ if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0)
+ continue;
+ }
+
+ name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
+ iconid = 0;
+ if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
+ iconid = ui_id_icon_get(C, itemptr.data, false);
+ }
+
+ if (name) {
+ if (skip_filter || BLI_strcasestr(name, str)) {
+ cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
+ cis->data = itemptr.data;
+ cis->name = MEM_dupallocN(name);
+ cis->index = i;
+ cis->iconid = iconid;
+ BLI_addtail(items_list, cis);
+ }
+ MEM_freeN(name);
+ }
+
+ i++;
+ }
+ RNA_PROP_END;
+
+ BLI_listbase_sort(items_list, sort_search_items_list);
+
+ /* add search items from temporary list */
+ for (cis = items_list->first; cis; cis = cis->next) {
+ if (UI_search_item_add(items, cis->name, cis->data, cis->iconid) == false) {
+ break;
+ }
+ }
+
+ for (cis = items_list->first; cis; cis = cis->next) {
+ MEM_freeN(cis->name);
+ }
+ BLI_freelistN(items_list);
+ MEM_freeN(items_list);
+}
+
+
/***************************** ID Utilities *******************************/
int UI_icon_from_id(ID *id)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index f7f2b422724..d0ec40bbb70 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -47,9 +47,6 @@
#include "RNA_access.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "BLF_api.h"
#include "UI_interface.h"
@@ -58,6 +55,9 @@
#include "interface_intern.h"
#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#ifdef WITH_INPUT_IME
# include "WM_types.h"
@@ -186,48 +186,58 @@ static const unsigned int check_tria_face[4][3] = {
/* ************************************************* */
-void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3)
+void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3,
+ const float color[4])
{
float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}};
- float color[4];
- int j;
-
+ float draw_color[4];
+
+ copy_v4_v4(draw_color, color);
+ draw_color[3] *= 0.125f;
+
glEnable(GL_BLEND);
- glGetFloatv(GL_CURRENT_COLOR, color);
- color[3] *= 0.125f;
- glColor4fv(color);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, tri_arr);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4fv(draw_color);
+ immBegin(PRIM_TRIANGLES, 3 * WIDGET_AA_JITTER);
/* for each AA step */
- for (j = 0; j < WIDGET_AA_JITTER; j++) {
- glTranslate2fv(jit[j]);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- glTranslatef(-jit[j][0], -jit[j][1], 0.0f);
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ immVertex2f(pos, tri_arr[0][0] + jit[j][0], tri_arr[0][1] + jit[j][1]);
+ immVertex2f(pos, tri_arr[1][0] + jit[j][0], tri_arr[1][1] + jit[j][1]);
+ immVertex2f(pos, tri_arr[2][0] + jit[j][0], tri_arr[2][1] + jit[j][1]);
}
- glDisableClientState(GL_VERTEX_ARRAY);
+ immEnd();
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha)
+/* belongs in interface_draw.c, but needs WIDGET_AA_JITTER from this file */
+void UI_draw_roundbox_aa(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4])
{
- float color[4];
- int j;
-
glEnable(GL_BLEND);
- glGetFloatv(GL_CURRENT_COLOR, color);
- if (use_alpha) {
- color[3] = 0.5f;
+
+ if (filled) {
+ /* plain antialiased filled box */
+ const float alpha = color[3] * 0.125f;
+
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ gpuPushMatrix();
+ gpuTranslate2fv(jit[j]);
+ UI_draw_roundbox_3fvAlpha(true, minx, miny, maxx, maxy, rad, color, alpha);
+ gpuPopMatrix();
+ }
}
- color[3] *= 0.125f;
- glColor4fv(color);
-
- for (j = 0; j < WIDGET_AA_JITTER; j++) {
- glTranslate2fv(jit[j]);
- UI_draw_roundbox_gl_mode(mode, minx, miny, maxx, maxy, rad);
- glTranslatef(-jit[j][0], -jit[j][1], 0.0f);
+ else {
+ /* plain antialiased unfilled box */
+ glEnable(GL_LINE_SMOOTH);
+ UI_draw_roundbox_4fv(false, minx, miny, maxx, maxy, rad, color);
+ glDisable(GL_LINE_SMOOTH);
}
glDisable(GL_BLEND);
@@ -537,12 +547,27 @@ static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float tr
scroll_circle_face, ARRAY_SIZE(scroll_circle_face));
}
-static void widget_trias_draw(uiWidgetTrias *tria)
+static void widget_trias_draw(uiWidgetTrias *tria, unsigned int pos)
+{
+ immBegin(PRIM_TRIANGLES, tria->tot * 3);
+ for (int i = 0; i < tria->tot; ++i)
+ for (int j = 0; j < 3; ++j)
+ immVertex2fv(pos, tria->vec[tria->index[i][j]]);
+ immEnd();
+}
+
+static void widget_draw_vertex_buffer(unsigned int pos, unsigned int col, int mode,
+ const float quads_pos[WIDGET_SIZE_MAX][2],
+ const unsigned char quads_col[WIDGET_SIZE_MAX][4],
+ unsigned int totvert)
{
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, tria->vec);
- glDrawElements(GL_TRIANGLES, tria->tot * 3, GL_UNSIGNED_INT, tria->index);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(mode, totvert);
+ for (int i = 0; i < totvert; ++i) {
+ if (quads_col)
+ immAttrib4ubv(col, quads_col[i]);
+ immVertex2fv(pos, quads_pos[i]);
+ }
+ immEnd();
}
static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
@@ -631,21 +656,18 @@ static void widget_verts_to_triangle_strip_open(uiWidgetBase *wtb, const int tot
}
}
-static void widgetbase_outline(uiWidgetBase *wtb)
+static void widgetbase_outline(uiWidgetBase *wtb, unsigned int pos)
{
float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, triangle_strip);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->totvert * 2 + 2);
- glDisableClientState(GL_VERTEX_ARRAY);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2);
}
static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
{
int j, a;
-
+
glEnable(GL_BLEND);
/* backdrop non AA */
@@ -655,78 +677,76 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
float inner_v_half[WIDGET_SIZE_MAX][2];
float x_mid = 0.0f; /* used for dumb clamping of values */
- /* dark checkers */
- glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
- glDrawArrays(GL_POLYGON, 0, wtb->totvert);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
- /* light checkers */
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_CHECKER_8PX);
+ /* checkers */
+ immUniform4f("color1", UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, 1.0f);
+ immUniform4f("color2", UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 1.0f);
+ immUniform1i("size", 8);
- glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
- glDrawArrays(GL_POLYGON, 0, wtb->totvert);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, wtb->inner_v, NULL, wtb->totvert);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immUnbindProgram();
/* alpha fill */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((unsigned char *)wcol->inner);
- glColor4ubv((unsigned char *)wcol->inner);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (a = 0; a < wtb->totvert; a++) {
x_mid += wtb->inner_v[a][0];
}
x_mid /= wtb->totvert;
- glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
- glDrawArrays(GL_POLYGON, 0, wtb->totvert);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, wtb->inner_v, NULL, wtb->totvert);
/* 1/2 solid color */
- glColor4ub(wcol->inner[0], wcol->inner[1], wcol->inner[2], 255);
+ immUniformColor3ubv((unsigned char *)wcol->inner);
for (a = 0; a < wtb->totvert; a++) {
inner_v_half[a][0] = MIN2(wtb->inner_v[a][0], x_mid);
inner_v_half[a][1] = wtb->inner_v[a][1];
}
- glVertexPointer(2, GL_FLOAT, 0, inner_v_half);
- glDrawArrays(GL_POLYGON, 0, wtb->totvert);
- glDisableClientState(GL_VERTEX_ARRAY);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, inner_v_half, NULL, wtb->totvert);
+
+ immUnbindProgram();
}
else {
/* simple fill */
- glColor4ubv((unsigned char *)wcol->inner);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((unsigned char *)wcol->inner);
+
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, wtb->inner_v, NULL, wtb->totvert);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
- glDrawArrays(GL_POLYGON, 0, wtb->totvert);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immUnbindProgram();
}
}
else {
char col1[4], col2[4];
- unsigned char col_array[WIDGET_SIZE_MAX * 4];
- unsigned char *col_pt = col_array;
-
+ unsigned char col_array[WIDGET_SIZE_MAX][4];
+ unsigned char *col_pt = &col_array[0][0];
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
shadecolors4(col1, col2, wcol->inner, wcol->shadetop, wcol->shadedown);
for (a = 0; a < wtb->totvert; a++, col_pt += 4) {
round_box_shade_col4_r(col_pt, col1, col2, wtb->inner_uv[a][wtb->draw_shadedir ? 1 : 0]);
}
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, col_array);
- glDrawArrays(GL_POLYGON, 0, wtb->totvert);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
+ widget_draw_vertex_buffer(pos, col, GL_TRIANGLE_FAN, wtb->inner_v, col_array, wtb->totvert);
+ immUnbindProgram();
}
}
-
+
/* for each AA step */
if (wtb->draw_outline) {
float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
@@ -745,52 +765,55 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss);
}
- glEnableClientState(GL_VERTEX_ARRAY);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
for (j = 0; j < WIDGET_AA_JITTER; j++) {
- glTranslate2fv(jit[j]);
+ gpuTranslate2fv(jit[j]);
/* outline */
- glColor4ubv(tcol);
+ immUniformColor4ubv(tcol);
- glVertexPointer(2, GL_FLOAT, 0, triangle_strip);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->totvert * 2 + 2);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2);
/* emboss bottom shadow */
if (wtb->draw_emboss) {
if (emboss[3]) {
- glColor4ubv(emboss);
- glVertexPointer(2, GL_FLOAT, 0, triangle_strip_emboss);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->halfwayvert * 2);
+ immUniformColor4ubv(emboss);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip_emboss, NULL, wtb->halfwayvert * 2);
}
}
- glTranslatef(-jit[j][0], -jit[j][1], 0.0f);
+ gpuTranslate2f(-jit[j][0], -jit[j][1]);
}
-
- glDisableClientState(GL_VERTEX_ARRAY);
+ immUnbindProgram();
}
-
+
/* decoration */
if (wtb->tria1.tot || wtb->tria2.tot) {
const unsigned char tcol[4] = {wcol->item[0],
wcol->item[1],
wcol->item[2],
(unsigned char)((float)wcol->item[3] / WIDGET_AA_JITTER)};
- glColor4ubv(tcol);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv(tcol);
/* for each AA step */
for (j = 0; j < WIDGET_AA_JITTER; j++) {
- glTranslate2fv(jit[j]);
+ gpuTranslate2fv(jit[j]);
if (wtb->tria1.tot)
- widget_trias_draw(&wtb->tria1);
+ widget_trias_draw(&wtb->tria1, pos);
if (wtb->tria2.tot)
- widget_trias_draw(&wtb->tria2);
+ widget_trias_draw(&wtb->tria2, pos);
- glTranslatef(-jit[j][0], -jit[j][1], 0.0f);
+ gpuTranslate2f(-jit[j][0], -jit[j][1]);
}
+
+ immUnbindProgram();
}
glDisable(GL_BLEND);
@@ -1246,6 +1269,7 @@ static void widget_draw_text_ime_underline(
int ofs_x, width;
int rect_x = BLI_rcti_size_x(rect);
int sel_start = ime_data->sel_start, sel_end = ime_data->sel_end;
+ float fcol[4];
if (drawstr[0] != 0) {
if (but->pos >= but->ofs) {
@@ -1258,8 +1282,8 @@ static void widget_draw_text_ime_underline(
width = BLF_width(fstyle->uifont_id, drawstr + but->ofs,
ime_data->composite_len + but->pos - but->ofs);
- glColor4ubv((unsigned char *)wcol->text);
- UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 1);
+ rgba_uchar_to_float(fcol, wcol->text);
+ UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 1, fcol);
/* draw the thick line */
if (sel_start != -1 && sel_end != -1) {
@@ -1276,7 +1300,7 @@ static void widget_draw_text_ime_underline(
width = BLF_width(fstyle->uifont_id, drawstr + but->ofs,
sel_end + sel_start - but->ofs);
- UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 2);
+ UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 2, fcol);
}
}
}
@@ -1360,11 +1384,16 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
selwidth_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selend - but->ofs);
- glColor4ubv((unsigned char *)wcol->item);
- glRecti(rect->xmin + selsta_draw,
- rect->ymin + 2,
- min_ii(rect->xmin + selwidth_draw, rect->xmax - 2),
- rect->ymax - 2);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4ubv((unsigned char *)wcol->item);
+ immRecti(pos, rect->xmin + selsta_draw,
+ rect->ymin + 2,
+ min_ii(rect->xmin + selwidth_draw, rect->xmax - 2),
+ rect->ymax - 2);
+
+ immUnbindProgram();
}
}
@@ -1387,13 +1416,18 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
t = 0;
}
- glColor3f(0.2, 0.6, 0.9);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(0.2f, 0.6f, 0.9f);
tx = rect->xmin + t + 2;
ty = rect->ymin + 2;
/* draw cursor */
- glRecti(rect->xmin + t, ty, tx, rect->ymax - 2);
+ immRecti(pos, rect->xmin + t, ty, tx, rect->ymax - 2);
+
+ immUnbindProgram();
}
#ifdef WITH_INPUT_IME
@@ -1452,43 +1486,46 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
}
#endif
- glColor4ubv((unsigned char *)wcol->text);
-
if (!use_right_only) {
/* for underline drawing */
float font_xofs, font_yofs;
- UI_fontstyle_draw_ex(fstyle, rect, drawstr + but->ofs,
- drawstr_left_len - but->ofs, &font_xofs, &font_yofs);
+ int drawlen = (drawstr_left_len == INT_MAX) ? strlen(drawstr + but->ofs) : (drawstr_left_len - but->ofs);
- if (but->menu_key != '\0') {
- char fixedbuf[128];
- const char *str;
+ if (drawlen > 0) {
+ UI_fontstyle_draw_ex(fstyle, rect, drawstr + but->ofs, (unsigned char *)wcol->text,
+ drawlen, &font_xofs, &font_yofs);
- BLI_strncpy(fixedbuf, drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawstr_left_len));
+ if (but->menu_key != '\0') {
+ char fixedbuf[128];
+ const char *str;
- str = strchr(fixedbuf, but->menu_key - 32); /* upper case */
- if (str == NULL)
- str = strchr(fixedbuf, but->menu_key);
+ BLI_strncpy(fixedbuf, drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawlen));
- if (str) {
- int ul_index = -1;
- float ul_advance;
+ str = strchr(fixedbuf, but->menu_key - 32); /* upper case */
+ if (str == NULL)
+ str = strchr(fixedbuf, but->menu_key);
- ul_index = (int)(str - fixedbuf);
+ if (str) {
+ int ul_index = -1;
+ float ul_advance;
- if (fstyle->kerning == 1) {
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
+ ul_index = (int)(str - fixedbuf);
+
+ if (fstyle->kerning == 1) {
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
- fixedbuf[ul_index] = '\0';
- ul_advance = BLF_width(fstyle->uifont_id, fixedbuf, ul_index);
+ fixedbuf[ul_index] = '\0';
+ ul_advance = BLF_width(fstyle->uifont_id, fixedbuf, ul_index);
- BLF_position(fstyle->uifont_id, rect->xmin + font_xofs + ul_advance, rect->ymin + font_yofs, 0.0f);
- BLF_draw(fstyle->uifont_id, "_", 2);
+ BLF_position(fstyle->uifont_id, rect->xmin + font_xofs + ul_advance, rect->ymin + font_yofs, 0.0f);
+ BLF_color4ubv(fstyle->uifont_id, (unsigned char *)wcol->text);
+ BLF_draw(fstyle->uifont_id, "_", 2);
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
}
}
@@ -1498,7 +1535,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
if (drawstr_right) {
fstyle->align = UI_STYLE_TEXT_RIGHT;
rect->xmax -= UI_TEXT_CLIP_MARGIN;
- UI_fontstyle_draw(fstyle, rect, drawstr_right);
+ UI_fontstyle_draw(fstyle, rect, drawstr_right, (unsigned char *)wcol->text);
}
}
@@ -1621,6 +1658,9 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
widget_draw_text(fstyle, wcol, but, rect);
ui_but_text_password_hide(password_str, but, true);
+
+ /* if a widget uses font shadow it has to be deactivated now */
+ BLF_disable(fstyle->uifont_id, BLF_SHADOW);
}
#undef UI_TEXT_CLIP_MARGIN
@@ -1879,6 +1919,19 @@ static struct uiWidgetColors wcol_list_item = {
0, 0
};
+struct uiWidgetColors wcol_tab = {
+ {255, 255, 255, 255},
+ {83, 83, 83, 255},
+ {114, 114, 114, 255},
+ {90, 90, 90, 255},
+
+ {0, 0, 0, 255},
+ {0, 0, 0, 255},
+
+ 0,
+ 0, 0
+};
+
/* free wcol struct to play with */
static struct uiWidgetColors wcol_tmp = {
{0, 0, 0, 255},
@@ -1901,6 +1954,7 @@ void ui_widget_color_init(ThemeUI *tui)
tui->wcol_tool = wcol_tool;
tui->wcol_text = wcol_text;
tui->wcol_radio = wcol_radio;
+ tui->wcol_tab = wcol_tab;
tui->wcol_option = wcol_option;
tui->wcol_toggle = wcol_toggle;
tui->wcol_num = wcol_num;
@@ -2159,23 +2213,24 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
/* we draw a number of increasing size alpha quad strips */
alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
-
- glEnableClientState(GL_VERTEX_ARRAY);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
for (step = 1; step <= (int)radout; step++) {
float expfac = sqrtf(step / radout);
round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
- glColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
+ immUniformColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip);
- glVertexPointer(2, GL_FLOAT, 0, triangle_strip);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, totvert * 2); /* add + 2 for getting a complete soft rect. Now it skips top edge to allow transparent menus */
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, totvert * 2);
}
- glDisableClientState(GL_VERTEX_ARRAY);
+ immUnbindProgram();
}
static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction)
@@ -2212,20 +2267,21 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
static void ui_hsv_cursor(float x, float y)
{
- glPushMatrix();
- glTranslatef(x, y, 0.0f);
-
- glColor3f(1.0f, 1.0f, 1.0f);
- glutil_draw_filled_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 8);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+ imm_draw_circle_fill(pos, x, y, 3.0f * U.pixelsize, 8);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glColor3f(0.0f, 0.0f, 0.0f);
- glutil_draw_lined_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 12);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ imm_draw_circle_wire(pos, x, y, 3.0f * U.pixelsize, 12);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
-
- glPopMatrix();
+
+ immUnbindProgram();
}
void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
@@ -2265,18 +2321,17 @@ void ui_hsvcircle_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float
static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
{
+ /* TODO(merwin): reimplement as shader for pixel-perfect colors */
+
const int tot = 64;
const float radstep = 2.0f * (float)M_PI / (float)tot;
const float centx = BLI_rcti_cent_x_fl(rect);
const float centy = BLI_rcti_cent_y_fl(rect);
float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
- /* gouraud triangle fan */
ColorPicker *cpicker = but->custom_data;
const float *hsv_ptr = cpicker->color_data;
- float xpos, ypos, ang = 0.0f;
float rgb[3], hsvo[3], hsv[3], col[3], colcent[3];
- int a;
bool color_profile = ui_but_is_colorpicker_display_space(but);
/* color */
@@ -2307,11 +2362,18 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
ui_color_picker_to_rgb(0.0f, 0.0f, hsv[2], colcent, colcent + 1, colcent + 2);
- glBegin(GL_TRIANGLE_FAN);
- glColor3fv(colcent);
- glVertex2f(centx, centy);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ immBegin(PRIM_TRIANGLE_FAN, tot + 2);
+ immAttrib3fv(color, colcent);
+ immVertex2f(pos, centx, centy);
- for (a = 0; a <= tot; a++, ang += radstep) {
+ float ang = 0.0f;
+ for (int a = 0; a <= tot; a++, ang += radstep) {
float si = sinf(ang);
float co = cosf(ang);
@@ -2319,25 +2381,32 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
ui_color_picker_to_rgb_v(hsv, col);
- glColor3fv(col);
- glVertex2f(centx + co * radius, centy + si * radius);
+ immAttrib3fv(color, col);
+ immVertex2f(pos, centx + co * radius, centy + si * radius);
}
- glEnd();
-
+ immEnd();
+ immUnbindProgram();
+
/* fully rounded outline */
- glPushMatrix();
- glTranslatef(centx, centy, 0.0f);
+ format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glColor3ubv((unsigned char *)wcol->outline);
- glutil_draw_lined_arc(0.0f, M_PI * 2.0, radius, tot + 1);
+
+ immUniformColor3ubv((unsigned char *)wcol->outline);
+ imm_draw_circle_wire(pos, centx, centy, radius, tot);
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
- glPopMatrix();
/* cursor */
+ float xpos, ypos;
ui_hsvcircle_pos_from_vals(but, rect, hsvo, &xpos, &ypos);
-
ui_hsv_cursor(xpos, ypos);
}
@@ -2347,7 +2416,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha)
{
/* allows for 4 steps (red->yellow) */
- const float color_step = 1.0f / 48.0f;
+ const int steps = 48;
+ const float color_step = 1.0f / steps;
int a;
float h = hsv[0], s = hsv[1], v = hsv[2];
float dx, dy, sx1, sx2, sy;
@@ -2401,9 +2471,14 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
copy_v3_v3(col1[3], col1[2]);
break;
}
-
+
/* old below */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ immBegin(PRIM_TRIANGLES, steps * 3 * 6);
for (dx = 0.0f; dx < 0.999f; dx += color_step) { /* 0.999 = prevent float inaccuracy for steps */
const float dx_next = dx + color_step;
@@ -2461,22 +2536,29 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
sy = rect->ymin;
dy = (float)BLI_rcti_size_y(rect) / 3.0f;
- glBegin(GL_QUADS);
for (a = 0; a < 3; a++, sy += dy) {
- glColor4f(col0[a][0], col0[a][1], col0[a][2], alpha);
- glVertex2f(sx1, sy);
+ immAttrib4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
+ immVertex2f(pos, sx1, sy);
- glColor4f(col1[a][0], col1[a][1], col1[a][2], alpha);
- glVertex2f(sx2, sy);
+ immAttrib4f(col, col1[a][0], col1[a][1], col1[a][2], alpha);
+ immVertex2f(pos, sx2, sy);
+
+ immAttrib4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
+ immVertex2f(pos, sx2, sy + dy);
+
+ immAttrib4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
+ immVertex2f(pos, sx1, sy);
- glColor4f(col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
- glVertex2f(sx2, sy + dy);
+ immAttrib4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
+ immVertex2f(pos, sx2, sy + dy);
- glColor4f(col0[a + 1][0], col0[a + 1][1], col0[a + 1][2], alpha);
- glVertex2f(sx1, sy + dy);
+ immAttrib4f(col, col0[a + 1][0], col0[a + 1][1], col0[a + 1][2], alpha);
+ immVertex2f(pos, sx1, sy + dy);
}
- glEnd();
}
+ immEnd();
+
+ immUnbindProgram();
}
bool ui_but_is_colorpicker_display_space(uiBut *but)
@@ -2552,8 +2634,11 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
ui_hsv_cursor(x, y);
/* outline */
- glColor3ub(0, 0, 0);
- fdrawbox((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ub(0, 0, 0);
+ imm_draw_line_box(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
+ immUnbindProgram();
}
/* vertical 'value' slider, using new widget code */
@@ -2621,12 +2706,22 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
wcol->text[2],
30
};
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glEnable(GL_BLEND);
- glColor4ubv(col);
+ immUniformColor4ubv(col);
glLineWidth(1.0f);
- sdrawline(rect->xmin, y, rect->xmax, y);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, rect->xmin, y);
+ immVertex2f(pos, rect->xmax, y);
+ immEnd();
+
glDisable(GL_BLEND);
+
+ immUnbindProgram();
}
/* ************ button callbacks, draw ***************** */
@@ -2698,11 +2793,14 @@ bool ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
}
#define LINK_RESOL 24
-void ui_draw_link_bezier(const rcti *rect)
+void ui_draw_link_bezier(const rcti *rect, const float color[4])
{
float coord_array[LINK_RESOL + 1][2];
if (ui_link_bezier_points(rect, coord_array, LINK_RESOL)) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
#if 0 /* unused */
/* we can reuse the dist variable here to increment the GL curve eval amount*/
const float dist = 1.0f / (float)LINK_RESOL;
@@ -2710,13 +2808,17 @@ void ui_draw_link_bezier(const rcti *rect)
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, coord_array);
- glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL + 1);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immUniformColor4fv(color);
+
+ immBegin(PRIM_LINE_STRIP, LINK_RESOL + 1);
+ for (int i = 0; i <= LINK_RESOL; ++i)
+ immVertex2fv(pos, coord_array[i]);
+ immEnd();
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
+
+ immUnbindProgram();
}
}
@@ -2898,15 +3000,16 @@ static void widget_link(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect, in
if (but->flag & UI_SELECT) {
rcti rectlink;
+ float color[4];
- UI_ThemeColor(TH_TEXT_HI);
+ UI_GetThemeColor4fv(TH_TEXT_HI, color);
rectlink.xmin = BLI_rcti_cent_x(rect);
rectlink.ymin = BLI_rcti_cent_y(rect);
rectlink.xmax = but->linkto[0];
rectlink.ymax = but->linkto[1];
- ui_draw_link_bezier(&rectlink);
+ ui_draw_link_bezier(&rectlink, color);
}
}
@@ -3058,13 +3161,18 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
float bw = rgb_to_grayscale(col);
bw += (bw < 0.5f) ? 0.5f : -0.5f;
-
- glColor4f(bw, bw, bw, 1.0);
- glBegin(GL_TRIANGLES);
- glVertex2f(rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
- glVertex2f(rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
- glVertex2f(rect->xmin + 0.5f * width, rect->ymin + 0.9f * height);
- glEnd();
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(bw, bw, bw);
+ immBegin(PRIM_TRIANGLES, 3);
+ immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
+ immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
+ immVertex2f(pos, rect->xmin + 0.5f * width, rect->ymin + 0.9f * height);
+ immEnd();
+
+ immUnbindProgram();
}
}
@@ -3360,12 +3468,50 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
widgetbase_draw(&wtb, wcol);
}
+static void widget_tab(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
+{
+ const uiStyle *style = UI_style_get();
+ const float rad = 0.15f * U.widget_unit;
+ const int fontid = style->widget.uifont_id;
+ const bool is_active = (but->flag & UI_SELECT);
+
+ uiWidgetBase wtb;
+ unsigned char theme_col_tab_highlight[3];
+
+ /* create outline highlight colors */
+ if (is_active) {
+ interp_v3_v3v3_uchar(theme_col_tab_highlight, (unsigned char *)wcol->inner_sel,
+ (unsigned char *)wcol->outline, 0.2f);
+ }
+ else {
+ interp_v3_v3v3_uchar(theme_col_tab_highlight, (unsigned char *)wcol->inner,
+ (unsigned char *)wcol->outline, 0.12f);
+ }
+
+ widget_init(&wtb);
+
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+
+ /* draw inner */
+ wtb.draw_outline = 0;
+ widgetbase_draw(&wtb, wcol);
+
+ /* draw outline (3d look) */
+ ui_draw_but_TAB_outline(rect, rad, theme_col_tab_highlight, (unsigned char *)wcol->inner);
+
+ /* text shadow */
+ BLF_enable(fontid, BLF_SHADOW);
+ BLF_shadow(fontid, 3, (const float[4]){1.0f, 1.0f, 1.0f, 0.25f});
+ BLF_shadow_offset(fontid, 0, -1);
+}
+
static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect)
{
uiWidgetBase wtb;
const float rad = 0.25f * U.widget_unit;
unsigned char col[4];
-
+
/* state copy! */
wt->wcol = *(wt->wcol_theme);
@@ -3375,12 +3521,17 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
/* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
but->block->drawextra(C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* make mask to draw over image */
UI_GetThemeColor3ubv(TH_BACK, col);
- glColor3ubv(col);
-
+ immUniformColor3ubv(col);
+
round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
- widgetbase_outline(&wtb);
+ widgetbase_outline(&wtb, pos);
+
+ immUnbindProgram();
}
/* outline */
@@ -3442,6 +3593,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
wt.draw = widget_roundbut;
break;
+ case UI_WTYPE_TAB:
+ wt.custom = widget_tab;
+ wt.wcol_theme = &btheme->tui.wcol_tab;
+ break;
+
case UI_WTYPE_TOOLTIP:
wt.wcol_theme = &btheme->tui.wcol_tooltip;
wt.draw = widget_menu_back;
@@ -3696,7 +3852,11 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
if (but->block->flag & UI_BLOCK_LOOP)
wt->wcol_theme = &btheme->tui.wcol_menu_back;
break;
-
+
+ case UI_BTYPE_TAB:
+ wt = widget_type(UI_WTYPE_TAB);
+ break;
+
case UI_BTYPE_BUT_TOGGLE:
case UI_BTYPE_TOGGLE:
case UI_BTYPE_TOGGLE_N:
@@ -3889,15 +4049,21 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
wt->draw(&wt->wcol, rect, 0, 0);
if (block) {
+ float draw_color[4];
+ unsigned char *color = (unsigned char *)wt->wcol.text;
+
+ draw_color[0] = ((float)color[0]) / 255.0f;
+ draw_color[1] = ((float)color[1]) / 255.0f;
+ draw_color[2] = ((float)color[2]) / 255.0f;
+ draw_color[3] = 1.0f;
+
if (block->flag & UI_BLOCK_CLIPTOP) {
/* XXX no scaling for UI here yet */
- glColor3ubv((unsigned char *)wt->wcol.text);
- UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymax - 8, 't');
+ UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymax - 8, 't', draw_color);
}
if (block->flag & UI_BLOCK_CLIPBOTTOM) {
/* XXX no scaling for UI here yet */
- glColor3ubv((unsigned char *)wt->wcol.text);
- UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v');
+ UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v', draw_color);
}
}
}
@@ -3915,33 +4081,21 @@ static void draw_disk_shaded(
float y1, y2;
float fac;
unsigned char r_col[4];
+ unsigned int pos, col;
- glBegin(GL_TRIANGLE_STRIP);
-
- s = sinf(start);
- c = cosf(start);
-
- y1 = s * radius_int;
- y2 = s * radius_ext;
-
+ VertexFormat *format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
if (shaded) {
- fac = (y1 + radius_ext) * radius_ext_scale;
- round_box_shade_col4_r(r_col, col1, col2, fac);
-
- glColor4ubv(r_col);
+ col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
}
-
- glVertex2f(c * radius_int, s * radius_int);
-
- if (shaded) {
- fac = (y2 + radius_ext) * radius_ext_scale;
- round_box_shade_col4_r(r_col, col1, col2, fac);
-
- glColor4ubv(r_col);
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((unsigned char *)col1);
}
- glVertex2f(c * radius_ext, s * radius_ext);
- for (i = 1; i < subd; i++) {
+ immBegin(PRIM_TRIANGLE_STRIP, subd * 2);
+ for (i = 0; i < subd; i++) {
float a;
a = start + ((i) / (float)(subd - 1)) * angle;
@@ -3953,20 +4107,20 @@ static void draw_disk_shaded(
if (shaded) {
fac = (y1 + radius_ext) * radius_ext_scale;
round_box_shade_col4_r(r_col, col1, col2, fac);
-
- glColor4ubv(r_col);
+ immAttrib4ubv(col, r_col);
}
- glVertex2f(c * radius_int, s * radius_int);
+ immVertex2f(pos, c * radius_int, s * radius_int);
if (shaded) {
fac = (y2 + radius_ext) * radius_ext_scale;
round_box_shade_col4_r(r_col, col1, col2, fac);
-
- glColor4ubv(r_col);
+ immAttrib4ubv(col, r_col);
}
- glVertex2f(c * radius_ext, s * radius_ext);
+ immVertex2f(pos, c * radius_ext, s * radius_ext);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
void ui_draw_pie_center(uiBlock *block)
@@ -3985,8 +4139,8 @@ void ui_draw_pie_center(uiBlock *block)
float angle = atan2f(pie_dir[1], pie_dir[0]);
float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4;
- glPushMatrix();
- glTranslatef(cx, cy, 0.0f);
+ gpuPushMatrix();
+ gpuTranslate2f(cx, cy);
glEnable(GL_BLEND);
if (btheme->tui.wcol_pie_menu.shaded) {
@@ -3995,8 +4149,7 @@ void ui_draw_pie_center(uiBlock *block)
draw_disk_shaded(0.0f, (float)(M_PI * 2.0), pie_radius_internal, pie_radius_external, subd, col1, col2, true);
}
else {
- glColor4ubv((GLubyte *)btheme->tui.wcol_pie_menu.inner);
- draw_disk_shaded(0.0f, (float)(M_PI * 2.0), pie_radius_internal, pie_radius_external, subd, NULL, NULL, false);
+ draw_disk_shaded(0.0f, (float)(M_PI * 2.0), pie_radius_internal, pie_radius_external, subd, btheme->tui.wcol_pie_menu.inner, NULL, false);
}
if (!(block->pie_data.flags & UI_PIE_INVALID_DIR)) {
@@ -4006,25 +4159,34 @@ void ui_draw_pie_center(uiBlock *block)
draw_disk_shaded(angle - range / 2.0f, range, pie_radius_internal, pie_radius_external, subd, col1, col2, true);
}
else {
- glColor4ubv((GLubyte *)btheme->tui.wcol_pie_menu.inner_sel);
- draw_disk_shaded(angle - range / 2.0f, range, pie_radius_internal, pie_radius_external, subd, NULL, NULL, false);
+ draw_disk_shaded(angle - range / 2.0f, range, pie_radius_internal, pie_radius_external, subd, btheme->tui.wcol_pie_menu.inner_sel, NULL, false);
}
}
- glColor4ubv((GLubyte *)btheme->tui.wcol_pie_menu.outline);
- glutil_draw_lined_arc(0.0f, (float)M_PI * 2.0f, pie_radius_internal, subd);
- glutil_draw_lined_arc(0.0f, (float)M_PI * 2.0f, pie_radius_external, subd);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((unsigned char *)btheme->tui.wcol_pie_menu.outline);
+
+ imm_draw_circle_wire(pos, 0.0f, 0.0f, pie_radius_internal, subd);
+ imm_draw_circle_wire(pos, 0.0f, 0.0f, pie_radius_external, subd);
+
+ immUnbindProgram();
if (U.pie_menu_confirm > 0 && !(block->pie_data.flags & (UI_PIE_INVALID_DIR | UI_PIE_CLICK_STYLE))) {
float pie_confirm_radius = U.pixelsize * (pie_radius_internal + U.pie_menu_confirm);
float pie_confirm_external = U.pixelsize * (pie_radius_internal + U.pie_menu_confirm + 7.0f);
- glColor4ub(btheme->tui.wcol_pie_menu.text_sel[0], btheme->tui.wcol_pie_menu.text_sel[1], btheme->tui.wcol_pie_menu.text_sel[2], 64);
- draw_disk_shaded(angle - range / 2.0f, range, pie_confirm_radius, pie_confirm_external, subd, NULL, NULL, false);
+ const char col[4] = {btheme->tui.wcol_pie_menu.text_sel[0],
+ btheme->tui.wcol_pie_menu.text_sel[1],
+ btheme->tui.wcol_pie_menu.text_sel[2],
+ 64};
+
+ draw_disk_shaded(angle - range / 2.0f, range, pie_confirm_radius, pie_confirm_external, subd, col, NULL, false);
}
glDisable(GL_BLEND);
- glPopMatrix();
+ gpuPopMatrix();
}
@@ -4108,8 +4270,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
}
- glColor4ubv((unsigned char *)wt->wcol.text);
- UI_fontstyle_draw(fstyle, rect, drawstr);
+ UI_fontstyle_draw(fstyle, rect, drawstr, (unsigned char *)wt->wcol.text);
}
/* part text right aligned */
@@ -4117,7 +4278,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
if (cpoin) {
fstyle->align = UI_STYLE_TEXT_RIGHT;
rect->xmax = _rect.xmax - 5;
- UI_fontstyle_draw(fstyle, rect, cpoin + 1);
+ UI_fontstyle_draw(fstyle, rect, cpoin + 1, (unsigned char *)wt->wcol.text);
*cpoin = UI_SEP_CHAR;
}
}
@@ -4175,7 +4336,6 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
BLI_strncpy(drawstr, name, sizeof(drawstr));
UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
- glColor4ubv((unsigned char *)wt->wcol.text);
- UI_fontstyle_draw(fstyle, &trect, drawstr);
+ UI_fontstyle_draw(fstyle, &trect, drawstr, (unsigned char *)wt->wcol.text);
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 539284030c2..e8eda567a4a 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -53,6 +53,8 @@
#include "BIF_gl.h"
+#include "BLF_api.h"
+
#include "UI_interface.h"
#include "UI_interface_icons.h"
@@ -1272,25 +1274,35 @@ void UI_ThemeColor4(int colorid)
cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
glColor4ubv(cp);
-
}
/* set the color with offset for shades */
void UI_ThemeColorShade(int colorid, int offset)
{
- int r, g, b;
+ unsigned char col[4];
+ UI_GetThemeColorShade4ubv(colorid, offset, col);
+ glColor4ubv(col);
+}
+
+void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
+{
+ int r, g, b, a;
const unsigned char *cp;
cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- r = offset + (int) cp[0];
+ r = coloffset + (int) cp[0];
CLAMP(r, 0, 255);
- g = offset + (int) cp[1];
+ g = coloffset + (int) cp[1];
CLAMP(g, 0, 255);
- b = offset + (int) cp[2];
+ b = coloffset + (int) cp[2];
CLAMP(b, 0, 255);
- glColor4ub(r, g, b, cp[3]);
+ a = alphaoffset + (int) cp[3];
+ CLAMP(a, 0, 255);
+
+ glColor4ub(r, g, b, a);
}
-void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
+
+void UI_GetThemeColorShadeAlpha4ubv(int colorid, int coloffset, int alphaoffset, unsigned char col[4])
{
int r, g, b, a;
const unsigned char *cp;
@@ -1304,7 +1316,11 @@ void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
CLAMP(b, 0, 255);
a = alphaoffset + (int) cp[3];
CLAMP(a, 0, 255);
- glColor4ub(r, g, b, a);
+
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = a;
}
void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned char col[3])
@@ -1320,6 +1336,19 @@ void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned c
col[2] = floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
}
+void UI_GetThemeColorBlend3f(int colorid1, int colorid2, float fac, float r_col[3])
+{
+ const unsigned char *cp1, *cp2;
+
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+
+ CLAMP(fac, 0.0f, 1.0f);
+ r_col[0] = ((1.0f - fac) * cp1[0] + fac * cp2[0]) / 255.0f;
+ r_col[1] = ((1.0f - fac) * cp1[1] + fac * cp2[1]) / 255.0f;
+ r_col[2] = ((1.0f - fac) * cp1[2] + fac * cp2[2]) / 255.0f;
+}
+
/* blend between to theme colors, and set it */
void UI_ThemeColorBlend(int colorid1, int colorid2, float fac)
{
@@ -1372,6 +1401,12 @@ void UI_ThemeColorBlendShadeAlpha(int colorid1, int colorid2, float fac, int off
glColor4ub(r, g, b, a);
}
+void UI_FontThemeColor(int fontid, int colorid)
+{
+ unsigned char color[4];
+ UI_GetThemeColor4ubv(colorid, color);
+ BLF_color4ubv(fontid, color);
+}
/* get individual values, not scaled */
float UI_GetThemeValuef(int colorid)
@@ -1470,6 +1505,111 @@ void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3])
col[2] = b;
}
+void UI_GetThemeColorBlendShade3ubv(int colorid1, int colorid2, float fac, int offset, unsigned char col[3])
+{
+ const unsigned char *cp1, *cp2;
+
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+
+ CLAMP(fac, 0.0f, 1.0f);
+
+ float blend[3];
+ blend[0] = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ blend[1] = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ blend[2] = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+
+ F3TOCHAR3(blend, col);
+}
+
+void UI_GetThemeColorShade4ubv(int colorid, int offset, unsigned char col[4])
+{
+ int r, g, b;
+ const unsigned char *cp;
+
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ r = offset + (int) cp[0];
+ CLAMP(r, 0, 255);
+ g = offset + (int) cp[1];
+ CLAMP(g, 0, 255);
+ b = offset + (int) cp[2];
+ CLAMP(b, 0, 255);
+
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = cp[3];
+}
+
+void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4])
+{
+ int r, g, b, a;
+ const unsigned char *cp;
+
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+
+ r = coloffset + (int) cp[0];
+ CLAMP(r, 0, 255);
+ g = coloffset + (int) cp[1];
+ CLAMP(g, 0, 255);
+ b = coloffset + (int) cp[2];
+ CLAMP(b, 0, 255);
+ a = alphaoffset + (int) cp[3];
+ CLAMP(b, 0, 255);
+
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
+ col[3] = ((float)a) / 255.0f;
+}
+
+void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int offset, float col[3])
+{
+ int r, g, b;
+ const unsigned char *cp1, *cp2;
+
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+
+ CLAMP(fac, 0.0f, 1.0f);
+
+ r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ CLAMP(r, 0, 255);
+ g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ CLAMP(g, 0, 255);
+ b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ CLAMP(b, 0, 255);
+
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
+}
+
+void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4])
+{
+ int r, g, b, a;
+ const unsigned char *cp1, *cp2;
+
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+
+ CLAMP(fac, 0.0f, 1.0f);
+
+ r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ CLAMP(r, 0, 255);
+ g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ CLAMP(g, 0, 255);
+ b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ CLAMP(b, 0, 255);
+ a = offset + floorf((1.0f - fac) * cp1[3] + fac * cp2[3]);
+ CLAMP(a, 0, 255);
+
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
+ col[3] = ((float)a) / 255.0f;
+}
+
/* get the color, in char pointer */
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
{
@@ -1664,6 +1804,8 @@ void init_userdef_do_versions(void)
U.tw_size = 25; /* percentage of window size */
U.tw_handlesize = 16; /* percentage of widget radius */
}
+ if (U.manipulator_scale == 0)
+ U.manipulator_scale = 75;
if (U.pad_rot_angle == 0.0f)
U.pad_rot_angle = 15.0f;
@@ -2764,7 +2906,23 @@ void init_userdef_do_versions(void)
* (keep this block even if it becomes empty).
*/
{
-
+ /* interface_widgets.c */
+ struct uiWidgetColors wcol_tab = {
+ {255, 255, 255, 255},
+ {83, 83, 83, 255},
+ {114, 114, 114, 255},
+ {90, 90, 90, 255},
+
+ {0, 0, 0, 255},
+ {0, 0, 0, 255},
+
+ 0,
+ 0, 0
+ };
+
+ for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
+ btheme->tui.wcol_tab = wcol_tab;
+ }
}
if (U.pixelsize == 0.0f)
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index c78d97ef86f..a12b033c936 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -49,11 +49,11 @@
#include "BKE_screen.h"
#include "BKE_global.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
-#include "BIF_gl.h"
-
#include "BLF_api.h"
#include "ED_screen.h"
@@ -1100,9 +1100,6 @@ void UI_view2d_view_ortho(View2D *v2d)
/* set matrix on all appropriate axes */
wmOrtho2(curmasked.xmin, curmasked.xmax, curmasked.ymin, curmasked.ymax);
-
- /* XXX is this necessary? */
- glLoadIdentity();
}
/**
@@ -1130,9 +1127,6 @@ void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, const bool xaxis)
wmOrtho2(curmasked.xmin - xofs, curmasked.xmax - xofs, -yofs, ar->winy - yofs);
else
wmOrtho2(-xofs, ar->winx - xofs, curmasked.ymin - yofs, curmasked.ymax - yofs);
-
- /* XXX is this necessary? */
- glLoadIdentity();
}
@@ -1144,7 +1138,7 @@ void UI_view2d_view_restore(const bContext *C)
int height = BLI_rcti_size_y(&ar->winrct) + 1;
wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
- glLoadIdentity();
+ gpuLoadIdentity();
// ED_region_pixelspace(CTX_wm_region(C));
}
@@ -1298,12 +1292,45 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
{
float vec1[2], vec2[2];
int a, step;
+ int vertical_minor_step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC),
+ horizontal_major_step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
+ unsigned char grid_line_color[3];
/* check for grid first, as it may not exist */
if (grid == NULL)
return;
- glBegin(GL_LINES);
+ /* Count the needed vertices for the gridlines */
+ unsigned vertex_count = 0;
+ if (flag & V2D_VERTICAL_LINES) {
+ /* vertical lines */
+ vertex_count += 2 * vertical_minor_step; /* minor gridlines */
+ vertex_count += 2 * (vertical_minor_step + 2); /* major gridlines */
+ }
+ if (flag & V2D_HORIZONTAL_LINES) {
+ /* horizontal lines */
+ vertex_count += 2 * (horizontal_major_step + 1); /* major gridlines */
+
+ /* fine lines */
+ if (flag & V2D_HORIZONTAL_FINELINES)
+ vertex_count += 2 * (horizontal_major_step + 1);
+ }
+ /* axes */
+ if (flag & V2D_HORIZONTAL_AXIS)
+ vertex_count += 2;
+ if (flag & V2D_VERTICAL_AXIS)
+ vertex_count += 2;
+
+ /* If there is nothing to render, exit early */
+ if (vertex_count == 0)
+ return;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINES, vertex_count);
/* vertical lines */
if (flag & V2D_VERTICAL_LINES) {
@@ -1313,24 +1340,31 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec2[1] = v2d->cur.ymax;
/* minor gridlines */
- step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
- UI_ThemeColor(TH_GRID);
-
- for (a = 0; a < step; a++) {
- glVertex2fv(vec1);
- glVertex2fv(vec2);
-
- vec2[0] = vec1[0] += grid->dx;
+ step = vertical_minor_step;
+ if (step != 0) {
+ UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
+
+ for (a = 0; a < step; a++) {
+ immSkipAttrib(color);
+ immVertex2fv(pos, vec1);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+
+ vec2[0] = vec1[0] += grid->dx;
+ }
}
/* major gridlines */
vec2[0] = vec1[0] -= 0.5f * grid->dx;
- UI_ThemeColorShade(TH_GRID, 16);
+
+ UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
step++;
for (a = 0; a <= step; a++) {
- glVertex2fv(vec1);
- glVertex2fv(vec2);
+ immSkipAttrib(color);
+ immVertex2fv(pos, vec1);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
vec2[0] = vec1[0] -= grid->dx;
}
@@ -1343,12 +1377,15 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec1[0] = grid->startx;
vec2[0] = v2d->cur.xmax;
- step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
-
- UI_ThemeColor(TH_GRID);
+ step = horizontal_major_step;
+
+ UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
+
for (a = 0; a <= step; a++) {
- glVertex2fv(vec1);
- glVertex2fv(vec2);
+ immSkipAttrib(color);
+ immVertex2fv(pos, vec1);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
vec2[1] = vec1[1] += grid->dy;
}
@@ -1358,10 +1395,12 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
step++;
if (flag & V2D_HORIZONTAL_FINELINES) {
- UI_ThemeColorShade(TH_GRID, 16);
+ UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
for (a = 0; a < step; a++) {
- glVertex2fv(vec1);
- glVertex2fv(vec2);
+ immSkipAttrib(color);
+ immVertex2fv(pos, vec1);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
vec2[1] = vec1[1] -= grid->dy;
}
@@ -1369,7 +1408,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
}
/* Axes are drawn as darker lines */
- UI_ThemeColorShade(TH_GRID, -50);
+ UI_GetThemeColorShade3ubv(TH_GRID, -50, grid_line_color);
/* horizontal axis */
if (flag & V2D_HORIZONTAL_AXIS) {
@@ -1377,8 +1416,10 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec2[0] = v2d->cur.xmax;
vec1[1] = vec2[1] = 0.0f;
- glVertex2fv(vec1);
- glVertex2fv(vec2);
+ immSkipAttrib(color);
+ immVertex2fv(pos, vec1);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
}
/* vertical axis */
@@ -1387,91 +1428,157 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec2[1] = v2d->cur.ymax;
vec1[0] = vec2[0] = 0.0f;
- glVertex2fv(vec1);
- glVertex2fv(vec2);
+ immSkipAttrib(color);
+ immVertex2fv(pos, vec1);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
}
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
/* Draw a constant grid in given 2d-region */
void UI_view2d_constant_grid_draw(View2D *v2d)
{
- float start, step = 25.0f;
-
- UI_ThemeColorShade(TH_BACK, -10);
+ float start_x, start_y, step = 25.0f;
+ int count_x, count_y;
- start = v2d->cur.xmin - (float)fmod(v2d->cur.xmin, step);
+ start_x = v2d->cur.xmin;
+ if (start_x < 0.0)
+ start_x += -(float)fmod(v2d->cur.xmin, step);
+ else
+ start_x += (step - (float)fmod(v2d->cur.xmin, step));
+
+ if (start_x > v2d->cur.xmax)
+ count_x = 0;
+ else
+ count_x = (v2d->cur.xmax - start_x) / step + 1;
+
+ start_y = v2d->cur.ymin;
+ if (start_y < 0.0)
+ start_y += -(float)fmod(v2d->cur.ymin, step);
+ else
+ start_y += (step - (float)fabs(fmod(v2d->cur.ymin, step)));
+
+ if (start_y > v2d->cur.ymax)
+ count_y = 0;
+ else
+ count_y = (v2d->cur.ymax - start_y) / step + 1;
- glBegin(GL_LINES);
- for (; start < v2d->cur.xmax; start += step) {
- glVertex2f(start, v2d->cur.ymin);
- glVertex2f(start, v2d->cur.ymax);
- }
+ if (count_x > 0 || count_y > 0) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+ float theme_color[3];
- start = v2d->cur.ymin - (float)fmod(v2d->cur.ymin, step);
- for (; start < v2d->cur.ymax; start += step) {
- glVertex2f(v2d->cur.xmin, start);
- glVertex2f(v2d->cur.xmax, start);
- }
+ UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINES, count_x * 2 + count_y * 2 + 4);
+
+ immAttrib3fv(color, theme_color);
+ for (int i = 0; i < count_x ; start_x += step, i++) {
+ immVertex2f(pos, start_x, v2d->cur.ymin);
+ immVertex2f(pos, start_x, v2d->cur.ymax);
+ }
+
+ for (int i = 0; i < count_y; start_y += step, i++) {
+ immVertex2f(pos, v2d->cur.xmin, start_y);
+ immVertex2f(pos, v2d->cur.xmax, start_y);
+ }
- /* X and Y axis */
- UI_ThemeColorShade(TH_BACK, -18);
- glVertex2f(0.0f, v2d->cur.ymin);
- glVertex2f(0.0f, v2d->cur.ymax);
- glVertex2f(v2d->cur.xmin, 0.0f);
- glVertex2f(v2d->cur.xmax, 0.0f);
+ /* X and Y axis */
+ UI_GetThemeColorShade3fv(TH_BACK, -18, theme_color);
+
+ immAttrib3fv(color, theme_color);
+ immVertex2f(pos, 0.0f, v2d->cur.ymin);
+ immVertex2f(pos, 0.0f, v2d->cur.ymax);
+ immVertex2f(pos, v2d->cur.xmin, 0.0f);
+ immVertex2f(pos, v2d->cur.xmax, 0.0f);
- glEnd();
+ immEnd();
+ immUnbindProgram();
+ }
}
/* Draw a multi-level grid in given 2d-region */
void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_size, int totlevels)
{
+ /* Exit if there is nothing to draw */
+ if (totlevels == 0)
+ return;
+
int offset = -10;
float lstep = step;
- int level;
+ unsigned char grid_line_color[3];
+
+ /* Make an estimate of at least how many vertices will be needed */
+ unsigned vertex_count = 4;
+ vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
+ vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
glLineWidth(1.0f);
- for (level = 0; level < totlevels; ++level) {
- int i;
- float start;
-
- UI_ThemeColorShade(colorid, offset);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBeginAtMost(PRIM_LINES, vertex_count);
+
+ for (int level = 0; level < totlevels; ++level) {
+ UI_GetThemeColorShade3ubv(colorid, offset, grid_line_color);
- i = (v2d->cur.xmin >= 0.0f ? -(int)(-v2d->cur.xmin / lstep) : (int)(v2d->cur.xmin / lstep));
- start = i * lstep;
+ int i = (int)(v2d->cur.xmin / lstep);
+ if (v2d->cur.xmin > 0.0f)
+ i++;
+ float start = i * lstep;
- glBegin(GL_LINES);
for (; start < v2d->cur.xmax; start += lstep, ++i) {
if (i == 0 || (level < totlevels - 1 && i % level_size == 0))
continue;
- glVertex2f(start, v2d->cur.ymin);
- glVertex2f(start, v2d->cur.ymax);
+
+ immSkipAttrib(color);
+ immVertex2f(pos, start, v2d->cur.ymin);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2f(pos, start, v2d->cur.ymax);
}
- i = (v2d->cur.ymin >= 0.0f ? -(int)(-v2d->cur.ymin / lstep) : (int)(v2d->cur.ymin / lstep));
+ i = (int)(v2d->cur.ymin / lstep);
+ if (v2d->cur.ymin > 0.0f)
+ i++;
start = i * lstep;
for (; start < v2d->cur.ymax; start += lstep, ++i) {
if (i == 0 || (level < totlevels - 1 && i % level_size == 0))
continue;
- glVertex2f(v2d->cur.xmin, start);
- glVertex2f(v2d->cur.xmax, start);
+
+ immSkipAttrib(color);
+ immVertex2f(pos, v2d->cur.xmin, start);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2f(pos, v2d->cur.xmax, start);
}
- /* X and Y axis */
- UI_ThemeColorShade(colorid, offset - 8);
- glVertex2f(0.0f, v2d->cur.ymin);
- glVertex2f(0.0f, v2d->cur.ymax);
- glVertex2f(v2d->cur.xmin, 0.0f);
- glVertex2f(v2d->cur.xmax, 0.0f);
-
- glEnd();
-
lstep *= level_size;
offset -= 6;
}
+
+ /* X and Y axis */
+ UI_GetThemeColorShade3ubv(colorid, -18 + ((totlevels - 1) * -6) , grid_line_color);
+
+ immSkipAttrib(color);
+ immVertex2f(pos, 0.0f, v2d->cur.ymin);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2f(pos, 0.0f, v2d->cur.ymax);
+
+ immSkipAttrib(color);
+ immVertex2f(pos, v2d->cur.xmin, 0.0f);
+ immAttrib3ubv(color, grid_line_color);
+ immVertex2f(pos, v2d->cur.xmax, 0.0f);
+
+ immEnd();
+ immUnbindProgram();
}
/* the price we pay for not exposting structs :( */
@@ -1693,6 +1800,10 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
Scene *scene = CTX_data_scene(C);
rcti vert, hor;
int scroll = view2d_scroll_mapped(v2d->scroll);
+ unsigned char scrollers_back_color[4];
+
+ /* Color for scrollbar backs */
+ UI_GetThemeColor4ubv(TH_BACK, scrollers_back_color);
/* make copies of rects for less typing */
vert = vs->vert;
@@ -1704,7 +1815,6 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
uiWidgetColors wcol = btheme->tui.wcol_scroll;
rcti slider;
int state;
- unsigned char col[4];
slider.xmin = vs->hor_min;
slider.xmax = vs->hor_max;
@@ -1728,16 +1838,23 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
}
/* clean rect behind slider, but not with transparent background */
- UI_GetThemeColor4ubv(TH_BACK, col);
- if (col[3] == 255) {
- glColor3ub(col[0], col[1], col[2]);
- glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax);
+ if (scrollers_back_color[3] == 255) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv(scrollers_back_color);
+ immRecti(pos, v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax);
+
+ immUnbindProgram();
}
UI_draw_widget_scroll(&wcol, &hor, &slider, state);
/* scale indicators */
if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) {
+ const int font_id = BLF_default();
View2DGrid *grid = vs->grid;
float fac, dfac, fac2, val;
@@ -1752,7 +1869,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
dfac = dfac * BLI_rcti_size_x(&hor);
/* set starting value, and text color */
- UI_ThemeColor(TH_TEXT);
+ UI_FontThemeColor(font_id, TH_TEXT);
val = grid->startx;
/* if we're clamping to whole numbers only, make sure entries won't be repeated */
@@ -1764,7 +1881,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
}
if (vs->xunits == V2D_UNIT_FRAMES)
grid->powerx = 1;
-
+
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin);
@@ -1805,7 +1922,6 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
uiWidgetColors wcol = btheme->tui.wcol_scroll;
rcti slider;
int state;
- unsigned char col[4];
slider.xmin = vert.xmin;
slider.xmax = vert.xmax;
@@ -1829,10 +1945,16 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
}
/* clean rect behind slider, but not with transparent background */
- UI_GetThemeColor4ubv(TH_BACK, col);
- if (col[3] == 255) {
- glColor3ub(col[0], col[1], col[2]);
- glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax);
+ if (scrollers_back_color[3] == 255) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv(scrollers_back_color);
+ immRecti(pos, v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax);
+
+ immUnbindProgram();
}
UI_draw_widget_scroll(&wcol, &vert, &slider, state);
@@ -1856,7 +1978,8 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
dfac = dfac * BLI_rcti_size_y(&vert);
/* set starting value, and text color */
- UI_ThemeColor(TH_TEXT);
+ const int font_id = BLF_default();
+ UI_FontThemeColor(font_id, TH_TEXT);
val = grid->starty;
/* if vertical clamping (to whole numbers) is used (i.e. in Sequencer), apply correction */
@@ -1865,9 +1988,8 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw vertical steps */
if (dfac > 0.0f) {
-
- BLF_rotation_default(M_PI_2);
- BLF_enable_default(BLF_ROTATION);
+ BLF_rotation(font_id, M_PI_2);
+ BLF_enable(font_id, BLF_ROTATION);
for (; fac < vert.ymax - 10; fac += dfac, val += grid->dy) {
@@ -1878,7 +2000,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
scroll_printstr(scene, (float)(vert.xmax) - 2.0f, fac, val, grid->powery, vs->yunits, 'v');
}
- BLF_disable_default(BLF_ROTATION);
+ BLF_disable(font_id, BLF_ROTATION);
}
}
}
@@ -2392,7 +2514,8 @@ void UI_view2d_text_cache_draw(ARegion *ar)
int col_pack_prev = 0;
/* investigate using BLF_ascender() */
- const float default_height = g_v2d_strings ? BLF_height_default("28", 3) : 0.0f;
+ const int font_id = BLF_default();
+ const float default_height = g_v2d_strings ? BLF_height(font_id, "28", 3) : 0.0f;
wmOrtho2_region_pixelspace(ar);
@@ -2403,7 +2526,7 @@ void UI_view2d_text_cache_draw(ARegion *ar)
if (yofs < 1) yofs = 1;
if (col_pack_prev != v2s->col.pack) {
- glColor3ubv(v2s->col.ub);
+ BLF_color3ubv(font_id, v2s->col.ub);
col_pack_prev = v2s->col.pack;
}
@@ -2411,11 +2534,11 @@ void UI_view2d_text_cache_draw(ARegion *ar)
BLF_draw_default((float)(v2s->mval[0] + xofs), (float)(v2s->mval[1] + yofs), 0.0,
v2s->str, BLF_DRAW_STR_DUMMY_MAX);
else {
- BLF_clipping_default(v2s->rect.xmin - 4, v2s->rect.ymin - 4, v2s->rect.xmax + 4, v2s->rect.ymax + 4);
- BLF_enable_default(BLF_CLIPPING);
+ BLF_enable(font_id, BLF_CLIPPING);
+ BLF_clipping(font_id, v2s->rect.xmin - 4, v2s->rect.ymin - 4, v2s->rect.xmax + 4, v2s->rect.ymax + 4);
BLF_draw_default(v2s->rect.xmin + xofs, v2s->rect.ymin + yofs, 0.0f,
v2s->str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_disable_default(BLF_CLIPPING);
+ BLF_disable(font_id, BLF_CLIPPING);
}
}
g_v2d_strings = NULL;
@@ -2424,11 +2547,6 @@ void UI_view2d_text_cache_draw(ARegion *ar)
BLI_memarena_free(g_v2d_strings_arena);
g_v2d_strings_arena = NULL;
}
-
- // glMatrixMode(GL_PROJECTION);
- // glPopMatrix();
- // glMatrixMode(GL_MODELVIEW);
- // glPopMatrix();
}
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 139c9817437..ba3966d5af6 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -87,7 +87,6 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int include_shapekeys;
int deform_bones_only;
- int include_uv_textures;
int include_material_textures;
int use_texture_copies;
int active_uv_only;
@@ -139,7 +138,6 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys");
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
- include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies");
active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only");
@@ -159,6 +157,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
export_count = collada_export(CTX_data_scene(C),
+ CTX_data_scene_layer(C),
filepath,
apply_modifiers,
export_mesh_type,
@@ -169,7 +168,6 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
deform_bones_only,
active_uv_only,
- include_uv_textures,
include_material_textures,
use_texture_copies,
@@ -241,9 +239,6 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
@@ -372,9 +367,6 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map",
"Export only the selected UV Map");
- RNA_def_boolean(func, "include_uv_textures", 0, "Include UV Textures",
- "Export textures assigned to the object UV Maps");
-
RNA_def_boolean(func, "include_material_textures", 0, "Include Material Textures",
"Export textures assigned to the object Materials");
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index be7eb2bf9ed..b3e6a369d90 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -36,6 +36,7 @@
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_task.h"
+#include "BLI_listbase.h"
#include "BKE_context.h"
#include "BKE_mask.h"
@@ -48,10 +49,13 @@
#include "ED_clip.h"
#include "ED_mask.h" /* own include */
#include "ED_space_api.h"
-#include "BIF_gl.h"
+
#include "BIF_glutil.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+#include "GPU_shader.h"
+#include "GPU_matrix.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -93,40 +97,6 @@ static void mask_spline_feather_color_get(MaskLayer *UNUSED(masklay), MaskSpline
r_rgb[3] = 255;
}
-#if 0
-static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline)
-{
- int i;
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
-
- if (!spline->tot_point)
- return;
-
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(1, 0xAAAA);
-
- glColor3ub(0, 0, 0);
- glBegin(GL_LINES);
-
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &points_array[i];
- BezTriple *bezt = &point->bezt;
-
- if (point->parent.id) {
- glVertex2f(bezt->vec[1][0],
- bezt->vec[1][1]);
-
- glVertex2f(bezt->vec[1][0] - point->parent.offset[0],
- bezt->vec[1][1] - point->parent.offset[1]);
- }
- }
-
- glEnd();
-
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
-}
-#endif
-
static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], const float co[2])
{
BKE_mask_coord_to_movieclip(sc->clip, &sc->user, r_co, co);
@@ -134,46 +104,9 @@ static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], const float c
BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co);
}
-static void draw_circle(const float x, const float y,
- const float size, const bool fill,
- const float xscale, const float yscale)
-{
- static GLuint wire_displist = 0;
- static GLuint fill_displist = 0;
- GLuint displist = fill ? fill_displist : wire_displist;
-
- /* Initialize round circle shape. */
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, fill ? GLU_FILL : GLU_SILHOUETTE);
- gluDisk(qobj, 0, 0.7, 8, 1);
- gluDeleteQuadric(qobj);
-
- glEndList();
-
- if (fill) {
- fill_displist = displist;
- }
- else {
- wire_displist = displist;
- }
- }
-
- glPushMatrix();
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * size, 1.0f / yscale * size, 1.0f);
- glCallList(displist);
- glPopMatrix();
-}
-
static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoint *point,
const eMaskWhichHandle which_handle, const int draw_type,
- const float handle_size, const float xscale, const float yscale,
+ const float handle_size,
const float point_pos[2], const float handle_pos[2])
{
const BezTriple *bezt = &point->bezt;
@@ -190,54 +123,70 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin
return;
}
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff};
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ubv(rgb_gray);
+
/* this could be split into its own loop */
if (draw_type == MASK_DT_OUTLINE) {
- const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff};
- glLineWidth(3);
- glColor4ubv(rgb_gray);
- glBegin(GL_LINES);
- glVertex2fv(point_pos);
- glVertex2fv(handle_pos);
- glEnd();
+ glLineWidth(3.0f);
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, point_pos);
+ immVertex2fv(pos, handle_pos);
+ immEnd();
}
switch (handle_type) {
case HD_FREE:
- UI_ThemeColor(TH_HANDLE_FREE);
+ immUniformThemeColor(TH_HANDLE_FREE);
break;
case HD_AUTO:
- UI_ThemeColor(TH_HANDLE_AUTO);
+ immUniformThemeColor(TH_HANDLE_AUTO);
break;
case HD_ALIGN:
case HD_ALIGN_DOUBLESIDE:
- UI_ThemeColor(TH_HANDLE_ALIGN);
+ immUniformThemeColor(TH_HANDLE_ALIGN);
break;
}
- glLineWidth(1);
- glBegin(GL_LINES);
- glVertex2fv(point_pos);
- glVertex2fv(handle_pos);
- glEnd();
+ glLineWidth(1.0f);
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, point_pos);
+ immVertex2fv(pos, handle_pos);
+ immEnd();
+ immUnbindProgram();
/* draw handle points */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniform1f("size", handle_size);
+ immUniform1f("outlineWidth", 1.5f);
+
+ float point_color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; /* active color by default */
if (MASKPOINT_ISSEL_HANDLE(point, which_handle)) {
- if (point == mask_layer->act_point)
- glColor3f(1.0f, 1.0f, 1.0f);
- else
- UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
+ if (point != mask_layer->act_point) {
+ UI_GetThemeColor3fv(TH_HANDLE_VERTEX_SELECT, point_color);
+ }
}
else {
- UI_ThemeColor(TH_HANDLE_VERTEX);
+ UI_GetThemeColor3fv(TH_HANDLE_VERTEX, point_color);
}
- draw_circle(handle_pos[0], handle_pos[1], handle_size, false, xscale, yscale);
+ immUniform4fv("outlineColor", point_color);
+ immUniformColor3fvAlpha(point_color, 0.25f);
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex2fv(pos, handle_pos);
+ immEnd();
+
+ immUnbindProgram();
}
/* return non-zero if spline is selected */
static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
- const char draw_flag, const char draw_type,
- const float xscale, const float yscale)
+ const char draw_flag, const char draw_type)
{
const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0;
const bool is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH) != 0;
@@ -247,7 +196,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
SpaceClip *sc = CTX_wm_space_clip(C);
bool undistort = false;
- int i, handle_size, tot_feather_point;
+ int tot_feather_point;
float (*feather_points)[2], (*fp)[2];
float min[2], max[2];
@@ -258,22 +207,24 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT);
/* TODO, add this to sequence editor */
- handle_size = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
-
- glPointSize(handle_size);
+ float handle_size = 2.0f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ immUniform1f("size", 0.7f * handle_size);
+
/* feather points */
feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point);
- for (i = 0; i < spline->tot_point; i++) {
+ for (int i = 0; i < spline->tot_point; i++) {
/* watch it! this is intentionally not the deform array, only check for sel */
MaskSplinePoint *point = &spline->points[i];
- int j;
-
- for (j = 0; j <= point->tot_uw; j++) {
+ for (int j = 0; j <= point->tot_uw; j++) {
float feather_point[2];
bool sel = false;
@@ -291,32 +242,32 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
if (sel) {
if (point == masklay->act_point)
- glColor3f(1.0f, 1.0f, 1.0f);
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
else
- UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
+ immUniformThemeColor(TH_HANDLE_VERTEX_SELECT);
}
else {
- UI_ThemeColor(TH_HANDLE_VERTEX);
+ immUniformThemeColor(TH_HANDLE_VERTEX);
}
- glBegin(GL_POINTS);
- glVertex2fv(feather_point);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex2fv(pos, feather_point);
+ immEnd();
fp++;
}
}
MEM_freeN(feather_points);
+ immUnbindProgram();
+
if (is_smooth) {
glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
/* control points */
INIT_MINMAX2(min, max);
- for (i = 0; i < spline->tot_point; i++) {
+ for (int i = 0; i < spline->tot_point; i++) {
/* watch it! this is intentionally not the deform array, only check for sel */
MaskSplinePoint *point = &spline->points[i];
@@ -339,7 +290,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
mask_point_undistort_pos(sc, handle, handle);
}
draw_single_handle(masklay, point, MASK_WHICH_HANDLE_STICK,
- draw_type, handle_size, xscale, yscale, vert, handle);
+ draw_type, handle_size, vert, handle);
}
else {
float handle_left[2], handle_right[2];
@@ -350,53 +301,62 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
mask_point_undistort_pos(sc, handle_left, handle_left);
}
draw_single_handle(masklay, point, MASK_WHICH_HANDLE_LEFT,
- draw_type, handle_size, xscale, yscale, vert, handle_left);
+ draw_type, handle_size, vert, handle_left);
draw_single_handle(masklay, point, MASK_WHICH_HANDLE_RIGHT,
- draw_type, handle_size, xscale, yscale, vert, handle_right);
+ draw_type, handle_size, vert, handle_right);
}
+ /* bind program in loop so it does not interfere with draw_single_handle */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+
/* draw CV point */
if (MASKPOINT_ISSEL_KNOT(point)) {
if (point == masklay->act_point)
- glColor3f(1.0f, 1.0f, 1.0f);
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
else
- UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
+ immUniformThemeColor(TH_HANDLE_VERTEX_SELECT);
}
else
- UI_ThemeColor(TH_HANDLE_VERTEX);
+ immUniformThemeColor(TH_HANDLE_VERTEX);
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex2fv(pos, vert);
+ immEnd();
- glBegin(GL_POINTS);
- glVertex2fv(vert);
- glEnd();
+ immUnbindProgram();
minmax_v2v2_v2(min, max, vert);
}
+ if (is_smooth) {
+ glDisable(GL_LINE_SMOOTH);
+ }
+
if (is_spline_sel) {
- float x = (min[0] + max[0]) / 2.0f;
- float y = (min[1] + max[1]) / 2.0f;
- /* TODO(sergey): Remove hardcoded colors. */
+ float x = (min[0] + max[0]) * 0.5f;
+ float y = (min[1] + max[1]) * 0.5f;
+
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniform1f("outlineWidth", 1.5f);
+
if (masklay->act_spline == spline) {
- glColor3ub(255, 255, 255);
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
}
else {
- glColor3ub(255, 255, 0);
+ immUniformColor3f(1.0f, 1.0f, 0.0f);
}
- draw_circle(x, y, 6.0f, true, xscale, yscale);
+ immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
+ immUniform1f("size", 12.0f);
- glColor3ub(0, 0, 0);
- draw_circle(x, y, 6.0f, false, xscale, yscale);
- }
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(pos, x, y);
+ immEnd();
- if (is_smooth) {
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ immUnbindProgram();
}
}
-/* #define USE_XOR */
-
static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char rgb[4], const bool is_active)
{
if (!is_active) {
@@ -410,13 +370,21 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r
}
}
+static void mask_draw_array(unsigned int pos, PrimitiveType prim_type, const float (*points)[2], unsigned int vertex_ct)
+{
+ immBegin(prim_type, vertex_ct);
+ for (unsigned int i = 0; i < vertex_ct; ++i) {
+ immVertex2fv(pos, points[i]);
+ }
+ immEnd();
+}
+
static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*orig_points)[2], int tot_point,
- const bool is_feather, const bool is_smooth, const bool is_active,
+ const bool is_feather, const bool is_active,
const unsigned char rgb_spline[4], const char draw_type)
{
- const int draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GL_LINE_LOOP : GL_LINE_STRIP;
+ const PrimitiveType draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? PRIM_LINE_LOOP : PRIM_LINE_STRIP;
const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff};
-// const unsigned char rgb_white[4] = {0xff, 0xff, 0xff, 0xff};
unsigned char rgb_tmp[4];
SpaceClip *sc = CTX_wm_space_clip(C);
float (*points)[2] = orig_points;
@@ -425,65 +393,45 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
const bool undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT);
if (undistort) {
- int i;
-
points = MEM_callocN(2 * tot_point * sizeof(float), "undistorthed mask curve");
- for (i = 0; i < tot_point; i++) {
+ for (int i = 0; i < tot_point; i++) {
mask_point_undistort_pos(sc, points[i], orig_points[i]);
}
}
}
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, points);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
switch (draw_type) {
case MASK_DT_OUTLINE:
- glLineWidth(3);
-
- mask_color_active_tint(rgb_tmp, rgb_black, is_active);
- glColor4ubv(rgb_tmp);
-
- glDrawArrays(draw_method, 0, tot_point);
+ /* TODO(merwin): use fancy line shader here
+ * probably better with geometry shader (after core profile switch)
+ */
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glLineWidth(1);
- mask_color_active_tint(rgb_tmp, rgb_spline, is_active);
- glColor4ubv(rgb_tmp);
- glDrawArrays(draw_method, 0, tot_point);
+ glLineWidth(3.0f);
- break;
+ mask_color_active_tint(rgb_tmp, rgb_black, is_active);
+ immUniformColor4ubv(rgb_tmp);
+ mask_draw_array(pos, draw_method, points, tot_point);
- case MASK_DT_DASH:
- default:
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
+ glLineWidth(1.0f);
-#ifdef USE_XOR
- glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_OR);
-#endif
mask_color_active_tint(rgb_tmp, rgb_spline, is_active);
- glColor4ubv(rgb_tmp);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, points);
- glDrawArrays(draw_method, 0, tot_point);
-
-#ifdef USE_XOR
- glDisable(GL_COLOR_LOGIC_OP);
-#endif
- mask_color_active_tint(rgb_tmp, rgb_black, is_active);
- glColor4ubv(rgb_tmp);
- GPU_basic_shader_line_stipple(3, 0x5555);
- glDrawArrays(draw_method, 0, tot_point);
+ immUniformColor4ubv(rgb_tmp);
+ mask_draw_array(pos, draw_method, points, tot_point);
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ immUnbindProgram();
break;
-
case MASK_DT_BLACK:
case MASK_DT_WHITE:
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ glLineWidth(1.0f);
+
if (draw_type == MASK_DT_BLACK) { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 0; }
else { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 255; }
/* alpha values seem too low but gl draws many points that compensate for it */
@@ -496,26 +444,39 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
rgb_tmp[2] = (unsigned char)(((short)rgb_tmp[2] + (short)rgb_spline[2]) / 2);
}
- if (is_smooth == false && is_feather) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
mask_color_active_tint(rgb_tmp, rgb_tmp, is_active);
- glColor4ubv(rgb_tmp);
+ immUniformColor4ubv(rgb_tmp);
+ mask_draw_array(pos, draw_method, points, tot_point);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, points);
- glDrawArrays(draw_method, 0, tot_point);
+ immUnbindProgram();
+ break;
- if (is_smooth == false && is_feather) {
- glDisable(GL_BLEND);
- }
+ case MASK_DT_DASH:
+ /* TODO(merwin): use dashed line shader here
+ * probably better with geometry shader (after core profile switch)
+ */
+#if 0
+ glLineWidth(1.0f);
+
+ GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ GPU_basic_shader_line_stipple(3, 0xAAAA);
+ mask_color_active_tint(rgb_tmp, rgb_spline, is_active);
+ immUniformColor4ubv(rgb_tmp);
+ mask_draw_array(pos, draw_method, points, tot_point);
+
+ mask_color_active_tint(rgb_tmp, rgb_black, is_active);
+ immUniformColor4ubv(rgb_tmp);
+ GPU_basic_shader_line_stipple(3, 0x5555);
+ mask_draw_array(pos, draw_method, points, tot_point);
+
+ GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+#endif
break;
- }
- glDisableClientState(GL_VERTEX_ARRAY);
+ default:
+ BLI_assert(false);
+ }
if (points != orig_points)
MEM_freeN(points);
@@ -548,8 +509,6 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
if (is_smooth) {
glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, &tot_feather_point, resol, (is_fill != false));
@@ -557,26 +516,24 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
/* draw feather */
mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp);
mask_draw_curve_type(C, spline, feather_points, tot_feather_point,
- true, is_smooth, is_active,
+ true, is_active,
rgb_tmp, draw_type);
if (!is_fill) {
-
const float *fp = &diff_points[0][0];
float *fp_feather = &feather_points[0][0];
- float tvec[2];
- int i;
BLI_assert(tot_diff_point == tot_feather_point);
- for (i = 0; i < tot_diff_point; i++, fp += 2, fp_feather += 2) {
+ for (int i = 0; i < tot_diff_point; i++, fp += 2, fp_feather += 2) {
+ float tvec[2];
sub_v2_v2v2(tvec, fp, fp_feather);
add_v2_v2v2(fp_feather, fp, tvec);
}
/* same as above */
mask_draw_curve_type(C, spline, feather_points, tot_feather_point,
- true, is_smooth, is_active,
+ true, is_active,
rgb_tmp, draw_type);
}
@@ -585,21 +542,22 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
/* draw main curve */
mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp);
mask_draw_curve_type(C, spline, diff_points, tot_diff_point,
- false, is_smooth, is_active,
+ false, is_active,
rgb_tmp, draw_type);
MEM_freeN(diff_points);
- if (draw_flag & MASK_DRAWFLAG_SMOOTH) {
+ if (is_smooth) {
glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
}
-
- (void)draw_type;
}
static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, const char draw_type,
- const int width, const int height, const float xscale, const float yscale)
+ const int width, const int height)
{
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_enable_program_point_size();
+
MaskLayer *masklay;
int i;
@@ -616,11 +574,9 @@ static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, c
/* draw curve itself first... */
draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height);
-// draw_spline_parents(masklay, spline);
-
if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) {
/* ...and then handles over the curve so they're nicely visible */
- draw_spline_points(C, masklay, spline, draw_flag, draw_type, xscale, yscale);
+ draw_spline_points(C, masklay, spline, draw_flag, draw_type);
}
/* show undeform for testing */
@@ -629,33 +585,29 @@ static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, c
spline->points_deform = NULL;
draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height);
-// draw_spline_parents(masklay, spline);
- draw_spline_points(C, masklay, spline, draw_flag, draw_type, xscale, yscale);
+ draw_spline_points(C, masklay, spline, draw_flag, draw_type);
spline->points_deform = back;
}
}
}
+
+ GPU_disable_program_point_size();
+ glDisable(GL_BLEND);
}
void ED_mask_draw(const bContext *C,
const char draw_flag, const char draw_type)
{
ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
-
Mask *mask = CTX_data_edit_mask(C);
int width, height;
- float aspx, aspy;
- float xscale, yscale;
if (!mask)
return;
ED_mask_get_size(sa, &width, &height);
- ED_mask_get_aspect(sa, ar, &aspx, &aspy);
- UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
- draw_masklays(C, mask, draw_flag, draw_type, width, height, xscale * aspx, yscale * aspy);
+ draw_masklays(C, mask, draw_flag, draw_type, width, height);
}
typedef struct ThreadedMaskRasterizeState {
@@ -802,28 +754,26 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
}
if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
+ float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
float *buffer = threaded_mask_rasterize(mask, width, height);
- int format;
- if (overlay_mode == MASK_OVERLAY_ALPHACHANNEL) {
- glColor3f(1.0f, 1.0f, 1.0f);
- format = GL_LUMINANCE;
- }
- else {
+ if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
/* More blending types could be supported in the future. */
glEnable(GL_BLEND);
- glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
- format = GL_ALPHA;
+ glBlendFunc(GL_DST_COLOR, GL_ZERO);
}
- glPushMatrix();
- glTranslatef(x, y, 0);
- glScalef(zoomx, zoomy, 0);
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+ gpuScale2f(zoomx, zoomy);
if (stabmat) {
- glMultMatrixf(stabmat);
+ gpuMultMatrix(stabmat);
}
- glaDrawPixelsTex(0.0f, 0.0f, width, height, format, GL_FLOAT, GL_NEAREST, buffer);
- glPopMatrix();
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
+ immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_RED, GL_FLOAT, GL_NEAREST, buffer, 1.0f, 1.0f, NULL);
+
+ gpuPopMatrix();
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
glDisable(GL_BLEND);
@@ -833,26 +783,26 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
}
/* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
- glPushMatrix();
- glTranslatef(x + xofs, y + yofs, 0);
- glScalef(zoomx, zoomy, 0);
+ gpuPushMatrix();
+ gpuTranslate2f(x + xofs, y + yofs);
+ gpuScale2f(zoomx, zoomy);
if (stabmat) {
- glMultMatrixf(stabmat);
+ gpuMultMatrix(stabmat);
}
- glScalef(maxdim, maxdim, 0);
+ gpuScale2f(maxdim, maxdim);
if (do_draw_cb) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
}
/* draw! */
- draw_masklays(C, mask, draw_flag, draw_type, width, height, maxdim * zoomx, maxdim * zoomy);
+ draw_masklays(C, mask, draw_flag, draw_type, width, height);
if (do_draw_cb) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
}
- glPopMatrix();
+ gpuPopMatrix();
}
void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra, const int efra)
@@ -861,25 +811,31 @@ void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra
MaskLayer *masklay = BKE_mask_layer_active(mask);
- glBegin(GL_LINES);
- glColor4ub(255, 175, 0, 255);
-
if (masklay) {
- MaskLayerShape *masklay_shape;
-
- for (masklay_shape = masklay->splines_shapes.first;
- masklay_shape;
- masklay_shape = masklay_shape->next)
- {
- int frame = masklay_shape->frame;
-
- /* draw_keyframe(i, CFRA, sfra, framelen, 1); */
- int height = (frame == cfra) ? 22 : 10;
- int x = (frame - sfra) * framelen;
- glVertex2i(x, 0);
- glVertex2i(x, height);
+ unsigned int num_lines = BLI_listbase_count(&masklay->splines_shapes);
+
+ if (num_lines > 0) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ub(255, 175, 0, 255);
+
+ immBegin(PRIM_LINES, 2 * num_lines);
+
+ for (MaskLayerShape *masklay_shape = masklay->splines_shapes.first;
+ masklay_shape;
+ masklay_shape = masklay_shape->next)
+ {
+ int frame = masklay_shape->frame;
+
+ /* draw_keyframe(i, CFRA, sfra, framelen, 1); */
+ int height = (frame == cfra) ? 22 : 10;
+ int x = (frame - sfra) * framelen;
+ immVertex2i(pos, x, 0);
+ immVertex2i(pos, x, height);
+ }
+ immEnd();
+ immUnbindProgram();
}
}
-
- glEnd();
}
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index a478526dee0..52ec22aaaf0 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -106,6 +106,8 @@ void paintface_flush_flags(Object *ob, short flag)
/* draw-object caches hidden faces, force re-generation T46867 */
GPU_drawobject_free(dm);
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_PAINT);
}
void paintface_hide(Object *ob, const bool unselected)
@@ -387,7 +389,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
}
/* image window redraw */
-
+
paintface_flush_flags(ob, SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
@@ -515,6 +517,8 @@ void paintvert_flush_flags(Object *ob)
dm_mv->flag = me->mvert[i].flag;
}
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_PAINT);
}
/* note: if the caller passes false to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */
void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index bf59693b856..3fe7c1d1c99 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -54,8 +54,8 @@
#include "BKE_editmesh_bvh.h"
#include "BKE_report.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h" /* for paint cursor */
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -1002,12 +1002,18 @@ static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
copy_v3_v3(v2, ray_hit_best[1]);
}
- UI_ThemeColor(TH_TRANSFORM);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_TRANSFORM);
glLineWidth(2.0);
- glBegin(GL_LINES);
- glVertex3fv(v1);
- glVertex3fv(v2);
- glEnd();
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immEnd();
+
+ immUnbindProgram();
}
static void knife_init_colors(KnifeColors *colors)
@@ -1035,66 +1041,69 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
glPolygonOffset(1.0f, 1.0f);
- glPushMatrix();
- glMultMatrixf(kcd->ob->obmat);
+ gpuPushMatrix();
+ gpuMultMatrix(kcd->ob->obmat);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (kcd->mode == MODE_DRAGGING) {
if (kcd->is_angle_snapping)
knifetool_draw_angle_snapping(kcd);
- glColor3ubv(kcd->colors.line);
-
+ immUniformColor3ubv(kcd->colors.line);
glLineWidth(2.0);
- glBegin(GL_LINES);
- glVertex3fv(kcd->prev.cage);
- glVertex3fv(kcd->curr.cage);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, kcd->prev.cage);
+ immVertex3fv(pos, kcd->curr.cage);
+ immEnd();
}
if (kcd->prev.vert) {
- glColor3ubv(kcd->colors.point);
+ immUniformColor3ubv(kcd->colors.point);
glPointSize(11);
- glBegin(GL_POINTS);
- glVertex3fv(kcd->prev.cage);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, kcd->prev.cage);
+ immEnd();
}
if (kcd->prev.bmface) {
- glColor3ubv(kcd->colors.curpoint);
+ immUniformColor3ubv(kcd->colors.curpoint);
glPointSize(9);
- glBegin(GL_POINTS);
- glVertex3fv(kcd->prev.cage);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, kcd->prev.cage);
+ immEnd();
}
if (kcd->curr.edge) {
- glColor3ubv(kcd->colors.edge);
+ immUniformColor3ubv(kcd->colors.edge);
glLineWidth(2.0);
- glBegin(GL_LINES);
- glVertex3fv(kcd->curr.edge->v1->cageco);
- glVertex3fv(kcd->curr.edge->v2->cageco);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, kcd->curr.edge->v1->cageco);
+ immVertex3fv(pos, kcd->curr.edge->v2->cageco);
+ immEnd();
}
else if (kcd->curr.vert) {
- glColor3ubv(kcd->colors.point);
+ immUniformColor3ubv(kcd->colors.point);
glPointSize(11);
- glBegin(GL_POINTS);
- glVertex3fv(kcd->curr.cage);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, kcd->curr.cage);
+ immEnd();
}
if (kcd->curr.bmface) {
- glColor3ubv(kcd->colors.curpoint);
+ immUniformColor3ubv(kcd->colors.curpoint);
glPointSize(9);
- glBegin(GL_POINTS);
- glVertex3fv(kcd->curr.cage);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, kcd->curr.cage);
+ immEnd();
}
if (kcd->totlinehit > 0) {
@@ -1105,26 +1114,35 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* draw any snapped verts first */
- glColor4ubv(kcd->colors.point_a);
+ immUniformColor4ubv(kcd->colors.point_a);
glPointSize(11);
- glBegin(GL_POINTS);
+
+ immBeginAtMost(PRIM_POINTS, kcd->totlinehit);
+
lh = kcd->linehits;
for (i = 0; i < kcd->totlinehit; i++, lh++) {
- if (lh->v)
- glVertex3fv(lh->cagehit);
+ if (lh->v) {
+ immVertex3fv(pos, lh->cagehit);
+ }
}
- glEnd();
+
+ immEnd();
/* now draw the rest */
- glColor4ubv(kcd->colors.curpoint_a);
+ immUniformColor4ubv(kcd->colors.curpoint_a);
glPointSize(7);
- glBegin(GL_POINTS);
+
+ immBeginAtMost(PRIM_POINTS, kcd->totlinehit);
+
lh = kcd->linehits;
for (i = 0; i < kcd->totlinehit; i++, lh++) {
- if (!lh->v)
- glVertex3fv(lh->cagehit);
+ if (!lh->v) {
+ immVertex3fv(pos, lh->cagehit);
+ }
}
- glEnd();
+
+ immEnd();
+
glDisable(GL_BLEND);
}
@@ -1132,44 +1150,46 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
BLI_mempool_iter iter;
KnifeEdge *kfe;
+ immUniformColor3ubv(kcd->colors.line);
glLineWidth(1.0);
- glBegin(GL_LINES);
+
+ immBeginAtMost(PRIM_LINES, BLI_mempool_count(kcd->kedges) * 2);
BLI_mempool_iternew(kcd->kedges, &iter);
for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
if (!kfe->is_cut)
continue;
- glColor3ubv(kcd->colors.line);
-
- glVertex3fv(kfe->v1->cageco);
- glVertex3fv(kfe->v2->cageco);
+ immVertex3fv(pos, kfe->v1->cageco);
+ immVertex3fv(pos, kfe->v2->cageco);
}
- glEnd();
+ immEnd();
}
if (kcd->totkvert > 0) {
BLI_mempool_iter iter;
KnifeVert *kfv;
+ immUniformColor3ubv(kcd->colors.point);
glPointSize(5.0);
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, BLI_mempool_count(kcd->kverts));
+
BLI_mempool_iternew(kcd->kverts, &iter);
for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
if (!kfv->is_cut)
continue;
- glColor3ubv(kcd->colors.point);
-
- glVertex3fv(kfv->cageco);
+ immVertex3fv(pos, kfv->cageco);
}
- glEnd();
+ immEnd();
}
- glPopMatrix();
+ immUnbindProgram();
+
+ gpuPopMatrix();
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -1396,7 +1416,7 @@ static bool bm_ray_cast_cb_elem_not_in_face_check(BMFace *f, void *user_data)
* intersecting faces matching this face (or connected when an vert/edge) will be ignored.
*/
static bool point_is_visible(
- KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats,
+ KnifeTool_OpData *kcd, const float p[3], const float s[2],
BMElem *ele_test)
{
BMFace *f_hit;
@@ -1414,7 +1434,7 @@ static bool point_is_visible(
float view[3], p_ofs[3];
/* TODO: I think there's a simpler way to get the required raycast ray */
- ED_view3d_unproject(mats, view, s[0], s[1], 0.0f);
+ ED_view3d_unproject(kcd->vc.ar, s[0], s[1], 0.0f, view);
mul_m4_v3(kcd->ob->imat, view);
@@ -1487,7 +1507,6 @@ static void set_linehit_depth(KnifeTool_OpData *kcd, KnifeLineHit *lh)
/* Finds visible (or all, if cutting through) edges that intersects the current screen drag line */
static void knife_find_line_hits(KnifeTool_OpData *kcd)
{
- bglMats mats;
SmallHash faces, kfes, kfvs;
float v1[3], v2[3], v3[3], v4[3], s1[2], s2[2];
BVHTree *planetree, *tree;
@@ -1517,8 +1536,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
const bool use_hit_prev = true;
const bool use_hit_curr = (kcd->is_drag_hold == false);
- bgl_get_mats(&mats);
-
if (kcd->linehits) {
MEM_freeN(kcd->linehits);
kcd->linehits = NULL;
@@ -1647,7 +1664,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
knife_project_v2(kcd, v->cageco, s);
d = dist_squared_to_line_segment_v2(s, s1, s2);
if ((d <= vert_tol_sq) &&
- (point_is_visible(kcd, v->cageco, s, &mats, bm_elem_from_knife_vert(v, &kfe_hit))))
+ (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit))))
{
memset(&hit, 0, sizeof(hit));
hit.v = v;
@@ -1710,7 +1727,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
* Need to find 3d intersection of ray through sint */
knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
isect_kind = isect_line_line_v3(kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_tmp);
- if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, &mats, bm_elem_from_knife_edge(kfe))) {
+ if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, bm_elem_from_knife_edge(kfe))) {
memset(&hit, 0, sizeof(hit));
if (kcd->snap_midpoints) {
/* choose intermediate point snap too */
@@ -1739,7 +1756,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
float p[3], p_cage[3];
if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s1, &mats, (BMElem *)f)) {
+ if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
copy_v3_v3(hit.hit, p);
@@ -1751,7 +1768,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s2, &mats, (BMElem *)f)) {
+ if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
copy_v3_v3(hit.hit, p);
@@ -1784,13 +1801,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_origin_ofs[3])
{
- bglMats mats;
-
- bgl_get_mats(&mats);
-
/* unproject to find view ray */
- ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
- ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
+ ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], 0.0f, r_origin);
+ ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], ofs, r_origin_ofs);
/* transform into object space */
invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
@@ -2992,7 +3005,6 @@ static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
{
KnifeTool_OpData *kcd;
- bglMats mats;
view3d_operator_needs_opengl(C);
@@ -3011,10 +3023,6 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
if (use_tag) {
BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
}
-
- if (kcd->cut_through == false) {
- bgl_get_mats(&mats);
- }
}
/* execute */
@@ -3123,7 +3131,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
float cent[3], cent_ss[2];
BM_face_calc_point_in_face(f, cent);
knife_project_v2(kcd, cent, cent_ss);
- if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats, (BMElem *)f)) &&
+ if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, (BMElem *)f)) &&
edbm_mesh_knife_point_isect(polys, cent_ss))
{
BM_elem_flag_enable(f, BM_ELEM_TAG);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index f1c1e4105d0..e7a6689b57c 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -45,7 +45,8 @@
#include "BKE_DerivedMesh.h"
#include "BKE_unit.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "UI_interface.h"
@@ -104,27 +105,41 @@ static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
if (v3d && v3d->zbuf)
glDisable(GL_DEPTH_TEST);
- glPushMatrix();
- glMultMatrixf(lcd->ob->obmat);
+ gpuPushMatrix();
+ gpuMultMatrix(lcd->ob->obmat);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ub(255, 0, 255);
- glColor3ub(255, 0, 255);
if (lcd->totedge > 0) {
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, lcd->edges);
- glDrawArrays(GL_LINES, 0, lcd->totedge * 2);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(PRIM_LINES, lcd->totedge * 2);
+
+ for (int i = 0; i < lcd->totedge; i++) {
+ immVertex3fv(pos, lcd->edges[i][0]);
+ immVertex3fv(pos, lcd->edges[i][1]);
+ }
+
+ immEnd();
}
if (lcd->totpoint > 0) {
glPointSize(3.0f);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, lcd->points);
- glDrawArrays(GL_POINTS, 0, lcd->totpoint);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(PRIM_POINTS, lcd->totpoint);
+
+ for (int i = 0; i < lcd->totpoint; i++) {
+ immVertex3fv(pos, lcd->points[i]);
+ }
+
+ immEnd();
}
- glPopMatrix();
+ immUnbindProgram();
+
+ gpuPopMatrix();
+
if (v3d && v3d->zbuf)
glEnable(GL_DEPTH_TEST);
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index a6de1b284b7..61891907050 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -985,13 +985,13 @@ static EnumPropertyItem prop_similar_types[] = {
#endif
{SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
- {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
{SIMFACE_AREA, "AREA", 0, "Area", ""},
{SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""},
{SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
{SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
+ {SIMFACE_FACEMAP, "FACE_MAP", 0, "Face-Map", ""},
#ifdef WITH_FREESTYLE
{SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""},
#endif
@@ -1169,7 +1169,7 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUS
#ifdef WITH_FREESTYLE
const int a_end = SIMFACE_FREESTYLE;
#else
- const int a_end = SIMFACE_SMOOTH;
+ const int a_end = SIMFACE_FACEMAP;
#endif
for (a = SIMFACE_MATERIAL; a <= a_end; a++) {
RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 1f90b60a1f5..077c0ca37bd 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -47,6 +47,7 @@
#include "BLI_rand.h"
#include "BLI_sort_utils.h"
+#include "BKE_layer.h"
#include "BKE_material.h"
#include "BKE_context.h"
#include "BKE_deform.h"
@@ -306,7 +307,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
ED_view3d_init_mats_rv3d(obedit, ar->regiondata);
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), 0,
+ CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), 0,
ar, CTX_wm_view3d(C));
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -3010,7 +3011,7 @@ enum {
MESH_SEPARATE_LOOSE = 2,
};
-static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
+static Base *mesh_separate_tagged(Main *bmain, Scene *scene, SceneLayer *sl, Base *base_old, BMesh *bm_old)
{
Base *base_new;
Object *obedit = base_old->object;
@@ -3031,11 +3032,11 @@ static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMe
CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
- base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
+ base_new = ED_object_add_duplicate(bmain, scene, sl, base_old, USER_DUP_MESH);
/* DAG_relations_tag_update(bmain); */ /* normally would call directly after but in this case delay recalc */
assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
- ED_base_object_select(base_new, BA_SELECT);
+ ED_object_base_select(base_new, BA_SELECT);
BMO_op_callf(bm_old, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"duplicate geom=%hvef dest=%p", BM_ELEM_TAG, bm_new);
@@ -3057,7 +3058,7 @@ static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMe
return base_new;
}
-static bool mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
+static bool mesh_separate_selected(Main *bmain, Scene *scene, SceneLayer *sl, Base *base_old, BMesh *bm_old)
{
/* we may have tags from previous operators */
BM_mesh_elem_hflag_disable_all(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, false);
@@ -3065,7 +3066,7 @@ static bool mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BM
/* sel -> tag */
BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, true, false, BM_ELEM_SELECT);
- return (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
+ return (mesh_separate_tagged(bmain, scene, sl, base_old, bm_old) != NULL);
}
/* flush a hflag to from verts to edges/faces */
@@ -3164,7 +3165,7 @@ static void mesh_separate_material_assign_mat_nr(Main *bmain, Object *ob, const
}
}
-static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
+static bool mesh_separate_material(Main *bmain, Scene *scene, SceneLayer *sl, Base *base_old, BMesh *bm_old)
{
BMFace *f_cmp, *f;
BMIter iter;
@@ -3205,7 +3206,7 @@ static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BM
}
/* Move selection into a separate object */
- base_new = mesh_separate_tagged(bmain, scene, base_old, bm_old);
+ base_new = mesh_separate_tagged(bmain, scene, sl, base_old, bm_old);
if (base_new) {
mesh_separate_material_assign_mat_nr(bmain, base_new->object, mat_nr);
}
@@ -3216,7 +3217,7 @@ static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BM
return result;
}
-static bool mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
+static bool mesh_separate_loose(Main *bmain, Scene *scene, SceneLayer *sl, Base *base_old, BMesh *bm_old)
{
int i;
BMEdge *e;
@@ -3269,7 +3270,7 @@ static bool mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
bm_mesh_hflag_flush_vert(bm_old, BM_ELEM_TAG);
/* Move selection into a separate object */
- result |= (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
+ result |= (mesh_separate_tagged(bmain, scene, sl, base_old, bm_old) != NULL);
}
return result;
@@ -3279,6 +3280,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
const int type = RNA_enum_get(op->ptr, "type");
int retval = 0;
@@ -3299,13 +3301,13 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
/* editmode separate */
switch (type) {
case MESH_SEPARATE_SELECTED:
- retval = mesh_separate_selected(bmain, scene, base, em->bm);
+ retval = mesh_separate_selected(bmain, scene, sl, base, em->bm);
break;
case MESH_SEPARATE_MATERIAL:
- retval = mesh_separate_material(bmain, scene, base, em->bm);
+ retval = mesh_separate_material(bmain, scene, sl, base, em->bm);
break;
case MESH_SEPARATE_LOOSE:
- retval = mesh_separate_loose(bmain, scene, base, em->bm);
+ retval = mesh_separate_loose(bmain, scene, sl, base, em->bm);
break;
default:
BLI_assert(0);
@@ -3340,10 +3342,10 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
switch (type) {
case MESH_SEPARATE_MATERIAL:
- retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
+ retval_iter = mesh_separate_material(bmain, scene, sl, base_iter, bm_old);
break;
case MESH_SEPARATE_LOOSE:
- retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
+ retval_iter = mesh_separate_loose(bmain, scene, sl, base_iter, bm_old);
break;
default:
BLI_assert(0);
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 438c3acdb11..7300d6f4e52 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -520,7 +520,6 @@ UvVertMap *BM_uv_vert_map_create(
/* vars from original func */
UvVertMap *vmap;
UvMapVert *buf;
- /* MTexPoly *tf; */ /* UNUSED */
MLoopUV *luv;
unsigned int a;
int totverts, i, totuv, totfaces;
@@ -602,7 +601,6 @@ UvVertMap *BM_uv_vert_map_create(
newvlist = v;
efa = BM_face_at_index(bm, v->f);
- /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->tfindex);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -614,7 +612,6 @@ UvVertMap *BM_uv_vert_map_create(
while (iterv) {
next = iterv->next;
efa = BM_face_at_index(bm, iterv->f);
- /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -929,29 +926,27 @@ UvElement *BM_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
/* last_sel, use em->act_face otherwise get the last selected face in the editselections
* at the moment, last_sel is mainly useful for making sure the space image dosnt flicker */
-MTexPoly *EDBM_mtexpoly_active_get(BMEditMesh *em, BMFace **r_act_efa, const bool sloppy, const bool selected)
+BMFace *EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool selected)
{
BMFace *efa = NULL;
- if (!EDBM_mtexpoly_check(em))
+ if (!EDBM_uv_check(em))
return NULL;
efa = BM_mesh_active_face_get(em->bm, sloppy, selected);
if (efa) {
- if (r_act_efa) *r_act_efa = efa;
- return CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ return efa;
}
- if (r_act_efa) *r_act_efa = NULL;
return NULL;
}
/* can we edit UV's for this mesh?*/
-bool EDBM_mtexpoly_check(BMEditMesh *em)
+bool EDBM_uv_check(BMEditMesh *em)
{
/* some of these checks could be a touch overkill */
- return em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY) &&
+ return em && em->bm->totface &&
CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV);
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 772bb1bd308..333c8b29667 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -251,8 +251,8 @@ void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum)
void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
{
/* could be ldata or pdata */
- CustomData *pdata = GET_CD_DATA(me, pdata);
- const int layernum = CustomData_get_active_layer_index(pdata, CD_MTEXPOLY);
+ CustomData *ldata = GET_CD_DATA(me, ldata);
+ const int layernum = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
ED_mesh_uv_loop_reset_ex(me, layernum);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
@@ -269,21 +269,10 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set)
if (me->edit_btmesh) {
em = me->edit_btmesh;
- layernum_dst = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
+ layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV);
if (layernum_dst >= MAX_MTFACE)
return -1;
- /* CD_MTEXPOLY */
- BM_data_layer_add_named(em->bm, &em->bm->pdata, CD_MTEXPOLY, name);
- /* copy data from active UV */
- if (layernum_dst) {
- const int layernum_src = CustomData_get_active_layer(&em->bm->pdata, CD_MTEXPOLY);
- BM_data_layer_copy(em->bm, &em->bm->pdata, CD_MTEXPOLY, layernum_src, layernum_dst);
- }
- if (active_set || layernum_dst == 0) {
- CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum_dst);
- }
-
/* CD_MLOOPUV */
BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name);
/* copy data from active UV */
@@ -298,26 +287,22 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set)
}
}
else {
- layernum_dst = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+ layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
if (layernum_dst >= MAX_MTFACE)
return -1;
- if (me->mtpoly) {
- CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DUPLICATE, me->mtpoly, me->totpoly, name);
+ if (me->mloopuv) {
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name);
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
is_init = true;
}
else {
- CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, name);
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, name);
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
}
if (active_set || layernum_dst == 0) {
- CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum_dst);
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst);
-
CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum_dst);
}
@@ -343,12 +328,12 @@ void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name)
if (me->edit_btmesh) {
em = me->edit_btmesh;
- layernum_dst = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
+ layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV);
if (layernum_dst == 0)
ED_mesh_uv_texture_add(me, name, true);
}
else {
- layernum_dst = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+ layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
if (layernum_dst == 0)
ED_mesh_uv_texture_add(me, name, true);
}
@@ -357,20 +342,16 @@ void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name)
bool ED_mesh_uv_texture_remove_index(Mesh *me, const int n)
{
- CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata);
- CustomDataLayer *cdlp, *cdlu;
+ CustomData *ldata = GET_CD_DATA(me, ldata);
+ CustomDataLayer *cdlu;
int index;
- index = CustomData_get_layer_index_n(pdata, CD_MTEXPOLY, n);
- cdlp = (index == -1) ? NULL : &pdata->layers[index];
-
index = CustomData_get_layer_index_n(ldata, CD_MLOOPUV, n);
cdlu = (index == -1) ? NULL : &ldata->layers[index];
- if (!cdlp || !cdlu)
+ if (!cdlu)
return false;
- delete_customdata_layer(me, cdlp);
delete_customdata_layer(me, cdlu);
DAG_id_tag_update(&me->id, 0);
@@ -381,14 +362,8 @@ bool ED_mesh_uv_texture_remove_index(Mesh *me, const int n)
bool ED_mesh_uv_texture_remove_active(Mesh *me)
{
/* texpoly/uv are assumed to be in sync */
- CustomData *pdata = GET_CD_DATA(me, pdata);
- const int n = CustomData_get_active_layer(pdata, CD_MTEXPOLY);
-
- /* double check active layers align! */
-#ifdef DEBUG
CustomData *ldata = GET_CD_DATA(me, ldata);
- BLI_assert(CustomData_get_active_layer(ldata, CD_MLOOPUV) == n);
-#endif
+ const int n = CustomData_get_active_layer(ldata, CD_MLOOPUV);
if (n != -1) {
return ED_mesh_uv_texture_remove_index(me, n);
@@ -400,8 +375,8 @@ bool ED_mesh_uv_texture_remove_active(Mesh *me)
bool ED_mesh_uv_texture_remove_named(Mesh *me, const char *name)
{
/* texpoly/uv are assumed to be in sync */
- CustomData *pdata = GET_CD_DATA(me, pdata);
- const int n = CustomData_get_named_layer(pdata, CD_MTEXPOLY, name);
+ CustomData *ldata = GET_CD_DATA(me, ldata);
+ const int n = CustomData_get_named_layer(ldata, CD_MLOOPUV, name);
if (n != -1) {
return ED_mesh_uv_texture_remove_index(me, n);
}
@@ -551,7 +526,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
- Base *base;
+ BaseLegacy *base;
Image *ima = NULL;
Mesh *me;
Object *obedit;
@@ -1292,7 +1267,6 @@ void ED_mesh_calc_tessface(Mesh *mesh, bool free_mpoly)
mesh->mloopcol = NULL;
mesh->mloopuv = NULL;
mesh->mpoly = NULL;
- mesh->mtpoly = NULL;
}
}
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index b95921964eb..443f2f0baa8 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -326,7 +326,7 @@ static bool buildNavMesh(const RecastData *recastParams, int nverts, float *vert
}
static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh,
- Base *base, unsigned int lay)
+ BaseLegacy *base, unsigned int lay)
{
float co[3], rot[3];
BMEditMesh *em;
@@ -461,14 +461,15 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
static int navmesh_create_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
LinkNode *obs = NULL;
- Base *navmeshBase = NULL;
+ BaseLegacy *navmeshBase = NULL;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
if (base->object->type == OB_MESH) {
if (base->object->body_type == OB_BODY_TYPE_NAVMESH) {
- if (!navmeshBase || base == scene->basact) {
+ if (!navmeshBase || base == sl->basact) {
navmeshBase = base;
}
}
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 3f06ba2ced4..8727511035e 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -531,7 +531,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* free base, now that data is merged */
if (base->object != ob) {
- ED_base_object_free_and_unlink(bmain, scene, base);
+ ED_base_object_free_and_unlink(bmain, scene, base->object);
}
}
}
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index b3d02d45e13..8050508983b 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../../blenlib
../../blentranslation
../../bmesh
+ ../../depsgraph
../../gpu
../../ikplugin
../../imbuf
@@ -46,6 +47,7 @@ set(SRC
object_bake_api.c
object_constraint.c
object_edit.c
+ object_facemap_ops.c
object_group.c
object_hook.c
object_lattice.c
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index b278d6e1e87..177168aa3c3 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -63,6 +63,7 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
+#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
@@ -74,6 +75,7 @@
#include "BKE_group.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
@@ -113,7 +115,7 @@
#include "UI_resources.h"
-#include "GPU_material.h"
+#include "GPU_lamp.h"
#include "object_intern.h"
@@ -406,10 +408,11 @@ Object *ED_object_add_type(
bContext *C,
int type, const char *name,
const float loc[3], const float rot[3],
- bool enter_editmode, unsigned int layer)
+ bool enter_editmode, unsigned int UNUSED(layer))
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob;
/* for as long scene has editmode... */
@@ -417,13 +420,12 @@ Object *ED_object_add_type(
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */
/* deselects all, sets scene->basact */
- ob = BKE_object_add(bmain, scene, type, name);
- BASACT->lay = ob->lay = layer;
+ ob = BKE_object_add(bmain, scene, sl, type, name);
/* editor level activate, notifiers */
- ED_base_object_activate(C, BASACT);
+ ED_object_base_activate(C, sl->basact);
/* more editor stuff */
- ED_object_base_init_transform(C, BASACT, loc, rot);
+ ED_object_base_init_transform(C, sl->basact, loc, rot);
/* Ignore collisions by default for non-mesh objects */
if (type != OB_MESH) {
@@ -442,6 +444,9 @@ Object *ED_object_add_type(
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+
return ob;
}
@@ -831,7 +836,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
{
Scene *scene = CTX_data_scene(C);
- Base *base = NULL;
+ BaseLegacy *base = NULL;
Image *ima = NULL;
Object *ob = NULL;
@@ -1110,21 +1115,19 @@ static void object_delete_check_glsl_update(Object *ob)
/* remove base from a specific scene */
/* note: now unlinks constraints as well */
-void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base)
+void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
{
- if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
- ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0)
+ if (BKE_library_ID_is_indirectly_used(bmain, ob) &&
+ ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0)
{
/* We cannot delete indirectly used object... */
printf("WARNING, undeletable object '%s', should have been catched before reaching this function!",
- base->object->id.name + 2);
+ ob->id.name + 2);
return;
}
- BKE_scene_base_unlink(scene, base);
- object_delete_check_glsl_update(base->object);
- BKE_libblock_free_us(bmain, base->object);
- MEM_freeN(base);
+ object_delete_check_glsl_update(ob);
+ BKE_collections_object_remove(bmain, scene, ob, true);
DAG_id_type_tag(bmain, ID_OB);
}
@@ -1140,18 +1143,18 @@ static int object_delete_exec(bContext *C, wmOperator *op)
if (CTX_data_edit_object(C))
return OPERATOR_CANCELLED;
- CTX_DATA_BEGIN (C, Base *, base, selected_bases)
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
- const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, base->object);
- if (base->object->id.tag & LIB_TAG_INDIRECT) {
+ const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, ob);
+ if (ob->id.tag & LIB_TAG_INDIRECT) {
/* Can this case ever happen? */
- BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
+ BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
continue;
}
- else if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
+ else if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
BKE_reportf(op->reports, RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
- base->object->id.name + 2, scene->id.name + 2);
+ ob->id.name + 2, scene->id.name + 2);
continue;
}
@@ -1159,9 +1162,9 @@ static int object_delete_exec(bContext *C, wmOperator *op)
* custom scene/object/base handling, and use generic lib remap/query for that.
* But this is for later (aka 2.8, once layers & co are settled and working).
*/
- if (use_global && base->object->id.lib == NULL) {
+ if (use_global && ob->id.lib == NULL) {
/* We want to nuke the object, let's nuke it the easy way (not for linked data though)... */
- BKE_libblock_delete(bmain, &base->object->id);
+ BKE_libblock_delete(bmain, &ob->id);
changed = true;
continue;
}
@@ -1172,38 +1175,28 @@ static int object_delete_exec(bContext *C, wmOperator *op)
for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->parent != NULL) {
- Object *ob = gpl->parent;
- Object *curob = base->object;
- if (ob == curob) {
+ if (gpl->parent == ob) {
gpl->parent = NULL;
}
}
}
}
- /* deselect object -- it could be used in other scenes */
- base->object->flag &= ~SELECT;
-
/* remove from current scene only */
- ED_base_object_free_and_unlink(bmain, scene, base);
+ ED_base_object_free_and_unlink(bmain, scene, ob);
changed = true;
if (use_global) {
Scene *scene_iter;
- Base *base_other;
-
for (scene_iter = bmain->scene.first; scene_iter; scene_iter = scene_iter->id.next) {
if (scene_iter != scene && !ID_IS_LINKED_DATABLOCK(scene_iter)) {
- base_other = BKE_scene_base_find(scene_iter, base->object);
- if (base_other) {
- if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
- base->object->id.name + 2, scene_iter->id.name + 2);
- break;
- }
- ED_base_object_free_and_unlink(bmain, scene_iter, base_other);
+ if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
+ ob->id.name + 2, scene_iter->id.name + 2);
+ break;
}
+ ED_base_object_free_and_unlink(bmain, scene_iter, ob);
}
}
}
@@ -1344,6 +1337,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
const bool use_hierarchy)
{
Main *bmain = CTX_data_main(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ListBase *lb;
DupliObject *dob;
GHash *dupli_gh = NULL, *parent_gh = NULL;
@@ -1375,12 +1369,10 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
*/
if (ob->mat == NULL) ob->totcol = 0;
- basen = MEM_dupallocN(base);
- basen->flag &= ~(OB_FROMDUPLI | OB_FROMGROUP);
- ob->flag = basen->flag;
- basen->lay = base->lay;
- BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */
- basen->object = ob;
+ BKE_collection_object_add_from(scene, dob->ob, ob);
+ basen = BKE_scene_layer_base_find(sl, ob);
+
+ BKE_scene_object_base_flag_sync_from_base(basen);
/* make sure apply works */
BKE_animdata_free(&ob->id, true);
@@ -1395,7 +1387,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
BKE_constraints_free(&ob->constraints);
ob->curve_cache = NULL;
ob->transflag &= ~OB_DUPLI;
- ob->lay = base->lay;
copy_m4_m4(ob->obmat, dob->mat);
BKE_object_apply_mat4(ob, ob->obmat, false, false);
@@ -1604,7 +1595,7 @@ static int convert_poll(bContext *C)
}
/* Helper for convert_exec */
-static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object *ob)
+static Base *duplibase_for_convert(Main *bmain, Scene *scene, SceneLayer *sl, Base *base, Object *ob)
{
Object *obn;
Base *basen;
@@ -1615,16 +1606,11 @@ static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object
obn = BKE_object_copy(bmain, ob);
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ BKE_collection_object_add_from(scene, ob, obn);
- basen = MEM_mallocN(sizeof(Base), "duplibase");
- *basen = *base;
- BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */
- basen->object = obn;
- basen->flag |= SELECT;
- obn->flag |= SELECT;
- base->flag &= ~SELECT;
- ob->flag &= ~SELECT;
-
+ basen = BKE_scene_layer_base_find(sl, obn);
+ ED_object_base_select(basen, BA_SELECT);
+ ED_object_base_select(basen, BA_DESELECT);
return basen;
}
@@ -1632,6 +1618,7 @@ static int convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *basen = NULL, *basact = NULL;
Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C);
DerivedMesh *dm;
@@ -1646,7 +1633,7 @@ static int convert_exec(bContext *C, wmOperator *op)
/* don't forget multiple users! */
{
- Base *base;
+ BaseLegacy *base;
for (base = scene->base.first; base; base = base->next) {
ob = base->object;
@@ -1710,7 +1697,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original mesh's usage count */
@@ -1735,7 +1722,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original mesh's usage count */
@@ -1766,7 +1753,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original curve's usage count */
@@ -1837,7 +1824,7 @@ static int convert_exec(bContext *C, wmOperator *op)
if (target == OB_MESH) {
if (keep_original) {
- basen = duplibase_for_convert(bmain, scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original curve's usage count */
@@ -1872,7 +1859,7 @@ static int convert_exec(bContext *C, wmOperator *op)
if (!(baseob->flag & OB_DONE)) {
baseob->flag |= OB_DONE;
- basen = duplibase_for_convert(bmain, scene, base, baseob);
+ basen = duplibase_for_convert(bmain, scene, sl, base, baseob);
newob = basen->object;
mb = newob->data;
@@ -1923,23 +1910,20 @@ static int convert_exec(bContext *C, wmOperator *op)
if (!keep_original) {
if (mballConverted) {
- Base *base, *base_next;
-
- for (base = scene->base.first; base; base = base_next) {
- base_next = base->next;
-
- ob = base->object;
+ FOREACH_SCENE_OBJECT(scene, ob_mball)
+ {
if (ob->type == OB_MBALL) {
if (ob->flag & OB_DONE) {
Object *ob_basis = NULL;
- if (BKE_mball_is_basis(ob) ||
- ((ob_basis = BKE_mball_basis_find(scene, ob)) && (ob_basis->flag & OB_DONE)))
+ if (BKE_mball_is_basis(ob_mball) ||
+ ((ob_basis = BKE_mball_basis_find(scene, ob_mball)) && (ob_basis->flag & OB_DONE)))
{
- ED_base_object_free_and_unlink(bmain, scene, base);
+ ED_base_object_free_and_unlink(bmain, scene, ob_mball);
}
}
}
}
+ FOREACH_SCENE_OBJECT_END
}
/* delete object should renew depsgraph */
@@ -1951,12 +1935,12 @@ static int convert_exec(bContext *C, wmOperator *op)
if (basact) {
/* active base was changed */
- ED_base_object_activate(C, basact);
- BASACT = basact;
+ ED_object_base_activate(C, basact);
+ BASACT_NEW = basact;
}
- else if (BASACT->object->flag & OB_DONE) {
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT->object);
- WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT->object);
+ else if (BASACT_NEW->object->flag & OB_DONE) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT_NEW->object);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT_NEW->object);
}
DAG_relations_tag_update(bmain);
@@ -1998,18 +1982,17 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* used below, assumes id.new is correct */
/* leaves selection of base/object unaltered */
/* Does set ID->newid pointers. */
-static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag)
+static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, SceneLayer *sl, Object *ob, int dupflag)
{
#define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
#define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
Base *basen = NULL;
Material ***matarar;
- Object *ob, *obn;
+ Object *obn;
ID *id;
int a, didit;
- ob = base->object;
if (ob->mode & OB_MODE_POSE) {
; /* nothing? */
}
@@ -2017,20 +2000,18 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
- basen = MEM_mallocN(sizeof(Base), "duplibase");
- *basen = *base;
- BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */
- basen->object = obn;
+ BKE_collection_object_add_from(scene, ob, obn);
+ basen = BKE_scene_layer_base_find(sl, obn);
/* 1) duplis should end up in same group as the original
* 2) Rigid Body sim participants MUST always be part of a group...
*/
// XXX: is 2) really a good measure here?
- if ((basen->flag & OB_FROMGROUP) || ob->rigidbody_object || ob->rigidbody_constraint) {
+ if ((ob->flag & OB_FROMGROUP) != 0 || ob->rigidbody_object || ob->rigidbody_constraint) {
Group *group;
for (group = bmain->group.first; group; group = group->id.next) {
if (BKE_group_object_exists(group, ob))
- BKE_group_object_add(group, obn, scene, basen);
+ BKE_group_object_add(group, obn);
}
}
@@ -2238,14 +2219,14 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
* note: don't call this within a loop since clear_* funcs loop over the entire database.
* note: caller must do DAG_relations_tag_update(bmain);
* this is not done automatic since we may duplicate many objects in a batch */
-Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag)
+Base *ED_object_add_duplicate(Main *bmain, Scene *scene, SceneLayer *sl, Base *base, int dupflag)
{
Base *basen;
Object *ob;
clear_sca_new_poins(); /* BGE logic */
- basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
+ basen = object_add_duplicate_internal(bmain, scene, sl, base->object, dupflag);
if (basen == NULL) {
return NULL;
}
@@ -2272,6 +2253,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
const bool linked = RNA_boolean_get(op->ptr, "linked");
int dupflag = (linked) ? 0 : U.dupflag;
@@ -2279,19 +2261,20 @@ static int duplicate_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
- Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
+ Base *basen = object_add_duplicate_internal(bmain, scene, sl, base->object, dupflag);
/* note that this is safe to do with this context iterator,
* the list is made in advance */
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
+ ED_object_base_select(basen, BA_SELECT);
if (basen == NULL) {
continue;
}
/* new object becomes active */
- if (BASACT == base)
- ED_base_object_activate(C, basen);
+ if (BASACT_NEW == base)
+ ED_object_base_activate(C, basen);
if (basen->object->data) {
DAG_id_tag_update(basen->object->data, 0);
@@ -2304,6 +2287,8 @@ static int duplicate_exec(bContext *C, wmOperator *op)
BKE_main_id_clear_newpoins(bmain);
DAG_relations_tag_update(bmain);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&CTX_data_scene(C)->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -2339,9 +2324,9 @@ static int add_named_exec(bContext *C, wmOperator *op)
wmWindow *win = CTX_wm_window(C);
const wmEvent *event = win ? win->eventstate : NULL;
Main *bmain = CTX_data_main(C);
- View3D *v3d = CTX_wm_view3d(C); /* may be NULL */
Scene *scene = CTX_data_scene(C);
- Base *basen, *base;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Base *basen;
Object *ob;
const bool linked = RNA_boolean_get(op->ptr, "linked");
int dupflag = (linked) ? 0 : U.dupflag;
@@ -2356,22 +2341,17 @@ static int add_named_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- base = MEM_callocN(sizeof(Base), "duplibase");
- base->object = ob;
- base->flag = ob->flag;
-
/* prepare dupli */
clear_sca_new_poins(); /* BGE logic */
- basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
+ basen = object_add_duplicate_internal(bmain, scene, sl, ob, dupflag);
+ BKE_scene_object_base_flag_sync_from_object(basen);
if (basen == NULL) {
- MEM_freeN(base);
BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
return OPERATOR_CANCELLED;
}
- basen->lay = basen->object->lay = BKE_screen_view3d_layer_active(v3d, scene);
basen->object->restrictflag &= ~OB_RESTRICT_VIEW;
if (event) {
@@ -2382,8 +2362,8 @@ static int add_named_exec(bContext *C, wmOperator *op)
ED_view3d_cursor3d_position(C, basen->object->loc, mval);
}
- ED_base_object_select(basen, BA_SELECT);
- ED_base_object_activate(C, basen);
+ ED_object_base_select(basen, BA_SELECT);
+ ED_object_base_activate(C, basen);
copy_object_set_idnew(C);
@@ -2391,8 +2371,6 @@ static int add_named_exec(bContext *C, wmOperator *op)
DAG_relations_tag_update(bmain);
- MEM_freeN(base);
-
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT | ND_OB_ACTIVE, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 11d96da5786..92a3850f2f3 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -52,6 +52,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_multires.h"
#include "BKE_report.h"
#include "BKE_cdderivedmesh.h"
@@ -86,6 +87,11 @@
* needed to make job totally thread-safe */
typedef struct MultiresBakerJobData {
struct MultiresBakerJobData *next, *prev;
+ /* material aligned image array (for per-face bake image) */
+ struct {
+ Image **array;
+ int len;
+ } ob_image;
DerivedMesh *lores_dm, *hires_dm;
bool simple;
int lvl, tot_lvl;
@@ -152,7 +158,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
break;
}
- if (!me->mtpoly) {
+ if (!me->mloopuv) {
BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
ok = false;
@@ -160,7 +166,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
else {
a = me->totpoly;
while (ok && a--) {
- Image *ima = me->mtpoly[a].tpage;
+ Image *ima = BKE_object_material_edit_image_get(ob, me->mpoly[a].mat_nr);
if (!ima) {
BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
@@ -283,20 +289,27 @@ static void clear_single_image(Image *image, ClearFlag flag)
}
}
-static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag)
+static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, ClearFlag flag)
{
- int a;
-
- for (a = 0; a < totpoly; a++) {
- mtpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
+ for (int i = 0; i < ob_image_array_len; i++) {
+ Image *image = ob_image_array[i];
+ if (image) {
+ image->id.tag &= ~LIB_TAG_DOIT;
+ }
}
- for (a = 0; a < totpoly; a++) {
- clear_single_image(mtpoly[a].tpage, flag);
+ for (int i = 0; i < ob_image_array_len; i++) {
+ Image *image = ob_image_array[i];
+ if (image) {
+ clear_single_image(image, flag);
+ }
}
- for (a = 0; a < totpoly; a++) {
- mtpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
+ for (int i = 0; i < ob_image_array_len; i++) {
+ Image *image = ob_image_array[i];
+ if (image) {
+ image->id.tag &= ~LIB_TAG_DOIT;
+ }
}
}
@@ -312,11 +325,10 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- Mesh *me;
ClearFlag clear_flag = 0;
ob = base->object;
- me = (Mesh *)ob->data;
+ // me = (Mesh *)ob->data;
if (scene->r.bake_mode == RE_BAKE_NORMALS) {
clear_flag = CLEAR_TANGENT_NORMAL;
@@ -325,7 +337,11 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
clear_flag = CLEAR_DISPLACEMENT;
}
- clear_images_poly(me->mtpoly, me->totpoly, clear_flag);
+ {
+ Image **ob_image_array = BKE_object_material_edit_image_get_array(ob);
+ clear_images_poly(ob_image_array, ob->totcol, clear_flag);
+ MEM_freeN(ob_image_array);
+ }
}
CTX_DATA_END;
}
@@ -351,11 +367,16 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
//bkr.reports= op->reports;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
+ bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob);
+ bkr.ob_image.len = ob->totcol;
+
bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
RE_multires_bake_images(&bkr);
+ MEM_freeN(bkr.ob_image.array);
+
BLI_freelistN(&bkr.image);
bkr.lores_dm->release(bkr.lores_dm);
@@ -401,6 +422,9 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
+ data->ob_image.array = BKE_object_material_edit_image_get_array(ob);
+ data->ob_image.len = ob->totcol;
+
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
@@ -421,8 +445,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
if (bkj->bake_clear) { /* clear images */
for (data = bkj->data.first; data; data = data->next) {
- DerivedMesh *dm = data->lores_dm;
- MTexPoly *mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY);
ClearFlag clear_flag = 0;
if (bkj->mode == RE_BAKE_NORMALS) {
@@ -432,7 +454,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
clear_flag = CLEAR_DISPLACEMENT;
}
- clear_images_poly(mtexpoly, dm->getNumPolys(dm), clear_flag);
+ clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag);
}
}
@@ -445,6 +467,8 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
bkr.use_lores_mesh = bkj->use_lores_mesh;
bkr.user_scale = bkj->user_scale;
//bkr.reports = bkj->reports;
+ bkr.ob_image.array = data->ob_image.array;
+ bkr.ob_image.len = data->ob_image.len;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
bkr.lores_dm = data->lores_dm;
@@ -493,6 +517,8 @@ static void multiresbake_freejob(void *bkv)
GPU_free_image(ima);
}
+ MEM_freeN(data->ob_image.array);
+
BLI_freelistN(&data->images);
MEM_freeN(data);
@@ -589,6 +615,7 @@ static int test_bake_internal(bContext *C, ReportList *reports)
static void init_bake_internal(BakeRender *bkr, bContext *C)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
bScreen *sc = CTX_wm_screen(C);
/* get editmode results */
@@ -597,7 +624,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */
bkr->main = CTX_data_main(C);
bkr->scene = scene;
- bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
+ bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT_NEW : NULL;
bkr->re = RE_NewRender("_Bake View_");
if (scene->r.bake_mode == RE_BAKE_AO) {
@@ -810,6 +837,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
int result = OPERATOR_CANCELLED;
if (is_multires_bake(scene)) {
@@ -829,7 +857,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
RE_test_break_cb(bkr.re, NULL, thread_break);
G.is_break = false; /* BKE_blender_test_break uses this global */
- RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL);
+ RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT_NEW : NULL);
/* baking itself is threaded, cannot use test_break in threads */
BLI_init_threads(&threads, do_bake_render, 1);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index ad43c48f0b9..a4aff5b10f3 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -59,6 +59,8 @@
#include "BKE_screen.h"
#include "BKE_depsgraph.h"
+#include "DEG_depsgraph.h"
+
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -83,6 +85,7 @@ static void bake_set_props(wmOperator *op, Scene *scene);
typedef struct BakeAPIRender {
Object *ob;
Main *main;
+ Depsgraph *depsgraph;
Scene *scene;
ReportList *reports;
ListBase selected_objects;
@@ -631,7 +634,7 @@ static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob)
}
static int bake(
- Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
+ Render *re, Main *bmain, Depsgraph *graph, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
const ScenePassType pass_type, const int pass_filter, const int margin,
const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage,
@@ -670,7 +673,7 @@ static int bake(
size_t num_pixels;
int tot_materials;
- RE_bake_engine_set_engine_parameters(re, bmain, scene);
+ RE_bake_engine_set_engine_parameters(re, bmain, graph, scene);
if (!RE_bake_has_engine(re)) {
BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
@@ -1118,6 +1121,7 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
bkr->ob = CTX_data_active_object(C);
bkr->main = CTX_data_main(C);
+ bkr->depsgraph = CTX_data_depsgraph(C);
bkr->scene = CTX_data_scene(C);
bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL;
@@ -1201,7 +1205,7 @@ static int bake_exec(bContext *C, wmOperator *op)
if (bkr.is_selected_to_active) {
result = bake(
- bkr.render, bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports,
+ bkr.render, bkr.main, bkr.depsgraph, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports,
bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage,
bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
@@ -1214,7 +1218,7 @@ static int bake_exec(bContext *C, wmOperator *op)
for (link = bkr.selected_objects.first; link; link = link->next) {
Object *ob_iter = link->ptr.data;
result = bake(
- bkr.render, bkr.main, bkr.scene, ob_iter, NULL, bkr.reports,
+ bkr.render, bkr.main, bkr.depsgraph, bkr.scene, ob_iter, NULL, bkr.reports,
bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage,
bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
@@ -1259,7 +1263,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
if (bkr->is_selected_to_active) {
bkr->result = bake(
- bkr->render, bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports,
+ bkr->render, bkr->main, bkr->depsgraph, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports,
bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage,
bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
@@ -1272,7 +1276,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
for (link = bkr->selected_objects.first; link; link = link->next) {
Object *ob_iter = link->ptr.data;
bkr->result = bake(
- bkr->render, bkr->main, bkr->scene, ob_iter, NULL, bkr->reports,
+ bkr->render, bkr->main, bkr->depsgraph, bkr->scene, ob_iter, NULL, bkr->reports,
bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage,
bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 59d78f13ccb..2437a6bff28 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -1682,14 +1682,15 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
if ((found == false) && (add)) {
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Base *base = BASACT, *newbase = NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Base *base = BASACT_NEW, *newbase = NULL;
Object *obt;
/* add new target object */
- obt = BKE_object_add(bmain, scene, OB_EMPTY, NULL);
+ obt = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL);
/* set layers OK */
- newbase = BASACT;
+ newbase = BASACT_NEW;
newbase->lay = base->lay;
obt->lay = newbase->lay;
@@ -1708,8 +1709,8 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
}
/* restore, BKE_object_add sets active */
- BASACT = base;
- base->flag |= SELECT;
+ BASACT_NEW = base;
+ base->flag |= BASE_SELECTED;
/* make our new target the new object */
*tar_ob = obt;
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index acee69daab7..250737a130c 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -135,19 +135,19 @@ static EnumPropertyItem *dt_layers_select_src_itemf(
if (ob_src) {
DerivedMesh *dm_src;
- CustomData *pdata;
+ CustomData *ldata;
int num_data, i;
/* XXX Is this OK? */
- dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY);
- pdata = dm_src->getPolyDataLayout(dm_src);
- num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+ dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPUV);
+ ldata = dm_src->getLoopDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index edd7b5dd1be..abdbf3afd5a 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -132,189 +132,6 @@ Object *ED_object_active_context(bContext *C)
}
-/* ********* clear/set restrict view *********/
-static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Main *bmain = CTX_data_main(C);
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- Scene *scene = CTX_data_scene(C);
- Base *base;
- bool changed = false;
-
- /* XXX need a context loop to handle such cases */
- for (base = FIRSTBASE; base; base = base->next) {
- if ((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) {
- if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) {
- base->flag |= SELECT;
- }
- base->object->flag = base->flag;
- base->object->restrictflag &= ~OB_RESTRICT_VIEW;
- changed = true;
- }
- }
- if (changed) {
- DAG_id_type_tag(bmain, ID_OB);
- DAG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
-{
-
- /* identifiers */
- ot->name = "Clear Restrict View";
- ot->description = "Reveal the object by setting the hide flag";
- ot->idname = "OBJECT_OT_hide_view_clear";
-
- /* api callbacks */
- ot->exec = object_hide_view_clear_exec;
- ot->poll = ED_operator_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-static int object_hide_view_set_exec(bContext *C, wmOperator *op)
-{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- bool changed = false;
- const bool unselected = RNA_boolean_get(op->ptr, "unselected");
-
- CTX_DATA_BEGIN(C, Base *, base, visible_bases)
- {
- if (!unselected) {
- if (base->flag & SELECT) {
- base->flag &= ~SELECT;
- base->object->flag = base->flag;
- base->object->restrictflag |= OB_RESTRICT_VIEW;
- changed = true;
- if (base == BASACT) {
- ED_base_object_activate(C, NULL);
- }
- }
- }
- else {
- if (!(base->flag & SELECT)) {
- base->object->restrictflag |= OB_RESTRICT_VIEW;
- changed = true;
- if (base == BASACT) {
- ED_base_object_activate(C, NULL);
- }
- }
- }
- }
- CTX_DATA_END;
-
- if (changed) {
- DAG_id_type_tag(bmain, ID_OB);
- DAG_relations_tag_update(bmain);
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-
- }
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_hide_view_set(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Set Restrict View";
- ot->description = "Hide the object by setting the hide flag";
- ot->idname = "OBJECT_OT_hide_view_set";
-
- /* api callbacks */
- ot->exec = object_hide_view_set_exec;
- ot->poll = ED_operator_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
-
-}
-
-/* 99% same as above except no need for scene refreshing (TODO, update render preview) */
-static int object_hide_render_clear_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bool changed = false;
-
- /* XXX need a context loop to handle such cases */
- CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
- {
- if (ob->restrictflag & OB_RESTRICT_RENDER) {
- ob->restrictflag &= ~OB_RESTRICT_RENDER;
- changed = true;
- }
- }
- CTX_DATA_END;
-
- if (changed)
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_hide_render_clear(wmOperatorType *ot)
-{
-
- /* identifiers */
- ot->name = "Clear Restrict Render";
- ot->description = "Reveal the render object by setting the hide render flag";
- ot->idname = "OBJECT_OT_hide_render_clear";
-
- /* api callbacks */
- ot->exec = object_hide_render_clear_exec;
- ot->poll = ED_operator_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-static int object_hide_render_set_exec(bContext *C, wmOperator *op)
-{
- const bool unselected = RNA_boolean_get(op->ptr, "unselected");
-
- CTX_DATA_BEGIN(C, Base *, base, visible_bases)
- {
- if (!unselected) {
- if (base->flag & SELECT) {
- base->object->restrictflag |= OB_RESTRICT_RENDER;
- }
- }
- else {
- if (!(base->flag & SELECT)) {
- base->object->restrictflag |= OB_RESTRICT_RENDER;
- }
- }
- }
- CTX_DATA_END;
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_hide_render_set(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Set Restrict Render";
- ot->description = "Hide the render object by setting the hide render flag";
- ot->idname = "OBJECT_OT_hide_render_set";
-
- /* api callbacks */
- ot->exec = object_hide_render_set_exec;
- ot->poll = ED_operator_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
-}
-
/* ******************* toggle editmode operator ***************** */
static bool mesh_needs_keyindex(const Mesh *me)
@@ -414,6 +231,7 @@ void ED_object_editmode_exit(bContext *C, int flag)
/* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */
/* Note! if 'EM_FREEDATA' isn't in the flag, use ED_object_editmode_load directly */
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
const bool freedata = (flag & EM_FREEDATA) != 0;
@@ -422,8 +240,8 @@ void ED_object_editmode_exit(bContext *C, int flag)
if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) {
/* in rare cases (background mode) its possible active object
* is flagged for editmode, without 'obedit' being set [#35489] */
- if (UNLIKELY(scene->basact && (scene->basact->object->mode & OB_MODE_EDIT))) {
- scene->basact->object->mode &= ~OB_MODE_EDIT;
+ if (UNLIKELY(sl->basact && (sl->basact->object->mode & OB_MODE_EDIT))) {
+ sl->basact->object->mode &= ~OB_MODE_EDIT;
}
if (flag & EM_WAITCURSOR) waitcursor(0);
return;
@@ -465,31 +283,22 @@ void ED_object_editmode_exit(bContext *C, int flag)
void ED_object_editmode_enter(bContext *C, int flag)
{
Scene *scene = CTX_data_scene(C);
- Base *base = NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob;
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = NULL;
bool ok = false;
if (ID_IS_LINKED_DATABLOCK(scene)) return;
- if (sa && sa->spacetype == SPACE_VIEW3D)
- v3d = sa->spacedata.first;
-
if ((flag & EM_IGNORE_LAYER) == 0) {
- base = CTX_data_active_base(C); /* active layer checked here for view3d */
+ ob = CTX_data_active_object(C); /* active layer checked here for view3d */
- if (base == NULL) return;
- else if (v3d && (base->lay & v3d->lay) == 0) return;
- else if (!v3d && (base->lay & scene->lay) == 0) return;
+ if (ob == NULL) return;
}
else {
- base = scene->basact;
+ ob = sl->basact->object;
}
- if (ELEM(NULL, base, base->object, base->object->data)) return;
-
- ob = base->object;
+ if (ELEM(NULL, ob, ob->data)) return;
/* this checks actual object->data, for cases when other scenes have it in editmode context */
if (BKE_object_is_in_editmode(ob))
@@ -694,7 +503,7 @@ void OBJECT_OT_posemode_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
+static void copymenu_properties(SceneLayer *sl, Object *ob)
{
//XXX no longer used - to be removed - replaced by game_properties_copy_exec
bProperty *prop;
@@ -727,8 +536,8 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
nr = pupmenu(str);
if (nr == 1 || nr == 2) {
- for (base = FIRSTBASE; base; base = base->next) {
- if ((base != BASACT) && (TESTBASELIB(v3d, base))) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if ((base != BASACT_NEW) && (TESTBASELIB_NEW(base))) {
if (nr == 1) { /* replace */
BKE_bproperty_copy_list(&base->object->prop, &ob->prop);
}
@@ -744,8 +553,8 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
prop = BLI_findlink(&ob->prop, nr - 4); /* account for first 3 menu items & menu index starting at 1*/
if (prop) {
- for (base = FIRSTBASE; base; base = base->next) {
- if ((base != BASACT) && (TESTBASELIB(v3d, base))) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if ((base != BASACT_NEW) && (TESTBASELIB_NEW(base))) {
BKE_bproperty_object_set(base->object, prop);
}
}
@@ -755,14 +564,14 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
}
-static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob)
+static void copymenu_logicbricks(SceneLayer *sl, Object *ob)
{
//XXX no longer used - to be removed - replaced by logicbricks_copy_exec
Base *base;
- for (base = FIRSTBASE; base; base = base->next) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
if (base->object != ob) {
- if (TESTBASELIB(v3d, base)) {
+ if (TESTBASELIB_NEW(base)) {
/* first: free all logic */
free_sensors(&base->object->sensors);
@@ -841,7 +650,7 @@ static void copy_texture_space(Object *to, Object *ob)
}
/* UNUSED, keep in case we want to copy functionality for use elsewhere */
-static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
+static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
{
Object *ob;
Base *base;
@@ -851,18 +660,18 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
if (ID_IS_LINKED_DATABLOCK(scene)) return;
- if (!(ob = OBACT)) return;
+ if (!(ob = OBACT_NEW)) return;
if (scene->obedit) { // XXX get from context
/* obedit_copymenu(); */
return;
}
if (event == 9) {
- copymenu_properties(scene, v3d, ob);
+ copymenu_properties(sl, ob);
return;
}
else if (event == 10) {
- copymenu_logicbricks(scene, v3d, ob);
+ copymenu_logicbricks(sl, ob);
return;
}
else if (event == 24) {
@@ -871,9 +680,9 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
return;
}
- for (base = FIRSTBASE; base; base = base->next) {
- if (base != BASACT) {
- if (TESTBASELIB(v3d, base)) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if (base != BASACT_NEW) {
+ if (TESTBASELIB_NEW(base)) {
DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
if (event == 1) { /* loc */
@@ -1092,13 +901,13 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
DAG_relations_tag_update(bmain);
}
-static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D *v3d)
+static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, SceneLayer *sl)
{
Object *ob;
short event;
char str[512];
- if (!(ob = OBACT)) return;
+ if (!(ob = OBACT_NEW)) return;
if (scene->obedit) { /* XXX get from context */
/* if (ob->type == OB_MESH) */
@@ -1146,7 +955,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D *
event = pupmenu(str);
if (event <= 0) return;
- copy_attr(bmain, scene, v3d, event);
+ copy_attr(bmain, scene, sl, event);
}
/* ******************* force field toggle operator ***************** */
@@ -1509,7 +1318,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
/* ********************** */
-static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
+static void UNUSED_FUNCTION(image_aspect) (Scene *scene, SceneLayer *sl)
{
/* all selected objects with an image map: scale in image aspect */
Base *base;
@@ -1522,8 +1331,8 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
if (scene->obedit) return; // XXX get from context
if (ID_IS_LINKED_DATABLOCK(scene)) return;
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASELIB(v3d, base)) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if (TESTBASELIB_NEW(base)) {
ob = base->object;
done = false;
diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c
new file mode 100644
index 00000000000..b8666fc7a65
--- /dev/null
+++ b/source/blender/editors/object/object_facemap_ops.c
@@ -0,0 +1,493 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_editmesh.h"
+#include "BKE_object.h"
+#include "BKE_object_facemap.h"
+#include "BKE_object_deform.h"
+
+#include "BKE_depsgraph.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "ED_mesh.h"
+#include "ED_object.h"
+
+#include "RNA_define.h"
+#include "RNA_access.h"
+
+#include <string.h>
+
+#include "object_intern.h"
+
+/* called while not in editmode */
+void ED_object_facemap_face_add(Object *ob, bFaceMap *fmap, int facenum)
+{
+ int fmap_nr;
+ if (GS(((ID *)ob->data)->name) != ID_ME)
+ return;
+
+ /* get the face map number, exit if it can't be found */
+ fmap_nr = BLI_findindex(&ob->fmaps, fmap);
+
+ if (fmap_nr != -1) {
+ int *facemap;
+ Mesh *me = ob->data;
+
+ /* if there's is no facemap layer then create one */
+ if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL)
+ facemap = CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_DEFAULT, NULL, me->totpoly);
+
+ facemap[facenum] = fmap_nr;
+ }
+}
+
+/* called while not in editmode */
+void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum)
+{
+ int fmap_nr;
+ if (GS(((ID *)ob->data)->name) != ID_ME)
+ return;
+
+ /* get the face map number, exit if it can't be found */
+ fmap_nr = BLI_findindex(&ob->fmaps, fmap);
+
+ if (fmap_nr != -1) {
+ int *facemap;
+ Mesh *me = ob->data;
+
+ /* if there's is no facemap layer then create one */
+ if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL)
+ return;
+
+ facemap[facenum] = -1;
+ }
+}
+
+static void object_fmap_swap_edit_mode(Object *ob, int num1, int num2)
+{
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (me->edit_btmesh) {
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
+
+ if (cd_fmap_offset != -1) {
+ BMFace *efa;
+ BMIter iter;
+ int *map;
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (map) {
+ if (num1 != -1) {
+ if (*map == num1)
+ *map = num2;
+ else if (*map == num2)
+ *map = num1;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void object_fmap_swap_object_mode(Object *ob, int num1, int num2)
+{
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+ int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+ int i;
+
+ if (map) {
+ for (i = 0; i < me->totpoly; i++) {
+ if (num1 != -1) {
+ if (map[i] == num1)
+ map[i] = num2;
+ else if (map[i]== num2)
+ map[i] = num1;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void object_facemap_swap(Object *ob, int num1, int num2)
+{
+ if (BKE_object_is_in_editmode(ob))
+ object_fmap_swap_edit_mode(ob, num1, num2);
+ else
+ object_fmap_swap_object_mode(ob, num1, num2);
+}
+
+static int face_map_supported_poll(bContext *C)
+{
+ Object *ob = ED_object_context(C);
+ ID *data = (ob) ? ob->data : NULL;
+ return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib);
+}
+
+static int face_map_supported_edit_mode_poll(bContext *C)
+{
+ Object *ob = ED_object_context(C);
+ ID *data = (ob) ? ob->data : NULL;
+ return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib && ob->mode == OB_MODE_EDIT);
+}
+
+static int face_map_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+
+ BKE_object_facemap_add(ob);
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_face_map_add(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Face Map";
+ ot->idname = "OBJECT_OT_face_map_add";
+ ot->description = "Add a new face map to the active object";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_poll;
+ ot->exec = face_map_add_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int face_map_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
+
+ if (fmap) {
+ BKE_object_facemap_remove(ob, fmap);
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_face_map_remove(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Face Map";
+ ot->idname = "OBJECT_OT_face_map_remove";
+ ot->description = "Remove a face map from the active object";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_poll;
+ ot->exec = face_map_remove_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int face_map_assign_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
+
+ if (fmap) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMFace *efa;
+ BMIter iter;
+ int *map;
+ int cd_fmap_offset;
+
+ if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP))
+ BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP);
+
+ cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ *map = ob->actfmap - 1;
+ }
+ }
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_face_map_assign(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Assign Face Map";
+ ot->idname = "OBJECT_OT_face_map_assign";
+ ot->description = "Assign faces to a face map";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_edit_mode_poll;
+ ot->exec = face_map_assign_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int face_map_remove_from_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
+
+ if (fmap) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMFace *efa;
+ BMIter iter;
+ int *map;
+ int cd_fmap_offset;
+ int mapindex = ob->actfmap - 1;
+
+ if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP))
+ return OPERATOR_CANCELLED;
+
+ cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && *map == mapindex) {
+ *map = -1;
+ }
+ }
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_face_map_remove_from(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove From Face Map";
+ ot->idname = "OBJECT_OT_face_map_remove_from";
+ ot->description = "Remove faces from a face map";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_edit_mode_poll;
+ ot->exec = face_map_remove_from_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static void fmap_select(Object *ob, bool select)
+{
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMFace *efa;
+ BMIter iter;
+ int *map;
+ int cd_fmap_offset;
+ int mapindex = ob->actfmap - 1;
+
+ if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP))
+ BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP);
+
+ cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (*map == mapindex) {
+ BM_face_select_set(em->bm, efa, select);
+ }
+ }
+}
+
+static int face_map_select_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
+
+ if (fmap) {
+ fmap_select(ob, true);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_face_map_select(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Face Map Faces";
+ ot->idname = "OBJECT_OT_face_map_select";
+ ot->description = "Select faces belonging to a face map";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_edit_mode_poll;
+ ot->exec = face_map_select_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int face_map_deselect_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
+
+ if (fmap) {
+ fmap_select(ob, false);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_face_map_deselect(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Deselect Face Map Faces";
+ ot->idname = "OBJECT_OT_face_map_deselect";
+ ot->description = "Deselect faces belonging to a face map";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_edit_mode_poll;
+ ot->exec = face_map_deselect_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
+static int face_map_move_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+ bFaceMap *fmap;
+ int dir = RNA_enum_get(op->ptr, "direction");
+ int pos1, pos2 = -1, count;
+
+ fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
+ if (!fmap) {
+ return OPERATOR_CANCELLED;
+ }
+
+ count = BLI_listbase_count(&ob->fmaps);
+ pos1 = BLI_findindex(&ob->fmaps, fmap);
+
+ if (dir == 1) { /*up*/
+ void *prev = fmap->prev;
+
+ if (prev) {
+ pos2 = pos1 - 1;
+ }
+ else {
+ pos2 = count - 1;
+ }
+
+ BLI_remlink(&ob->fmaps, fmap);
+ BLI_insertlinkbefore(&ob->fmaps, prev, fmap);
+ }
+ else { /*down*/
+ void *next = fmap->next;
+
+ if (next) {
+ pos2 = pos1 + 1;
+ }
+ else {
+ pos2 = 0;
+ }
+
+ BLI_remlink(&ob->fmaps, fmap);
+ BLI_insertlinkafter(&ob->fmaps, next, fmap);
+ }
+
+ /* iterate through mesh and substitute the indices as necessary */
+ object_facemap_swap(ob, pos2, pos1);
+
+ ob->actfmap = pos2 + 1;
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+
+void OBJECT_OT_face_map_move(wmOperatorType *ot)
+{
+ static EnumPropertyItem fmap_slot_move[] = {
+ {1, "UP", 0, "Up", ""},
+ {-1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Move Face Map";
+ ot->idname = "OBJECT_OT_face_map_move";
+ ot->description = "Move the active face map up/down in the list";
+
+ /* api callbacks */
+ ot->poll = face_map_supported_poll;
+ ot->exec = face_map_move_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "direction", fmap_slot_move, 0, "Direction", "Direction to move, UP or DOWN");
+}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 0fe43c44d7d..b22b034ecab 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -128,7 +128,6 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
@@ -151,7 +150,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
continue;
if (!BKE_group_object_cyclic_check(bmain, base->object, group)) {
- BKE_group_object_add(group, base->object, scene, base);
+ BKE_group_object_add(group, base->object);
updated = true;
}
else {
@@ -200,8 +199,8 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot)
static int objects_remove_active_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
@@ -221,7 +220,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
/* Remove groups from selected objects */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- BKE_group_object_unlink(group, base->object, scene, base);
+ BKE_group_object_unlink(group, base->object);
ok = 1;
}
CTX_DATA_END;
@@ -264,11 +263,10 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot)
static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- BKE_object_groups_clear(scene, base, base->object);
+ BKE_object_groups_clear(base->object);
}
CTX_DATA_END;
@@ -297,7 +295,6 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
@@ -315,7 +312,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
/* now remove all selected objects from the group */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- BKE_group_object_unlink(group, base->object, scene, base);
+ BKE_group_object_unlink(group, base->object);
updated = true;
}
CTX_DATA_END;
@@ -357,7 +354,6 @@ void GROUP_OT_objects_remove(wmOperatorType *ot)
static int group_create_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
Group *group = NULL;
char name[MAX_ID_NAME - 2]; /* id name */
@@ -367,7 +363,7 @@ static int group_create_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
- BKE_group_object_add(group, base->object, scene, base);
+ BKE_group_object_add(group, base->object);
}
CTX_DATA_END;
@@ -398,7 +394,6 @@ void GROUP_OT_create(wmOperatorType *ot)
static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
Main *bmain = CTX_data_main(C);
Group *group;
@@ -407,7 +402,7 @@ static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
group = BKE_group_add(bmain, "Group");
- BKE_group_object_add(group, ob, scene, NULL);
+ BKE_group_object_add(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -432,7 +427,6 @@ void OBJECT_OT_group_add(wmOperatorType *ot)
static int group_link_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
Group *group = BLI_findlink(&bmain->group, RNA_enum_get(op->ptr, "group"));
@@ -457,7 +451,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_group_object_add(group, ob, scene, NULL);
+ BKE_group_object_add(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -490,14 +484,13 @@ void OBJECT_OT_group_link(wmOperatorType *ot)
static int group_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data;
if (!ob || !group)
return OPERATOR_CANCELLED;
- BKE_group_object_unlink(group, ob, scene, NULL); /* base will be used if found */
+ BKE_group_object_unlink(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -560,8 +553,10 @@ static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select o
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) {
- ED_base_object_select(base, BA_SELECT);
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (BKE_group_object_exists(group, base->object)) {
+ ED_object_base_select(base, BA_SELECT);
+ }
}
}
CTX_DATA_END;
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 438c10c51fa..abb0172d9ce 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -49,6 +49,7 @@
#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -445,26 +446,26 @@ static int hook_op_edit_poll(bContext *C)
return 0;
}
-static Object *add_hook_object_new(Main *bmain, Scene *scene, Object *obedit)
+static Object *add_hook_object_new(Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit)
{
Base *base, *basedit;
Object *ob;
- ob = BKE_object_add(bmain, scene, OB_EMPTY, NULL);
+ ob = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL);
- basedit = BKE_scene_base_find(scene, obedit);
- base = scene->basact;
+ basedit = BKE_scene_layer_base_find(sl, obedit);
+ base = sl->basact;
base->lay = ob->lay = obedit->lay;
- BLI_assert(scene->basact->object == ob);
+ BLI_assert(sl->basact->object == ob);
/* icky, BKE_object_add sets new base as active.
* so set it back to the original edit object */
- scene->basact = basedit;
+ sl->basact = basedit;
return ob;
}
-static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode, ReportList *reports)
+static int add_hook_object(Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit, Object *ob, int mode, ReportList *reports)
{
ModifierData *md = NULL;
HookModifierData *hmd = NULL;
@@ -482,7 +483,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
if (mode == OBJECT_ADDHOOK_NEWOB && !ob) {
- ob = add_hook_object_new(bmain, scene, obedit);
+ ob = add_hook_object_new(bmain, scene, sl, obedit);
/* transform cent to global coords for loc */
mul_v3_m4v3(ob->loc, obedit->obmat, cent);
@@ -556,6 +557,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Object *obsel = NULL;
const bool use_bone = RNA_boolean_get(op->ptr, "use_bone");
@@ -580,7 +582,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (add_hook_object(bmain, scene, obedit, obsel, mode, op->reports)) {
+ if (add_hook_object(bmain, scene, sl, obedit, obsel, mode, op->reports)) {
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;
}
@@ -611,9 +613,10 @@ static int object_add_hook_newob_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
- if (add_hook_object(bmain, scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) {
+ if (add_hook_object(bmain, scene, sl, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index b8957bdedf9..ed64f1c8ec1 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -70,7 +70,6 @@ void OBJECT_OT_make_local(struct wmOperatorType *ot);
void OBJECT_OT_make_single_user(struct wmOperatorType *ot);
void OBJECT_OT_make_links_scene(struct wmOperatorType *ot);
void OBJECT_OT_make_links_data(struct wmOperatorType *ot);
-void OBJECT_OT_move_to_layer(struct wmOperatorType *ot);
void OBJECT_OT_drop_named_material(struct wmOperatorType *ot);
void OBJECT_OT_unlink_data(struct wmOperatorType *ot);
@@ -78,10 +77,6 @@ void OBJECT_OT_unlink_data(struct wmOperatorType *ot);
void OBJECT_OT_mode_set(struct wmOperatorType *ot);
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot);
-void OBJECT_OT_hide_view_set(struct wmOperatorType *ot);
-void OBJECT_OT_hide_view_clear(struct wmOperatorType *ot);
-void OBJECT_OT_hide_render_set(struct wmOperatorType *ot);
-void OBJECT_OT_hide_render_clear(struct wmOperatorType *ot);
void OBJECT_OT_proxy_make(struct wmOperatorType *ot);
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
@@ -247,6 +242,15 @@ void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_normalize_active_vertex(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot);
+/* object_facemap_ops.c */
+void OBJECT_OT_face_map_add(struct wmOperatorType *ot);
+void OBJECT_OT_face_map_remove(struct wmOperatorType *ot);
+void OBJECT_OT_face_map_assign(struct wmOperatorType *ot);
+void OBJECT_OT_face_map_remove_from(struct wmOperatorType *ot);
+void OBJECT_OT_face_map_select(struct wmOperatorType *ot);
+void OBJECT_OT_face_map_deselect(struct wmOperatorType *ot);
+void OBJECT_OT_face_map_move(struct wmOperatorType *ot);
+
/* object_warp.c */
void TRANSFORM_OT_vertex_warp(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 1aa1407797b..d614be175f2 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -411,7 +411,7 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *
return 1;
}
-int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
+int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, SceneLayer *sl, Object *ob, ModifierData *md)
{
Object *obn;
ParticleSystem *psys;
@@ -463,7 +463,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
if (totvert == 0) return 0;
/* add new mesh */
- obn = BKE_object_add(bmain, scene, OB_MESH, NULL);
+ obn = BKE_object_add(bmain, scene, sl, OB_MESH, NULL);
me = obn->data;
me->totvert = totvert;
@@ -872,7 +872,7 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
static int modifier_remove_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int mode_orig = ob->mode;
@@ -885,7 +885,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
/* if cloth/softbody was removed, particle mode could be cleared */
if (mode_orig & OB_MODE_PARTICLE_EDIT)
if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0)
- if (scene->basact && scene->basact->object == ob)
+ if (sl->basact && sl->basact->object == ob)
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
return OPERATOR_FINISHED;
@@ -1048,10 +1048,11 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
+ if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, sl, ob, md))
return OPERATOR_CANCELLED;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -1684,7 +1685,7 @@ static void skin_armature_bone_create(Object *skin_ob,
}
}
-static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob)
+static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, SceneLayer *sl, Object *skin_ob)
{
BLI_bitmap *edges_visited;
DerivedMesh *deform_dm;
@@ -1707,7 +1708,7 @@ static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *
NULL,
me->totvert);
- arm_ob = BKE_object_add(bmain, scene, OB_ARMATURE, NULL);
+ arm_ob = BKE_object_add(bmain, scene, sl, OB_ARMATURE, NULL);
BKE_object_transform_copy(arm_ob, skin_ob);
arm = arm_ob->data;
arm->layer = 1;
@@ -1766,6 +1767,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = CTX_data_active_object(C), *arm_ob;
Mesh *me = ob->data;
ModifierData *skin_md;
@@ -1777,7 +1779,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
}
/* create new armature */
- arm_ob = modifier_skin_armature_create(bmain, scene, ob);
+ arm_ob = modifier_skin_armature_create(bmain, scene, sl, ob);
/* add a modifier to connect the new armature to the mesh */
arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 5fe5a884354..5641f62ec7a 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -67,10 +67,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_editmode_toggle);
WM_operatortype_append(OBJECT_OT_posemode_toggle);
WM_operatortype_append(OBJECT_OT_proxy_make);
- WM_operatortype_append(OBJECT_OT_hide_view_clear);
- WM_operatortype_append(OBJECT_OT_hide_view_set);
- WM_operatortype_append(OBJECT_OT_hide_render_clear);
- WM_operatortype_append(OBJECT_OT_hide_render_set);
WM_operatortype_append(OBJECT_OT_shade_smooth);
WM_operatortype_append(OBJECT_OT_shade_flat);
WM_operatortype_append(OBJECT_OT_paths_calculate);
@@ -90,13 +86,11 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_make_single_user);
WM_operatortype_append(OBJECT_OT_make_links_scene);
WM_operatortype_append(OBJECT_OT_make_links_data);
- WM_operatortype_append(OBJECT_OT_move_to_layer);
WM_operatortype_append(OBJECT_OT_select_random);
WM_operatortype_append(OBJECT_OT_select_all);
WM_operatortype_append(OBJECT_OT_select_same_group);
WM_operatortype_append(OBJECT_OT_select_by_type);
- WM_operatortype_append(OBJECT_OT_select_by_layer);
WM_operatortype_append(OBJECT_OT_select_linked);
WM_operatortype_append(OBJECT_OT_select_grouped);
WM_operatortype_append(OBJECT_OT_select_mirror);
@@ -202,6 +196,14 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active_vertex);
WM_operatortype_append(OBJECT_OT_vertex_weight_copy);
+ WM_operatortype_append(OBJECT_OT_face_map_add);
+ WM_operatortype_append(OBJECT_OT_face_map_remove);
+ WM_operatortype_append(OBJECT_OT_face_map_assign);
+ WM_operatortype_append(OBJECT_OT_face_map_remove_from);
+ WM_operatortype_append(OBJECT_OT_face_map_select);
+ WM_operatortype_append(OBJECT_OT_face_map_deselect);
+ WM_operatortype_append(OBJECT_OT_face_map_move);
+
WM_operatortype_append(TRANSFORM_OT_vertex_warp);
WM_operatortype_append(OBJECT_OT_game_property_new);
@@ -383,25 +385,6 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
- kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", false);
-
- kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", true);
-
- /* same as above but for rendering */
- WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_clear", HKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
- WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_CTRL, 0);
-
- /* conflicts, removing */
-#if 0
- kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)
- RNA_boolean_set(kmi->ptr, "unselected", true);
-#endif
-
- WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
-
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_global", false);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 7ec43b02b38..f19b5619066 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -63,6 +63,7 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
+#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
@@ -75,6 +76,7 @@
#include "BKE_idprop.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
@@ -123,6 +125,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
BMVert *eve;
BMIter iter;
@@ -239,7 +242,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
else {
Object workob;
- ob->parent = BASACT->object;
+ ob->parent = BASACT_NEW->object;
if (v3) {
ob->partype = PARVERT3;
ob->par1 = v1 - 1;
@@ -333,6 +336,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
Object *ob, *gob = ED_object_active_context(C);
GroupObject *go;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
if (gob->dup_group != NULL) {
go = BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "object"));
@@ -345,16 +349,16 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
if (ob) {
Object *newob;
- Base *newbase, *oldbase = BASACT;
+ BaseLegacy *newbase, *oldbase = BASACT_NEW;
char name[MAX_ID_NAME + 4];
BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name + 2);
/* Add new object for the proxy */
- newob = BKE_object_add(bmain, scene, OB_EMPTY, name);
+ newob = BKE_object_add(bmain, scene, sl, OB_EMPTY, name);
/* set layers OK */
- newbase = BASACT; /* BKE_object_add sets active... */
+ newbase = BASACT_NEW; /* BKE_object_add sets active... */
newbase->lay = oldbase->lay;
newob->lay = newbase->lay;
@@ -1307,119 +1311,6 @@ void OBJECT_OT_track_set(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", "");
}
-/************************** Move to Layer Operator *****************************/
-
-static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
-{
- int values[20], a;
- unsigned int lay = 0;
-
- if (!RNA_struct_property_is_set(op->ptr, "layers")) {
- /* note: layers are set in bases, library objects work for this */
- CTX_DATA_BEGIN (C, Base *, base, selected_bases)
- {
- lay |= base->lay;
- }
- CTX_DATA_END;
-
- for (a = 0; a < 20; a++)
- values[a] = (lay & (1 << a)) != 0;
-
- RNA_boolean_set_array(op->ptr, "layers", values);
- }
- else {
- RNA_boolean_get_array(op->ptr, "layers", values);
-
- for (a = 0; a < 20; a++)
- if (values[a])
- lay |= (1 << a);
- }
-
- return lay;
-}
-
-static int move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d && v3d->localvd) {
- return WM_operator_confirm_message(C, op, "Move out of Local View");
- }
- else {
- move_to_layer_init(C, op);
- return WM_operator_props_popup(C, op, event);
- }
-}
-
-static int move_to_layer_exec(bContext *C, wmOperator *op)
-{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- unsigned int lay, local;
- /* bool is_lamp = false; */ /* UNUSED */
-
- lay = move_to_layer_init(C, op);
- lay &= 0xFFFFFF;
-
- if (lay == 0) return OPERATOR_CANCELLED;
-
- if (v3d && v3d->localvd) {
- /* now we can move out of localview. */
- /* note: layers are set in bases, library objects work for this */
- CTX_DATA_BEGIN (C, Base *, base, selected_bases)
- {
- lay = base->lay & ~v3d->lay;
- base->lay = lay;
- base->object->lay = lay;
- base->object->flag &= ~SELECT;
- base->flag &= ~SELECT;
- /* if (base->object->type == OB_LAMP) is_lamp = true; */
- }
- CTX_DATA_END;
- }
- else {
- /* normal non localview operation */
- /* note: layers are set in bases, library objects work for this */
- CTX_DATA_BEGIN (C, Base *, base, selected_bases)
- {
- /* upper byte is used for local view */
- local = base->lay & 0xFF000000;
- base->lay = lay + local;
- base->object->lay = base->lay;
- /* if (base->object->type == OB_LAMP) is_lamp = true; */
- }
- CTX_DATA_END;
- }
-
- /* warning, active object may be hidden now */
-
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
-
- DAG_relations_tag_update(bmain);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_move_to_layer(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Move to Layer";
- ot->description = "Move the object to different layers";
- ot->idname = "OBJECT_OT_move_to_layer";
-
- /* api callbacks */
- ot->invoke = move_to_layer_invoke;
- ot->exec = move_to_layer_exec;
- ot->poll = ED_operator_objectmode;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", "");
-}
-
/************************** Link to Scene Operator *****************************/
#if 0
@@ -1442,20 +1333,6 @@ static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr))
}
#endif
-Base *ED_object_scene_link(Scene *scene, Object *ob)
-{
- Base *base;
-
- if (BKE_scene_base_find(scene, ob)) {
- return NULL;
- }
-
- base = BKE_scene_base_add(scene, ob);
- id_us_plus(&ob->id);
-
- return base;
-}
-
static int make_links_scene_exec(bContext *C, wmOperator *op)
{
Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
@@ -1475,9 +1352,10 @@ static int make_links_scene_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ SceneCollection *sc_to = BKE_collection_master(scene_to);
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
- ED_object_scene_link(scene_to, base->object);
+ BKE_collection_object_add(scene_to, sc_to, base->object);
}
CTX_DATA_END;
@@ -1533,7 +1411,6 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
static int make_links_data_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
const int type = RNA_enum_get(op->ptr, "type");
Object *ob_src;
ID *obdata_id;
@@ -1596,12 +1473,12 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
LinkNode *group_node;
/* first clear groups */
- BKE_object_groups_clear(scene, base_dst, ob_dst);
+ BKE_object_groups_clear(ob_dst);
/* now add in the groups from the link nodes */
for (group_node = ob_groups; group_node; group_node = group_node->next) {
if (ob_dst->dup_group != group_node->link) {
- BKE_group_object_add(group_node->link, ob_dst, scene, base_dst);
+ BKE_group_object_add(group_node->link, ob_dst);
}
else {
is_cycle = true;
@@ -1734,48 +1611,82 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
+static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, const bool copy_groups)
+{
+ if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
+ /* base gets copy of object */
+ Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
+
+ if (copy_groups) {
+ if (ob->flag & OB_FROMGROUP) {
+ obn->flag |= OB_FROMGROUP;
+ }
+ }
+ else {
+ /* copy already clears */
+ }
+ /* remap gpencil parenting */
+
+ if (scene->gpd) {
+ bGPdata *gpd = scene->gpd;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if (gpl->parent == ob) {
+ gpl->parent = obn;
+ }
+ }
+ }
+
+ id_us_min(&ob->id);
+ return obn;
+ }
+ return NULL;
+}
+
+static void libblock_relink_scene_collection(SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ BKE_libblock_relink_to_newid(link->data);
+ }
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ libblock_relink_scene_collection(nsc);
+ }
+}
+
+static void single_object_users_scene_collection(Main *bmain, Scene *scene, SceneCollection *sc, const int flag, const bool copy_groups)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ Object *ob = link->data;
+ /* an object may be in more than one collection */
+ if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
+ link->data = single_object_users_object(bmain, scene, link->data, copy_groups);
+ }
+ }
+
+ /* we reset filter objects because they should be regenerated after this */
+ BLI_freelistN(&sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ single_object_users_scene_collection(bmain, scene, nsc, flag, copy_groups);
+ }
+}
+
/* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
{
- Base *base;
- Object *ob, *obn;
Group *group, *groupn;
GroupObject *go;
clear_sca_new_poins(); /* BGE logic */
- /* duplicate (must set newid) */
- for (base = FIRSTBASE; base; base = base->next) {
- ob = base->object;
-
- if ((base->flag & flag) == flag) {
- if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
- /* base gets copy of object */
- base->object = obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
+ /* duplicate all the objects of the scene */
+ SceneCollection *msc = BKE_collection_master(scene);
+ single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups);
- if (copy_groups) {
- if (ob->flag & OB_FROMGROUP) {
- obn->flag |= OB_FROMGROUP;
- }
- }
- else {
- /* copy already clears */
- }
- /* remap gpencil parenting */
-
- if (scene->gpd) {
- bGPdata *gpd = scene->gpd;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- if (gpl->parent == ob) {
- gpl->parent = obn;
- }
- }
- }
-
- base->flag = obn->flag;
-
- id_us_min(&ob->id);
- }
+ /* loop over SceneLayers and assign the pointers accordingly */
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ ID_NEW_REMAP(base->object);
}
}
@@ -1808,27 +1719,28 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
if (v3d) ID_NEW_REMAP(v3d->camera);
/* object and group pointers */
- for (base = FIRSTBASE; base; base = base->next) {
- BKE_libblock_relink_to_newid(&base->object->id);
- }
+ libblock_relink_scene_collection(msc);
set_sca_new_poins();
+
+ /* TODO redo filter */
+ TODO_LAYER_SYNC_FILTER
}
/* not an especially efficient function, only added so the single user
* button can be functional.*/
void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
{
- Base *base;
- const bool copy_groups = false;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->object == ob) base->flag |= OB_DONE;
- else base->flag &= ~OB_DONE;
+ FOREACH_SCENE_OBJECT(scene, ob_iter)
+ {
+ ob_iter->flag &= ~OB_DONE;
}
+ FOREACH_SCENE_OBJECT_END
- single_object_users(bmain, scene, NULL, OB_DONE, copy_groups);
+ /* tag only the one object */
+ ob->flag |= OB_DONE;
+ single_object_users(bmain, scene, NULL, OB_DONE, false);
BKE_main_id_clear_newpoins(bmain);
}
@@ -1853,21 +1765,19 @@ static void new_id_matar(Main *bmain, Material **matar, const int totcol)
}
}
-static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
+static void single_obdata_users(Main *bmain, Scene *scene, SceneLayer *sl, const int flag)
{
- Object *ob;
Lamp *la;
Curve *cu;
/* Camera *cam; */
- Base *base;
Mesh *me;
Lattice *lat;
ID *id;
int a;
- for (base = FIRSTBASE; base; base = base->next) {
- ob = base->object;
- if (!ID_IS_LINKED_DATABLOCK(ob) && (base->flag & flag) == flag) {
+ FOREACH_OBJECT_FLAG(scene, sl, flag, ob)
+ {
+ if (!ID_IS_LINKED_DATABLOCK(ob)) {
id = ob->data;
if (id && id->us > 1 && !ID_IS_LINKED_DATABLOCK(id)) {
@@ -1933,6 +1843,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
}
}
}
+ FOREACH_OBJECT_FLAG_END
me = bmain->mesh.first;
while (me) {
@@ -1941,31 +1852,24 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
}
}
-static void single_object_action_users(Scene *scene, const int flag)
+static void single_object_action_users(Scene *scene, SceneLayer *sl, const int flag)
{
- Object *ob;
- Base *base;
-
- for (base = FIRSTBASE; base; base = base->next) {
- ob = base->object;
- if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) {
+ FOREACH_OBJECT_FLAG(scene, sl, flag, ob)
+ if (!ID_IS_LINKED_DATABLOCK(ob)) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
BKE_animdata_copy_id_action(&ob->id, false);
}
- }
+ FOREACH_OBJECT_FLAG_END
}
-static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bool do_textures)
+static void single_mat_users(Main *bmain, Scene *scene, SceneLayer *sl, const int flag, const bool do_textures)
{
- Object *ob;
- Base *base;
Material *ma, *man;
Tex *tex;
int a, b;
- for (base = FIRSTBASE; base; base = base->next) {
- ob = base->object;
- if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) {
+ FOREACH_OBJECT_FLAG(scene, sl, flag, ob)
+ if (!ID_IS_LINKED_DATABLOCK(ob)) {
for (a = 1; a <= ob->totcol; a++) {
ma = give_current_material(ob, a);
if (ma) {
@@ -1994,7 +1898,7 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo
}
}
}
- }
+ FOREACH_OBJECT_FLAG_END
}
static void do_single_tex_user(Main *bmain, Tex **from)
@@ -2097,8 +2001,8 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo
single_object_users(bmain, scene, NULL, 0, copy_groups);
if (full) {
- single_obdata_users(bmain, scene, 0);
- single_object_action_users(scene, 0);
+ single_obdata_users(bmain, scene, NULL, 0);
+ single_object_action_users(scene, NULL, 0);
single_mat_users_expand(bmain);
single_tex_users_expand(bmain);
}
@@ -2229,7 +2133,7 @@ static void tag_localizable_objects(bContext *C, const int mode)
* Instance indirectly referenced zero user objects,
* otherwise they're lost on reload, see T40595.
*/
-static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene)
+static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene, SceneLayer *sl, SceneCollection *sc)
{
Object *ob;
bool changed = false;
@@ -2240,9 +2144,10 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene)
id_us_plus(&ob->id);
- base = BKE_scene_base_add(scene, ob);
- base->flag |= SELECT;
- base->object->flag = base->flag;
+ BKE_collection_object_add(scene, sc, ob);
+ base = BKE_scene_layer_base_find(sl, ob);
+ base->flag |= BASE_SELECTED;
+ BKE_scene_object_base_flag_sync_from_base(base);
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
changed = true;
@@ -2256,6 +2161,8 @@ static int make_local_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ SceneCollection *sc = CTX_data_scene_collection(C);
AnimData *adt;
ParticleSystem *psys;
Material *ma, ***matarar;
@@ -2268,7 +2175,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
/* de-select so the user can differentiate newly instanced from existing objects */
BKE_scene_base_deselect_all(scene);
- if (make_local_all__instance_indirect_unused(bmain, scene)) {
+ if (make_local_all__instance_indirect_unused(bmain, scene, sl, sc)) {
BKE_report(op->reports, RPT_INFO,
"Orphan library objects added to the current scene to avoid loss");
}
@@ -2408,24 +2315,31 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */
const int flag = (RNA_enum_get(op->ptr, "type") == MAKE_SINGLE_USER_SELECTED) ? SELECT : 0;
const bool copy_groups = false;
bool update_deps = false;
if (RNA_boolean_get(op->ptr, "object")) {
- single_object_users(bmain, scene, v3d, flag, copy_groups);
+ if (flag == SELECT) {
+ BKE_scene_layer_selected_objects_tag(sl, OB_DONE);
+ single_object_users(bmain, scene, v3d, OB_DONE, copy_groups);
+ }
+ else {
+ single_object_users(bmain, scene, v3d, 0, copy_groups);
+ }
/* needed since object relationships may have changed */
update_deps = true;
}
if (RNA_boolean_get(op->ptr, "obdata")) {
- single_obdata_users(bmain, scene, flag);
+ single_obdata_users(bmain, scene, sl, flag);
}
if (RNA_boolean_get(op->ptr, "material")) {
- single_mat_users(bmain, scene, flag, RNA_boolean_get(op->ptr, "texture"));
+ single_mat_users(bmain, scene, sl, flag, RNA_boolean_get(op->ptr, "texture"));
}
#if 0 /* can't do this separate from materials */
@@ -2433,7 +2347,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
single_mat_users(scene, flag, true);
#endif
if (RNA_boolean_get(op->ptr, "animation")) {
- single_object_action_users(scene, flag);
+ single_object_action_users(scene, sl, flag);
}
BKE_main_id_clear_newpoins(bmain);
@@ -2480,7 +2394,7 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+ BaseLegacy *base = ED_view3d_give_base_under_cursor(C, event->mval);
Material *ma;
char name[MAX_ID_NAME - 2];
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index b5131df3eaa..4bdd524f110 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -52,6 +52,7 @@
#include "BKE_context.h"
#include "BKE_group.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_particle.h"
@@ -86,22 +87,22 @@
/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or
* or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */
-void ED_base_object_select(Base *base, short mode)
+void ED_base_object_select(BaseLegacy *base, short mode)
{
if (base) {
if (mode == BA_SELECT) {
if (!(base->object->restrictflag & OB_RESTRICT_SELECT))
- base->flag |= SELECT;
+ base->flag_legacy |= SELECT;
}
else if (mode == BA_DESELECT) {
- base->flag &= ~SELECT;
+ base->flag_legacy &= ~SELECT;
}
- base->object->flag = base->flag;
+ BKE_scene_base_flag_sync_from_base(base);
}
}
/* also to set active NULL */
-void ED_base_object_activate(bContext *C, Base *base)
+void ED_base_object_activate(bContext *C, BaseLegacy *base)
{
Scene *scene = CTX_data_scene(C);
@@ -119,6 +120,33 @@ void ED_base_object_activate(bContext *C, Base *base)
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, NULL);
}
+void ED_object_base_select(Base *base, short mode)
+{
+ if (base) {
+ if (mode == BA_SELECT) {
+ if ((base->flag & BASE_SELECTABLED) != 0) {
+ base->flag |= BASE_SELECTED;
+ }
+ }
+ else if (mode == BA_DESELECT) {
+ base->flag &= ~BASE_SELECTED;
+ }
+ }
+}
+
+void ED_object_base_activate(bContext *C, Base *base)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ sl->basact = base;
+
+ if (base) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, sl);
+ }
+ else {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, NULL);
+ }
+}
+
/********************** Selection Operators **********************/
static int objects_selectable_poll(bContext *C)
@@ -147,7 +175,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
}
CTX_DATA_END;
}
@@ -155,7 +183,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
if (base->object->type == obtype) {
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_select(base, BA_SELECT);
}
}
CTX_DATA_END;
@@ -210,38 +238,15 @@ static EnumPropertyItem prop_select_linked_types[] = {
{0, NULL, 0, NULL, NULL}
};
-// XXX old animation system
-#if 0
-static int object_select_all_by_ipo(bContext *C, Ipo *ipo)
-{
- bool changed = false;
-
- CTX_DATA_BEGIN (C, Base *, base, visible_bases)
- {
- if (base->object->ipo == ipo) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
-
- changed = true;
- }
- }
- CTX_DATA_END;
-
- return changed;
-}
-#endif
-
static bool object_select_all_by_obdata(bContext *C, void *obdata)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if ((base->flag & SELECT) == 0) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (base->object->data == obdata) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
-
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -257,7 +262,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if ((base->flag & SELECT) == 0) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
Object *ob = base->object;
Material *mat1;
int a, b;
@@ -267,7 +272,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
if (!use_texture) {
if (mat1 == mat) {
- base->flag |= SELECT;
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -275,7 +280,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
for (b = 0; b < MAX_MTEX; b++) {
if (mat1->mtex[b]) {
if (tex == mat1->mtex[b]->tex) {
- base->flag |= SELECT;
+ ED_object_base_select(base, BA_SELECT);
changed = true;
break;
}
@@ -283,8 +288,6 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
}
}
}
-
- base->object->flag = base->flag;
}
}
CTX_DATA_END;
@@ -299,12 +302,10 @@ static bool object_select_all_by_dup_group(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if ((base->flag & SELECT) == 0) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
Group *dup_group_other = (base->object->transflag & OB_DUPLIGROUP) ? base->object->dup_group : NULL;
if (dup_group == dup_group_other) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
-
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -321,23 +322,21 @@ static bool object_select_all_by_particle(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if ((base->flag & SELECT) == 0) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
/* loop through other particles*/
ParticleSystem *psys;
for (psys = base->object->particlesystem.first; psys; psys = psys->next) {
if (psys->part == psys_act->part) {
- base->flag |= SELECT;
+ ED_object_base_select(base, BA_SELECT);
changed = true;
break;
}
- if (base->flag & SELECT) {
+ if (base->flag & BASE_SELECTED) {
break;
}
}
-
- base->object->flag = base->flag;
}
}
CTX_DATA_END;
@@ -351,11 +350,9 @@ static bool object_select_all_by_library(bContext *C, Library *lib)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if ((base->flag & SELECT) == 0) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (lib == base->object->id.lib) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
-
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -371,11 +368,9 @@ static bool object_select_all_by_library_obdata(bContext *C, Library *lib)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if ((base->flag & SELECT) == 0) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (base->object->data && lib == ((ID *)base->object->data)->lib) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
-
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -408,6 +403,7 @@ void ED_object_select_linked_by_id(bContext *C, ID *id)
static int object_select_linked_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob;
int nr = RNA_enum_get(op->ptr, "type");
bool changed = false, extend;
@@ -417,12 +413,12 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
}
CTX_DATA_END;
}
- ob = OBACT;
+ ob = OBACT_NEW;
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
@@ -517,7 +513,7 @@ enum {
OBJECT_GRPSEL_PARENT = 2,
OBJECT_GRPSEL_SIBLINGS = 3,
OBJECT_GRPSEL_TYPE = 4,
- OBJECT_GRPSEL_LAYER = 5,
+ /*OBJECT_GRPSEL_LAYER = 5,*/
OBJECT_GRPSEL_GROUP = 6,
OBJECT_GRPSEL_HOOK = 7,
OBJECT_GRPSEL_PASS = 8,
@@ -533,7 +529,6 @@ static EnumPropertyItem prop_select_grouped_types[] = {
{OBJECT_GRPSEL_PARENT, "PARENT", 0, "Parent", ""},
{OBJECT_GRPSEL_SIBLINGS, "SIBLINGS", 0, "Siblings", "Shared Parent"},
{OBJECT_GRPSEL_TYPE, "TYPE", 0, "Type", "Shared object type"},
- {OBJECT_GRPSEL_LAYER, "LAYER", 0, "Layer", "Shared layers"},
{OBJECT_GRPSEL_GROUP, "GROUP", 0, "Group", "Shared group"},
{OBJECT_GRPSEL_HOOK, "HOOK", 0, "Hook", ""},
{OBJECT_GRPSEL_PASS, "PASS", 0, "Pass", "Render pass Index"},
@@ -551,13 +546,14 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
if (ob == base->object->parent) {
- if (!(base->flag & SELECT)) {
- ED_base_object_select(base, BA_SELECT);
+ if ((base->flag & BASE_SELECTED) == 0) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
- if (recursive)
+ if (recursive) {
changed |= select_grouped_children(C, base->object, 1);
+ }
}
}
CTX_DATA_END;
@@ -566,20 +562,20 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv
static bool select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- bool changed = false;
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *baspar, *basact = CTX_data_active_base(C);
+ bool changed = false;
- if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */
+ if (!basact || !(basact->object->parent)) {
+ return 0; /* we know OBACT is valid */
+ }
- baspar = BKE_scene_base_find(scene, basact->object->parent);
+ baspar = BKE_scene_layer_base_find(sl, basact->object->parent);
/* can be NULL if parent in other scene */
- if (baspar && BASE_SELECTABLE(v3d, baspar)) {
- ED_base_object_select(baspar, BA_SELECT);
- ED_base_object_activate(C, baspar);
+ if (baspar && BASE_SELECTABLE_NEW(baspar)) {
+ ED_object_base_select(baspar, BA_SELECT);
+ ED_object_base_activate(C, baspar);
changed = true;
}
return changed;
@@ -608,9 +604,11 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in
group = ob_groups[0];
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) {
- ED_base_object_select(base, BA_SELECT);
- changed = true;
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (BKE_group_object_exists(group, base->object)) {
+ ED_object_base_select(base, BA_SELECT);
+ changed = true;
+ }
}
}
CTX_DATA_END;
@@ -632,8 +630,7 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in
static bool select_grouped_object_hooks(bContext *C, Object *ob)
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
bool changed = false;
Base *base;
@@ -644,8 +641,8 @@ static bool select_grouped_object_hooks(bContext *C, Object *ob)
if (md->type == eModifierType_Hook) {
hmd = (HookModifierData *) md;
if (hmd->object && !(hmd->object->flag & SELECT)) {
- base = BKE_scene_base_find(scene, hmd->object);
- if (base && (BASE_SELECTABLE(v3d, base))) {
+ base = BKE_scene_layer_base_find(sl, hmd->object);
+ if (base && (BASE_SELECTABLE_NEW(base))) {
ED_base_object_select(base, BA_SELECT);
changed = true;
}
@@ -663,8 +660,8 @@ static bool select_grouped_siblings(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if ((base->object->parent == ob->parent) && !(base->flag & SELECT)) {
- ED_base_object_select(base, BA_SELECT);
+ if ((base->object->parent == ob->parent) && ((base->flag & BASE_SELECTED) == 0)) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -681,8 +678,8 @@ static bool select_grouped_lamptype(bContext *C, Object *ob)
{
if (base->object->type == OB_LAMP) {
Lamp *la_test = base->object->data;
- if ((la->type == la_test->type) && !(base->flag & SELECT)) {
- ED_base_object_select(base, BA_SELECT);
+ if ((la->type == la_test->type) && ((base->flag & BASE_SELECTED) == 0)) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -696,23 +693,8 @@ static bool select_grouped_type(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if ((base->object->type == ob->type) && !(base->flag & SELECT)) {
- ED_base_object_select(base, BA_SELECT);
- changed = true;
- }
- }
- CTX_DATA_END;
- return changed;
-}
-
-static bool select_grouped_layer(bContext *C, Object *ob)
-{
- bool changed = false;
-
- CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
- {
- if ((base->lay & ob->lay) && !(base->flag & SELECT)) {
- ED_base_object_select(base, BA_SELECT);
+ if ((base->object->type == ob->type) && ((base->flag & BASE_SELECTED) == 0)) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -726,8 +708,8 @@ static bool select_grouped_index_object(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if ((base->object->index == ob->index) && !(base->flag & SELECT)) {
- ED_base_object_select(base, BA_SELECT);
+ if ((base->object->index == ob->index) && ((base->flag & BASE_SELECTED) == 0)) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -741,8 +723,8 @@ static bool select_grouped_color(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if (!(base->flag & SELECT) && (compare_v3v3(base->object->col, ob->col, 0.005f))) {
- ED_base_object_select(base, BA_SELECT);
+ if (((base->flag & BASE_SELECTED) == 0) && (compare_v3v3(base->object->col, ob->col, 0.005f))) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -768,8 +750,8 @@ static bool select_grouped_gameprops(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
- ED_base_object_select(base, BA_SELECT);
+ if (((base->flag & BASE_SELECTED) == 0) && (objects_share_gameprop(base->object, ob))) {
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -807,7 +789,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
/* only check for this object if it isn't selected already, to limit time wasted */
- if ((base->flag & SELECT) == 0) {
+ if ((base->flag & BASE_SELECTED) == 0) {
KS_Path *ksp;
/* this is the slow way... we could end up with > 500 items here,
@@ -816,7 +798,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
/* if id matches, select then stop looping (match found) */
if (ksp->id == (ID *)base->object) {
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_select(base, BA_SELECT);
changed = true;
break;
}
@@ -831,6 +813,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
static int object_select_grouped_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob;
const int type = RNA_enum_get(op->ptr, "type");
bool changed = false, extend;
@@ -840,13 +823,13 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
changed = true;
}
CTX_DATA_END;
}
- ob = OBACT;
+ ob = OBACT_NEW;
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
@@ -868,9 +851,6 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
case OBJECT_GRPSEL_TYPE:
changed |= select_grouped_type(C, ob);
break;
- case OBJECT_GRPSEL_LAYER:
- changed |= select_grouped_layer(C, ob);
- break;
case OBJECT_GRPSEL_GROUP:
changed |= select_grouped_group(C, ob);
break;
@@ -928,85 +908,6 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
}
-/************************* Select by Layer **********************/
-enum {
- OB_SEL_LAYERMATCH_EXACT = 1,
- OB_SEL_LAYERMATCH_SHARED = 2,
-};
-
-static int object_select_by_layer_exec(bContext *C, wmOperator *op)
-{
- unsigned int layernum;
- bool extend;
- int match;
-
- extend = RNA_boolean_get(op->ptr, "extend");
- layernum = RNA_int_get(op->ptr, "layers");
- match = RNA_enum_get(op->ptr, "match");
-
- if (extend == false) {
- CTX_DATA_BEGIN (C, Base *, base, visible_bases)
- {
- ED_base_object_select(base, BA_DESELECT);
- }
- CTX_DATA_END;
- }
-
- CTX_DATA_BEGIN (C, Base *, base, visible_bases)
- {
- bool ok = false;
-
- switch (match) {
- case OB_SEL_LAYERMATCH_EXACT:
- /* Mask out bits used for local view, only work on real layer ones, see T45783. */
- ok = ((base->lay & ((1 << 20) - 1)) == (1 << (layernum - 1)));
- break;
- case OB_SEL_LAYERMATCH_SHARED:
- ok = (base->lay & (1 << (layernum - 1))) != 0;
- break;
- default:
- break;
- }
-
- if (ok) {
- ED_base_object_select(base, BA_SELECT);
- }
- }
- CTX_DATA_END;
-
- /* undo? */
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_select_by_layer(wmOperatorType *ot)
-{
- static EnumPropertyItem match_items[] = {
- {OB_SEL_LAYERMATCH_EXACT, "EXACT", 0, "Exact Match", ""},
- {OB_SEL_LAYERMATCH_SHARED, "SHARED", 0, "Shared Layers", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
- /* identifiers */
- ot->name = "Select by Layer";
- ot->description = "Select all visible objects on a layer";
- ot->idname = "OBJECT_OT_select_by_layer";
-
- /* api callbacks */
- /*ot->invoke = XXX - need a int grid popup*/
- ot->exec = object_select_by_layer_exec;
- ot->poll = objects_selectable_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_enum(ot->srna, "match", match_items, OB_SEL_LAYERMATCH_EXACT, "Match", "");
- RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
- RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20);
-}
-
/**************************** (De)select All ****************************/
static int object_select_all_exec(bContext *C, wmOperator *op)
@@ -1020,7 +921,7 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
action = SEL_SELECT;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (base->flag & SELECT) {
+ if ((base->flag & BASE_SELECTED) != 0) {
action = SEL_DESELECT;
break;
}
@@ -1032,17 +933,17 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
{
switch (action) {
case SEL_SELECT:
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_select(base, BA_SELECT);
break;
case SEL_DESELECT:
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
break;
case SEL_INVERT:
- if (base->flag & SELECT) {
- ED_base_object_select(base, BA_DESELECT);
+ if ((base->flag & BASE_SELECTED) != 0) {
+ ED_object_base_select(base, BA_DESELECT);
}
else {
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_select(base, BA_SELECT);
}
break;
}
@@ -1092,8 +993,11 @@ static int object_select_same_group_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object))
- ED_base_object_select(base, BA_SELECT);
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (BKE_group_object_exists(group, base->object)) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
}
CTX_DATA_END;
@@ -1124,6 +1028,7 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot)
static int object_select_mirror_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
bool extend;
extend = RNA_boolean_get(op->ptr, "extend");
@@ -1137,15 +1042,15 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
if (!STREQ(name_flip, primbase->object->id.name + 2)) {
Object *ob = (Object *)BKE_libblock_find_name(ID_OB, name_flip);
if (ob) {
- Base *secbase = BKE_scene_base_find(scene, ob);
+ Base *secbase = BKE_scene_layer_base_find(sl, ob);
if (secbase) {
- ED_base_object_select(secbase, BA_SELECT);
+ ED_object_base_select(secbase, BA_SELECT);
}
}
}
- if (extend == false) ED_base_object_select(primbase, BA_DESELECT);
+ if (extend == false) ED_object_base_select(primbase, BA_DESELECT);
}
CTX_DATA_END;
@@ -1180,9 +1085,9 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
static bool object_select_more_less(bContext *C, const bool select)
{
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (BaseLegacy *base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
ob->flag &= ~OB_DONE;
ob->id.tag &= ~LIB_TAG_DOIT;
@@ -1223,7 +1128,7 @@ static bool object_select_more_less(bContext *C, const bool select)
Base *base = ctx_base->ptr.data;
Object *ob = base->object;
if ((ob->id.tag & LIB_TAG_DOIT) && ((ob->flag & SELECT) != select_flag)) {
- ED_base_object_select(base, select_mode);
+ ED_object_base_select(base, select_mode);
changed = true;
}
}
@@ -1305,7 +1210,7 @@ static int object_select_random_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
if (BLI_rng_get_float(rng) < randfac) {
- ED_base_object_select(base, select);
+ ED_object_base_select(base, select);
}
}
CTX_DATA_END;
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 3c406764157..d93275a353e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -59,6 +59,7 @@
#include "BKE_depsgraph.h"
#include "BKE_mesh_mapping.h"
#include "BKE_editmesh.h"
+#include "BKE_layer.h"
#include "BKE_modifier.h"
#include "BKE_report.h"
#include "BKE_DerivedMesh.h"
@@ -3300,25 +3301,26 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Object *ob = ED_object_context(C);
- Base *base;
+ Object *ob_active = ED_object_context(C);
int retval = OPERATOR_CANCELLED;
- for (base = scene->base.first; base; base = base->next) {
- if (base->object->type == ob->type) {
- if (base->object != ob && base->object->data == ob->data) {
- BLI_freelistN(&base->object->defbase);
- BLI_duplicatelist(&base->object->defbase, &ob->defbase);
- base->object->actdef = ob->actdef;
+ FOREACH_SCENE_OBJECT(scene, ob_iter)
+ {
+ if (ob_iter->type == ob_active->type) {
+ if (ob_iter != ob_active && ob_iter->data == ob_active->data) {
+ BLI_freelistN(&ob_iter->defbase);
+ BLI_duplicatelist(&ob_iter->defbase, &ob_active->defbase);
+ ob_iter->actdef = ob_active->actdef;
- DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, base->object);
- WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, base->object->data);
+ DAG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
+ WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob_iter->data);
retval = OPERATOR_FINISHED;
}
}
}
+ FOREACH_SCENE_OBJECT_END
return retval;
}
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 3d7a45843cc..af2dc31e34f 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -286,6 +286,7 @@ typedef struct DynamicPaintBakeJob {
struct Main *bmain;
Scene *scene;
+ SceneLayer *scene_layer;
Object *ob;
DynamicPaintSurface *surface;
@@ -384,7 +385,7 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
/* calculate a frame */
scene->r.cfra = (int)frame;
ED_update_for_newframe(job->bmain, scene, 1);
- if (!dynamicPaint_calculateFrame(surface, scene, cObject, frame)) {
+ if (!dynamicPaint_calculateFrame(surface, scene, job->scene_layer, cObject, frame)) {
job->success = 0;
return;
}
@@ -452,6 +453,7 @@ static int dynamicpaint_bake_exec(struct bContext *C, struct wmOperator *op)
DynamicPaintCanvasSettings *canvas;
Object *ob = ED_object_context(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
DynamicPaintSurface *surface;
@@ -479,6 +481,7 @@ static int dynamicpaint_bake_exec(struct bContext *C, struct wmOperator *op)
DynamicPaintBakeJob *job = MEM_mallocN(sizeof(DynamicPaintBakeJob), "DynamicPaintBakeJob");
job->bmain = CTX_data_main(C);
job->scene = scene;
+ job->scene_layer = sl;
job->ob = ob;
job->canvas = canvas;
job->surface = surface;
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index e22a145b3a6..4eb6345c7e6 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -65,7 +65,6 @@
#include "BKE_pointcache.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "ED_object.h"
#include "ED_physics.h"
@@ -73,6 +72,9 @@
#include "ED_particle.h"
#include "ED_view3d.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "UI_resources.h"
#include "WM_api.h"
@@ -83,7 +85,7 @@
#include "physics_intern.h"
-void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys);
+void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys);
void PTCacheUndo_clear(PTCacheEdit *edit);
void recalc_lengths(PTCacheEdit *edit);
void recalc_emitter_field(Object *ob, ParticleSystem *psys);
@@ -109,24 +111,26 @@ void update_world_cos(Object *ob, PTCacheEdit *edit);
int PE_poll(bContext *C)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
+ if (!scene || !sl || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
return 0;
- return (PE_get_current(scene, ob) != NULL);
+ return (PE_get_current(scene, sl, ob) != NULL);
}
int PE_hair_poll(bContext *C)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
PTCacheEdit *edit;
if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
return 0;
- edit= PE_get_current(scene, ob);
+ edit= PE_get_current(scene, sl, ob);
return (edit && edit->psys);
}
@@ -211,7 +215,7 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br
*
* note: this function runs on poll, therefor it can runs many times a second
* keep it fast! */
-static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create)
+static PTCacheEdit *pe_get_current(Scene *scene, SceneLayer *sl, Object *ob, int create)
{
ParticleEditSettings *pset= PE_settings(scene);
PTCacheEdit *edit = NULL;
@@ -222,6 +226,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create)
return NULL;
pset->scene = scene;
+ pset->scene_layer = sl;
pset->object = ob;
BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
@@ -250,18 +255,18 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create)
if (psys->part && psys->part->type == PART_HAIR) {
if (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) {
if (create && !psys->pointcache->edit)
- PE_create_particle_edit(scene, ob, pid->cache, NULL);
+ PE_create_particle_edit(scene, sl, ob, pid->cache, NULL);
edit = pid->cache->edit;
}
else {
if (create && !psys->edit && psys->flag & PSYS_HAIR_DONE)
- PE_create_particle_edit(scene, ob, NULL, psys);
+ PE_create_particle_edit(scene, sl, ob, NULL, psys);
edit = psys->edit;
}
}
else {
if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit)
- PE_create_particle_edit(scene, ob, pid->cache, psys);
+ PE_create_particle_edit(scene, sl, ob, pid->cache, psys);
edit = pid->cache->edit;
}
@@ -272,7 +277,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create)
if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) {
pset->flag |= PE_FADE_TIME;
// NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB;
- PE_create_particle_edit(scene, ob, pid->cache, NULL);
+ PE_create_particle_edit(scene, sl, ob, pid->cache, NULL);
}
edit = pid->cache->edit;
break;
@@ -281,7 +286,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create)
if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) {
pset->flag |= PE_FADE_TIME;
// NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB;
- PE_create_particle_edit(scene, ob, pid->cache, NULL);
+ PE_create_particle_edit(scene, sl, ob, pid->cache, NULL);
}
edit = pid->cache->edit;
break;
@@ -296,14 +301,14 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create)
return edit;
}
-PTCacheEdit *PE_get_current(Scene *scene, Object *ob)
+PTCacheEdit *PE_get_current(Scene *scene, SceneLayer *sl, Object *ob)
{
- return pe_get_current(scene, ob, 0);
+ return pe_get_current(scene, sl, ob, 0);
}
PTCacheEdit *PE_create_current(Scene *scene, Object *ob)
{
- return pe_get_current(scene, ob, 1);
+ return pe_get_current(scene, NULL, ob, 1);
}
void PE_current_changed(Scene *scene, Object *ob)
@@ -351,9 +356,9 @@ static int pe_x_mirror(Object *ob)
typedef struct PEData {
ViewContext vc;
- bglMats mats;
Scene *scene;
+ SceneLayer *scene_layer;
Object *ob;
DerivedMesh *dm;
PTCacheEdit *edit;
@@ -388,8 +393,9 @@ static void PE_set_data(bContext *C, PEData *data)
memset(data, 0, sizeof(*data));
data->scene= CTX_data_scene(C);
+ data->scene_layer = CTX_data_scene_layer(C);
data->ob= CTX_data_active_object(C);
- data->edit= PE_get_current(data->scene, data->ob);
+ data->edit= PE_get_current(data->scene, data->scene_layer, data->ob);
}
static void PE_set_view3d_data(bContext *C, PEData *data)
@@ -397,8 +403,6 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
PE_set_data(C, data);
view3d_set_viewcontext(C, &data->vc);
- /* note, the object argument means the modelview matrix does not account for the objects matrix, use viewmat rather than (obmat * viewmat) */
- view3d_get_transformation(data->vc.ar, data->vc.rv3d, NULL, &data->mats);
if (V3D_IS_ZBUF(data->vc.v3d)) {
if (data->vc.v3d->flag & V3D_INVALID_BACKBUF) {
@@ -439,7 +443,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
{
View3D *v3d= data->vc.v3d;
ViewDepths *vd = data->vc.rv3d->depths;
- double ux, uy, uz;
float depth;
/* nothing to do */
@@ -455,9 +458,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
}
#endif
- gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection,
- (GLint *)data->mats.viewport, &ux, &uy, &uz);
-
/* check if screen_co is within bounds because brush_cut uses out of screen coords */
if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
BLI_assert(vd && vd->depths);
@@ -467,7 +467,10 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
else
return 0;
- if ((float)uz - 0.00001f > depth)
+ float win[3];
+ ED_view3d_project(data->vc.ar, co, win);
+
+ if (win[2] - 0.00001f > depth)
return 0;
else
return 1;
@@ -1152,9 +1155,9 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys)
BLI_kdtree_balance(edit->emitter_field);
}
-static void PE_update_selection(Scene *scene, Object *ob, int useflag)
+static void PE_update_selection(Scene *scene, SceneLayer *sl, Object *ob, int useflag)
{
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
HairKey *hkey;
POINT_P; KEY_K;
@@ -1259,12 +1262,12 @@ static void update_velocities(PTCacheEdit *edit)
}
}
-void PE_update_object(Scene *scene, Object *ob, int useflag)
+void PE_update_object(Scene *scene, SceneLayer *sl, Object *ob, int useflag)
{
/* use this to do partial particle updates, not usable when adding or
* removing, then a full redo is necessary and calling this may crash */
ParticleEditSettings *pset= PE_settings(scene);
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
POINT_P;
if (!edit)
@@ -1399,8 +1402,9 @@ static void select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, in
static int pe_select_all_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
POINT_P; KEY_K;
int action = RNA_enum_get(op->ptr, "action");
@@ -1423,7 +1427,7 @@ static int pe_select_all_exec(bContext *C, wmOperator *op)
}
}
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
return OPERATOR_FINISHED;
@@ -1452,8 +1456,9 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec
{
PEData data;
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
POINT_P; KEY_K;
if (!PE_start_edit(edit))
@@ -1480,7 +1485,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec
else
for_mouse_hit_keys(&data, toggle_key_select, 1);
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -1521,7 +1526,7 @@ static int select_roots_exec(bContext *C, wmOperator *op)
data.select_action = action;
foreach_point(&data, select_root);
- PE_update_selection(data.scene, data.ob, 1);
+ PE_update_selection(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -1586,7 +1591,7 @@ static int select_tips_exec(bContext *C, wmOperator *op)
data.select_action = action;
foreach_point(&data, select_tip);
- PE_update_selection(data.scene, data.ob, 1);
+ PE_update_selection(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -1625,6 +1630,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
PEData data;
int type;
Scene *scene;
+ SceneLayer *sl;
Object *ob;
/* used by LOOP_VISIBLE_POINTS, LOOP_VISIBLE_KEYS and LOOP_KEYS */
@@ -1644,8 +1650,9 @@ static int select_random_exec(bContext *C, wmOperator *op)
PE_set_data(C, &data);
data.select_action = SEL_SELECT;
scene = CTX_data_scene(C);
+ sl = CTX_data_scene_layer(C);
ob = CTX_data_active_object(C);
- edit = PE_get_current(scene, ob);
+ edit = PE_get_current(scene, sl, ob);
rng = BLI_rng_new_srandom(seed);
@@ -1670,7 +1677,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
BLI_rng_free(rng);
- PE_update_selection(data.scene, data.ob, 1);
+ PE_update_selection(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -1714,7 +1721,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
data.select= !RNA_boolean_get(op->ptr, "deselect");
for_mouse_hit_keys(&data, select_keys, 1); /* nearest only */
- PE_update_selection(data.scene, data.ob, 1);
+ PE_update_selection(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -1762,8 +1769,9 @@ void PE_deselect_all_visible(PTCacheEdit *edit)
int PE_border_select(bContext *C, rcti *rect, bool select, bool extend)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
PEData data;
if (!PE_start_edit(edit))
@@ -1778,7 +1786,7 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend)
for_mouse_hit_keys(&data, select_key, 0);
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
return OPERATOR_FINISHED;
@@ -1789,8 +1797,9 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend)
int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
PEData data;
if (!PE_start_edit(edit))
@@ -1803,7 +1812,7 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
for_mouse_hit_keys(&data, select_key, 0);
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
return OPERATOR_FINISHED;
@@ -1814,10 +1823,11 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool extend, bool select)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
ARegion *ar= CTX_wm_region(C);
ParticleEditSettings *pset= PE_settings(scene);
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
POINT_P; KEY_K;
@@ -1891,7 +1901,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
}
}
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
return OPERATOR_FINISHED;
@@ -1903,7 +1913,8 @@ static int hide_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_active_object(C);
Scene *scene= CTX_data_scene(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
POINT_P; KEY_K;
if (RNA_enum_get(op->ptr, "unselected")) {
@@ -1925,7 +1936,7 @@ static int hide_exec(bContext *C, wmOperator *op)
}
}
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
return OPERATOR_FINISHED;
@@ -1955,7 +1966,8 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob= CTX_data_active_object(C);
Scene *scene= CTX_data_scene(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
POINT_P; KEY_K;
LOOP_POINTS {
@@ -1968,7 +1980,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- PE_update_selection(scene, ob, 1);
+ PE_update_selection(scene, sl, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
return OPERATOR_FINISHED;
@@ -2027,7 +2039,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
PE_set_data(C, &data);
foreach_point(&data, select_less_keys);
- PE_update_selection(data.scene, data.ob, 1);
+ PE_update_selection(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -2089,7 +2101,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op))
PE_set_data(C, &data);
foreach_point(&data, select_more_keys);
- PE_update_selection(data.scene, data.ob, 1);
+ PE_update_selection(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
@@ -2186,7 +2198,7 @@ static int rekey_exec(bContext *C, wmOperator *op)
foreach_selected_point(&data, rekey_particle);
recalc_lengths(data.edit);
- PE_update_object(data.scene, data.ob, 1);
+ PE_update_object(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
return OPERATOR_FINISHED;
@@ -2211,9 +2223,9 @@ void PARTICLE_OT_rekey(wmOperatorType *ot)
RNA_def_int(ot->srna, "keys_number", 2, 2, INT_MAX, "Number of Keys", "", 2, 100);
}
-static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float path_time)
+static void rekey_particle_to_time(Scene *scene, SceneLayer *sl, Object *ob, int pa_index, float path_time)
{
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ParticleSystem *psys;
ParticleSimulationData sim= {0};
ParticleData *pa;
@@ -2517,7 +2529,7 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op))
foreach_point(&data, subdivide_particle);
recalc_lengths(data.edit);
- PE_update_object(data.scene, data.ob, 1);
+ PE_update_object(data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
return OPERATOR_FINISHED;
@@ -2543,8 +2555,9 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot)
static int remove_doubles_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd;
KDTree *tree;
@@ -2635,9 +2648,10 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot)
static int weight_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ParticleEditSettings *pset= PE_settings(scene);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
POINT_P;
KEY_K;
@@ -2690,24 +2704,27 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
ParticleEditSettings *pset= PE_settings(scene);
ParticleBrushData *brush;
- if (pset->brushtype < 0)
+ if (pset->brushtype < 0) {
return;
+ }
- brush= &pset->brush[pset->brushtype];
+ brush = &pset->brush[pset->brushtype];
if (brush) {
- glPushMatrix();
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glTranslatef((float)x, (float)y, 0.0f);
+ immUniformColor4ub(255, 255, 255, 128);
- glColor4ub(255, 255, 255, 128);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40);
+
+ imm_draw_circle_wire(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40);
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
-
- glPopMatrix();
+
+ immUnbindProgram();
}
}
@@ -2791,11 +2808,11 @@ void PARTICLE_OT_delete(wmOperatorType *ot)
/*************************** mirror operator **************************/
-static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
+static void PE_mirror_x(Scene *scene, SceneLayer *sl, Object *ob, int tagged)
{
Mesh *me= (Mesh *)(ob->data);
ParticleSystemModifierData *psmd;
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
ParticleData *pa, *newpa, *new_pars;
PTCacheEditPoint *newpoint, *new_points;
@@ -2942,10 +2959,11 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
static int mirror_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
- PE_mirror_x(scene, ob, 0);
+ PE_mirror_x(scene, sl, ob, 0);
update_world_cos(ob, edit);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
@@ -3082,7 +3100,7 @@ static void brush_cut(PEData *data, int pa_index)
edit->points[pa_index].flag |= PEP_TAG;
}
else {
- rekey_particle_to_time(data->scene, ob, pa_index, cut_time);
+ rekey_particle_to_time(data->scene, data->scene_layer, ob, pa_index, cut_time);
edit->points[pa_index].flag |= PEP_EDIT_RECALC;
}
}
@@ -3711,6 +3729,7 @@ static int brush_add(PEData *data, short number)
typedef struct BrushEdit {
Scene *scene;
+ SceneLayer *sl;
Object *ob;
PTCacheEdit *edit;
@@ -3725,9 +3744,10 @@ typedef struct BrushEdit {
static int brush_edit_init(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= CTX_data_active_object(C);
ParticleEditSettings *pset= PE_settings(scene);
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ARegion *ar= CTX_wm_region(C);
BrushEdit *bedit;
float min[3], max[3];
@@ -3737,7 +3757,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
/* set the 'distance factor' for grabbing (used in comb etc) */
INIT_MINMAX(min, max);
- PE_minmax(scene, min, max);
+ PE_minmax(scene, sl, min, max);
mid_v3_v3v3(min, min, max);
bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit");
@@ -3745,6 +3765,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
op->customdata= bedit;
bedit->scene= scene;
+ bedit->sl = sl;
bedit->ob= ob;
bedit->edit= edit;
@@ -3760,6 +3781,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
BrushEdit *bedit= op->customdata;
Scene *scene= bedit->scene;
+ SceneLayer *sl = bedit->sl;
Object *ob= bedit->ob;
PTCacheEdit *edit= bedit->edit;
ParticleEditSettings *pset= PE_settings(scene);
@@ -3950,14 +3972,14 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT) && (added || removed)) {
if (pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob))
- PE_mirror_x(scene, ob, 1);
+ PE_mirror_x(scene, sl, ob, 1);
update_world_cos(ob, edit);
psys_free_path_cache(NULL, edit);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
else
- PE_update_object(scene, ob, 1);
+ PE_update_object(scene, sl, ob, 1);
}
if (edit->psys) {
@@ -4170,7 +4192,7 @@ static void shape_cut(PEData *data, int pa_index)
edit->points[pa_index].flag |= PEP_TAG;
}
else {
- rekey_particle_to_time(data->scene, ob, pa_index, cut_time);
+ rekey_particle_to_time(data->scene, data->scene_layer, ob, pa_index, cut_time);
edit->points[pa_index].flag |= PEP_EDIT_RECALC;
}
}
@@ -4179,9 +4201,10 @@ static void shape_cut(PEData *data, int pa_index)
static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = CTX_data_active_object(C);
ParticleEditSettings *pset = PE_settings(scene);
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
Object *shapeob = pset->shape_object;
int selected = count_selected_keys(scene, edit);
int lock_root = pset->flag & PE_LOCK_FIRST;
@@ -4217,7 +4240,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
else
- PE_update_object(scene, ob, 1);
+ PE_update_object(scene, sl, ob, 1);
if (edit->psys) {
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
@@ -4389,9 +4412,9 @@ static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo)
}
}
-void PE_undo_push(Scene *scene, const char *str)
+void PE_undo_push(Scene *scene, SceneLayer *sl, const char *str)
{
- PTCacheEdit *edit= PE_get_current(scene, OBACT);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
PTCacheUndo *undo;
int nr;
@@ -4431,9 +4454,9 @@ void PE_undo_push(Scene *scene, const char *str)
make_PTCacheUndo(edit, edit->curundo);
}
-void PE_undo_step(Scene *scene, int step)
+void PE_undo_step(Scene *scene, SceneLayer *sl, int step)
{
- PTCacheEdit *edit= PE_get_current(scene, OBACT);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
if (!edit) return;
@@ -4464,12 +4487,12 @@ void PE_undo_step(Scene *scene, int step)
}
}
- DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
+ DAG_id_tag_update(&OBACT_NEW->id, OB_RECALC_DATA);
}
-bool PE_undo_is_valid(Scene *scene)
+bool PE_undo_is_valid(Scene *scene, SceneLayer *sl)
{
- PTCacheEdit *edit= PE_get_current(scene, OBACT);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
if (edit) {
return (edit->undo.last != edit->undo.first);
@@ -4492,19 +4515,19 @@ void PTCacheUndo_clear(PTCacheEdit *edit)
edit->curundo= NULL;
}
-void PE_undo(Scene *scene)
+void PE_undo(Scene *scene, SceneLayer *sl)
{
- PE_undo_step(scene, 1);
+ PE_undo_step(scene, sl, 1);
}
-void PE_redo(Scene *scene)
+void PE_redo(Scene *scene, SceneLayer *sl)
{
- PE_undo_step(scene, -1);
+ PE_undo_step(scene, sl, -1);
}
-void PE_undo_number(Scene *scene, int nr)
+void PE_undo_number(Scene *scene, SceneLayer *sl, int nr)
{
- PTCacheEdit *edit= PE_get_current(scene, OBACT);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
PTCacheUndo *undo;
int a=0;
@@ -4512,15 +4535,15 @@ void PE_undo_number(Scene *scene, int nr)
if (a==nr) break;
}
edit->curundo= undo;
- PE_undo_step(scene, 0);
+ PE_undo_step(scene, sl, 0);
}
/* get name of undo item, return null if no item with this index */
/* if active pointer, set it to 1 if true */
-const char *PE_undo_get_name(Scene *scene, int nr, bool *r_active)
+const char *PE_undo_get_name(Scene *scene, SceneLayer *sl, int nr, bool *r_active)
{
- PTCacheEdit *edit= PE_get_current(scene, OBACT);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
PTCacheUndo *undo;
if (r_active) *r_active = false;
@@ -4539,10 +4562,10 @@ const char *PE_undo_get_name(Scene *scene, int nr, bool *r_active)
/************************ utilities ******************************/
-int PE_minmax(Scene *scene, float min[3], float max[3])
+int PE_minmax(Scene *scene, SceneLayer *sl, float min[3], float max[3])
{
- Object *ob= OBACT;
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ Object *ob= OBACT_NEW;
+ PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ParticleSystem *psys;
ParticleSystemModifierData *psmd = NULL;
POINT_P; KEY_K;
@@ -4579,7 +4602,7 @@ int PE_minmax(Scene *scene, float min[3], float max[3])
/************************ particle edit toggle operator ************************/
/* initialize needed data for bake edit */
-void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
+void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys)
{
PTCacheEdit *edit;
ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
@@ -4680,10 +4703,10 @@ void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, Partic
recalc_lengths(edit);
if (psys && !cache)
recalc_emitter_field(ob, psys);
- PE_update_object(scene, ob, 1);
+ PE_update_object(scene, sl, ob, 1);
PTCacheUndo_clear(edit);
- PE_undo_push(scene, "Original");
+ PE_undo_push(scene, sl, "Original");
}
}
@@ -4710,6 +4733,9 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
const int mode_flag = OB_MODE_PARTICLE_EDIT;
const bool is_mode_set = (ob->mode & mode_flag) != 0;
+ BKE_report(op->reports, RPT_INFO, "Particles are changing, editing is not possible");
+ return OPERATOR_CANCELLED;
+
if (!is_mode_set) {
if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
@@ -4887,14 +4913,15 @@ static int unify_length_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
float average_length = calculate_average_length(edit);
if (average_length == 0.0f) {
return OPERATOR_CANCELLED;
}
scale_points_to_length(edit, average_length);
- PE_update_object(scene, ob, 1);
+ PE_update_object(scene, sl, ob, 1);
if (edit->psys) {
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
}
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 4a4474868a2..782e0253267 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -69,7 +69,7 @@
#include "physics_intern.h"
-extern void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys);
+extern void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys);
extern void PTCacheUndo_clear(PTCacheEdit *edit);
extern void recalc_lengths(PTCacheEdit *edit);
extern void recalc_emitter_field(Object *ob, ParticleSystem *psys);
@@ -133,6 +133,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
int mode_orig;
if (!scene || !ob)
@@ -146,7 +147,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
*/
if (mode_orig & OB_MODE_PARTICLE_EDIT) {
if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
- if (scene->basact && scene->basact->object == ob) {
+ if (sl->basact && sl->basact->object == ob) {
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
}
}
@@ -565,7 +566,7 @@ void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
/************************ connect/disconnect hair operators *********************/
-static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static void disconnect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
ParticleEditSettings *pset= PE_settings(scene);
@@ -611,12 +612,13 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF))
pset->brushtype = PE_BRUSH_NONE;
- PE_update_object(scene, ob, 0);
+ PE_update_object(scene, sl, ob, 0);
}
static int disconnect_hair_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= ED_object_context(C);
ParticleSystem *psys= NULL;
const bool all = RNA_boolean_get(op->ptr, "all");
@@ -626,12 +628,12 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op)
if (all) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- disconnect_hair(scene, ob, psys);
+ disconnect_hair(scene, sl, ob, psys);
}
}
else {
psys = psys_get_current(ob);
- disconnect_hair(scene, ob, psys);
+ disconnect_hair(scene, sl, ob, psys);
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -657,7 +659,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
/* from/to_world_space : whether from/to particles are in world or hair space
* from/to_mat : additional transform for from/to particles (e.g. for using object space copying)
*/
-static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
+static bool remap_hair_emitter(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys,
Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
{
@@ -843,19 +845,19 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
psys_free_path_cache(target_psys, target_edit);
- PE_update_object(scene, target_ob, 0);
+ PE_update_object(scene, sl, target_ob, 0);
return true;
}
-static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static bool connect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys)
{
bool ok;
if (!psys)
return false;
- ok = remap_hair_emitter(scene, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
+ ok = remap_hair_emitter(scene, sl, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
psys->flag &= ~PSYS_GLOBAL_HAIR;
return ok;
@@ -864,6 +866,7 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
static int connect_hair_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= ED_object_context(C);
ParticleSystem *psys= NULL;
const bool all = RNA_boolean_get(op->ptr, "all");
@@ -874,12 +877,12 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
if (all) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- any_connected |= connect_hair(scene, ob, psys);
+ any_connected |= connect_hair(scene, sl, ob, psys);
}
}
else {
psys = psys_get_current(ob);
- any_connected |= connect_hair(scene, ob, psys);
+ any_connected |= connect_hair(scene, sl, ob, psys);
}
if (!any_connected) {
@@ -915,7 +918,7 @@ typedef enum eCopyParticlesSpace {
PAR_COPY_SPACE_WORLD = 1,
} eCopyParticlesSpace;
-static void copy_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
+static void copy_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
{
PTCacheEdit *edit_from = psys_from->edit, *edit;
ParticleData *pa;
@@ -965,10 +968,10 @@ static void copy_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys, P
recalc_lengths(edit);
recalc_emitter_field(ob, psys);
- PE_update_object(scene, ob, true);
+ PE_update_object(scene, sl, ob, true);
PTCacheUndo_clear(edit);
- PE_undo_push(scene, "Original");
+ PE_undo_push(scene, sl, "Original");
}
static void remove_particle_systems_from_object(Object *ob_to)
@@ -998,6 +1001,7 @@ static void remove_particle_systems_from_object(Object *ob_to)
/* single_psys_from is optional, if NULL all psys of ob_from are copied */
static bool copy_particle_systems_to_object(Main *bmain,
Scene *scene,
+ SceneLayer *sl,
Object *ob_from,
ParticleSystem *single_psys_from,
Object *ob_to,
@@ -1078,7 +1082,7 @@ static bool copy_particle_systems_to_object(Main *bmain,
DM_ensure_tessface(psmd->dm_final);
if (psys_from->edit)
- copy_particle_edit(scene, ob_to, psys, psys_from);
+ copy_particle_edit(scene, sl, ob_to, psys, psys_from);
if (duplicate_settings) {
id_us_min(&psys->part->id);
@@ -1112,7 +1116,7 @@ static bool copy_particle_systems_to_object(Main *bmain,
break;
}
if (ob_from != ob_to) {
- remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
+ remap_hair_emitter(scene, sl, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
}
/* tag for recalc */
@@ -1147,6 +1151,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
const bool use_active = RNA_boolean_get(op->ptr, "use_active");
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob_from = ED_object_active_context(C);
ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL;
@@ -1161,7 +1166,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
remove_particle_systems_from_object(ob_to);
changed = true;
}
- if (copy_particle_systems_to_object(bmain, scene, ob_from, psys_from, ob_to, space, false))
+ if (copy_particle_systems_to_object(bmain, scene, sl, ob_from, psys_from, ob_to, space, false))
changed = true;
else
fail++;
@@ -1222,7 +1227,7 @@ static int duplicate_particle_systems_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
- copy_particle_systems_to_object(CTX_data_main(C), scene, ob, psys, ob,
+ copy_particle_systems_to_object(CTX_data_main(C), scene, CTX_data_scene_layer(C), ob, psys, ob,
PAR_COPY_SPACE_OBJECT, duplicate_settings);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 6460e83e2a0..6e62dbabbca 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -329,6 +329,7 @@ static void free_all_fluidobject_channels(ListBase *fobjects)
static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), FluidsimSettings *domainSettings, FluidAnimChannels *channels, ListBase *fobjects)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base;
int i;
int length = channels->length;
@@ -343,7 +344,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
channels->DomainTime = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
/* allocate fluid objects */
- for (base=scene->base.first; base; base= base->next) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
Object *ob = base->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
@@ -570,14 +571,14 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length)
}
}
-static int fluid_validate_scene(ReportList *reports, Scene *scene, Object *fsDomain)
+static int fluid_validate_scene(ReportList *reports, SceneLayer *sl, Object *fsDomain)
{
Base *base;
Object *newdomain = NULL;
int channelObjCount = 0;
int fluidInputCount = 0;
- for (base=scene->base.first; base; base= base->next) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
Object *ob = base->object;
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
@@ -835,7 +836,8 @@ static void fluidsim_delete_until_lastframe(FluidsimSettings *fss, const char *r
static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, short do_job)
{
- Scene *scene= CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
int i;
FluidsimSettings *domainSettings;
@@ -882,7 +884,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
}
/* check scene for sane object/modifier settings */
- if (!fluid_validate_scene(reports, scene, fsDomain)) {
+ if (!fluid_validate_scene(reports, sl, fsDomain)) {
fluidbake_free_data(channels, fobjects, fsset, fb);
return 0;
}
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index b1d708ebc07..758ef43590e 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -137,23 +137,6 @@ static void keymap_particle(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
- /* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", true);
-
- /* Using KM_ANY here to allow holding modifiers before starting to transform. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index e81aa584586..5a2bb1e74c7 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -42,6 +42,7 @@
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -253,22 +254,23 @@ static void ptcache_bake_cancel(bContext *C, wmOperator *op)
static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene= CTX_data_scene(C);
- Base *base;
+ Scene *scene = CTX_data_scene(C);
PTCacheID *pid;
ListBase pidlist;
- for (base=scene->base.first; base; base= base->next) {
- BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
- for (pid=pidlist.first; pid; pid=pid->next) {
+ for (pid = pidlist.first; pid; pid = pid->next) {
ptcache_free_bake(pid->cache);
}
BLI_freelistN(&pidlist);
- WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object);
+ WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
}
+ FOREACH_SCENE_OBJECT_END
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index 1bfc162a331..fb75e27131b 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -89,7 +89,7 @@ bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type
ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE;
/* add constraint to rigid body constraint group */
- BKE_group_object_add(rbw->constraints, ob, scene, NULL);
+ BKE_group_object_add(rbw->constraints, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
@@ -102,7 +102,7 @@ void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob)
BKE_rigidbody_remove_constraint(scene, ob);
if (rbw)
- BKE_group_object_unlink(rbw->constraints, ob, scene, NULL);
+ BKE_group_object_unlink(rbw->constraints, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
@@ -117,8 +117,9 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
- Object *ob = (scene) ? OBACT : NULL;
+ Object *ob = OBACT_NEW;
int type = RNA_enum_get(op->ptr, "type");
bool changed;
@@ -166,11 +167,8 @@ static int rigidbody_con_remove_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Object *ob = (scene) ? OBACT : NULL;
-
- /* sanity checks */
- if (scene == NULL)
- return OPERATOR_CANCELLED;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
/* apply to active object */
if (ELEM(NULL, ob, ob->rigidbody_constraint)) {
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 30597d95497..c9e32fa5194 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -119,7 +119,7 @@ bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, Re
ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
/* add object to rigid body group */
- BKE_group_object_add(rbw->group, ob, scene, NULL);
+ BKE_group_object_add(rbw->group, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
@@ -133,7 +133,7 @@ void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob)
BKE_rigidbody_remove_object(scene, ob);
if (rbw)
- BKE_group_object_unlink(rbw->group, ob, scene, NULL);
+ BKE_group_object_unlink(rbw->group, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt
index 971ab9f3458..ec00a258ebb 100644
--- a/source/blender/editors/render/CMakeLists.txt
+++ b/source/blender/editors/render/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../../blenlib
../../blenloader
../../blentranslation
+ ../../depsgraph
../../gpu
../../imbuf
../../bmesh
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 43b1d033d23..d4e9956b189 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -81,6 +81,7 @@
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
+#include "GPU_shader.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -306,6 +307,7 @@ static int screen_render_exec(bContext *C, wmOperator *op)
}
re = RE_NewRender(scene->id.name);
+ RE_SetDepsgraph(re, CTX_data_depsgraph(C));
lay_override = (v3d && v3d->lay != scene->lay) ? v3d->lay : 0;
G.is_break = false;
@@ -782,7 +784,7 @@ static void screen_render_cancel(bContext *C, wmOperator *op)
WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
}
-static void clean_viewport_memory(Main *bmain, Scene *scene, int renderlay)
+static void clean_viewport_memory(Main *bmain, Scene *scene)
{
Object *object;
Scene *sce_iter;
@@ -793,7 +795,7 @@ static void clean_viewport_memory(Main *bmain, Scene *scene, int renderlay)
}
for (SETLOOPER(scene, sce_iter, base)) {
- if ((base->lay & renderlay) == 0) {
+ if ((base->flag & BASE_VISIBLED) == 0) {
continue;
}
if (RE_allow_render_generic_object(base->object)) {
@@ -930,8 +932,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* Lock the user interface depending on render settings. */
if (scene->r.use_lock_interface) {
- int renderlay = rj->lay_override ? rj->lay_override : scene->lay;
-
WM_set_locked_interface(CTX_wm_manager(C), true);
/* Set flag interface need to be unlocked.
@@ -945,7 +945,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj->interface_locked = true;
/* Clean memory used by viewport? */
- clean_viewport_memory(rj->main, scene, renderlay);
+ clean_viewport_memory(rj->main, scene);
}
/* setup job */
@@ -971,6 +971,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
RE_current_scene_update_cb(re, rj, current_scene_update);
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
RE_progress_cb(re, rj, render_progress_update);
+ RE_SetDepsgraph(re, CTX_data_depsgraph(C));
rj->re = re;
G.is_break = false;
@@ -1542,11 +1543,10 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
if (force_fallback == false) {
if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, dither, true)) {
glEnable(GL_BLEND);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glPixelZoom(scale_x, scale_y);
- glaDrawPixelsTex(xof, yof, rres.rectx, rres.recty,
- GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf);
- glPixelZoom(1.0f, 1.0f);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, xof, yof, rres.rectx, rres.recty,
+ GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf,
+ scale_x, scale_y, NULL);;
glDisable(GL_BLEND);
IMB_colormanagement_finish_glsl_draw();
@@ -1563,12 +1563,11 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
4, dither, &scene->view_settings, &scene->display_settings);
glEnable(GL_BLEND);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glPixelZoom(scale_x, scale_y);
- glaDrawPixelsAuto(xof, yof, rres.rectx, rres.recty,
- GL_RGBA, GL_UNSIGNED_BYTE,
- GL_NEAREST, display_buffer);
- glPixelZoom(1.0f, 1.0f);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, xof, yof, rres.rectx, rres.recty,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ GL_NEAREST, display_buffer,
+ scale_x, scale_y, NULL);
glDisable(GL_BLEND);
MEM_freeN(display_buffer);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 01050eda70b..93cc9f30868 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -70,9 +70,9 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_glew.h"
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
+#include "GPU_matrix.h"
#include "render_intern.h"
@@ -91,6 +91,7 @@ typedef struct OGLRender {
Main *bmain;
Render *re;
Scene *scene;
+ SceneLayer *scene_layer;
View3D *v3d;
RegionView3D *rv3d;
@@ -148,17 +149,6 @@ typedef struct OGLRender {
#endif
} OGLRender;
-/* added because v3d is not always valid */
-static unsigned int screen_opengl_layers(OGLRender *oglrender)
-{
- if (oglrender->v3d) {
- return oglrender->scene->lay | oglrender->v3d->lay;
- }
- else {
- return oglrender->scene->lay;
- }
-}
-
static bool screen_opengl_is_multiview(OGLRender *oglrender)
{
View3D *v3d = oglrender->v3d;
@@ -274,6 +264,7 @@ static void screen_opengl_views_setup(OGLRender *oglrender)
static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
{
Scene *scene = oglrender->scene;
+ SceneLayer *sl = oglrender->scene_layer;
ARegion *ar = oglrender->ar;
View3D *v3d = oglrender->v3d;
RegionView3D *rv3d = oglrender->rv3d;
@@ -330,7 +321,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
wmOrtho2(0, sizex, 0, sizey);
- glTranslatef(sizex / 2, sizey / 2, 0.0f);
+ gpuTranslate2f(sizex / 2, sizey / 2);
G.f |= G_RENDER_OGL;
ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
@@ -355,7 +346,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
if (view_context) {
ibuf_view = ED_view3d_draw_offscreen_imbuf(
- scene, v3d, ar, sizex, sizey,
+ scene, sl, v3d, ar, sizex, sizey,
IB_rect, draw_bgpic,
alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname,
oglrender->fx, oglrender->ofs, err_out);
@@ -367,7 +358,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
}
else {
ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(
- scene, scene->camera, oglrender->sizex, oglrender->sizey,
+ scene, sl, scene->camera, oglrender->sizex, oglrender->sizey,
IB_rect, OB_SOLID, false, true, true,
alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname,
oglrender->fx, oglrender->ofs, err_out);
@@ -647,6 +638,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->sizey = sizey;
oglrender->bmain = CTX_data_main(C);
oglrender->scene = scene;
+ oglrender->scene_layer = CTX_data_scene_layer(C);
oglrender->cfrao = scene->r.cfra;
oglrender->write_still = is_write_still && !is_animation;
@@ -790,7 +782,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
if (oglrender->timer) { /* exec will not have a timer */
scene->r.cfra = oglrender->cfrao;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
}
@@ -1000,12 +992,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (CFRA < oglrender->nfra)
CFRA++;
while (CFRA < oglrender->nfra) {
- unsigned int lay = screen_opengl_layers(oglrender);
-
- if (lay & 0xFF000000)
- lay &= 0xFF000000;
-
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
CFRA++;
}
@@ -1027,7 +1014,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
WM_cursor_time(oglrender->win, scene->r.cfra);
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
if (view_context) {
if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index fa18b82507e..1caec1cca2c 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -64,11 +64,13 @@
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_colortools.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_icons.h"
#include "BKE_lamp.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_main.h"
@@ -78,6 +80,8 @@
#include "BKE_texture.h"
#include "BKE_world.h"
+#include "DEG_depsgraph_build.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_thumbs.h"
@@ -85,6 +89,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_shader.h"
#include "RE_pipeline.h"
#include "RE_engine.h"
@@ -94,6 +99,7 @@
#include "ED_datafiles.h"
#include "ED_render.h"
+#include "ED_screen.h"
#ifndef NDEBUG
/* Used for database init assert(). */
@@ -269,20 +275,62 @@ static Scene *preview_get_scene(Main *pr_main)
return pr_main->scene.first;
}
+static const char *preview_layer_name(const char pr_type)
+{
+ switch (pr_type) {
+ case MA_FLAT:
+ return "Flat";
+ case MA_SPHERE:
+ return "Sphere";
+ case MA_CUBE:
+ return "Cube";
+ case MA_MONKEY:
+ return "Monkey";
+ case MA_SPHERE_A:
+ return "World Sphere";
+ case MA_TEXTURE:
+ return "Texture";
+ case MA_LAMP:
+ return "Lamp";
+ case MA_SKY:
+ return "Sky";
+ case MA_HAIR:
+ return "Hair";
+ case MA_ATMOS:
+ return "Atmosphere";
+ default:
+ BLI_assert(!"Unknown preview type");
+ return "";
+ }
+}
+
+static void set_preview_layer(SceneLayer *scene_layer, char pr_type)
+{
+ LayerCollection *lc;
+ const char *collection_name = preview_layer_name(pr_type);
+ for (lc = scene_layer->layer_collections.first; lc; lc = lc->next) {
+ if (STREQ(lc->scene_collection->name, collection_name)) {
+ lc->flag = COLLECTION_VISIBLE;
+ }
+ else {
+ lc->flag = 0;
+ }
+ }
+}
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp)
{
Scene *sce;
- Base *base;
Main *pr_main = sp->pr_main;
memcpy(pr_main->name, bmain->name, sizeof(pr_main->name));
sce = preview_get_scene(pr_main);
if (sce) {
-
+ SceneLayer *scene_layer = BKE_scene_layer_render_active(sce);
+
/* this flag tells render to not execute depsgraph or ipos etc */
sce->r.scemode |= R_BUTS_PREVIEW;
/* set world always back, is used now */
@@ -357,26 +405,34 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
/* this only works in a specific case where the preview.blend contains
* an object starting with 'c' which has a material linked to it (not the obdata)
* and that material has a fake shadow texture in the active texture slot */
- for (base = sce->base.first; base; base = base->next) {
- if (base->object->id.name[2] == 'c') {
- Material *shadmat = give_current_material(base->object, base->object->actcol);
+ for (Base *base = scene_layer->object_bases.first; base; base = base->next) {
+ Object *ob = base->object;
+ if (ob->id.name[2] == 'c') {
+ Material *shadmat = give_current_material(ob, ob->actcol);
if (shadmat) {
- if (mat->mode2 & MA_CASTSHADOW) shadmat->septex = 0;
- else shadmat->septex |= 1;
+ if (mat->mode2 & MA_CASTSHADOW) {
+ shadmat->septex = 0;
+ }
+ else {
+ shadmat->septex |= 1;
+ }
}
}
}
/* turn off bounce lights for volume,
* doesn't make much visual difference and slows it down too */
- for (base = sce->base.first; base; base = base->next) {
- if (base->object->type == OB_LAMP) {
+ for (Base *base = scene_layer->object_bases.first; base; base = base->next) {
+ Object *ob = base->object;
+ if (ob->type == OB_LAMP) {
/* if doesn't match 'Lamp.002' --> main key light */
- if (!STREQ(base->object->id.name + 2, "Lamp.002")) {
- if (mat->material_type == MA_TYPE_VOLUME)
- base->object->restrictflag |= OB_RESTRICT_RENDER;
- else
- base->object->restrictflag &= ~OB_RESTRICT_RENDER;
+ if (!STREQ(ob->id.name + 2, "Lamp.002")) {
+ if (mat->material_type == MA_TYPE_VOLUME) {
+ base->flag &= ~BASE_VISIBLED;
+ }
+ else {
+ base->flag |= BASE_VISIBLED;
+ }
}
}
}
@@ -389,10 +445,10 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
if (sp->pr_method == PR_ICON_RENDER) {
if (mat->material_type == MA_TYPE_HALO) {
- sce->lay = 1 << MA_FLAT;
+ set_preview_layer(scene_layer, MA_FLAT);
}
else {
- sce->lay = 1 << MA_SPHERE_A;
+ set_preview_layer(scene_layer, MA_SPHERE_A);
/* same as above, use current scene world to light sphere */
if (BKE_scene_use_new_shading_nodes(scene))
@@ -400,7 +456,8 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
}
else {
- sce->lay = 1 << mat->pr_type;
+ set_preview_layer(scene_layer, mat->pr_type);
+
if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true);
@@ -413,7 +470,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
- for (base = sce->base.first; base; base = base->next) {
+ for (Base *base = scene_layer->object_bases.first; base; base = base->next) {
if (base->object->id.name[2] == 'p') {
/* copy over object color, in case material uses it */
copy_v4_v4(base->object->col, sp->col);
@@ -427,7 +484,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
(*matar)[actcol] = mat;
}
else if (base->object->type == OB_LAMP) {
- base->object->restrictflag &= ~OB_RESTRICT_RENDER;
+ base->flag |= BASE_VISIBLED;
}
}
}
@@ -440,9 +497,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
sp->texcopy = tex;
BLI_addtail(&pr_main->tex, tex);
}
- sce->lay = 1 << MA_TEXTURE;
+ set_preview_layer(scene_layer, MA_TEXTURE);
- for (base = sce->base.first; base; base = base->next) {
+ for (Base *base = scene_layer->object_bases.first; base; base = base->next) {
if (base->object->id.name[2] == 't') {
Material *mat = give_current_material(base->object, base->object->actcol);
if (mat && mat->mtex[0]) {
@@ -481,21 +538,23 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
BLI_addtail(&pr_main->lamp, la);
}
- sce->lay = 1 << MA_LAMP;
-
if (!BKE_scene_use_new_shading_nodes(scene)) {
if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) {
- sce->lay = 1 << MA_ATMOS;
+ set_preview_layer(scene_layer, MA_ATMOS);
sce->world = scene->world;
sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2);
}
else {
sce->world = NULL;
sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2);
+ set_preview_layer(scene_layer, MA_LAMP);
}
}
+ else {
+ set_preview_layer(scene_layer, MA_LAMP);
+ }
- for (base = sce->base.first; base; base = base->next) {
+ for (Base *base = scene_layer->object_bases.first; base; base = base->next) {
if (base->object->id.name[2] == 'p') {
if (base->object->type == OB_LAMP)
base->object->data = la;
@@ -517,7 +576,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
BLI_addtail(&pr_main->world, wrld);
}
- sce->lay = 1 << MA_SKY;
+ set_preview_layer(scene_layer, MA_SKY);
sce->world = wrld;
if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) {
@@ -527,6 +586,11 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
}
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&sce->id, 0);
+ DEG_relations_tag_update(pr_main);
+ BKE_scene_update_tagged(pr_main->eval_ctx, pr_main, sce);
+
return sce;
}
@@ -593,7 +657,9 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
if (re)
RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0);
- glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, fx, fy, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect_byte,
+ 1.0f, 1.0f, NULL);
MEM_freeN(rect_byte);
@@ -1022,6 +1088,12 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
*do_update = true;
}
+ else if (idtype == ID_SCR) {
+ bScreen *screen = (bScreen *)id;
+
+ ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect);
+ *do_update = true;
+ }
else {
/* re-use shader job */
shader_preview_startjob(customdata, stop, do_update);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 0878636d0fa..e031e9a641c 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -54,6 +54,7 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
@@ -626,11 +627,12 @@ static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- BKE_scene_add_render_layer(scene, NULL);
- scene->r.actlay = BLI_listbase_count(&scene->r.layers) - 1;
+ BKE_scene_layer_add(scene, NULL);
+ scene->active_layer = BLI_listbase_count(&scene->render_layers) - 1;
DAG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ DAG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
return OPERATOR_FINISHED;
}
@@ -652,12 +654,14 @@ void SCENE_OT_render_layer_add(wmOperatorType *ot)
static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- SceneRenderLayer *rl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+ SceneLayer *sl = BKE_scene_layer_context_active(scene);
- if (!BKE_scene_remove_render_layer(CTX_data_main(C), scene, rl))
+ if (!BKE_scene_layer_remove(CTX_data_main(C), scene, sl)) {
return OPERATOR_CANCELLED;
+ }
DAG_id_tag_update(&scene->id, 0);
+ DAG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 4e02ff77a31..e019bc9f697 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -48,12 +48,14 @@
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
#include "BKE_icons.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
+#include "GPU_lamp.h"
#include "GPU_material.h"
#include "GPU_buffers.h"
@@ -378,6 +380,7 @@ static void texture_changed(Main *bmain, Tex *tex)
Lamp *la;
World *wo;
Scene *scene;
+ SceneLayer *sl;
Object *ob;
bNode *node;
bool texture_draw = false;
@@ -386,8 +389,11 @@ static void texture_changed(Main *bmain, Tex *tex)
BKE_icon_changed(BKE_icon_id_ensure(&tex->id));
/* paint overlays */
- for (scene = bmain->scene.first; scene; scene = scene->id.next)
- BKE_paint_invalidate_overlay_tex(scene, tex);
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
+ for (sl = scene->render_layers.first; sl; sl = sl->next) {
+ BKE_paint_invalidate_overlay_tex(scene, sl, tex);
+ }
+ }
/* find materials */
for (ma = bmain->mat.first; ma; ma = ma->id.next) {
@@ -572,6 +578,6 @@ void ED_render_internal_init(void)
RenderEngineType *ret = RE_engines_find(RE_engine_id_BLENDER_RENDER);
ret->view_update = render_view3d_update;
- ret->view_draw = render_view3d_draw;
+ ret->render_to_view = render_view3d_draw;
}
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index ed86ffa5e16..43e044b613a 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
area.c
glutil.c
screen_context.c
+ screen_draw.c
screen_edit.c
screen_ops.c
screendump.c
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 9cfaf3b4c1d..3b933b0182a 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -57,8 +57,11 @@
#include "ED_screen_types.h"
#include "ED_space_api.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_draw.h"
+
#include "BLF_api.h"
#include "IMB_imbuf.h"
@@ -71,7 +74,7 @@
#include "screen_intern.h"
-extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
+extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3, const float color[4]); /* xxx temp */
/* general area and region code */
@@ -89,21 +92,30 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINE_STRIP, 5);
+
/* right */
- glColor4ub(0, 0, 0, 30);
- sdrawline(rect.xmax, rect.ymin, rect.xmax, rect.ymax);
+ immAttrib4ub(color, 0, 0, 0, 30);
+ immVertex2f(pos, rect.xmax, rect.ymax);
+ immVertex2f(pos, rect.xmax, rect.ymin);
/* bottom */
- glColor4ub(0, 0, 0, 30);
- sdrawline(rect.xmin, rect.ymin, rect.xmax, rect.ymin);
+ immVertex2f(pos, rect.xmin, rect.ymin);
- /* top */
- glColor4ub(255, 255, 255, 30);
- sdrawline(rect.xmin, rect.ymax, rect.xmax, rect.ymax);
-
/* left */
- glColor4ub(255, 255, 255, 30);
- sdrawline(rect.xmin, rect.ymin, rect.xmin, rect.ymax);
+ immAttrib4ub(color, 255, 255, 255, 30);
+ immVertex2f(pos, rect.xmin, rect.ymax);
+
+ /* top */
+ immVertex2f(pos, rect.xmax, rect.ymax);
+
+ immEnd();
+ immUnbindProgram();
glDisable(GL_BLEND);
}
@@ -111,11 +123,11 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct)
void ED_region_pixelspace(ARegion *ar)
{
wmOrtho2_region_pixelspace(ar);
- glLoadIdentity();
+ gpuLoadIdentity();
}
/* only exported for WM */
-void ED_region_do_listen(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *note)
+void ED_region_do_listen(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *note, const Scene *scene)
{
/* generic notes first */
switch (note->category) {
@@ -129,15 +141,15 @@ void ED_region_do_listen(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *note
}
if (ar->type && ar->type->listener)
- ar->type->listener(sc, sa, ar, note);
+ ar->type->listener(sc, sa, ar, note, scene);
}
/* only exported for WM */
-void ED_area_do_listen(bScreen *sc, ScrArea *sa, wmNotifier *note)
+void ED_area_do_listen(bScreen *sc, ScrArea *sa, wmNotifier *note, const Scene *scene)
{
/* no generic notes? */
if (sa->type && sa->type->listener) {
- sa->type->listener(sc, sa, note);
+ sa->type->listener(sc, sa, note, scene);
}
}
@@ -206,15 +218,27 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f
if (G.debug_value == 1) {
rcti click_rect;
float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC;
- char alpha_debug = 255 * alpha;
+ unsigned char alpha_debug = 255 * alpha;
BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size);
- glColor4ub(255, 0, 0, alpha_debug);
- fdrawbox(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
- glColor4ub(0, 255, 255, alpha_debug);
- fdrawline(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
- fdrawline(click_rect.xmin, click_rect.ymax, click_rect.xmax, click_rect.ymin);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immAttrib4ub(color, 255, 0, 0, alpha_debug);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ imm_draw_line_box(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
+
+ immAttrib4ub(color, 0, 255, 255, alpha_debug);
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, click_rect.xmin, click_rect.ymin);
+ immVertex2f(pos, click_rect.xmax, click_rect.ymax);
+ immVertex2f(pos, click_rect.xmin, click_rect.ymax);
+ immVertex2f(pos, click_rect.xmax, click_rect.ymin);
+ immEnd();
+
+ immUnbindProgram();
}
}
@@ -229,69 +253,96 @@ static void area_draw_azone(short x1, short y1, short x2, short y2)
dx = copysign(ceilf(0.3f * abs(dx)), dx);
dy = copysign(ceilf(0.3f * abs(dy)), dy);
- glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINES, 12);
+
+ immAttrib4ub(col, 255, 255, 255, 180);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y1);
+
+ immAttrib4ub(col, 255, 255, 255, 130);
+ immVertex2f(pos, x1, y2 - dy);
+ immVertex2f(pos, x2 - dx, y1);
+
+ immAttrib4ub(col, 255, 255, 255, 80);
+ immVertex2f(pos, x1, y2 - 2 * dy);
+ immVertex2f(pos, x2 - 2 * dx, y1);
- glColor4ub(255, 255, 255, 180);
- fdrawline(x1, y2, x2, y1);
- glColor4ub(255, 255, 255, 130);
- fdrawline(x1, y2 - dy, x2 - dx, y1);
- glColor4ub(255, 255, 255, 80);
- fdrawline(x1, y2 - 2 * dy, x2 - 2 * dx, y1);
-
- glColor4ub(0, 0, 0, 210);
- fdrawline(x1, y2 + 1, x2 + 1, y1);
- glColor4ub(0, 0, 0, 180);
- fdrawline(x1, y2 - dy + 1, x2 - dx + 1, y1);
- glColor4ub(0, 0, 0, 150);
- fdrawline(x1, y2 - 2 * dy + 1, x2 - 2 * dx + 1, y1);
+ immAttrib4ub(col, 0, 0, 0, 210);
+ immVertex2f(pos, x1, y2 + 1);
+ immVertex2f(pos, x2 + 1, y1);
+
+ immAttrib4ub(col, 0, 0, 0, 180);
+ immVertex2f(pos, x1, y2 - dy + 1);
+ immVertex2f(pos, x2 - dx + 1, y1);
+
+ immAttrib4ub(col, 0, 0, 0, 150);
+ immVertex2f(pos, x1, y2 - 2 * dy + 1);
+ immVertex2f(pos, x2 - 2 * dx + 1, y1);
+
+ immEnd();
+ immUnbindProgram();
glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
}
static void region_draw_azone_icon(AZone *az)
{
- GLUquadricObj *qobj = NULL;
- short midx = az->x1 + (az->x2 - az->x1) / 2;
- short midy = az->y1 + (az->y2 - az->y1) / 2;
-
- qobj = gluNewQuadric();
-
- glPushMatrix();
- glTranslatef(midx, midy, 0.0);
-
- /* outlined circle */
- glEnable(GL_LINE_SMOOTH);
+ float midx = az->x1 + (az->x2 - az->x1) * 0.5f;
+ float midy = az->y1 + (az->y2 - az->y1) * 0.5f;
- glColor4f(1.f, 1.f, 1.f, 0.8f);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
- gluQuadricDrawStyle(qobj, GLU_FILL);
- gluDisk(qobj, 0.0, 4.25f, 16, 1);
+ /* outlined circle */
+ GPU_enable_program_point_size(); /* TODO: make a fixed-size shader to avoid this */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ immUniform4f("outlineColor", 0.2f, 0.2f, 0.2f, 0.9f);
+ immUniform1f("outlineWidth", 1.0f);
+ immUniform1f("size", 9.5f);
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(pos, midx, midy);
+ immEnd();
+ immUnbindProgram();
+ GPU_disable_program_point_size();
- glColor4f(0.2f, 0.2f, 0.2f, 0.9f);
-
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0.0, 4.25f, 16, 1);
-
- glDisable(GL_LINE_SMOOTH);
-
- glPopMatrix();
- gluDeleteQuadric(qobj);
-
/* + */
- sdrawline(midx, midy - 2, midx, midy + 3);
- sdrawline(midx - 2, midy, midx + 3, midy);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.2f, 0.2f, 0.2f, 0.9f);
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, midx, midy - 2);
+ immVertex2f(pos, midx, midy + 3);
+ immVertex2f(pos, midx - 2, midy);
+ immVertex2f(pos, midx + 3, midy);
+ immEnd();
+ immUnbindProgram();
}
static void draw_azone_plus(float x1, float y1, float x2, float y2)
{
float width = 0.1f * U.widget_unit;
float pad = 0.2f * U.widget_unit;
-
- glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad);
- glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f);
- glRectf((x1 + x2 + width) * 0.5f, (y1 + y2 - width) * 0.5f, x2 - pad, (y1 + y2 + width) * 0.5f);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ glEnable(GL_BLEND);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.8f, 0.8f, 0.8f, 0.4f);
+
+ immRectf(pos, (x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad);
+ immRectf(pos, x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f);
+ immRectf(pos, (x1 + x2 + width) * 0.5f, (y1 + y2 - width) * 0.5f, x2 - pad, (y1 + y2 + width) * 0.5f);
+
+ immUnbindProgram();
+ glDisable(GL_BLEND);
}
static void region_draw_azone_tab_plus(AZone *az)
@@ -314,54 +365,41 @@ static void region_draw_azone_tab_plus(AZone *az)
break;
}
- glColor4f(0.05f, 0.05f, 0.05f, 0.4f);
- UI_draw_roundbox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+ float color[4] = {0.05f, 0.05f, 0.05f, 0.4f};
+ UI_draw_roundbox_aa(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color);
- glEnable(GL_BLEND);
-
- glColor4f(0.8f, 0.8f, 0.8f, 0.4f);
draw_azone_plus((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2);
-
- glDisable(GL_BLEND);
}
static void region_draw_azone_tab(AZone *az)
{
- float col[3];
+ float col[4], black[4] = {0.0f, 0.0f, 0.0f, 0.5f};
glEnable(GL_BLEND);
UI_GetThemeColor3fv(TH_HEADER, col);
- glColor4f(col[0], col[1], col[2], 0.5f);
-
+ col[3] = 0.5f;
+
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
- UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA);
-
- UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
- glColor4ub(0, 0, 0, 255);
- UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
+ UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
+ UI_draw_roundbox_aa(false, (float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f, black);
break;
case AE_BOTTOM_TO_TOPLEFT:
- UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
-
- UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
- glColor4ub(0, 0, 0, 255);
- UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
+ UI_draw_roundbox_aa(false, (float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f, black);
break;
case AE_LEFT_TO_TOPRIGHT:
- UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
-
- UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
- glColor4ub(0, 0, 0, 255);
- UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
+ UI_draw_roundbox_aa(false, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, black);
break;
case AE_RIGHT_TO_TOPLEFT:
- UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA);
-
- UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
- glColor4ub(0, 0, 0, 255);
- UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
+ UI_draw_roundbox_aa(false, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, black);
break;
}
@@ -372,24 +410,24 @@ static void region_draw_azone_tria(AZone *az)
{
glEnable(GL_BLEND);
//UI_GetThemeColor3fv(TH_HEADER, col);
- glColor4f(0.0f, 0.0f, 0.0f, 0.35f);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.35f};
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
- ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y1, (float)(az->x1 + az->x2) / 2, (float)az->y2);
+ ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y1, (float)(az->x1 + az->x2) / 2, (float)az->y2, color);
break;
case AE_BOTTOM_TO_TOPLEFT:
- ui_draw_anti_tria((float)az->x1, (float)az->y2, (float)az->x2, (float)az->y2, (float)(az->x1 + az->x2) / 2, (float)az->y1);
+ ui_draw_anti_tria((float)az->x1, (float)az->y2, (float)az->x2, (float)az->y2, (float)(az->x1 + az->x2) / 2, (float)az->y1, color);
break;
case AE_LEFT_TO_TOPRIGHT:
- ui_draw_anti_tria((float)az->x2, (float)az->y1, (float)az->x2, (float)az->y2, (float)az->x1, (float)(az->y1 + az->y2) / 2);
+ ui_draw_anti_tria((float)az->x2, (float)az->y1, (float)az->x2, (float)az->y2, (float)az->x1, (float)(az->y1 + az->y2) / 2, color);
break;
case AE_RIGHT_TO_TOPLEFT:
- ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x1, (float)az->y2, (float)az->x2, (float)(az->y1 + az->y2) / 2);
+ ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x1, (float)az->y2, (float)az->x2, (float)(az->y1 + az->y2) / 2, color);
break;
}
@@ -413,8 +451,8 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPushMatrix();
- glTranslatef(-ar->winrct.xmin, -ar->winrct.ymin, 0.0f);
+ gpuPushMatrix();
+ gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin);
for (az = sa->actionzones.first; az; az = az->next) {
/* test if action zone is over this region */
@@ -451,7 +489,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
}
}
- glPopMatrix();
+ gpuPopMatrix();
glDisable(GL_BLEND);
}
@@ -511,7 +549,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
UI_ThemeClearColor(TH_HEADER);
glClear(GL_COLOR_BUFFER_BIT);
- UI_ThemeColor(TH_TEXT);
+ UI_FontThemeColor(BLF_default(), TH_TEXT);
BLF_draw_default(UI_UNIT_X, 0.4f * UI_UNIT_Y, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX);
}
else if (at->draw) {
@@ -528,9 +566,13 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
/* for debugging unneeded area redraws and partial redraw */
#if 0
glEnable(GL_BLEND);
- glColor4f(drand48(), drand48(), drand48(), 0.1f);
- glRectf(ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin,
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(drand48(), drand48(), drand48(), 0.1f);
+ immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin,
ar->drawrct.xmax - ar->winrct.xmin, ar->drawrct.ymax - ar->winrct.ymin);
+ immUnbindProgram();
glDisable(GL_BLEND);
#endif
@@ -655,7 +697,7 @@ void ED_area_headerprint(ScrArea *sa, const char *str)
/* ************************************************************ */
-static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa)
+static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *sa)
{
AZone *az;
@@ -1968,8 +2010,12 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
/* view should be in pixelspace */
UI_view2d_view_restore(C);
glEnable(GL_BLEND);
- UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
- glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct) + 1);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
+ immRecti(pos, 0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct) + 1);
+ immUnbindProgram();
glDisable(GL_BLEND);
}
else {
@@ -2073,22 +2119,37 @@ int ED_area_headersize(void)
return (int)(HEADERY * UI_DPI_FAC);
}
-void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], const bool full_redraw)
+void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float fill_color[4], const bool full_redraw)
{
const int header_height = UI_UNIT_Y;
uiStyle *style = UI_style_get_dpi();
int fontid = style->widget.uifont_id;
GLint scissor[4];
rcti rect;
+ int num_lines = 0;
/* background box */
ED_region_visible_rect(ar, &rect);
- rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height;
- /* box fill entire width or just around text */
- if (!full_redraw)
- rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, text, BLF_DRAW_STR_DUMMY_MAX) + 1.2f * U.widget_unit);
+ /* Box fill entire width or just around text. */
+ if (!full_redraw) {
+ const char **text = &text_array[0];
+ while (*text) {
+ rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, *text, BLF_DRAW_STR_DUMMY_MAX) + 1.2f * U.widget_unit);
+ text++;
+ num_lines++;
+ }
+ }
+ /* Just count the line number. */
+ else {
+ const char **text = &text_array[0];
+ while (*text) {
+ text++;
+ num_lines++;
+ }
+ }
+ rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height * num_lines;
rect.ymax = BLI_rcti_size_y(&ar->winrct);
/* setup scissor */
@@ -2098,17 +2159,28 @@ void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], con
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4fv(fill_color);
- glRecti(rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(fill_color);
+ immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
+ immUnbindProgram();
glDisable(GL_BLEND);
/* text */
- UI_ThemeColor(TH_TEXT_HI);
+ UI_FontThemeColor(fontid, TH_TEXT_HI);
BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
BLF_enable(fontid, BLF_CLIPPING);
- BLF_position(fontid, rect.xmin + 0.6f * U.widget_unit, rect.ymin + 0.3f * U.widget_unit, 0.0f);
-
- BLF_draw(fontid, text, BLF_DRAW_STR_DUMMY_MAX);
+ int offset = num_lines - 1;
+ {
+ const char **text = &text_array[0];
+ while (*text) {
+ BLF_position(fontid, rect.xmin + 0.6f * U.widget_unit, rect.ymin + 0.3f * U.widget_unit + offset * header_height, 0.0f);
+ BLF_draw(fontid, *text, BLF_DRAW_STR_DUMMY_MAX);
+ text++;
+ offset--;
+ }
+ }
BLF_disable(fontid, BLF_CLIPPING);
@@ -2116,6 +2188,11 @@ void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], con
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
}
+void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], const bool full_redraw)
+{
+ ED_region_info_draw_multiline(ar, (const char *[2]){text, NULL}, fill_color, full_redraw);
+}
+
#define MAX_METADATA_STR 1024
static const char *meta_data_list[] =
@@ -2284,11 +2361,11 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
return;
/* find window pixel coordinates of origin */
- glPushMatrix();
+ gpuPushMatrix();
/* offset and zoom using ogl */
- glTranslatef(x, y, 0.0f);
- glScalef(zoomx, zoomy, 1.0f);
+ gpuTranslate2f(x, y);
+ gpuScale2f(zoomx, zoomy);
BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
@@ -2298,17 +2375,20 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
box_y = metadata_box_height_get(ibuf, blf_mono_font, true);
if (box_y) {
- UI_ThemeColor(TH_METADATA_BG);
-
/* set up rect */
BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y);
/* draw top box */
- glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_METADATA_BG);
+ immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ immUnbindProgram();
BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
BLF_enable(blf_mono_font, BLF_CLIPPING);
- UI_ThemeColor(TH_METADATA_TEXT);
+ UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT);
metadata_draw_imbuf(ibuf, &rect, blf_mono_font, true);
BLF_disable(blf_mono_font, BLF_CLIPPING);
@@ -2320,23 +2400,26 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
box_y = metadata_box_height_get(ibuf, blf_mono_font, false);
if (box_y) {
- UI_ThemeColor(TH_METADATA_BG);
-
/* set up box rect */
BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin);
/* draw top box */
- glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_METADATA_BG);
+ immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ immUnbindProgram();
BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
BLF_enable(blf_mono_font, BLF_CLIPPING);
- UI_ThemeColor(TH_METADATA_TEXT);
+ UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT);
metadata_draw_imbuf(ibuf, &rect, blf_mono_font, false);
BLF_disable(blf_mono_font, BLF_CLIPPING);
}
- glPopMatrix();
+ gpuPopMatrix();
}
void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
@@ -2346,11 +2429,16 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
int x1, y1, x2, y2;
/* the image is located inside (0, 0), (1, 1) as set by view2d */
- UI_ThemeColorShade(TH_BACK, 20);
-
UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
- glRectf(x1, y1, x2, y2);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShade(TH_BACK, 20);
+ immRectf(pos, x1, y1, x2, y2);
+ immUnbindProgram();
/* gridsize adapted to zoom level */
gridsize = 0.5f * (zoomx + zoomy);
@@ -2370,33 +2458,52 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
}
}
- /* the fine resolution level */
blendfac = 0.25f * gridsize - floorf(0.25f * gridsize);
CLAMP(blendfac, 0.0f, 1.0f);
- UI_ThemeColorShade(TH_BACK, (int)(20.0f * (1.0f - blendfac)));
- fac = 0.0f;
- glBegin(GL_LINES);
- while (fac < 1.0f) {
- glVertex2f(x1, y1 * (1.0f - fac) + y2 * fac);
- glVertex2f(x2, y1 * (1.0f - fac) + y2 * fac);
- glVertex2f(x1 * (1.0f - fac) + x2 * fac, y1);
- glVertex2f(x1 * (1.0f - fac) + x2 * fac, y2);
- fac += gridstep;
- }
+ int count_fine = 1.0f / gridstep;
+ int count_large = 1.0f / (4.0f * gridstep);
- /* the large resolution level */
- UI_ThemeColor(TH_BACK);
+ if (count_fine > 0) {
+ VertexFormat_clear(format);
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINES, 4 * count_fine + 4 * count_large);
+
+ float theme_color[3];
+ UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color);
+ immAttrib3fv(color, theme_color);
+ fac = 0.0f;
+
+ /* the fine resolution level */
+ for (int i = 0; i < count_fine; i++) {
+ immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac);
+ immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac);
+ immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1);
+ immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2);
+ fac += gridstep;
+ }
+
+ if (count_large > 0) {
+ UI_GetThemeColor3fv(TH_BACK, theme_color);
+ immAttrib3fv(color, theme_color);
+ fac = 0.0f;
+
+ /* the large resolution level */
+ for (int i = 0; i < count_large; i++) {
+ immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac);
+ immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac);
+ immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1);
+ immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2);
+ fac += 4.0f * gridstep;
+ }
+ }
- fac = 0.0f;
- while (fac < 1.0f) {
- glVertex2f(x1, y1 * (1.0f - fac) + y2 * fac);
- glVertex2f(x2, y1 * (1.0f - fac) + y2 * fac);
- glVertex2f(x1 * (1.0f - fac) + x2 * fac, y1);
- glVertex2f(x1 * (1.0f - fac) + x2 * fac, y2);
- fac += 4.0f * gridstep;
+ immEnd();
+ immUnbindProgram();
}
- glEnd();
}
/* If the area has overlapping regions, it returns visible rect for Region *ar */
@@ -2433,8 +2540,11 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect)
void ED_region_cache_draw_background(const ARegion *ar)
{
- glColor4ub(128, 128, 255, 64);
- glRecti(0, 0, ar->winx, 8 * UI_DPI_FAC);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ub(128, 128, 255, 64);
+ immRecti(pos, 0, 0, ar->winx, 8 * UI_DPI_FAC);
+ immUnbindProgram();
}
void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y)
@@ -2450,9 +2560,13 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f
BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]);
- glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CFRAME);
+ immRecti(pos, x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
+ immUnbindProgram();
- UI_ThemeColor(TH_TEXT);
+ UI_FontThemeColor(fontid, TH_TEXT);
BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f);
BLF_draw(fontid, numstr, sizeof(numstr));
}
@@ -2460,17 +2574,18 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f
void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra)
{
if (num_segments) {
- int a;
-
- glColor4ub(128, 128, 255, 128);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ub(128, 128, 255, 128);
- for (a = 0; a < num_segments; a++) {
- float x1, x2;
+ for (int a = 0; a < num_segments; a++) {
+ float x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
+ float x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
- x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
- x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
-
- glRecti(x1, 0, x2, 8 * UI_DPI_FAC);
+ immRecti(pos, x1, 0, x2, 8 * UI_DPI_FAC);
+ /* TODO(merwin): use primitive restart to draw multiple rects more efficiently */
}
+
+ immUnbindProgram();
}
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 216cbe9d7f4..2eb981467f2 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -49,133 +49,11 @@
#include "IMB_imbuf_types.h"
#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "UI_interface.h"
-#ifndef GL_CLAMP_TO_EDGE
-#define GL_CLAMP_TO_EDGE 0x812F
-#endif
-
-/* UNUSED */
-#if 0
-void fdrawbezier(float vec[4][3])
-{
- float dist;
- float curve_res = 24, spline_step = 0.0f;
-
- dist = 0.5f * fabsf(vec[0][0] - vec[3][0]);
-
- /* check direction later, for top sockets */
- vec[1][0] = vec[0][0] + dist;
- vec[1][1] = vec[0][1];
-
- vec[2][0] = vec[3][0] - dist;
- vec[2][1] = vec[3][1];
- /* we can reuse the dist variable here to increment the GL curve eval amount */
- dist = 1.0f / curve_res;
-
- cpack(0x0);
- glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]);
- glBegin(GL_LINE_STRIP);
- while (spline_step < 1.000001f) {
-#if 0
- if (do_shaded)
- UI_ThemeColorBlend(th_col1, th_col2, spline_step);
-#endif
- glEvalCoord1f(spline_step);
- spline_step += dist;
- }
- glEnd();
-}
-#endif
-
-void fdrawline(float x1, float y1, float x2, float y2)
-{
- glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glEnd();
-}
-
-void fdrawbox(float x1, float y1, float x2, float y2)
-{
- glBegin(GL_LINE_LOOP);
-
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
-
- glEnd();
-}
-
-void fdrawcheckerboard(float x1, float y1, float x2, float y2)
-{
- unsigned char col1[4] = {40, 40, 40}, col2[4] = {50, 50, 50};
-
- glColor3ubv(col1);
- glRectf(x1, y1, x2, y2);
- glColor3ubv(col2);
-
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_CHECKER_8PX);
- glRectf(x1, y1, x2, y2);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-}
-
-void sdrawline(int x1, int y1, int x2, int y2)
-{
- glBegin(GL_LINES);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
-}
-
-/* UNUSED */
-#if 0
-/*
- * x1,y2
- * | \
- * | \
- * | \
- * x1,y1-- x2,y1
- */
-
-static void sdrawtripoints(int x1, int y1, int x2, int y2)
-{
- glVertex2i(x1, y1);
- glVertex2i(x1, y2);
- glVertex2i(x2, y1);
-}
-
-void sdrawtri(int x1, int y1, int x2, int y2)
-{
- glBegin(GL_LINE_STRIP);
- sdrawtripoints(x1, y1, x2, y2);
- glEnd();
-}
-
-void sdrawtrifill(int x1, int y1, int x2, int y2)
-{
- glBegin(GL_TRIANGLES);
- sdrawtripoints(x1, y1, x2, y2);
- glEnd();
-}
-#endif
-
-void sdrawbox(int x1, int y1, int x2, int y2)
-{
- glBegin(GL_LINE_LOOP);
-
- glVertex2i(x1, y1);
- glVertex2i(x1, y2);
- glVertex2i(x2, y2);
- glVertex2i(x2, y1);
-
- glEnd();
-}
-
-
/* ******************************************** */
void setlinestyle(int nr)
@@ -204,122 +82,6 @@ void set_inverted_drawing(int enable)
GL_TOGGLE(GL_DITHER, !enable);
}
-/* UNUSED */
-#if 0
-void sdrawXORline(int x0, int y0, int x1, int y1)
-{
- if (x0 == x1 && y0 == y1) return;
-
- set_inverted_drawing(1);
-
- glBegin(GL_LINES);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glEnd();
-
- set_inverted_drawing(0);
-}
-
-void sdrawXORline4(int nr, int x0, int y0, int x1, int y1)
-{
- static int old[4][2][2];
- static char flags[4] = {0, 0, 0, 0};
-
- /* with builtin memory, max 4 lines */
-
- set_inverted_drawing(1);
-
- glBegin(GL_LINES);
- if (nr == -1) { /* flush */
- for (nr = 0; nr < 4; nr++) {
- if (flags[nr]) {
- glVertex2iv(old[nr][0]);
- glVertex2iv(old[nr][1]);
- flags[nr] = 0;
- }
- }
- }
- else {
- if (nr >= 0 && nr < 4) {
- if (flags[nr]) {
- glVertex2iv(old[nr][0]);
- glVertex2iv(old[nr][1]);
- }
-
- old[nr][0][0] = x0;
- old[nr][0][1] = y0;
- old[nr][1][0] = x1;
- old[nr][1][1] = y1;
-
- flags[nr] = 1;
- }
-
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- }
- glEnd();
-
- set_inverted_drawing(0);
-}
-
-void fdrawXORellipse(float xofs, float yofs, float hw, float hh)
-{
- if (hw == 0) return;
-
- set_inverted_drawing(1);
-
- glPushMatrix();
- glTranslatef(xofs, yofs, 0.0f);
- glScalef(1.0f, hh / hw, 1.0f);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, hw, 20);
- glPopMatrix();
-
- set_inverted_drawing(0);
-}
-
-#endif
-
-void fdrawXORcirc(float xofs, float yofs, float rad)
-{
- set_inverted_drawing(1);
-
- glPushMatrix();
- glTranslatef(xofs, yofs, 0.0);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, rad, 20);
- glPopMatrix();
-
- set_inverted_drawing(0);
-}
-
-void glutil_draw_filled_arc(float start, float angle, float radius, int nsegments)
-{
- int i;
-
- glBegin(GL_TRIANGLE_FAN);
- glVertex2f(0.0, 0.0);
- for (i = 0; i < nsegments; i++) {
- float t = (float) i / (nsegments - 1);
- float cur = start + t * angle;
-
- glVertex2f(cosf(cur) * radius, sinf(cur) * radius);
- }
- glEnd();
-}
-
-void glutil_draw_lined_arc(float start, float angle, float radius, int nsegments)
-{
- int i;
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i < nsegments; i++) {
- float t = (float) i / (nsegments - 1);
- float cur = start + t * angle;
-
- glVertex2f(cosf(cur) * radius, sinf(cur) * radius);
- }
- glEnd();
-}
-
float glaGetOneFloat(int param)
{
GLfloat v;
@@ -375,24 +137,66 @@ static int get_cached_work_texture(int *r_w, int *r_h)
return texid;
}
-void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
+static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
+{
+ VertexFormat *vert_format = immVertexFormat();
+ state->pos = VertexFormat_add_attrib(vert_format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ state->texco = VertexFormat_add_attrib(vert_format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+}
+
+/* To be used before calling immDrawPixelsTex
+ * Default shader is GPU_SHADER_2D_IMAGE_COLOR
+ * You can still set uniforms with :
+ * GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);
+ * */
+IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
+{
+ IMMDrawPixelsTexState state;
+ immDrawPixelsTexSetupAttributes(&state);
+
+ state.shader = GPU_shader_get_builtin_shader(builtin);
+
+ /* Shader will be unbind by immUnbindProgram in immDrawPixelsTexScaled_clipping */
+ immBindBuiltinProgram(builtin);
+ immUniform1i("image", 0);
+ state.do_shader_unbind = true;
+
+ return state;
+}
+
+/* Use the currently bound shader.
+ *
+ * Use immDrawPixelsTexSetup to bind the shader you
+ * want before calling immDrawPixelsTex.
+ *
+ * If using a special shader double check it uses the same
+ * attributes "pos" "texCoord" and uniform "image".
+ *
+ * If color is NULL then use white by default
+ *
+ * Be also aware that this function unbinds the shader when
+ * it's finished.
+ * */
+void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h,
int format, int type, int zoomfilter, void *rect,
float scaleX, float scaleY,
float clip_min_x, float clip_min_y,
- float clip_max_x, float clip_max_y)
+ float clip_max_x, float clip_max_y,
+ float xzoom, float yzoom, float color[4])
{
unsigned char *uc_rect = (unsigned char *) rect;
const float *f_rect = (float *)rect;
- float xzoom = glaGetOneFloat(GL_ZOOM_X), yzoom = glaGetOneFloat(GL_ZOOM_Y);
int subpart_x, subpart_y, tex_w, tex_h;
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
int texid = get_cached_work_texture(&tex_w, &tex_h);
int components;
const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y));
+ float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ GLint unpack_row_length;
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
- /* Specify the color outside this function, and tex will modulate it.
- * This is useful for changing alpha without using glPixelTransferf()
- */
glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w);
glBindTexture(GL_TEXTURE_2D, texid);
@@ -401,18 +205,12 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter);
-#if defined(__APPLE__) && 0
- /* [merwin] disable this workaround and see if anyone is affected. If not scrap it! Also at end of this function */
- /* workaround for os x 10.5/10.6 driver bug: http://lists.apple.com/archives/Mac-opengl/2008/Jul/msg00117.html */
- glPixelZoom(1.0f, 1.0f);
-#endif
-
/* setup seamless 2=on, 0=off */
seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
-
+
offset_x = tex_w - seamless;
offset_y = tex_h - seamless;
-
+
nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
@@ -420,7 +218,7 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
components = 4;
else if (format == GL_RGB)
components = 3;
- else if (ELEM(format, GL_LUMINANCE, GL_ALPHA))
+ else if (format == GL_RED)
components = 1;
else {
BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
@@ -436,6 +234,7 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
* it's possible to use GL_RGBA16F_ARB
*/
+ /* TODO viewport : remove extension */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, tex_w, tex_h, 0, format, GL_FLOAT, NULL);
}
else {
@@ -443,6 +242,16 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL);
}
+ unsigned int pos = state->pos, texco = state->texco;
+
+ /* optional */
+ /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
+ * it does not need color.
+ */
+ if (state->shader != NULL && GPU_shader_get_uniform(state->shader, "color") != -1) {
+ immUniformColor4fv((color) ? color : white);
+ }
+
for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) {
for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) {
int remainder_x = img_w - subpart_x * offset_x;
@@ -474,7 +283,7 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
if (type == GL_FLOAT) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]);
-
+
/* add an extra border of pixels so linear looks ok at edges of full image */
if (subpart_w < tex_w)
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
@@ -485,7 +294,7 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
}
else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]);
-
+
if (subpart_w < tex_w)
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
if (subpart_h < tex_h)
@@ -494,158 +303,55 @@ void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h,
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
}
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
- glBegin(GL_QUADS);
- glTexCoord2f((float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
- glVertex2f(rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immAttrib2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
+ immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
- glTexCoord2f((float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h);
- glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * yzoom);
+ immAttrib2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h);
+ immVertex2f(pos, rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * yzoom);
- glTexCoord2f((float)(subpart_w - offset_right) / tex_w, (float)(subpart_h - offset_top) / tex_h);
- glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
+ immAttrib2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(subpart_h - offset_top) / tex_h);
+ immVertex2f(pos, rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
- glTexCoord2f((float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h);
- glVertex2f(rast_x + (float)offset_left * xzoom, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
- glEnd();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immAttrib2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h);
+ immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
+ immEnd();
}
}
+ if (state->do_shader_unbind) {
+ immUnbindProgram();
+ }
+
glBindTexture(GL_TEXTURE_2D, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
-#if defined(__APPLE__) && 0
- /* workaround for os x 10.5/10.6 driver bug (above) */
- glPixelZoom(xzoom, yzoom);
-#endif
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length);
}
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h,
+void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h,
int format, int type, int zoomfilter, void *rect,
- float scaleX, float scaleY)
+ float scaleX, float scaleY, float xzoom, float yzoom, float color[4])
{
- glaDrawPixelsTexScaled_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect,
- scaleX, scaleY, 0.0f, 0.0f, 0.0f, 0.0f);
+ immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect,
+ scaleX, scaleY, 0.0f, 0.0f, 0.0f, 0.0f, xzoom, yzoom, color);
}
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect)
+void immDrawPixelsTex(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect,
+ float xzoom, float yzoom, float color[4])
{
- glaDrawPixelsTexScaled_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f,
- 0.0f, 0.0f, 0.0f, 0.0f);
+ immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, xzoom, yzoom, color);
}
-void glaDrawPixelsTex_clipping(float x, float y, int img_w, int img_h,
+void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
+ float x, float y, int img_w, int img_h,
int format, int type, int zoomfilter, void *rect,
- float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y)
-{
- glaDrawPixelsTexScaled_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f,
- clip_min_x, clip_min_y, clip_max_x, clip_max_y);
-}
-
-void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect)
-{
- float xzoom = glaGetOneFloat(GL_ZOOM_X);
- float yzoom = glaGetOneFloat(GL_ZOOM_Y);
-
- /* The pixel space coordinate of the intersection of
- * the [zoomed] image with the origin.
- */
- float ix = -x / xzoom;
- float iy = -y / yzoom;
-
- /* The maximum pixel amounts the image can be cropped
- * at the lower left without exceeding the origin.
- */
- int off_x = floor(max_ff(ix, 0.0f));
- int off_y = floor(max_ff(iy, 0.0f));
-
- /* The zoomed space coordinate of the raster position
- * (starting at the lower left most unclipped pixel).
- */
- float rast_x = x + off_x * xzoom;
- float rast_y = y + off_y * yzoom;
-
- GLfloat viewport[4];
- int draw_w, draw_h;
-
- /* Determine the smallest number of pixels we need to draw
- * before the image would go off the upper right corner.
- *
- * It may seem this is just an optimization but some graphics
- * cards (ATI) freak out if there is a large zoom factor and
- * a large number of pixels off the screen (probably at some
- * level the number of image pixels to draw is getting multiplied
- * by the zoom and then clamped). Making sure we draw the
- * fewest pixels possible keeps everyone mostly happy (still
- * fails if we zoom in on one really huge pixel so that it
- * covers the entire screen).
- */
- glGetFloatv(GL_VIEWPORT, viewport);
- draw_w = min_ii(img_w - off_x, ceil((viewport[2] - rast_x) / xzoom));
- draw_h = min_ii(img_h - off_y, ceil((viewport[3] - rast_y) / yzoom));
-
- if (draw_w > 0 && draw_h > 0) {
-
- int bound_options;
- GPU_BASIC_SHADER_DISABLE_AND_STORE(bound_options);
-
- /* Don't use safe RasterPos (slower) if we can avoid it. */
- if (rast_x >= 0 && rast_y >= 0) {
- glRasterPos2f(rast_x, rast_y);
- }
- else {
- glaRasterPosSafe2f(rast_x, rast_y, 0, 0);
- }
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, row_w);
- if (format == GL_LUMINANCE || format == GL_RED) {
- if (type == GL_FLOAT) {
- const float *f_rect = (float *)rect;
- glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y * row_w + off_x));
- }
- else if (type == GL_INT || type == GL_UNSIGNED_INT) {
- const int *i_rect = (int *)rect;
- glDrawPixels(draw_w, draw_h, format, type, i_rect + (off_y * row_w + off_x));
- }
- }
- else { /* RGBA */
- if (type == GL_FLOAT) {
- const float *f_rect = (float *)rect;
- glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y * row_w + off_x) * 4);
- }
- else if (type == GL_UNSIGNED_BYTE) {
- unsigned char *uc_rect = (unsigned char *) rect;
- glDrawPixels(draw_w, draw_h, format, type, uc_rect + (off_y * row_w + off_x) * 4);
- }
- }
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- GPU_BASIC_SHADER_ENABLE_AND_RESTORE(bound_options);
- }
-}
-
-/* uses either DrawPixelsSafe or DrawPixelsTex, based on user defined maximum */
-void glaDrawPixelsAuto_clipping(float x, float y, int img_w, int img_h,
- int format, int type, int zoomfilter, void *rect,
- float clip_min_x, float clip_min_y,
- float clip_max_x, float clip_max_y)
+ float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y,
+ float xzoom, float yzoom, float color[4])
{
- if (U.image_draw_method != IMAGE_DRAW_METHOD_DRAWPIXELS) {
- glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTex_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect,
- clip_min_x, clip_min_y, clip_max_x, clip_max_y);
- }
- else {
- glaDrawPixelsSafe(x, y, img_w, img_h, img_w, format, type, rect);
- }
-}
-
-void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect)
-{
- glaDrawPixelsAuto_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect,
- 0.0f, 0.0f, 0.0f, 0.0f);
+ immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f,
+ clip_min_x, clip_min_y, clip_max_x, clip_max_y, xzoom, yzoom, color);
}
/* 2D Drawing Assistance */
@@ -664,15 +370,12 @@ void glaDefine2DArea(rcti *screen_rect)
* Programming Guide, Appendix H, Correctness Tips.
*/
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, sc_w, 0.0, sc_h, -1, 1);
- glTranslatef(GLA_PIXEL_OFS, GLA_PIXEL_OFS, 0.0);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ gpuOrtho2D(GLA_PIXEL_OFS, sc_w + GLA_PIXEL_OFS, GLA_PIXEL_OFS, sc_h + GLA_PIXEL_OFS);
+ gpuLoadIdentity();
}
+/* TODO(merwin): put the following 2D code to use, or build new 2D code inspired & informd by it */
+
#if 0 /* UNUSED */
struct gla2DDrawInfo {
@@ -726,8 +429,8 @@ gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect)
glGetIntegerv(GL_VIEWPORT, (GLint *)di->orig_vp);
glGetIntegerv(GL_SCISSOR_BOX, (GLint *)di->orig_sc);
- glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)di->orig_projmat);
- glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)di->orig_viewmat);
+ gpuGetProjectionMatrix(di->orig_projmat);
+ gpuGetModelViewMatrix(di->orig_viewmat);
di->screen_rect = *screen_rect;
if (world_rect) {
@@ -778,42 +481,14 @@ void glaEnd2DDraw(gla2DDrawInfo *di)
{
glViewport(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]);
glScissor(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]);
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(di->orig_projmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(di->orig_viewmat);
+ gpuLoadProjectionMatrix(di->orig_projmat);
+ gpuLoadMatrix(di->orig_viewmat);
MEM_freeN(di);
}
-#endif
+#endif /* UNUSED */
-/* Uses current OpenGL state to get view matrices for gluProject/gluUnProject */
-void bgl_get_mats(bglMats *mats)
-{
- const double badvalue = 1.0e-6;
-
- glGetDoublev(GL_MODELVIEW_MATRIX, mats->modelview);
- glGetDoublev(GL_PROJECTION_MATRIX, mats->projection);
- glGetIntegerv(GL_VIEWPORT, (GLint *)mats->viewport);
-
- /* Very strange code here - it seems that certain bad values in the
- * modelview matrix can cause gluUnProject to give bad results. */
- if (mats->modelview[0] < badvalue &&
- mats->modelview[0] > -badvalue)
- {
- mats->modelview[0] = 0;
- }
- if (mats->modelview[5] < badvalue &&
- mats->modelview[5] > -badvalue)
- {
- mats->modelview[5] = 0;
- }
-
- /* Set up viewport so that gluUnProject will give correct values */
- mats->viewport[0] = 0;
- mats->viewport[1] = 0;
-}
/* *************** glPolygonOffset hack ************* */
@@ -831,8 +506,7 @@ void bglPolygonOffset(float viewdist, float dist)
// glPolygonOffset(-1.0, -1.0);
/* hack below is to mimic polygon offset */
- glMatrixMode(GL_PROJECTION);
- glGetFloatv(GL_PROJECTION_MATRIX, (float *)winmat);
+ gpuGetProjectionMatrix(winmat);
/* dist is from camera to center point */
@@ -863,17 +537,13 @@ void bglPolygonOffset(float viewdist, float dist)
winmat[14] -= offs;
offset += offs;
-
- glLoadMatrixf(winmat);
- glMatrixMode(GL_MODELVIEW);
}
else {
- glMatrixMode(GL_PROJECTION);
winmat[14] += offset;
offset = 0.0;
- glLoadMatrixf(winmat);
- glMatrixMode(GL_MODELVIEW);
}
+
+ gpuLoadProjectionMatrix(winmat);
}
/* **** Color management helper functions for GLSL display/transform ***** */
@@ -883,7 +553,8 @@ void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float clip_min_x, float clip_min_y,
- float clip_max_x, float clip_max_y)
+ float clip_max_x, float clip_max_y,
+ float zoom_x, float zoom_y)
{
bool force_fallback = false;
bool need_fallback = true;
@@ -902,6 +573,11 @@ void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
if (force_fallback == false) {
int ok;
+ IMMDrawPixelsTexState state = {0};
+ /* We want GLSL state to be fully handled by OCIO. */
+ state.do_shader_unbind = false;
+ immDrawPixelsTexSetupAttributes(&state);
+
if (ibuf->rect_float) {
if (ibuf->float_colorspace) {
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
@@ -920,8 +596,6 @@ void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
}
if (ok) {
- glColor4f(1.0, 1.0, 1.0, 1.0);
-
if (ibuf->rect_float) {
int format = 0;
@@ -933,16 +607,20 @@ void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
BLI_assert(!"Incompatible number of channels for GLSL display");
if (format != 0) {
- glaDrawPixelsTex_clipping(x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
+ immDrawPixelsTex_clipping(&state,
+ x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
zoomfilter, ibuf->rect_float,
- clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+ clip_min_x, clip_min_y, clip_max_x, clip_max_y,
+ zoom_x, zoom_y, NULL);
}
}
else if (ibuf->rect) {
/* ibuf->rect is always RGBA */
- glaDrawPixelsTex_clipping(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
+ immDrawPixelsTex_clipping(&state,
+ x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
zoomfilter, ibuf->rect,
- clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+ clip_min_x, clip_min_y, clip_max_x, clip_max_y,
+ zoom_x, zoom_y, NULL);
}
IMB_colormanagement_finish_glsl_draw();
@@ -959,9 +637,12 @@ void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);
if (display_buffer) {
- glaDrawPixelsAuto_clipping(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
- zoomfilter, display_buffer,
- clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex_clipping(&state,
+ x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
+ zoomfilter, display_buffer,
+ clip_min_x, clip_min_y, clip_max_x, clip_max_y,
+ zoom_x, zoom_y, NULL);
}
IMB_display_buffer_release(cache_handle);
@@ -970,10 +651,11 @@ void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
ColorManagedViewSettings *view_settings,
- ColorManagedDisplaySettings *display_settings)
+ ColorManagedDisplaySettings *display_settings,
+ float zoom_x, float zoom_y)
{
glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings,
- 0.0f, 0.0f, 0.0f, 0.0f);
+ 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
}
void glaDrawImBuf_glsl_ctx_clipping(const bContext *C,
@@ -981,7 +663,8 @@ void glaDrawImBuf_glsl_ctx_clipping(const bContext *C,
float x, float y,
int zoomfilter,
float clip_min_x, float clip_min_y,
- float clip_max_x, float clip_max_y)
+ float clip_max_x, float clip_max_y,
+ float zoom_x, float zoom_y)
{
ColorManagedViewSettings *view_settings;
ColorManagedDisplaySettings *display_settings;
@@ -989,22 +672,19 @@ void glaDrawImBuf_glsl_ctx_clipping(const bContext *C,
IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings,
- clip_min_x, clip_min_y, clip_max_x, clip_max_y);
-}
-
-void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter)
-{
- glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f);
+ clip_min_x, clip_min_y, clip_max_x, clip_max_y,
+ zoom_x, zoom_y);
}
-void cpack(unsigned int x)
+void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter,
+ float zoom_x, float zoom_y)
{
- glColor3ub(( (x) & 0xFF),
- (((x) >> 8) & 0xFF),
- (((x) >> 16) & 0xFF));
+ glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
}
-void glaDrawBorderCorners(const rcti *border, float zoomx, float zoomy)
+/* don't move to GPU_immediate_util.h because this uses user-prefs
+ * and isn't very low level */
+void immDrawBorderCorners(unsigned int pos, const rcti *border, float zoomx, float zoomy)
{
float delta_x = 4.0f * UI_DPI_FAC / zoomx;
float delta_y = 4.0f * UI_DPI_FAC / zoomy;
@@ -1013,30 +693,30 @@ void glaDrawBorderCorners(const rcti *border, float zoomx, float zoomy)
delta_y = min_ff(delta_y, border->ymax - border->ymin);
/* left bottom corner */
- glBegin(GL_LINE_STRIP);
- glVertex2f(border->xmin, border->ymin + delta_y);
- glVertex2f(border->xmin, border->ymin);
- glVertex2f(border->xmin + delta_x, border->ymin);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, border->xmin, border->ymin + delta_y);
+ immVertex2f(pos, border->xmin, border->ymin);
+ immVertex2f(pos, border->xmin + delta_x, border->ymin);
+ immEnd();
/* left top corner */
- glBegin(GL_LINE_STRIP);
- glVertex2f(border->xmin, border->ymax - delta_y);
- glVertex2f(border->xmin, border->ymax);
- glVertex2f(border->xmin + delta_x, border->ymax);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, border->xmin, border->ymax - delta_y);
+ immVertex2f(pos, border->xmin, border->ymax);
+ immVertex2f(pos, border->xmin + delta_x, border->ymax);
+ immEnd();
/* right bottom corner */
- glBegin(GL_LINE_STRIP);
- glVertex2f(border->xmax - delta_x, border->ymin);
- glVertex2f(border->xmax, border->ymin);
- glVertex2f(border->xmax, border->ymin + delta_y);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, border->xmax - delta_x, border->ymin);
+ immVertex2f(pos, border->xmax, border->ymin);
+ immVertex2f(pos, border->xmax, border->ymin + delta_y);
+ immEnd();
/* right top corner */
- glBegin(GL_LINE_STRIP);
- glVertex2f(border->xmax - delta_x, border->ymax);
- glVertex2f(border->xmax, border->ymax);
- glVertex2f(border->xmax, border->ymax - delta_y);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, border->xmax - delta_x, border->ymax);
+ immVertex2f(pos, border->xmax, border->ymax);
+ immVertex2f(pos, border->xmax, border->ymax - delta_y);
+ immEnd();
}
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index c165bbfd301..0448fba78e6 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -47,6 +47,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_gpencil.h"
+#include "BKE_layer.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
@@ -60,20 +61,8 @@
#include "screen_intern.h"
-static unsigned int context_layers(bScreen *sc, Scene *scene, ScrArea *sa_ctx)
-{
- /* needed for 'USE_ALLSELECT' define, otherwise we end up editing off-screen layers. */
- if (sc && sa_ctx && (sa_ctx->spacetype == SPACE_BUTS)) {
- const unsigned int lay = BKE_screen_view3d_layer_all(sc);
- if (lay) {
- return lay;
- }
- }
- return scene->lay;
-}
-
const char *screen_context_dir[] = {
- "scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
+ "scene", "render_layer", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"selected_objects", "selected_bases",
"editable_objects", "editable_bases",
"selected_editable_objects", "selected_editable_bases",
@@ -95,17 +84,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bScreen *sc = CTX_wm_screen(C);
ScrArea *sa = CTX_wm_area(C);
Scene *scene = sc->scene;
- Base *base;
-
-#if 0 /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
- Object *obact = CTX_data_active_object(C);
- Object *obedit = CTX_data_edit_object(C);
- base = CTX_data_active_base(C);
-#else
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = scene->obedit;
- Object *obact = OBACT;
- base = BASACT;
-#endif
+ Object *obact = sl->basact ? sl->basact->object : NULL;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);
@@ -115,84 +96,100 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_id_pointer_set(result, &scene->id);
return 1;
}
- else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
- const unsigned int lay = context_layers(sc, scene, sa);
- const bool visible_objects = CTX_data_equals(member, "visible_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
- if (visible_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ else if (CTX_data_equals(member, "visible_objects")) {
+ FOREACH_VISIBLE_OBJECT(sl, ob)
+ {
+ CTX_data_id_list_add(result, &ob->id);
+ }
+ FOREACH_VISIBLE_BASE_END
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selectable_objects")) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ CTX_data_id_list_add(result, &base->object->id);
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
- const unsigned int lay = context_layers(sc, scene, sa);
- const bool selectable_objects = CTX_data_equals(member, "selectable_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & lay) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
- if (selectable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
+ else if (CTX_data_equals(member, "selected_objects")) {
+ FOREACH_SELECTED_OBJECT(sl, ob)
+ {
+ CTX_data_id_list_add(result, &ob->id);
+ }
+ FOREACH_SELECTED_OBJECT_END
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selected_editable_objects")) {
+ FOREACH_SELECTED_OBJECT(sl, ob)
+ {
+ if (0 == BKE_object_is_libdata(ob)) {
+ CTX_data_id_list_add(result, &ob->id);
}
}
+ FOREACH_SELECTED_OBJECT_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
- const unsigned int lay = context_layers(sc, scene, sa);
- const bool selected_objects = CTX_data_equals(member, "selected_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if ((base->flag & SELECT) && (base->lay & lay)) {
- if (selected_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ else if (CTX_data_equals(member, "editable_objects")) {
+ /* Visible + Editable, but not necessarily selected */
+ FOREACH_VISIBLE_OBJECT(sl, ob)
+ {
+ if (0 == BKE_object_is_libdata(ob)) {
+ CTX_data_id_list_add(result, &ob->id);
}
}
+ FOREACH_VISIBLE_OBJECT_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
- const unsigned int lay = context_layers(sc, scene, sa);
- const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if ((base->flag & SELECT) && (base->lay & lay)) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (0 == BKE_object_is_libdata(base->object)) {
- if (selected_editable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
+ else if ( CTX_data_equals(member, "visible_bases")) {
+ FOREACH_VISIBLE_BASE(sl, base)
+ {
+ CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ }
+ FOREACH_VISIBLE_BASE_END
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selectable_bases")) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTABLED) != 0) {
+ CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ }
+ }
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selected_bases")) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ }
+ }
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selected_editable_bases")) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ if (0 == BKE_object_is_libdata(base->object)) {
+ CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "editable_objects") || CTX_data_equals(member, "editable_bases")) {
- const unsigned int lay = context_layers(sc, scene, sa);
- const bool editable_objects = CTX_data_equals(member, "editable_objects");
-
+ else if (CTX_data_equals(member, "editable_bases")) {
/* Visible + Editable, but not necessarily selected */
- for (base = scene->base.first; base; base = base->next) {
- if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
if (0 == BKE_object_is_libdata(base->object)) {
- if (editable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
}
@@ -344,8 +341,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
else if (CTX_data_equals(member, "active_base")) {
- if (base)
- CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);
+ if (sl->basact)
+ CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, sl->basact);
return 1;
}
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
new file mode 100644
index 00000000000..4e43a7f96e7
--- /dev/null
+++ b/source/blender/editors/screen/screen_draw.c
@@ -0,0 +1,495 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/screen/screen_draw.c
+ * \ingroup edscr
+ */
+
+#include "ED_screen.h"
+
+#include "GPU_framebuffer.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "screen_intern.h"
+
+
+/**
+ * Draw horizontal shape visualizing future joining (left as well right direction of future joining).
+ */
+static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos)
+{
+ vec2f points[10];
+ short i;
+ float w, h;
+ float width = sa->v3->vec.x - sa->v1->vec.x;
+ float height = sa->v3->vec.y - sa->v1->vec.y;
+
+ if (height < width) {
+ h = height / 8;
+ w = height / 4;
+ }
+ else {
+ h = width / 8;
+ w = width / 4;
+ }
+
+ points[0].x = sa->v1->vec.x;
+ points[0].y = sa->v1->vec.y + height / 2;
+
+ points[1].x = sa->v1->vec.x;
+ points[1].y = sa->v1->vec.y;
+
+ points[2].x = sa->v4->vec.x - w;
+ points[2].y = sa->v4->vec.y;
+
+ points[3].x = sa->v4->vec.x - w;
+ points[3].y = sa->v4->vec.y + height / 2 - 2 * h;
+
+ points[4].x = sa->v4->vec.x - 2 * w;
+ points[4].y = sa->v4->vec.y + height / 2;
+
+ points[5].x = sa->v4->vec.x - w;
+ points[5].y = sa->v4->vec.y + height / 2 + 2 * h;
+
+ points[6].x = sa->v3->vec.x - w;
+ points[6].y = sa->v3->vec.y;
+
+ points[7].x = sa->v2->vec.x;
+ points[7].y = sa->v2->vec.y;
+
+ points[8].x = sa->v4->vec.x;
+ points[8].y = sa->v4->vec.y + height / 2 - h;
+
+ points[9].x = sa->v4->vec.x;
+ points[9].y = sa->v4->vec.y + height / 2 + h;
+
+ if (dir == 'l') {
+ /* when direction is left, then we flip direction of arrow */
+ float cx = sa->v1->vec.x + width;
+ for (i = 0; i < 10; i++) {
+ points[i].x -= cx;
+ points[i].x = -points[i].x;
+ points[i].x += sa->v1->vec.x;
+ }
+ }
+
+ immBegin(PRIM_TRIANGLE_FAN, 5);
+
+ for (i = 0; i < 5; i++) {
+ immVertex2f(pos, points[i].x, points[i].y);
+ }
+
+ immEnd();
+
+ immBegin(PRIM_TRIANGLE_FAN, 5);
+
+ for (i = 4; i < 8; i++) {
+ immVertex2f(pos, points[i].x, points[i].y);
+ }
+
+ immVertex2f(pos, points[0].x, points[0].y);
+ immEnd();
+
+ immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y);
+ immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y);
+}
+
+/**
+ * Draw vertical shape visualizing future joining (up/down direction).
+ */
+static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos)
+{
+ vec2f points[10];
+ short i;
+ float w, h;
+ float width = sa->v3->vec.x - sa->v1->vec.x;
+ float height = sa->v3->vec.y - sa->v1->vec.y;
+
+ if (height < width) {
+ h = height / 4;
+ w = height / 8;
+ }
+ else {
+ h = width / 4;
+ w = width / 8;
+ }
+
+ points[0].x = sa->v1->vec.x + width / 2;
+ points[0].y = sa->v3->vec.y;
+
+ points[1].x = sa->v2->vec.x;
+ points[1].y = sa->v2->vec.y;
+
+ points[2].x = sa->v1->vec.x;
+ points[2].y = sa->v1->vec.y + h;
+
+ points[3].x = sa->v1->vec.x + width / 2 - 2 * w;
+ points[3].y = sa->v1->vec.y + h;
+
+ points[4].x = sa->v1->vec.x + width / 2;
+ points[4].y = sa->v1->vec.y + 2 * h;
+
+ points[5].x = sa->v1->vec.x + width / 2 + 2 * w;
+ points[5].y = sa->v1->vec.y + h;
+
+ points[6].x = sa->v4->vec.x;
+ points[6].y = sa->v4->vec.y + h;
+
+ points[7].x = sa->v3->vec.x;
+ points[7].y = sa->v3->vec.y;
+
+ points[8].x = sa->v1->vec.x + width / 2 - w;
+ points[8].y = sa->v1->vec.y;
+
+ points[9].x = sa->v1->vec.x + width / 2 + w;
+ points[9].y = sa->v1->vec.y;
+
+ if (dir == 'u') {
+ /* when direction is up, then we flip direction of arrow */
+ float cy = sa->v1->vec.y + height;
+ for (i = 0; i < 10; i++) {
+ points[i].y -= cy;
+ points[i].y = -points[i].y;
+ points[i].y += sa->v1->vec.y;
+ }
+ }
+
+ immBegin(PRIM_TRIANGLE_FAN, 5);
+
+ for (i = 0; i < 5; i++) {
+ immVertex2f(pos, points[i].x, points[i].y);
+ }
+
+ immEnd();
+
+ immBegin(PRIM_TRIANGLE_FAN, 5);
+
+ for (i = 4; i < 8; i++) {
+ immVertex2f(pos, points[i].x, points[i].y);
+ }
+
+ immVertex2f(pos, points[0].x, points[0].y);
+ immEnd();
+
+ immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y);
+ immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y);
+}
+
+/**
+ * Draw join shape due to direction of joining.
+ */
+static void draw_join_shape(ScrArea *sa, char dir, unsigned int pos)
+{
+ if (dir == 'u' || dir == 'd') {
+ draw_vertical_join_shape(sa, dir, pos);
+ }
+ else {
+ draw_horizontal_join_shape(sa, dir, pos);
+ }
+}
+
+/**
+ * Draw screen area darker with arrow (visualization of future joining).
+ */
+static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos)
+{
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ immUniformColor4ub(0, 0, 0, 50);
+
+ draw_join_shape(sa, dir, pos);
+}
+
+/**
+ * Draw screen area ligher with arrow shape ("eraser" of previous dark shape).
+ */
+static void scrarea_draw_shape_light(ScrArea *sa, char UNUSED(dir), unsigned int pos)
+{
+ glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
+ /* value 181 was hardly computed: 181~105 */
+ immUniformColor4ub(255, 255, 255, 50);
+ /* draw_join_shape(sa, dir); */
+
+ immRectf(pos, sa->v1->vec.x, sa->v1->vec.y, sa->v3->vec.x, sa->v3->vec.y);
+}
+
+static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, short x2, short y2, unsigned int pos)
+{
+ int count = 0;
+
+ if (x2 < sizex - 1) count += 2;
+ if (x1 > 0) count += 2;
+ if (y2 < sizey - 1) count += 2;
+ if (y1 > 0) count += 2;
+
+ if (count == 0) {
+ return;
+ }
+
+ immBegin(PRIM_LINES, count);
+
+ /* right border area */
+ if (x2 < sizex - 1) {
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y2);
+ }
+
+ /* left border area */
+ if (x1 > 0) { /* otherwise it draws the emboss of window over */
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y2);
+ }
+
+ /* top border area */
+ if (y2 < sizey - 1) {
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y2);
+ }
+
+ /* bottom border area */
+ if (y1 > 0) {
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y1);
+ }
+
+ immEnd();
+}
+
+/**
+ * \brief Screen edges drawing.
+ */
+static void drawscredge_area(ScrArea *sa, int sizex, int sizey, unsigned int pos)
+{
+ short x1 = sa->v1->vec.x;
+ short y1 = sa->v1->vec.y;
+ short x2 = sa->v3->vec.x;
+ short y2 = sa->v3->vec.y;
+
+ drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, pos);
+}
+
+/**
+ * Only for edge lines between areas, and the blended join arrows.
+ */
+void ED_screen_draw(wmWindow *win)
+{
+ const int winsize_x = WM_window_pixels_x(win);
+ const int winsize_y = WM_window_pixels_y(win);
+
+ ScrArea *sa;
+ ScrArea *sa1 = NULL;
+ ScrArea *sa2 = NULL;
+ ScrArea *sa3 = NULL;
+
+ wmSubWindowSet(win, win->screen->mainwin);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* Note: first loop only draws if U.pixelsize > 1, skip otherwise */
+ if (U.pixelsize > 1.0f) {
+ /* FIXME: doesn't our glLineWidth already scale by U.pixelsize? */
+ glLineWidth((2.0f * U.pixelsize) - 1);
+ immUniformColor3ub(0x50, 0x50, 0x50);
+
+ for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ drawscredge_area(sa, winsize_x, winsize_y, pos);
+ }
+ }
+
+ glLineWidth(1);
+ immUniformColor3ub(0, 0, 0);
+
+ for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ drawscredge_area(sa, winsize_x, winsize_y, pos);
+
+ /* gather area split/join info */
+ if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa;
+ if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa;
+ if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa;
+ }
+
+ /* blended join arrow */
+ if (sa1 && sa2) {
+ int dir = area_getorientation(sa1, sa2);
+ int dira = -1;
+ if (dir != -1) {
+ switch (dir) {
+ case 0: /* W */
+ dir = 'r';
+ dira = 'l';
+ break;
+ case 1: /* N */
+ dir = 'd';
+ dira = 'u';
+ break;
+ case 2: /* E */
+ dir = 'l';
+ dira = 'r';
+ break;
+ case 3: /* S */
+ dir = 'u';
+ dira = 'd';
+ break;
+ }
+ }
+
+ glEnable(GL_BLEND);
+
+ scrarea_draw_shape_dark(sa2, dir, pos);
+ scrarea_draw_shape_light(sa1, dira, pos);
+
+ glDisable(GL_BLEND);
+ }
+
+ /* splitpoint */
+ if (sa3) {
+ glEnable(GL_BLEND);
+ immUniformColor4ub(255, 255, 255, 100);
+
+ immBegin(PRIM_LINES, 2);
+
+ if (sa3->flag & AREA_FLAG_DRAWSPLIT_H) {
+ immVertex2f(pos, sa3->totrct.xmin, win->eventstate->y);
+ immVertex2f(pos, sa3->totrct.xmax, win->eventstate->y);
+
+ immEnd();
+
+ immUniformColor4ub(0, 0, 0, 100);
+
+ immBegin(PRIM_LINES, 2);
+
+ immVertex2f(pos, sa3->totrct.xmin, win->eventstate->y + 1);
+ immVertex2f(pos, sa3->totrct.xmax, win->eventstate->y + 1);
+ }
+ else {
+ immVertex2f(pos, win->eventstate->x, sa3->totrct.ymin);
+ immVertex2f(pos, win->eventstate->x, sa3->totrct.ymax);
+
+ immEnd();
+
+ immUniformColor4ub(0, 0, 0, 100);
+
+ immBegin(PRIM_LINES, 2);
+
+ immVertex2f(pos, win->eventstate->x + 1, sa3->totrct.ymin);
+ immVertex2f(pos, win->eventstate->x + 1, sa3->totrct.ymax);
+ }
+
+ immEnd();
+
+ glDisable(GL_BLEND);
+ }
+
+ immUnbindProgram();
+
+ win->screen->do_draw = false;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Screen Thumbnail Preview */
+
+/**
+ * Calculates a scale factor to squash the preview for \a screen into a rectangle of given size and aspect.
+ */
+static void screen_preview_scale_get(
+ const bScreen *screen, float size_x, float size_y,
+ const float asp[2],
+ float r_scale[2])
+{
+ float max_x = 0, max_y = 0;
+
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ max_x = MAX2(max_x, sa->totrct.xmax);
+ max_y = MAX2(max_y, sa->totrct.ymax);
+ }
+ r_scale[0] = (size_x * asp[0]) / max_x;
+ r_scale[1] = (size_y * asp[1]) / max_y;
+}
+
+static void screen_preview_draw_areas(const bScreen *screen, const float scale[2], const float col[4],
+ const float ofs_between_areas)
+{
+ const float ofs_h = ofs_between_areas * 0.5f;
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(col);
+
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ rctf rect = {
+ .xmin = sa->totrct.xmin * scale[0] + ofs_h,
+ .xmax = sa->totrct.xmax * scale[0] - ofs_h,
+ .ymin = sa->totrct.ymin * scale[1] + ofs_h,
+ .ymax = sa->totrct.ymax * scale[1] - ofs_h
+ };
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immVertex2f(pos, rect.xmin, rect.ymin);
+ immVertex2f(pos, rect.xmax, rect.ymin);
+ immVertex2f(pos, rect.xmax, rect.ymax);
+ immVertex2f(pos, rect.xmin, rect.ymax);
+ immEnd();
+ }
+
+ immUnbindProgram();
+}
+
+static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
+{
+ const float asp[2] = {1.0f, 0.8f}; /* square previews look a bit ugly */
+ /* could use theme color (tui.wcol_menu_item.text), but then we'd need to regenerate all previews when changing */
+ const float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ float scale[2];
+
+ wmOrtho2(0.0f, size_x, 0.0f, size_y);
+ /* center */
+ gpuPushMatrix();
+ gpuTranslate2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f);
+
+ screen_preview_scale_get(screen, size_x, size_y, asp, scale);
+ screen_preview_draw_areas(screen, scale, col, 1.5f);
+
+ gpuPopMatrix();
+}
+
+/**
+ * Render the preview for a screen layout in \a screen.
+ */
+void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect)
+{
+ char err_out[256] = "unknown";
+ GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, err_out);
+
+ GPU_offscreen_bind(offscreen, true);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ screen_preview_draw(screen, size_x, size_y);
+
+ GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect);
+ GPU_offscreen_unbind(offscreen, true);
+
+ GPU_offscreen_free(offscreen);
+}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 7d2b77028fc..d59109a5baa 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -42,6 +42,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -51,9 +52,6 @@
#include "BKE_screen.h"
#include "BKE_scene.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -615,7 +613,9 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2)
screen_delarea(C, scr, sa2);
removedouble_scrverts(scr);
sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
-
+ /* Update preview thumbnail */
+ BKE_icon_changed(scr->id.icon_id);
+
return 1;
}
@@ -838,217 +838,6 @@ static void screen_test_scale(bScreen *sc, int winsize_x, int winsize_y)
}
-/* *********************** DRAWING **************************************** */
-
-/* draw vertical shape visualizing future joining (left as well
- * right direction of future joining) */
-static void draw_horizontal_join_shape(ScrArea *sa, char dir)
-{
- vec2f points[10];
- short i;
- float w, h;
- float width = sa->v3->vec.x - sa->v1->vec.x;
- float height = sa->v3->vec.y - sa->v1->vec.y;
-
- if (height < width) {
- h = height / 8;
- w = height / 4;
- }
- else {
- h = width / 8;
- w = width / 4;
- }
-
- points[0].x = sa->v1->vec.x;
- points[0].y = sa->v1->vec.y + height / 2;
-
- points[1].x = sa->v1->vec.x;
- points[1].y = sa->v1->vec.y;
-
- points[2].x = sa->v4->vec.x - w;
- points[2].y = sa->v4->vec.y;
-
- points[3].x = sa->v4->vec.x - w;
- points[3].y = sa->v4->vec.y + height / 2 - 2 * h;
-
- points[4].x = sa->v4->vec.x - 2 * w;
- points[4].y = sa->v4->vec.y + height / 2;
-
- points[5].x = sa->v4->vec.x - w;
- points[5].y = sa->v4->vec.y + height / 2 + 2 * h;
-
- points[6].x = sa->v3->vec.x - w;
- points[6].y = sa->v3->vec.y;
-
- points[7].x = sa->v2->vec.x;
- points[7].y = sa->v2->vec.y;
-
- points[8].x = sa->v4->vec.x;
- points[8].y = sa->v4->vec.y + height / 2 - h;
-
- points[9].x = sa->v4->vec.x;
- points[9].y = sa->v4->vec.y + height / 2 + h;
-
- if (dir == 'l') {
- /* when direction is left, then we flip direction of arrow */
- float cx = sa->v1->vec.x + width;
- for (i = 0; i < 10; i++) {
- points[i].x -= cx;
- points[i].x = -points[i].x;
- points[i].x += sa->v1->vec.x;
- }
- }
-
- glBegin(GL_POLYGON);
- for (i = 0; i < 5; i++)
- glVertex2f(points[i].x, points[i].y);
- glEnd();
- glBegin(GL_POLYGON);
- for (i = 4; i < 8; i++)
- glVertex2f(points[i].x, points[i].y);
- glVertex2f(points[0].x, points[0].y);
- glEnd();
-
- glRectf(points[2].x, points[2].y, points[8].x, points[8].y);
- glRectf(points[6].x, points[6].y, points[9].x, points[9].y);
-}
-
-/* draw vertical shape visualizing future joining (up/down direction) */
-static void draw_vertical_join_shape(ScrArea *sa, char dir)
-{
- vec2f points[10];
- short i;
- float w, h;
- float width = sa->v3->vec.x - sa->v1->vec.x;
- float height = sa->v3->vec.y - sa->v1->vec.y;
-
- if (height < width) {
- h = height / 4;
- w = height / 8;
- }
- else {
- h = width / 4;
- w = width / 8;
- }
-
- points[0].x = sa->v1->vec.x + width / 2;
- points[0].y = sa->v3->vec.y;
-
- points[1].x = sa->v2->vec.x;
- points[1].y = sa->v2->vec.y;
-
- points[2].x = sa->v1->vec.x;
- points[2].y = sa->v1->vec.y + h;
-
- points[3].x = sa->v1->vec.x + width / 2 - 2 * w;
- points[3].y = sa->v1->vec.y + h;
-
- points[4].x = sa->v1->vec.x + width / 2;
- points[4].y = sa->v1->vec.y + 2 * h;
-
- points[5].x = sa->v1->vec.x + width / 2 + 2 * w;
- points[5].y = sa->v1->vec.y + h;
-
- points[6].x = sa->v4->vec.x;
- points[6].y = sa->v4->vec.y + h;
-
- points[7].x = sa->v3->vec.x;
- points[7].y = sa->v3->vec.y;
-
- points[8].x = sa->v1->vec.x + width / 2 - w;
- points[8].y = sa->v1->vec.y;
-
- points[9].x = sa->v1->vec.x + width / 2 + w;
- points[9].y = sa->v1->vec.y;
-
- if (dir == 'u') {
- /* when direction is up, then we flip direction of arrow */
- float cy = sa->v1->vec.y + height;
- for (i = 0; i < 10; i++) {
- points[i].y -= cy;
- points[i].y = -points[i].y;
- points[i].y += sa->v1->vec.y;
- }
- }
-
- glBegin(GL_POLYGON);
- for (i = 0; i < 5; i++)
- glVertex2f(points[i].x, points[i].y);
- glEnd();
- glBegin(GL_POLYGON);
- for (i = 4; i < 8; i++)
- glVertex2f(points[i].x, points[i].y);
- glVertex2f(points[0].x, points[0].y);
- glEnd();
-
- glRectf(points[2].x, points[2].y, points[8].x, points[8].y);
- glRectf(points[6].x, points[6].y, points[9].x, points[9].y);
-}
-
-/* draw join shape due to direction of joining */
-static void draw_join_shape(ScrArea *sa, char dir)
-{
- if (dir == 'u' || dir == 'd')
- draw_vertical_join_shape(sa, dir);
- else
- draw_horizontal_join_shape(sa, dir);
-}
-
-/* draw screen area darker with arrow (visualization of future joining) */
-static void scrarea_draw_shape_dark(ScrArea *sa, char dir)
-{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(0, 0, 0, 50);
- draw_join_shape(sa, dir);
-}
-
-/* draw screen area ligher with arrow shape ("eraser" of previous dark shape) */
-static void scrarea_draw_shape_light(ScrArea *sa, char UNUSED(dir))
-{
- glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
- /* value 181 was hardly computed: 181~105 */
- glColor4ub(255, 255, 255, 50);
- /* draw_join_shape(sa, dir); */
- glRecti(sa->v1->vec.x, sa->v1->vec.y, sa->v3->vec.x, sa->v3->vec.y);
-}
-
-static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, short x2, short y2)
-{
- /* right border area */
- if (x2 < sizex - 1) {
- glVertex2s(x2, y1);
- glVertex2s(x2, y2);
- }
-
- /* left border area */
- if (x1 > 0) { /* otherwise it draws the emboss of window over */
- glVertex2s(x1, y1);
- glVertex2s(x1, y2);
- }
-
- /* top border area */
- if (y2 < sizey - 1) {
- glVertex2s(x1, y2);
- glVertex2s(x2, y2);
- }
-
- /* bottom border area */
- if (y1 > 0) {
- glVertex2s(x1, y1);
- glVertex2s(x2, y1);
- }
-}
-
-/** screen edges drawing **/
-static void drawscredge_area(ScrArea *sa, int sizex, int sizey)
-{
- short x1 = sa->v1->vec.x;
- short y1 = sa->v1->vec.y;
- short x2 = sa->v3->vec.x;
- short y2 = sa->v3->vec.y;
-
- drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2);
-}
/* ****************** EXPORTED API TO OTHER MODULES *************************** */
@@ -1073,6 +862,9 @@ static void region_cursor_set(wmWindow *win, int swinid, int swin_changed)
for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->swinid == swinid) {
if (swin_changed || (ar->type && ar->type->event_cursor)) {
+ if (WM_manipulatormap_cursor_set(ar->manipulator_map, win)) {
+ return;
+ }
ED_region_cursor_set(win, sa, ar);
}
return;
@@ -1105,100 +897,6 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note)
}
}
-/* only for edge lines between areas, and the blended join arrows */
-void ED_screen_draw(wmWindow *win)
-{
- const int winsize_x = WM_window_pixels_x(win);
- const int winsize_y = WM_window_pixels_y(win);
-
- ScrArea *sa;
- ScrArea *sa1 = NULL;
- ScrArea *sa2 = NULL;
- ScrArea *sa3 = NULL;
-
- wmSubWindowSet(win, win->screen->mainwin);
-
- /* Note: first loop only draws if U.pixelsize > 1, skip otherwise */
- if (U.pixelsize > 1.0f) {
- /* FIXME: doesn't our glLineWidth already scale by U.pixelsize? */
- glLineWidth((2.0f * U.pixelsize) - 1);
- glColor3ub(0x50, 0x50, 0x50);
- glBegin(GL_LINES);
- for (sa = win->screen->areabase.first; sa; sa = sa->next)
- drawscredge_area(sa, winsize_x, winsize_y);
- glEnd();
- }
-
- glLineWidth(1);
- glColor3ub(0, 0, 0);
- glBegin(GL_LINES);
- for (sa = win->screen->areabase.first; sa; sa = sa->next) {
- drawscredge_area(sa, winsize_x, winsize_y);
-
- /* gather area split/join info */
- if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa;
- if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa;
- if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa;
- }
- glEnd();
-
- /* blended join arrow */
- if (sa1 && sa2) {
- int dir = area_getorientation(sa1, sa2);
- int dira = -1;
- if (dir != -1) {
- switch (dir) {
- case 0: /* W */
- dir = 'r';
- dira = 'l';
- break;
- case 1: /* N */
- dir = 'd';
- dira = 'u';
- break;
- case 2: /* E */
- dir = 'l';
- dira = 'r';
- break;
- case 3: /* S */
- dir = 'u';
- dira = 'd';
- break;
- }
- }
- glEnable(GL_BLEND);
- scrarea_draw_shape_dark(sa2, dir);
- scrarea_draw_shape_light(sa1, dira);
- glDisable(GL_BLEND);
- }
-
- /* splitpoint */
- if (sa3) {
- glEnable(GL_BLEND);
- glBegin(GL_LINES);
- glColor4ub(255, 255, 255, 100);
-
- if (sa3->flag & AREA_FLAG_DRAWSPLIT_H) {
- glVertex2s(sa3->totrct.xmin, win->eventstate->y);
- glVertex2s(sa3->totrct.xmax, win->eventstate->y);
- glColor4ub(0, 0, 0, 100);
- glVertex2s(sa3->totrct.xmin, win->eventstate->y + 1);
- glVertex2s(sa3->totrct.xmax, win->eventstate->y + 1);
- }
- else {
- glVertex2s(win->eventstate->x, sa3->totrct.ymin);
- glVertex2s(win->eventstate->x, sa3->totrct.ymax);
- glColor4ub(0, 0, 0, 100);
- glVertex2s(win->eventstate->x + 1, sa3->totrct.ymin);
- glVertex2s(win->eventstate->x + 1, sa3->totrct.ymax);
- }
- glEnd();
- glDisable(GL_BLEND);
- }
-
- win->screen->do_draw = false;
-}
-
/* helper call for below, dpi changes headers */
static void screen_refresh_headersizes(void)
{
@@ -1278,25 +976,28 @@ void ED_screens_initialize(wmWindowManager *wm)
void ED_region_exit(bContext *C, ARegion *ar)
{
wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
ARegion *prevar = CTX_wm_region(C);
if (ar->type && ar->type->exit)
ar->type->exit(wm, ar);
CTX_wm_region_set(C, ar);
+
WM_event_remove_handlers(C, &ar->handlers);
+ WM_event_modal_handler_region_replace(win, ar, NULL);
if (ar->swinid) {
- wm_subwindow_close(CTX_wm_window(C), ar->swinid);
+ wm_subwindow_close(win, ar->swinid);
ar->swinid = 0;
}
-
+
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
}
if (ar->regiontimer) {
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer);
+ WM_event_remove_timer(wm, win, ar->regiontimer);
ar->regiontimer = NULL;
}
@@ -1306,6 +1007,7 @@ void ED_region_exit(bContext *C, ARegion *ar)
void ED_area_exit(bContext *C, ScrArea *sa)
{
wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
ScrArea *prevsa = CTX_wm_area(C);
ARegion *ar;
@@ -1313,10 +1015,13 @@ void ED_area_exit(bContext *C, ScrArea *sa)
sa->type->exit(wm, sa);
CTX_wm_area_set(C, sa);
+
for (ar = sa->regionbase.first; ar; ar = ar->next)
ED_region_exit(C, ar);
WM_event_remove_handlers(C, &sa->handlers);
+ WM_event_modal_handler_area_replace(win, sa, NULL);
+
CTX_wm_area_set(C, prevsa);
}
@@ -2138,10 +1843,6 @@ void ED_screen_animation_timer_update(bScreen *screen, int redraws, int refresh)
* screen can be NULL */
void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
{
- wmWindowManager *wm = bmain->wm.first;
- wmWindow *window;
- int layers = 0;
-
#ifdef DURIAN_CAMERA_SWITCH
void *camera = BKE_scene_camera_switch_find(scene);
if (camera && scene->camera != camera) {
@@ -2156,12 +1857,8 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
ED_clip_update_frame(bmain, scene->r.cfra);
- /* get layers from all windows */
- for (window = wm->windows.first; window; window = window->next)
- layers |= BKE_screen_visible_layers(window->screen, scene);
-
/* this function applies the changes too */
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, layers);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
/* composite */
if (scene->use_nodes && scene->nodetree)
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index ccb6d5a6dca..49c0869fcfb 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -31,6 +31,8 @@
#ifndef __SCREEN_INTERN_H__
#define __SCREEN_INTERN_H__
+struct bContextDataResult;
+
/* internal exports only */
#define AZONESPOT (0.6f * U.widget_unit)
@@ -40,12 +42,12 @@
/* area.c */
void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free);
void ED_area_data_swap(ScrArea *sa1, ScrArea *sa2);
-void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade);
+void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
/* screen_edit.c */
ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge);
-int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2);
+int screen_area_join(struct bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2);
int area_getorientation(ScrArea *sa, ScrArea *sb);
void select_connected_scredge(bScreen *sc, ScrEdge *edge);
@@ -61,7 +63,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc,
struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]);
/* screen_context.c */
-int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
+int ed_screen_context(const struct bContext *C, const char *member, struct bContextDataResult *result);
extern const char *screen_context_dir[]; /* doc access */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 9dbc082c119..69d13beee48 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -53,6 +53,7 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
+#include "BKE_icons.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -571,8 +572,8 @@ int ED_operator_mask(bContext *C)
case SPACE_IMAGE:
{
SpaceImage *sima = sa->spacedata.first;
- Scene *scene = CTX_data_scene(C);
- return ED_space_image_check_show_maskedit(scene, sima);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ return ED_space_image_check_show_maskedit(sl, sima);
}
}
}
@@ -1220,6 +1221,8 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int
}
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */
+ /* Update preview thumbnail */
+ BKE_icon_changed(sc->id.icon_id);
}
}
@@ -1508,7 +1511,9 @@ static int area_split_apply(bContext *C, wmOperator *op)
ED_area_tag_redraw(sd->narea);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+ /* Update preview thumbnail */
+ BKE_icon_changed(sc->id.icon_id);
+
return 1;
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 2dd7400bc37..a0b077a6b29 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -54,7 +54,9 @@
#include "BKE_writeavi.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -451,25 +453,24 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
/* Helper callback for drawing the cursor itself */
static void screencast_draw_cursor(bContext *UNUSED(C), int x, int y, void *UNUSED(p_ptr))
{
-
- glPushMatrix();
-
- glTranslatef((float)x, (float)y, 0.0f);
-
-
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
-
- glColor4ub(0, 0, 0, 32);
- glutil_draw_filled_arc(0.0, M_PI * 2.0, 20, 40);
-
- glColor4ub(255, 255, 255, 128);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, 20, 40);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4ub(0, 0, 0, 32);
+ imm_draw_circle_fill(pos, (float)x, (float)y, 20, 40);
+
+ immUniformColor4ub(255, 255, 255, 128);
+ imm_draw_circle_wire(pos, (float)x, (float)y, 20, 40);
+
+ immUnbindProgram();
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
-
- glPopMatrix();
}
/* Turn brush cursor in 3D view on/off */
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 53c11e2a6a9..d48b6f86831 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -53,14 +53,14 @@
#include "WM_api.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "IMB_imbuf_types.h"
#include "ED_view3d.h"
-#include "GPU_basic_shader.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "UI_resources.h"
@@ -335,8 +335,8 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
glBindTexture(GL_TEXTURE_2D, target->overlay_texture);
if (refresh) {
- GLenum format = col ? GL_RGBA : GL_ALPHA;
- GLenum internalformat = col ? GL_RGBA8 : GL_ALPHA8;
+ GLenum format = col ? GL_RGBA : GL_RED;
+ GLenum internalformat = col ? GL_RGBA8 : GL_R8;
if (!init || (target->old_col != col)) {
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, size, size, 0, format, GL_UNSIGNED_BYTE, buffer);
@@ -351,8 +351,6 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
target->old_col = col;
}
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -459,18 +457,16 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
if (refresh) {
if (!init) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size, size, 0, GL_RED, GL_UNSIGNED_BYTE, buffer);
}
else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_RED, GL_UNSIGNED_BYTE, buffer);
}
if (buffer)
MEM_freeN(buffer);
}
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -604,22 +600,20 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
glDepthMask(GL_FALSE);
glDepthFunc(GL_ALWAYS);
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glLoadIdentity();
-
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ gpuPushMatrix();
+
/* brush rotation */
- glTranslatef(0.5, 0.5, 0);
- glRotatef((double)RAD2DEGF((primary) ? ups->brush_rotation : ups->brush_rotation_sec),
- 0.0, 0.0, 1.0);
- glTranslatef(-0.5f, -0.5f, 0);
+ gpuTranslate2f(x, y);
+ gpuRotate2D(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec));
+ gpuTranslate2f(-x, -y);
/* scale based on tablet pressure */
if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
- glTranslatef(0.5f, 0.5f, 0);
- glScalef(1.0f / ups->size_pressure_value, 1.0f / ups->size_pressure_value, 1);
- glTranslatef(-0.5f, -0.5f, 0);
+ const float scale = ups->size_pressure_value;
+ gpuTranslate2f(x, y);
+ gpuScale2f(scale, scale);
+ gpuTranslate2f(-x, -y);
}
if (ups->draw_anchored) {
@@ -657,41 +651,46 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
quad.xmax = brush->mask_stencil_dimension[0];
quad.ymax = brush->mask_stencil_dimension[1];
}
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ gpuPushMatrix();
if (primary)
- glTranslate2fv(brush->stencil_pos);
+ gpuTranslate2fv(brush->stencil_pos);
else
- glTranslate2fv(brush->mask_stencil_pos);
- glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1);
- glMatrixMode(GL_TEXTURE);
+ gpuTranslate2fv(brush->mask_stencil_pos);
+ gpuRotate2D(RAD2DEGF(mtex->rot));
}
/* set quad color. Colored overlay does not get blending */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+
if (col) {
- glColor4f(1.0, 1.0, 1.0, overlay_alpha / 100.0f);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, overlay_alpha * 0.01f);
}
else {
- glColor4f(UNPACK3(U.sculpt_paint_overlay_col), overlay_alpha / 100.0f);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA_COLOR);
+ immUniformColor3fvAlpha(U.sculpt_paint_overlay_col, overlay_alpha * 0.01f);
}
/* draw textured quad */
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(quad.xmin, quad.ymin);
- glTexCoord2f(1, 0);
- glVertex2f(quad.xmax, quad.ymin);
- glTexCoord2f(1, 1);
- glVertex2f(quad.xmax, quad.ymax);
- glTexCoord2f(0, 1);
- glVertex2f(quad.xmin, quad.ymax);
- glEnd();
-
- glPopMatrix();
-
- if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ immUniform1i("image", GL_TEXTURE0);
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, quad.xmin, quad.ymin);
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, quad.xmax, quad.ymin);
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, quad.xmax, quad.ymax);
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, quad.xmin, quad.ymax);
+ immEnd();
+
+ immUnbindProgram();
+
+ if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) {
+ gpuPopMatrix();
}
}
}
@@ -739,32 +738,41 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush,
/* scale based on tablet pressure */
if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
do_pop = true;
- glPushMatrix();
- glLoadIdentity();
- glTranslate2fv(center);
- glScalef(ups->size_pressure_value, ups->size_pressure_value, 1);
- glTranslatef(-center[0], -center[1], 0);
+ gpuPushMatrix();
+ gpuLoadIdentity();
+ gpuTranslate2fv(center);
+ gpuScaleUniform(ups->size_pressure_value);
+ gpuTranslate2f(-center[0], -center[1]);
}
- glColor4f(U.sculpt_paint_overlay_col[0],
- U.sculpt_paint_overlay_col[1],
- U.sculpt_paint_overlay_col[2],
- brush->cursor_overlay_alpha / 100.0f);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
+
+ immUniformColor3fvAlpha(U.sculpt_paint_overlay_col, brush->cursor_overlay_alpha * 0.01f);
+
+ /* draw textured quad */
/* draw textured quad */
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(quad.xmin, quad.ymin);
- glTexCoord2f(1, 0);
- glVertex2f(quad.xmax, quad.ymin);
- glTexCoord2f(1, 1);
- glVertex2f(quad.xmax, quad.ymax);
- glTexCoord2f(0, 1);
- glVertex2f(quad.xmin, quad.ymax);
- glEnd();
+ immUniform1i("image", GL_TEXTURE0);
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, quad.xmin, quad.ymin);
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, quad.xmax, quad.ymin);
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, quad.xmax, quad.ymax);
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, quad.xmin, quad.ymax);
+ immEnd();
+
+ immUnbindProgram();
if (do_pop)
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -774,19 +782,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
/* color means that primary brush texture is colured and secondary is used for alpha/mask control */
bool col = ELEM(mode, ePaintTextureProjective, ePaintTexture2D, ePaintVertex) ? true : false;
OverlayControlFlags flags = BKE_paint_get_overlay_flags();
- /* save lots of GL state
- * TODO: check on whether all of these are needed? */
- glPushAttrib(GL_COLOR_BUFFER_BIT |
- GL_CURRENT_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_ENABLE_BIT |
- GL_LINE_BIT |
- GL_POLYGON_BIT |
- GL_STENCIL_BUFFER_BIT |
- GL_TRANSFORM_BIT |
- GL_VIEWPORT_BIT |
- GL_TEXTURE_BIT);
-
+ gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_BLEND_BIT);
/* coloured overlay should be drawn separately */
if (col) {
@@ -804,86 +800,98 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
}
- glPopAttrib();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ gpuPopAttrib();
}
-BLI_INLINE void draw_tri_point(float *co, float width, bool selected)
+BLI_INLINE void draw_tri_point(
+ unsigned int pos, float sel_col[4], float pivot_col[4],
+ float *co, float width, bool selected)
{
+ immUniformColor4fv(selected ? sel_col : pivot_col);
+
+ glLineWidth(3.0f);
+
float w = width / 2.0f;
- if (selected)
- UI_ThemeColor4(TH_VERTEX_SELECT);
- else
- UI_ThemeColor4(TH_PAINT_CURVE_PIVOT);
-
- glLineWidth(3.0);
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(co[0], co[1] + w);
- glVertex2f(co[0] - w, co[1] - w);
- glVertex2f(co[0] + w, co[1] - w);
- glEnd();
-
- glColor4f(1.0, 1.0, 1.0, 0.5);
- glLineWidth(1.0);
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(co[0], co[1] + w);
- glVertex2f(co[0] - w, co[1] - w);
- glVertex2f(co[0] + w, co[1] - w);
- glEnd();
+ float tri[3][2] = {
+ {co[0], co[1] + w},
+ {co[0] - w, co[1] - w},
+ {co[0] + w, co[1] - w},
+ };
+
+ immBegin(PRIM_LINE_LOOP, 3);
+ immVertex2fv(pos, tri[0]);
+ immVertex2fv(pos, tri[1]);
+ immVertex2fv(pos, tri[2]);
+ immEnd();
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
+ glLineWidth(1.0f);
+
+ immBegin(PRIM_LINE_LOOP, 3);
+ immVertex2fv(pos, tri[0]);
+ immVertex2fv(pos, tri[1]);
+ immVertex2fv(pos, tri[2]);
+ immEnd();
}
-BLI_INLINE void draw_rect_point(float *co, float width, bool selected)
+BLI_INLINE void draw_rect_point(
+ unsigned int pos, float sel_col[4], float handle_col[4],
+ float *co, float width, bool selected)
{
+ immUniformColor4fv(selected ? sel_col : handle_col);
+
+ glLineWidth(3.0f);
+
float w = width / 2.0f;
- if (selected)
- UI_ThemeColor4(TH_VERTEX_SELECT);
- else
- UI_ThemeColor4(TH_PAINT_CURVE_HANDLE);
- glLineWidth(3.0);
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(co[0] + w, co[1] + w);
- glVertex2f(co[0] - w, co[1] + w);
- glVertex2f(co[0] - w, co[1] - w);
- glVertex2f(co[0] + w, co[1] - w);
- glEnd();
-
- glColor4f(1.0, 1.0, 1.0, 0.5);
- glLineWidth(1.0);
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(co[0] + w, co[1] + w);
- glVertex2f(co[0] - w, co[1] + w);
- glVertex2f(co[0] - w, co[1] - w);
- glVertex2f(co[0] + w, co[1] - w);
- glEnd();
+ float minx = co[0] - w;
+ float miny = co[1] - w;
+ float maxx = co[0] + w;
+ float maxy = co[1] + w;
+
+ imm_draw_line_box(pos, minx, miny, maxx, maxy);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
+ glLineWidth(1.0f);
+
+ imm_draw_line_box(pos, minx, miny, maxx, maxy);
}
-BLI_INLINE void draw_bezier_handle_lines(BezTriple *bez)
+BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], BezTriple *bez)
{
- short line1[] = {0, 1};
- short line2[] = {1, 2};
-
- glVertexPointer(2, GL_FLOAT, 3 * sizeof(float), bez->vec);
- glColor4f(0.0, 0.0, 0.0, 0.5);
- glLineWidth(3.0);
- glDrawArrays(GL_LINE_STRIP, 0, 3);
-
- glLineWidth(1.0);
- if (bez->f1 || bez->f2)
- UI_ThemeColor4(TH_VERTEX_SELECT);
- else
- glColor4f(1.0, 1.0, 1.0, 0.5);
- glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line1);
- if (bez->f3 || bez->f2)
- UI_ThemeColor4(TH_VERTEX_SELECT);
- else
- glColor4f(1.0, 1.0, 1.0, 0.5);
- glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line2);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+ glLineWidth(3.0f);
+
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2fv(pos, bez->vec[0]);
+ immVertex2fv(pos, bez->vec[1]);
+ immVertex2fv(pos, bez->vec[2]);
+ immEnd();
+
+ glLineWidth(1.0f);
+
+ if (bez->f1 || bez->f2) {
+ immUniformColor4fv(sel_col);
+ }
+ else {
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
+ }
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, bez->vec[0]);
+ immVertex2fv(pos, bez->vec[1]);
+ immEnd();
+
+ if (bez->f3 || bez->f2) {
+ immUniformColor4fv(sel_col);
+ }
+ else {
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
+ }
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, bez->vec[1]);
+ immVertex2fv(pos, bez->vec[2]);
+ immEnd();
}
static void paint_draw_curve_cursor(Brush *brush)
@@ -895,18 +903,26 @@ static void paint_draw_curve_cursor(Brush *brush)
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glEnableClientState(GL_VERTEX_ARRAY);
/* draw the bezier handles and the curve segment between the current and next point */
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ float selec_col[4], handle_col[4], pivot_col[4];
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, selec_col);
+ UI_GetThemeColor4fv(TH_PAINT_CURVE_HANDLE, handle_col);
+ UI_GetThemeColor4fv(TH_PAINT_CURVE_PIVOT, pivot_col);
+
for (i = 0; i < pc->tot_points - 1; i++, cp++) {
int j;
PaintCurvePoint *cp_next = cp + 1;
float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
/* use color coding to distinguish handles vs curve segments */
- draw_bezier_handle_lines(&cp->bez);
- draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2);
- draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2);
- draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2);
+ draw_bezier_handle_lines(pos, selec_col, &cp->bez);
+ draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
+ draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2);
+ draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
for (j = 0; j < 2; j++)
BKE_curve_forward_diff_bezier(
@@ -916,25 +932,35 @@ static void paint_draw_curve_cursor(Brush *brush)
cp_next->bez.vec[1][j],
data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2]));
- glVertexPointer(2, GL_FLOAT, 0, data);
- glLineWidth(3.0);
- glColor4f(0.0, 0.0, 0.0, 0.5);
- glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1);
+ float (*v)[2] = (float(*)[2])data;
+
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+ glLineWidth(3.0f);
+ immBegin(PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1);
+ for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
+ immVertex2fv(pos, v[j]);
+ }
+ immEnd();
- glLineWidth(1.0);
- glColor4f(0.9, 0.9, 1.0, 0.5);
- glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1);
+ immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f);
+ glLineWidth(1.0f);
+ immBegin(PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1);
+ for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
+ immVertex2fv(pos, v[j]);
+ }
+ immEnd();
}
/* draw last line segment */
- draw_bezier_handle_lines(&cp->bez);
- draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2);
- draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2);
- draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2);
+ draw_bezier_handle_lines(pos, selec_col, &cp->bez);
+ draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
+ draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2);
+ draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
- glDisableClientState(GL_VERTEX_ARRAY);
+
+ immUnbindProgram();
}
}
@@ -988,11 +1014,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
PaintMode mode = BKE_paintmode_get_active_from_context(C);
- ViewContext vc;
- float final_radius;
- float translation[2];
- float outline_alpha, *outline_col;
- float zoomx, zoomy;
/* check that brush drawing is enabled */
if (ommit_cursor_drawing(paint, mode, brush))
@@ -1000,8 +1021,10 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* can't use stroke vc here because this will be called during
* mouse over too, not just during a stroke */
+ ViewContext vc;
view3d_set_viewcontext(C, &vc);
+ float zoomx, zoomy;
get_imapaint_zoom(C, &zoomx, &zoomy);
zoomx = max_ff(zoomx, zoomy);
@@ -1012,11 +1035,10 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
}
/* set various defaults */
- translation[0] = x;
- translation[1] = y;
- outline_alpha = 0.5;
- outline_col = brush->add_col;
- final_radius = (BKE_brush_size_get(scene, brush) * zoomx);
+ const float *outline_col = brush->add_col;
+ const float outline_alpha = 0.5f;
+ float translation[2] = { x, y };
+ float final_radius = (BKE_brush_size_get(scene, brush) * zoomx);
/* don't calculate rake angles while a stroke is active because the rake variables are global and
* we may get interference with the stroke itself. For line strokes, such interference is visible */
@@ -1032,10 +1054,9 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
if ((mode == ePaintSculpt) && vc.obact->sculpt) {
float location[3];
int pixel_radius;
- bool hit;
/* test if brush is over the mesh */
- hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups);
+ bool hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups);
if (BKE_brush_use_locked_size(scene, brush))
BKE_brush_size_set(scene, brush, pixel_radius);
@@ -1065,24 +1086,25 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* make lines pretty */
glLineWidth(1.0f);
- glEnable(GL_BLEND);
+ glEnable(GL_BLEND); /* TODO: also set blend mode? */
glEnable(GL_LINE_SMOOTH);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* set brush color */
- glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha);
+ immUniformColor3fvAlpha(outline_col, outline_alpha);
/* draw brush outline */
- glTranslate2fv(translation);
-
- /* draw an inner brush */
if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
/* inner at full alpha */
- glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius * ups->size_pressure_value, 40);
+ imm_draw_circle_wire(pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
/* outer at half alpha */
- glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha * 0.5f);
+ immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
}
- glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius, 40);
- glTranslatef(-translation[0], -translation[1], 0);
+ imm_draw_circle_wire(pos, translation[0], translation[1], final_radius, 40);
+
+ immUnbindProgram();
/* restore GL state */
glDisable(GL_BLEND);
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 5af6792f10f..d7c3b7377da 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -52,8 +52,6 @@
#include "BKE_paint.h"
#include "BKE_subsurf.h"
-#include "BIF_glutil.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -323,12 +321,10 @@ static void clip_planes_from_rect(bContext *C,
{
ViewContext vc;
BoundBox bb;
- bglMats mats = {{0}};
view3d_operator_needs_opengl(C);
view3d_set_viewcontext(C, &vc);
- view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats);
- ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, rect);
negate_m4(clip_planes);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index bf344e1f721..1b18dd4e41c 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -78,9 +78,9 @@
#include "GPU_draw.h"
#include "GPU_buffers.h"
+#include "GPU_immediate.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "IMB_colormanagement.h"
@@ -721,12 +721,28 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glLineWidth(4.0);
- glColor4ub(0, 0, 0, 255);
- sdrawline(x, y, pop->startmouse[0], pop->startmouse[1]);
+ immUniformColor4ub(0, 0, 0, 255);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2i(pos, x, y);
+ immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
+ immEnd();
+
glLineWidth(2.0);
- glColor4ub(255, 255, 255, 255);
- sdrawline(x, y, pop->startmouse[0], pop->startmouse[1]);
+ immUniformColor4ub(255, 255, 255, 255);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2i(pos, x, y);
+ immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
+ immEnd();
+
+ immUnbindProgram();
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
@@ -748,7 +764,8 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
/* initialize from context */
if (CTX_wm_region_view3d(C)) {
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
bool uvs, mat, tex, stencil;
if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index d0f1cc99b8d..e743607b75b 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -3487,7 +3487,7 @@ static void proj_paint_layer_clone_init(
/* use clone mtface? */
if (ps->do_layer_clone) {
- const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
+ const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV);
ps->dm_mloopuv_clone = MEM_mallocN(ps->dm_totpoly * sizeof(MLoopUV *), "proj_paint_mtfaces");
@@ -3846,7 +3846,7 @@ static void project_paint_begin(
if (ps->do_layer_stencil || ps->do_stencil_brush) {
//int layer_num = CustomData_get_stencil_layer(&ps->dm->loopData, CD_MLOOPUV);
- int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
+ int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV);
if (layer_num != -1)
ps->dm_mloopuv_stencil = CustomData_get_layer_n(&ps->dm->loopData, CD_MLOOPUV, layer_num);
@@ -5017,6 +5017,7 @@ void paint_proj_stroke(
/* clone gets special treatment here to avoid going through image initialization */
if (ps_handle->is_clone_cursor_pick) {
Scene *scene = ps_handle->scene;
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
float *cursor = ED_view3d_cursor3d_get(scene, v3d);
@@ -5024,8 +5025,9 @@ void paint_proj_stroke(
view3d_operator_needs_opengl(C);
- if (!ED_view3d_autodist(scene, ar, v3d, mval_i, cursor, false, NULL))
+ if (!ED_view3d_autodist(graph, ar, v3d, mval_i, cursor, false, NULL)) {
return;
+ }
ED_region_tag_redraw(ar);
@@ -5203,7 +5205,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m
project_state_init(C, ob, ps, mode);
- if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) {
+ if (ps->ob == NULL) {
ps_handle->ps_views_tot = i + 1;
goto fail;
}
@@ -5305,11 +5307,12 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
{
Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ProjPaintState ps = {NULL};
int orig_brush_size;
IDProperty *idgroup;
IDProperty *view_data = NULL;
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
bool uvs, mat, tex;
if (ob == NULL || ob->type != OB_MESH) {
@@ -5438,6 +5441,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
char filename[FILE_MAX];
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ToolSettings *settings = scene->toolsettings;
int w = settings->imapaint.screen_grab_size[0];
int h = settings->imapaint.screen_grab_size[1];
@@ -5452,7 +5456,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (h > maxsize) h = maxsize;
ibuf = ED_view3d_draw_offscreen_imbuf(
- scene, CTX_wm_view3d(C), CTX_wm_region(C),
+ scene, sl, CTX_wm_view3d(C), CTX_wm_region(C),
w, h, IB_rect, false, R_ALPHAPREMUL, 0, false, NULL,
NULL, NULL, err_out);
if (!ibuf) {
@@ -5586,7 +5590,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
}
me = BKE_mesh_from_object(ob);
- layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+ layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
if (layernum == 0) {
hasuvs = false;
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 7e05ab929ae..69c4621945b 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -209,7 +209,6 @@ bool paint_convert_bb_to_rect(struct rcti *rect,
* 2D screens-space bounding box into four 3D planes) */
void paint_calc_redraw_planes(float planes[4][4],
const struct ARegion *ar,
- struct RegionView3D *rv3d,
struct Object *ob,
const struct rcti *screen_rect);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index a4887c579ac..1ac40b0354e 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -35,8 +35,6 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BIF_glutil.h"
-
#include "BLI_bitmap_draw_2d.h"
#include "BLI_math_matrix.h"
#include "BLI_math_geom.h"
@@ -251,7 +249,6 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
{
Sculpt *sd = vc->scene->toolsettings->sculpt;
BoundBox bb;
- bglMats mats = {{0}};
float clip_planes[4][4];
float clip_planes_final[4][4];
ARegion *ar = vc->ar;
@@ -269,8 +266,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
value = select ? 1.0 : 0.0;
/* transform the clip planes in object space */
- view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, &mats);
- ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, vc->ar, vc->obact, rect);
negate_m4(clip_planes);
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
@@ -411,7 +407,6 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
if (mcords) {
float clip_planes[4][4], clip_planes_final[4][4];
BoundBox bb;
- bglMats mats = {{0}};
Object *ob;
ViewContext vc;
LassoMaskData data;
@@ -429,7 +424,6 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
* calculations done. Bounding box PBVH collision is not computed against enclosing rectangle
* of lasso */
view3d_set_viewcontext(C, &vc);
- view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats);
/* lasso data calculations */
data.vc = &vc;
@@ -445,7 +439,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
mcords, mcords_tot,
mask_lasso_px_cb, &data);
- ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, &data.rect);
negate_m4(clip_planes);
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 05270dbfa09..bc561c345b4 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -51,6 +51,7 @@
#include "BKE_curve.h"
#include "BKE_colortools.h"
#include "BKE_image.h"
+#include "BKE_mesh.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -58,7 +59,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -145,9 +146,18 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata
if (stroke && brush) {
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glColor4ubv(paint->paint_cursor_col);
- sdrawline(x, y, (int)stroke->last_mouse_position[0],
- (int)stroke->last_mouse_position[1]);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv(paint->paint_cursor_col);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, x, y);
+ immVertex2f(pos, stroke->last_mouse_position[0], stroke->last_mouse_position[1]);
+ immEnd();
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
@@ -159,36 +169,35 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
PaintStroke *stroke = customdata;
glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
- GPU_basic_shader_line_width(3.0);
+ uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- glColor4ub(0, 0, 0, paint->paint_cursor_col[3]);
- if (stroke->constrain_line) {
- sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
- stroke->constrained_pos[0], stroke->constrained_pos[1]);
- }
- else {
- sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
- x, y);
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float alpha = (float)paint->paint_cursor_col[3] / 255.0f;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(PRIM_LINES, 2);
- glColor4ub(255, 255, 255, paint->paint_cursor_col[3]);
- GPU_basic_shader_line_width(1.0);
if (stroke->constrain_line) {
- sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
- stroke->constrained_pos[0], stroke->constrained_pos[1]);
+ immVertex2f(shdr_pos, stroke->last_mouse_position[0], stroke->last_mouse_position[1]);
+ immVertex2f(shdr_pos, stroke->constrained_pos[0], stroke->constrained_pos[1]);
}
else {
- sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
- x, y);
+ immVertex2f(shdr_pos, stroke->last_mouse_position[0], stroke->last_mouse_position[1]);
+ immVertex2f(shdr_pos, x, y);
}
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ immEnd();
+
+ immUnbindProgram();
- glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 31c471c3517..e36cc275ba9 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -59,8 +59,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "GPU_matrix.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
@@ -130,17 +129,12 @@ bool paint_convert_bb_to_rect(rcti *rect,
* 2D screens-space bounding box into four 3D planes) */
void paint_calc_redraw_planes(float planes[4][4],
const ARegion *ar,
- RegionView3D *rv3d,
Object *ob,
const rcti *screen_rect)
{
BoundBox bb;
- bglMats mats;
rcti rect;
- memset(&bb, 0, sizeof(BoundBox));
- view3d_get_transformation(ar, rv3d, ob, &mats);
-
/* use some extra space just in case */
rect = *screen_rect;
rect.xmin -= 2;
@@ -148,7 +142,7 @@ void paint_calc_redraw_planes(float planes[4][4],
rect.ymin -= 2;
rect.ymax += 2;
- ED_view3d_clipping_calc(&bb, planes, &mats, &rect);
+ ED_view3d_clipping_calc(&bb, planes, ar, ob, &rect);
negate_m4(planes);
}
@@ -290,8 +284,8 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c
/* get the needed opengl matrices */
glGetIntegerv(GL_VIEWPORT, view);
- glGetFloatv(GL_MODELVIEW_MATRIX, (float *)matrix);
- glGetFloatv(GL_PROJECTION_MATRIX, (float *)proj);
+ gpuGetModelViewMatrix(matrix);
+ gpuGetProjectionMatrix(proj);
view[0] = view[1] = 0;
mul_m4_m4m4(matrix, matrix, ob->obmat);
mul_m4_m4m4(matrix, proj, matrix);
@@ -447,7 +441,8 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
if (CTX_wm_view3d(C) && texpaint_proj) {
/* first try getting a colour directly from the mesh faces if possible */
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
bool sample_success = false;
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
@@ -561,8 +556,9 @@ static int brush_curve_preset_exec(bContext *C, wmOperator *op)
if (br) {
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape"));
- BKE_paint_invalidate_cursor_overlay(scene, br->curve);
+ BKE_paint_invalidate_cursor_overlay(scene, sl, br->curve);
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 729dd9dc57b..efd1f0914c7 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1822,6 +1822,8 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
ED_vgroup_sync_from_pose(ob);
}
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
+
/* Weightpaint works by overriding colors in mesh,
* so need to make sure we recalc on enter and
* exit (exit needs doing regardless because we
@@ -2382,6 +2384,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* also needed for "View Selected" on last stroke */
paint_last_stroke_update(scene, vc->ar, mval);
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
+
DAG_id_tag_update(ob->data, 0);
ED_region_tag_redraw(vc->ar);
}
@@ -2587,6 +2591,8 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
BKE_paint_init(scene, ePaintVertex, PAINT_CURSOR_VERTEX_PAINT);
}
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
+
/* update modifier stack for mapping requirements */
DAG_id_tag_update(&me->id, 0);
@@ -2859,6 +2865,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* also needed for "View Selected" on last stroke */
paint_last_stroke_update(scene, vc->ar, mval);
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
+
ED_region_tag_redraw(vc->ar);
if (vpd->use_fast_update == false) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 44cc2720a32..d1965d93172 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -626,8 +626,7 @@ static bool sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
return 1;
}
-void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
- RegionView3D *rv3d, Object *ob)
+void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, Object *ob)
{
PBVH *pbvh = ob->sculpt->pbvh;
/* copy here, original will be used below */
@@ -635,7 +634,7 @@ void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
sculpt_extend_redraw_rect_previous(ob, &rect);
- paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect);
+ paint_calc_redraw_planes(planes, ar, ob, &rect);
/* we will draw this rect, so now we can set it as the previous partial rect.
* Note that we don't update with the union of previous/current (rect), only with
@@ -2044,6 +2043,10 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
+ /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
+ * initialize before threads so they can do curve mapping */
+ curvemapping_initialize(brush->curve);
+
/* threaded loop over nodes */
SculptThreadedTaskData data = {
.sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index fd2a0b15cb9..b9b808e529d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -55,6 +55,9 @@
#include "ED_image.h"
#include "ED_mesh.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -64,9 +67,6 @@
#include "paint_intern.h"
#include "uvedit_intern.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "UI_view2d.h"
#define MARK_BOUNDARY 1
@@ -173,7 +173,7 @@ static int uv_sculpt_brush_poll_do(bContext *C, const bool check_region)
}
em = BKE_editmesh_from_object(obedit);
- ret = EDBM_mtexpoly_check(em);
+ ret = EDBM_uv_check(em);
if (ret) {
ARegion *ar = CTX_wm_region(C);
@@ -212,18 +212,17 @@ static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(cu
alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
}
- glPushMatrix();
-
- glTranslatef((float)x, (float)y, 0.0f);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fvAlpha(brush->add_col, alpha);
- glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0, (float)(M_PI * 2.0), size, 40);
+ imm_draw_circle_wire(pos, (float)x, (float)y, size, 40);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
- glPopMatrix();
+ immUnbindProgram();
}
#undef PX_SIZE_FADE_MAX
#undef PX_SIZE_FADE_MIN
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index e273d3a40f0..d103530fa81 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -318,11 +318,11 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
scene->r.cfra = cfra;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
}
scene->r.cfra = oldfra;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 0764f586de9..1cf97af7a35 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -61,6 +61,7 @@
#include "ED_keyframes_draw.h"
#include "action_intern.h"
+#include "GPU_immediate.h"
/* ************************************************************************* */
/* Channel List */
@@ -156,15 +157,12 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
- int filter;
View2D *v2d = &ar->v2d;
bDopeSheet *ads = &saction->ads;
AnimData *adt = NULL;
float act_start, act_end, y;
- size_t items;
- int height;
unsigned char col1[3], col2[3];
unsigned char col1a[3], col2a[3];
@@ -194,10 +192,10 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
}
/* build list of channels to draw */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
+ int height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
@@ -205,6 +203,12 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* first backdrop strips */
y = (float)(-ACHANNEL_HEIGHT(ac));
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glEnable(GL_BLEND);
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -223,28 +227,26 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* determine if channel is selected */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
sel = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
-
+
if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) {
switch (ale->type) {
case ANIMTYPE_SUMMARY:
{
/* reddish color from NLA */
- UI_ThemeColor4(TH_ANIM_ACTIVE);
+ immUniformThemeColor(TH_ANIM_ACTIVE);
break;
}
case ANIMTYPE_SCENE:
case ANIMTYPE_OBJECT:
{
- if (sel) glColor4ub(col1b[0], col1b[1], col1b[2], 0x45);
- else glColor4ub(col1b[0], col1b[1], col1b[2], 0x22);
+ immUniformColor3ubvAlpha(col1b, sel ? 0x45 : 0x22);
break;
}
case ANIMTYPE_FILLACTD:
case ANIMTYPE_DSSKEY:
case ANIMTYPE_DSWOR:
{
- if (sel) glColor4ub(col2b[0], col2b[1], col2b[2], 0x45);
- else glColor4ub(col2b[0], col2b[1], col2b[2], 0x22);
+ immUniformColor3ubvAlpha(col2b, sel ? 0x45 : 0x22);
break;
}
case ANIMTYPE_GROUP:
@@ -252,17 +254,14 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
bActionGroup *agrp = ale->data;
if (show_group_colors && agrp->customCol) {
if (sel) {
- unsigned char *cp = (unsigned char *)agrp->cs.select;
- glColor4ub(cp[0], cp[1], cp[2], 0x45);
+ immUniformColor3ubvAlpha((unsigned char *)agrp->cs.select, 0x45);
}
else {
- unsigned char *cp = (unsigned char *)agrp->cs.solid;
- glColor4ub(cp[0], cp[1], cp[2], 0x1D);
+ immUniformColor3ubvAlpha((unsigned char *)agrp->cs.solid, 0x1D);
}
}
else {
- if (sel) glColor4ub(col1a[0], col1a[1], col1a[2], 0x22);
- else glColor4ub(col2a[0], col2a[1], col2a[2], 0x22);
+ immUniformColor3ubvAlpha(sel ? col1a : col2a, 0x22);
}
break;
}
@@ -270,53 +269,43 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
{
FCurve *fcu = ale->data;
if (show_group_colors && fcu->grp && fcu->grp->customCol) {
- unsigned char *cp = (unsigned char *)fcu->grp->cs.active;
-
- if (sel) glColor4ub(cp[0], cp[1], cp[2], 0x65);
- else glColor4ub(cp[0], cp[1], cp[2], 0x0B);
+ immUniformColor3ubvAlpha((unsigned char *)fcu->grp->cs.active, sel ? 0x65 : 0x0B);
}
else {
- if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+ immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
}
break;
}
default:
{
- if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- break;
+ immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
}
}
/* draw region twice: firstly backdrop, then the current range */
- glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
if (ac->datatype == ANIMCONT_ACTION)
- glRectf(act_start, (float)y - ACHANNEL_HEIGHT_HALF(ac), act_end, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ immRectf(pos, act_start, (float)y - ACHANNEL_HEIGHT_HALF(ac), act_end, (float)y + ACHANNEL_HEIGHT_HALF(ac));
}
else if (ac->datatype == ANIMCONT_GPENCIL) {
/* frames less than one get less saturated background */
- if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
+ immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
/* frames one and higher get a saturated background */
- if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44);
- else glColor4ub(col2[0], col2[1], col2[2], 0x44);
- glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ immUniformColor3ubvAlpha(sel ? col1 : col2, 0x44);
+ immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
}
else if (ac->datatype == ANIMCONT_MASK) {
/* TODO --- this is a copy of gpencil */
/* frames less than one get less saturated background */
- if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
+ immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
/* frames one and higher get a saturated background */
- if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44);
- else glColor4ub(col2[0], col2[1], col2[2], 0x44);
- glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ immUniformColor3ubvAlpha(sel ? col1 : col2, 0x44);
+ immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
}
}
}
@@ -325,18 +314,29 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
y -= ACHANNEL_STEP(ac);
}
glDisable(GL_BLEND);
-
- /* Draw keyframes
+
+ /* black line marking 'current frame' for Time-Slide transform mode */
+ if (saction->flag & SACTION_MOVING) {
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
+ immVertex2f(pos, saction->timeslide, v2d->cur.ymax);
+ immEnd();
+ }
+ immUnbindProgram();
+
+ /* Draw keyframes
* 1) Only channels that are visible in the Action Editor get drawn/evaluated.
* This is to try to optimize this for heavier data sets
* 2) Keyframes which are out of view horizontally are disregarded
*/
y = (float)(-ACHANNEL_HEIGHT(ac));
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -344,7 +344,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* check if anything to show for this channel */
if (ale->datatype != ALE_NONE) {
adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* draw 'keyframes' for each specific datatype */
switch (ale->datatype) {
case ALE_ALL:
@@ -374,20 +374,10 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
}
}
}
-
+
y -= ACHANNEL_STEP(ac);
}
-
- /* free tempolary channels used for drawing */
- ANIM_animdata_freelist(&anim_data);
- /* black line marking 'current frame' for Time-Slide transform mode */
- if (saction->flag & SACTION_MOVING) {
- glColor3f(0.0f, 0.0f, 0.0f);
-
- glBegin(GL_LINES);
- glVertex2f(saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
- glVertex2f(saction->timeslide, v2d->cur.ymax);
- glEnd();
- }
+ /* free temporary channels used for drawing */
+ ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 83655a2ba9e..e76d83715a2 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -308,7 +308,9 @@ static void action_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void action_channel_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void action_channel_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -351,7 +353,9 @@ static void action_channel_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(
}
}
-static void action_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void action_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -400,7 +404,8 @@ static void action_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa)
}
/* editor level listener */
-static void action_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void action_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
@@ -507,7 +512,9 @@ static void action_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
}
}
-static void action_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void action_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
// SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
@@ -559,7 +566,9 @@ static void action_buttons_area_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void action_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void action_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index ac6e3123e4e..4d601a31251 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -121,12 +121,17 @@ void ED_spacetypes_init(void)
ED_operatortypes_view2d();
ED_operatortypes_ui();
-
- /* register operators */
+
+ /* register types for operators and manipulators */
spacetypes = BKE_spacetypes_list();
for (type = spacetypes->first; type; type = type->next) {
- if (type->operatortypes)
+ /* init manipulator types first, operator-types need them */
+ if (type->manipulators) {
+ type->manipulators();
+ }
+ if (type->operatortypes) {
type->operatortypes();
+ }
}
/* register internal render callbacks */
@@ -251,7 +256,6 @@ void ED_region_draw_cb_draw(const bContext *C, ARegion *ar, int type)
for (rdc = ar->type->drawcalls.first; rdc; rdc = rdc->next) {
if (rdc->type == type) {
- UI_reinit_gl_state();
rdc->draw(C, ar, rdc->customdata);
}
}
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index da3364d872d..1f59007d3b4 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -49,6 +49,7 @@
#include "BKE_context.h"
#include "BKE_action.h"
+#include "BKE_layer.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_paint.h"
@@ -180,7 +181,9 @@ static int buttons_context_path_object(ButsContextPath *path)
/* if we have a scene, use the scene's active object */
else if (buttons_context_path_scene(path)) {
scene = path->ptr[path->len - 1].data;
- ob = (scene->basact) ? scene->basact->object : NULL;
+
+ SceneLayer *sl = BKE_scene_layer_context_active(scene);
+ ob = (sl->basact) ? sl->basact->object : NULL;
if (ob) {
RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
@@ -367,7 +370,7 @@ static int buttons_context_path_particle(ButsContextPath *path)
return 0;
}
-static int buttons_context_path_brush(ButsContextPath *path)
+static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
{
Scene *scene;
Brush *br = NULL;
@@ -381,8 +384,10 @@ static int buttons_context_path_brush(ButsContextPath *path)
else if (buttons_context_path_scene(path)) {
scene = path->ptr[path->len - 1].data;
- if (scene)
- br = BKE_paint_brush(BKE_paint_get_active(scene));
+ if (scene) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ br = BKE_paint_brush(BKE_paint_get_active(scene, sl));
+ }
if (br) {
RNA_id_pointer_create((ID *)br, &path->ptr[path->len]);
@@ -396,7 +401,7 @@ static int buttons_context_path_brush(ButsContextPath *path)
return 0;
}
-static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct)
+static int buttons_context_path_texture(const bContext *C, ButsContextPath *path, ButsContextTexture *ct)
{
if (ct) {
/* new shading system */
@@ -414,7 +419,7 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
if (id) {
if (GS(id->name) == ID_BR)
- buttons_context_path_brush(path);
+ buttons_context_path_brush(C, path);
else if (GS(id->name) == ID_MA)
buttons_context_path_material(path, false, true);
else if (GS(id->name) == ID_WO)
@@ -553,6 +558,36 @@ static bool buttons_context_linestyle_pinnable(const bContext *C)
}
#endif
+static int buttons_context_path_collection(const bContext *C, ButsContextPath *path)
+{
+ PointerRNA *ptr = &path->ptr[path->len - 1];
+
+ /* if we already have a (pinned) Collection, we're done */
+ if (RNA_struct_is_a(ptr->type, &RNA_LayerCollection)) {
+ return 1;
+ }
+
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ LayerCollection *sc = BKE_layer_collection_get_active(sl);
+
+ if (sc) {
+ RNA_pointer_create(NULL, &RNA_LayerCollection, sc, &path->ptr[path->len]);
+ path->len++;
+
+ /* temporary object in context path to get edit mode */
+ Object *ob = CTX_data_active_object(C);
+ if (ob) {
+ RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
+ path->len++;
+ }
+
+ return 1;
+ }
+
+ /* no path to a collection possible */
+ return 0;
+}
+
static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
{
SpaceButs *sbuts = CTX_wm_space_buts(C);
@@ -617,7 +652,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
found = buttons_context_path_material(path, false, (sbuts->texuser != NULL));
break;
case BCONTEXT_TEXTURE:
- found = buttons_context_path_texture(path, sbuts->texuser);
+ found = buttons_context_path_texture(C, path, sbuts->texuser);
break;
case BCONTEXT_BONE:
found = buttons_context_path_bone(path);
@@ -627,7 +662,10 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
case BCONTEXT_BONE_CONSTRAINT:
found = buttons_context_path_pose_bone(path);
break;
- default:
+ case BCONTEXT_COLLECTION:
+ found = buttons_context_path_collection(C, path);
+ break;
+ default:
found = 0;
break;
}
@@ -744,7 +782,7 @@ const char *buttons_context_dir[] = {
"texture", "texture_user", "texture_user_property", "bone", "edit_bone",
"pose_bone", "particle_system", "particle_system_editable", "particle_settings",
"cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint",
- "line_style", NULL
+ "line_style", "collection", NULL
};
int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -1064,6 +1102,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
set_pointer_type(path, result, &RNA_FreestyleLineStyle);
return 1;
}
+ else if (CTX_data_equals(member, "collection")) {
+ set_pointer_type(path, result, &RNA_LayerCollection);
+ return 1;
+ }
else {
return 0; /* not found */
}
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index e4c23ad74f8..47297e84242 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -171,6 +171,8 @@ static void buttons_main_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, "constraint", sbuts->mainb, vertical);
else if (sbuts->mainb == BCONTEXT_BONE_CONSTRAINT)
ED_region_panels(C, ar, "bone_constraint", sbuts->mainb, vertical);
+ else if (sbuts->mainb == BCONTEXT_COLLECTION)
+ ED_region_panels(C, ar, "collection", sbuts->mainb, vertical);
sbuts->re_align = 0;
sbuts->mainbo = sbuts->mainb;
@@ -218,7 +220,8 @@ static void buttons_area_redraw(ScrArea *sa, short buttons)
}
/* reused! */
-static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void buttons_area_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
SpaceButs *sbuts = sa->spacedata.first;
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 4bf4c1e7baa..954b3f2bd1a 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -42,8 +42,6 @@
#include "ED_screen.h"
#include "ED_clip.h"
-#include "BIF_gl.h"
-
#include "WM_types.h"
#include "UI_interface.h"
@@ -54,6 +52,9 @@
#include "RNA_access.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+
#include "clip_intern.h" /* own include */
static void track_channel_color(MovieTrackingTrack *track, float default_color[3], float color[3])
@@ -72,78 +73,25 @@ static void track_channel_color(MovieTrackingTrack *track, float default_color[3
}
}
-static void draw_keyframe_shape(float x, float y, float xscale, float yscale, bool sel, float alpha)
+static void draw_keyframe_shape(float x, float y, bool sel, float alpha,
+ unsigned int pos_id, unsigned int color_id)
{
- /* coordinates for diamond shape */
- static const float _unit_diamond_shape[4][2] = {
- {0.0f, 1.0f}, /* top vert */
- {1.0f, 0.0f}, /* mid-right */
- {0.0f, -1.0f}, /* bottom vert */
- {-1.0f, 0.0f} /* mid-left */
- };
- static GLuint displist1 = 0;
- static GLuint displist2 = 0;
- int hsize = STRIP_HEIGHT_HALF;
-
- /* initialize 2 display lists for diamond shape - one empty, one filled */
- if (displist1 == 0) {
- displist1 = glGenLists(1);
- glNewList(displist1, GL_COMPILE);
-
- glBegin(GL_LINE_LOOP);
- glVertex2fv(_unit_diamond_shape[0]);
- glVertex2fv(_unit_diamond_shape[1]);
- glVertex2fv(_unit_diamond_shape[2]);
- glVertex2fv(_unit_diamond_shape[3]);
- glEnd();
- glEndList();
+ float color[4] = { 0.91f, 0.91f, 0.91f, alpha };
+ if (sel) {
+ UI_GetThemeColorShadeAlpha4fv(TH_STRIP_SELECT, 50, -255 * (1.0f - alpha), color);
}
- if (displist2 == 0) {
- displist2 = glGenLists(1);
- glNewList(displist2, GL_COMPILE);
-
- glBegin(GL_QUADS);
- glVertex2fv(_unit_diamond_shape[0]);
- glVertex2fv(_unit_diamond_shape[1]);
- glVertex2fv(_unit_diamond_shape[2]);
- glVertex2fv(_unit_diamond_shape[3]);
- glEnd();
- glEndList();
- }
-
- glPushMatrix();
-
- /* adjust view transform before starting */
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
-
- /* anti-aliased lines for more consistent appearance */
- glEnable(GL_LINE_SMOOTH);
-
- if (sel)
- UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255 * (1.0f - alpha));
- else
- glColor4f(0.91f, 0.91f, 0.91f, alpha);
-
- glCallList(displist2);
- /* exterior - black frame */
- glColor4f(0.0f, 0.0f, 0.0f, alpha);
- glCallList(displist1);
-
- glDisable(GL_LINE_SMOOTH);
-
- /* restore view transform */
- glPopMatrix();
+ immAttrib4fv(color_id, color);
+ immVertex2f(pos_id, x, y);
}
-static void clip_draw_dopesheet_background(ARegion *ar, MovieClip *clip)
+static void clip_draw_dopesheet_background(ARegion *ar, MovieClip *clip, unsigned int pos_id)
{
View2D *v2d = &ar->v2d;
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
MovieTrackingDopesheetCoverageSegment *coverage_segment;
-
+
for (coverage_segment = dopesheet->coverage_segments.first;
coverage_segment;
coverage_segment = coverage_segment->next)
@@ -153,12 +101,13 @@ static void clip_draw_dopesheet_background(ARegion *ar, MovieClip *clip)
int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, coverage_segment->end_frame);
if (coverage_segment->coverage == TRACKING_COVERAGE_BAD) {
- glColor4f(1.0f, 0.0f, 0.0f, 0.07f);
+ immUniformColor4f(1.0f, 0.0f, 0.0f, 0.07f);
+ }
+ else {
+ immUniformColor4f(1.0f, 1.0f, 0.0f, 0.07f);
}
- else
- glColor4f(1.0f, 1.0f, 0.0f, 0.07f);
- glRectf(start_frame, v2d->cur.ymin, end_frame, v2d->cur.ymax);
+ immRectf(pos_id, start_frame, v2d->cur.ymin, end_frame, v2d->cur.ymax);
}
}
}
@@ -175,18 +124,21 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
MovieTrackingDopesheetChannel *channel;
- float y, xscale, yscale;
float strip[4], selected_strip[4];
float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
+ unsigned int keyframe_ct = 0;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
- y = (float) CHANNEL_FIRST;
-
- UI_view2d_scale_get(v2d, &xscale, &yscale);
+ float y = (float) CHANNEL_FIRST;
/* setup colors for regular and selected strips */
UI_GetThemeColor3fv(TH_STRIP, strip);
@@ -197,7 +149,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
glEnable(GL_BLEND);
- clip_draw_dopesheet_background(ar, clip);
+ clip_draw_dopesheet_background(ar, clip, pos_id);
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
@@ -208,7 +160,6 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
{
MovieTrackingTrack *track = channel->track;
- float alpha;
int i;
bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
@@ -218,32 +169,26 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f};
track_channel_color(track, default_color, color);
- glColor4fv(color);
+ immUniformColor4fv(color);
- glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
- v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
+ immRectf(pos_id, v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
+ v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
}
- alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f;
-
/* tracked segments */
for (i = 0; i < channel->tot_segment; i++) {
int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]);
int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]);
- if (sel)
- glColor4fv(selected_strip);
- else
- glColor4fv(strip);
+ immUniformColor4fv(sel ? selected_strip : strip);
if (start_frame != end_frame) {
- glRectf(start_frame, (float) y - STRIP_HEIGHT_HALF,
- end_frame, (float) y + STRIP_HEIGHT_HALF);
- draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha);
- draw_keyframe_shape(end_frame, y, xscale, yscale, sel, alpha);
+ immRectf(pos_id, start_frame, (float) y - STRIP_HEIGHT_HALF,
+ end_frame, (float) y + STRIP_HEIGHT_HALF);
+ keyframe_ct += 2;
}
else {
- draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha);
+ keyframe_ct++;
}
}
@@ -253,9 +198,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
MovieTrackingMarker *marker = &track->markers[i];
if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
- int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
-
- draw_keyframe_shape(framenr, y, xscale, yscale, sel, alpha);
+ keyframe_ct++;
}
i++;
@@ -266,6 +209,76 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
y -= CHANNEL_STEP;
}
+ immUnbindProgram();
+
+ if (keyframe_ct > 0) {
+ /* draw keyframe markers */
+ format = immVertexFormat();
+ pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int size_id = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color_id = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+ unsigned int outline_color_id = VertexFormat_add_attrib(format, "outlineColor", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, keyframe_ct);
+
+ /* all same size with black outline */
+ immAttrib1f(size_id, 2.0f * STRIP_HEIGHT_HALF);
+ immAttrib4ub(outline_color_id, 0, 0, 0, 255);
+
+ y = (float) CHANNEL_FIRST; /* start again at the top */
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
+ float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF);
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
+ {
+ MovieTrackingTrack *track = channel->track;
+ int i;
+ bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
+ float alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f;
+
+ /* tracked segments */
+ for (i = 0; i < channel->tot_segment; i++) {
+ int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]);
+ int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]);
+
+ if (start_frame != end_frame) {
+ draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id);
+ draw_keyframe_shape(end_frame, y, sel, alpha, pos_id, color_id);
+ }
+ else {
+ draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id);
+ }
+ }
+
+ /* keyframes */
+ i = 0;
+ while (i < track->markersnr) {
+ MovieTrackingMarker *marker = &track->markers[i];
+
+ if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
+ int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
+
+ draw_keyframe_shape(framenr, y, sel, alpha, pos_id, color_id);
+ }
+
+ i++;
+ }
+ }
+
+ /* adjust y-position for next one */
+ y -= CHANNEL_STEP;
+ }
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
+ }
+
glDisable(GL_BLEND);
}
@@ -279,22 +292,15 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
SpaceClip *sc = CTX_wm_space_clip(C);
View2D *v2d = &ar->v2d;
MovieClip *clip = ED_space_clip_get_clip(sc);
- MovieTracking *tracking;
- MovieTrackingDopesheet *dopesheet;
- MovieTrackingDopesheetChannel *channel;
uiStyle *style = UI_style_get();
- uiBlock *block;
int fontid = style->widget.uifont_id;
- int height;
- float y;
- PropertyRNA *chan_prop_lock;
-
+
if (!clip)
return;
- tracking = &clip->tracking;
- dopesheet = &tracking->dopesheet;
- height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ int height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
if (height > BLI_rcti_size_y(&v2d->mask)) {
/* don't use totrect set, as the width stays the same
@@ -309,6 +315,37 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
/* loop through channels, and set up drawing depending on their type
* first pass: just the standard GL-drawing for backdrop + text
*/
+ float y = (float) CHANNEL_FIRST;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ MovieTrackingDopesheetChannel *channel;
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
+ float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF);
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
+ {
+ MovieTrackingTrack *track = channel->track;
+ float color[3];
+ track_channel_color(track, NULL, color);
+ immUniformColor3fv(color);
+
+ immRectf(pos, v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
+ v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
+ }
+
+ /* adjust y-position for next one */
+ y -= CHANNEL_STEP;
+ }
+ immUnbindProgram();
+
+ /* second pass: text */
y = (float) CHANNEL_FIRST;
BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
@@ -322,21 +359,11 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
{
MovieTrackingTrack *track = channel->track;
- float font_height, color[3];
bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
- track_channel_color(track, NULL, color);
- glColor3fv(color);
-
- glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
- v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
-
- if (sel)
- UI_ThemeColor(TH_TEXT_HI);
- else
- UI_ThemeColor(TH_TEXT);
+ UI_FontThemeColor(fontid, sel ? TH_TEXT_HI : TH_TEXT);
- font_height = BLF_height(fontid, channel->name, sizeof(channel->name));
+ float font_height = BLF_height(fontid, channel->name, sizeof(channel->name));
BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD,
y - font_height / 2.0f, 0.0f);
BLF_draw(fontid, channel->name, strlen(channel->name));
@@ -346,12 +373,12 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
y -= CHANNEL_STEP;
}
- /* second pass: widgets */
- block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ /* third pass: widgets */
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
y = (float) CHANNEL_FIRST;
/* get RNA properties (once) */
- chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock");
+ PropertyRNA *chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock");
BLI_assert(chan_prop_lock);
glEnable(GL_BLEND);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 695d04d3850..0108e23af02 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -55,10 +55,11 @@
#include "ED_mask.h"
#include "ED_gpencil.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "WM_types.h"
@@ -66,26 +67,25 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-
#include "BLF_api.h"
#include "clip_intern.h" // own include
/*********************** main area drawing *************************/
-static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width)
+static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width, unsigned int pos)
{
int height = (frame == cfra) ? 22 : 10;
int x = (frame - sfra) * framelen;
if (width == 1) {
- glBegin(GL_LINES);
- glVertex2i(x, 0);
- glVertex2i(x, height * UI_DPI_FAC);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex2i(pos, x, 0);
+ immVertex2i(pos, x, height * UI_DPI_FAC);
+ immEnd();
}
else {
- glRecti(x, 0, x + width, height * UI_DPI_FAC);
+ immRecti(pos, x, 0, x + width, height * UI_DPI_FAC);
}
}
@@ -166,6 +166,9 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* track */
if (act_track || act_plane_track) {
for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
@@ -189,14 +192,17 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) {
framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
- if (framenr != i)
- glColor4ub(128, 128, 0, 96);
- else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a))
- glColor4ub(255, 255, 0, 196);
- else
- glColor4ub(255, 255, 0, 96);
+ if (framenr != i) {
+ immUniformColor4ub(128, 128, 0, 96);
+ }
+ else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a)) {
+ immUniformColor4ub(255, 255, 0, 196);
+ }
+ else {
+ immUniformColor4ub(255, 255, 0, 96);
+ }
- glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
+ immRecti(pos, (i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
}
}
}
@@ -206,7 +212,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
int n = reconstruction->camnr;
MovieReconstructedCamera *cameras = reconstruction->cameras;
- glColor4ub(255, 0, 0, 96);
+ immUniformColor4ub(255, 0, 0, 96);
for (i = sfra, a = 0; i <= efra; i++) {
bool ok = false;
@@ -223,8 +229,9 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
a++;
}
- if (!ok)
- glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
+ if (!ok) {
+ immRecti(pos, (i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
+ }
}
}
@@ -233,15 +240,22 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
/* current frame */
x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
- UI_ThemeColor(TH_CFRAME);
- glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
+ immUniformThemeColor(TH_CFRAME);
+ immRecti(pos, x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
+
+ immUnbindProgram();
ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* solver keyframes */
- glColor4ub(175, 255, 0, 255);
- draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
- draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
+ immUniformColor4ub(175, 255, 0, 255);
+ draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2, pos);
+ draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2, pos);
+
+ immUnbindProgram();
/* movie clip animation */
if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) {
@@ -275,11 +289,16 @@ static void draw_movieclip_muted(ARegion *ar, int width, int height, float zoomx
{
int x, y;
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* find window pixel coordinates of origin */
UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
- glColor3f(0.0f, 0.0f, 0.0f);
- glRectf(x, y, x + zoomx * width, y + zoomy * height);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ immRectf(pos, x, y, x + zoomx * width, y + zoomy * height);
+
+ immUnbindProgram();
}
static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
@@ -297,7 +316,7 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
+ imm_draw_checker_box(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
}
/* non-scaled proxy shouldn't use filtering */
@@ -307,13 +326,7 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
filter = GL_NEAREST;
}
- /* set zoom */
- glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
-
- glaDrawImBuf_glsl_ctx(C, ibuf, x, y, filter);
- /* reset zoom */
- glPixelZoom(1.0f, 1.0f);
-
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
if (sc->flag & SC_SHOW_METADATA) {
rctf frame;
@@ -335,31 +348,37 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int
/* draw boundary border for frame if stabilization is enabled */
if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
- glColor3f(0.0f, 0.0f, 0.0f);
-
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ /* Exclusive OR allows to get orig value when second operand is 0,
+ * and negative of orig value when second operand is 1. */
glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_NOR);
+ glLogicOp(GL_XOR);
+
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+
+ gpuScale2f(zoomx, zoomy);
+ gpuMultMatrix(sc->stabmat);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- glPushMatrix();
- glTranslatef(x, y, 0.0f);
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.0f);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- glScalef(zoomx, zoomy, 1.0f);
- glMultMatrixf(sc->stabmat);
+ imm_draw_line_box(shdr_pos, 0.0f, 0.0f, width, height);
- glBegin(GL_LINE_LOOP);
- glVertex2f(0.0f, 0.0f);
- glVertex2f(width, 0.0f);
- glVertex2f(width, height);
- glVertex2f(0.0f, height);
- glEnd();
+ immUnbindProgram();
- glPopMatrix();
+ gpuPopMatrix();
glDisable(GL_COLOR_LOGIC_OP);
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
}
}
@@ -423,69 +442,113 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
i++;
}
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
if (!tiny) {
- UI_ThemeColor(TH_MARKER_OUTLINE);
+ immUniformThemeColor(TH_MARKER_OUTLINE);
if (TRACK_VIEW_SELECTED(sc, track)) {
- glPointSize(5.0f);
- glBegin(GL_POINTS);
- for (i = a; i < b; i++) {
- if (i != curindex)
- glVertex2f(path[i][0], path[i][1]);
+ if ((b - a - 1) >= 1) {
+ glPointSize(5.0f);
+
+ immBegin(PRIM_POINTS, b - a - 1);
+
+ for (i = a; i < b; i++) {
+ if (i != curindex) {
+ immVertex2f(pos, path[i][0], path[i][1]);
+ }
+ }
+
+ immEnd();
}
- glEnd();
}
- glLineWidth(3.0f);
- glBegin(GL_LINE_STRIP);
- for (i = a; i < b; i++)
- glVertex2f(path[i][0], path[i][1]);
- glEnd();
- }
+ if ((b - a) >= 2) {
+ glLineWidth(3.0f);
+
+ immBegin(PRIM_LINE_STRIP, b - a);
+
+ for (i = a; i < b; i++) {
+ immVertex2f(pos, path[i][0], path[i][1]);
+ }
- UI_ThemeColor(TH_PATH_BEFORE);
+ immEnd();
+ }
+ }
if (TRACK_VIEW_SELECTED(sc, track)) {
glPointSize(3.0f);
- glBegin(GL_POINTS);
- for (i = a; i < b; i++) {
- if (i == count + 1)
- UI_ThemeColor(TH_PATH_AFTER);
- if (i != curindex)
- glVertex2f(path[i][0], path[i][1]);
+ if ((curindex - a) >= 1) {
+ immUniformThemeColor(TH_PATH_BEFORE);
+
+ immBegin(PRIM_POINTS, curindex - a);
+
+ for (i = a; i < curindex; i++) {
+ immVertex2f(pos, path[i][0], path[i][1]);
+ }
+
+ immEnd();
}
- glEnd();
- }
- UI_ThemeColor(TH_PATH_BEFORE);
+ if ((b - curindex - 1) >= 1) {
+ immUniformThemeColor(TH_PATH_AFTER);
+
+ immBegin(PRIM_POINTS, b - curindex - 1);
+
+ for (i = curindex + 1; i < b; i++) {
+ immVertex2f(pos, path[i][0], path[i][1]);
+ }
+
+ immEnd();
+ }
+ }
glLineWidth(1);
- glBegin(GL_LINE_STRIP);
- for (i = a; i < b; i++) {
- if (i == count + 1)
- UI_ThemeColor(TH_PATH_AFTER);
+ if ((curindex - a + 1) >= 2) {
+ immUniformThemeColor(TH_PATH_BEFORE);
+
+ immBegin(PRIM_LINE_STRIP, curindex - a + 1);
+
+ for (i = a; i <= curindex; i++) {
+ immVertex2f(pos, path[i][0], path[i][1]);
+ }
+
+ immEnd();
+ }
+
+ if ((b - curindex) >= 2) {
+ immUniformThemeColor(TH_PATH_AFTER);
+
+ immBegin(PRIM_LINE_STRIP, b - curindex);
+
+ for (i = curindex; i < b; i++) {
+ immVertex2f(pos, path[i][0], path[i][1]);
+ }
- glVertex2f(path[i][0], path[i][1]);
+ immEnd();
}
- glEnd();
+
+ immUnbindProgram();
}
static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- const float marker_pos[2], int width, int height)
+ const float marker_pos[2], int width, int height, unsigned int position)
{
int tiny = sc->flag & SC_SHOW_TINY_MARKER;
bool show_search = false;
float px[2];
- UI_ThemeColor(TH_MARKER_OUTLINE);
-
px[0] = 1.0f / width / sc->zoom;
px[1] = 1.0f / height / sc->zoom;
glLineWidth(tiny ? 1.0f : 3.0f);
+ immUniformThemeColor(TH_MARKER_OUTLINE);
+
if ((marker->flag & MARKER_DISABLED) == 0) {
float pos[2];
float p[2];
@@ -500,51 +563,54 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT
marker->pattern_corners[2], marker->pattern_corners[3]))
{
glPointSize(tiny ? 3.0f : 4.0f);
- glBegin(GL_POINTS);
- glVertex2f(pos[0], pos[1]);
- glEnd();
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(position, pos[0], pos[1]);
+ immEnd();
}
else {
- glBegin(GL_LINES);
- glVertex2f(pos[0] + px[0] * 2, pos[1]);
- glVertex2f(pos[0] + px[0] * 8, pos[1]);
+ immBegin(PRIM_LINES, 8);
+
+ immVertex2f(position, pos[0] + px[0] * 2, pos[1]);
+ immVertex2f(position, pos[0] + px[0] * 8, pos[1]);
+
+ immVertex2f(position, pos[0] - px[0] * 2, pos[1]);
+ immVertex2f(position, pos[0] - px[0] * 8, pos[1]);
- glVertex2f(pos[0] - px[0] * 2, pos[1]);
- glVertex2f(pos[0] - px[0] * 8, pos[1]);
+ immVertex2f(position, pos[0], pos[1] - px[1] * 2);
+ immVertex2f(position, pos[0], pos[1] - px[1] * 8);
- glVertex2f(pos[0], pos[1] - px[1] * 2);
- glVertex2f(pos[0], pos[1] - px[1] * 8);
+ immVertex2f(position, pos[0], pos[1] + px[1] * 2);
+ immVertex2f(position, pos[0], pos[1] + px[1] * 8);
- glVertex2f(pos[0], pos[1] + px[1] * 2);
- glVertex2f(pos[0], pos[1] + px[1] * 8);
- glEnd();
+ immEnd();
}
}
/* pattern and search outline */
- glPushMatrix();
- glTranslate2fv(marker_pos);
+ gpuPushMatrix();
+ gpuTranslate2fv(marker_pos);
if (sc->flag & SC_SHOW_MARKER_PATTERN) {
- glBegin(GL_LINE_LOOP);
- glVertex2fv(marker->pattern_corners[0]);
- glVertex2fv(marker->pattern_corners[1]);
- glVertex2fv(marker->pattern_corners[2]);
- glVertex2fv(marker->pattern_corners[3]);
- glEnd();
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2fv(position, marker->pattern_corners[0]);
+ immVertex2fv(position, marker->pattern_corners[1]);
+ immVertex2fv(position, marker->pattern_corners[2]);
+ immVertex2fv(position, marker->pattern_corners[3]);
+ immEnd();
}
show_search = (TRACK_VIEW_SELECTED(sc, track) &&
((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
+
if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
- glBegin(GL_LINE_LOOP);
- glVertex2f(marker->search_min[0], marker->search_min[1]);
- glVertex2f(marker->search_max[0], marker->search_min[1]);
- glVertex2f(marker->search_max[0], marker->search_max[1]);
- glVertex2f(marker->search_min[0], marker->search_max[1]);
- glEnd();
- }
- glPopMatrix();
+ imm_draw_line_box(position, marker->search_min[0],
+ marker->search_min[1],
+ marker->search_max[0],
+ marker->search_max[1]);
+ }
+
+ gpuPopMatrix();
}
static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
@@ -568,11 +634,12 @@ static void track_colors(MovieTrackingTrack *track, int act, float col[3], float
}
static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- const float marker_pos[2], int width, int height, int act, int sel)
+ const float marker_pos[2], int width, int height, int act, int sel, const uint shdr_pos)
{
int tiny = sc->flag & SC_SHOW_TINY_MARKER;
bool show_search = false;
- float col[3], scol[3], px[2];
+ float col[3], scol[3];
+ float px[2];
track_colors(track, act, col, scol);
@@ -581,23 +648,34 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
glLineWidth(1.0f);
+ /* Since we are switching solid and dashed lines in rather complex logic here, just always go with dashed shader. */
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+
/* marker position and offset position */
if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
float pos[2], p[2];
if (track->flag & TRACK_LOCKED) {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else if (track->flag & SELECT)
- UI_ThemeColorShade(TH_LOCK_MARKER, 64);
- else
- UI_ThemeColor(TH_LOCK_MARKER);
+ if (act) {
+ immUniformThemeColor(TH_ACT_MARKER);
+ }
+ else if (track->flag & SELECT) {
+ immUniformThemeColorShade(TH_LOCK_MARKER, 64);
+ }
+ else {
+ immUniformThemeColor(TH_LOCK_MARKER);
+ }
}
else {
- if (track->flag & SELECT)
- glColor3fv(scol);
- else
- glColor3fv(col);
+ immUniformColor3fv((track->flag & SELECT) ? scol : col);
}
add_v2_v2v2(pos, marker->pos, track->offset);
@@ -609,123 +687,114 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
marker->pattern_corners[2], marker->pattern_corners[3]))
{
glPointSize(tiny ? 1.0f : 2.0f);
- glBegin(GL_POINTS);
- glVertex2f(pos[0], pos[1]);
- glEnd();
+
+ immUniform1f("dash_factor", 2.0f); /* Solid "line" */
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, pos[0], pos[1]);
+ immEnd();
}
else {
- glBegin(GL_LINES);
- glVertex2f(pos[0] + px[0] * 3, pos[1]);
- glVertex2f(pos[0] + px[0] * 7, pos[1]);
+ immUniform1f("dash_factor", 2.0f); /* Solid line */
+
+ immBegin(PRIM_LINES, 8);
+
+ immVertex2f(shdr_pos, pos[0] + px[0] * 3, pos[1]);
+ immVertex2f(shdr_pos, pos[0] + px[0] * 7, pos[1]);
+
+ immVertex2f(shdr_pos, pos[0] - px[0] * 3, pos[1]);
+ immVertex2f(shdr_pos, pos[0] - px[0] * 7, pos[1]);
- glVertex2f(pos[0] - px[0] * 3, pos[1]);
- glVertex2f(pos[0] - px[0] * 7, pos[1]);
+ immVertex2f(shdr_pos, pos[0], pos[1] - px[1] * 3);
+ immVertex2f(shdr_pos, pos[0], pos[1] - px[1] * 7);
- glVertex2f(pos[0], pos[1] - px[1] * 3);
- glVertex2f(pos[0], pos[1] - px[1] * 7);
+ immVertex2f(shdr_pos, pos[0], pos[1] + px[1] * 3);
+ immVertex2f(shdr_pos, pos[0], pos[1] + px[1] * 7);
- glVertex2f(pos[0], pos[1] + px[1] * 3);
- glVertex2f(pos[0], pos[1] + px[1] * 7);
- glEnd();
+ immEnd();
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.0f);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- glColor3f(0.0f, 0.0f, 0.0f);
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_NOR);
+ glLogicOp(GL_XOR);
- glBegin(GL_LINES);
- glVertex2fv(pos);
- glVertex2fv(marker_pos);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(shdr_pos, pos);
+ immVertex2fv(shdr_pos, marker_pos);
+ immEnd();
glDisable(GL_COLOR_LOGIC_OP);
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
}
}
/* pattern */
- glPushMatrix();
- glTranslate2fv(marker_pos);
-
- if (tiny) {
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
- }
- else {
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE);
- }
+ gpuPushMatrix();
+ gpuTranslate2fv(marker_pos);
- if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
- if (track->flag & TRACK_LOCKED) {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else if (track->pat_flag & SELECT)
- UI_ThemeColorShade(TH_LOCK_MARKER, 64);
- else UI_ThemeColor(TH_LOCK_MARKER);
+ if (track->flag & TRACK_LOCKED) {
+ if (act) {
+ immUniformThemeColor(TH_ACT_MARKER);
}
- else if (marker->flag & MARKER_DISABLED) {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else if (track->pat_flag & SELECT)
- UI_ThemeColorShade(TH_DIS_MARKER, 128);
- else UI_ThemeColor(TH_DIS_MARKER);
+ else if (track->pat_flag & SELECT) {
+ immUniformThemeColorShade(TH_LOCK_MARKER, 64);
}
else {
- if (track->pat_flag & SELECT)
- glColor3fv(scol);
- else glColor3fv(col);
+ immUniformThemeColor(TH_LOCK_MARKER);
}
-
- glBegin(GL_LINE_LOOP);
- glVertex2fv(marker->pattern_corners[0]);
- glVertex2fv(marker->pattern_corners[1]);
- glVertex2fv(marker->pattern_corners[2]);
- glVertex2fv(marker->pattern_corners[3]);
- glEnd();
}
-
- /* search */
- show_search = (TRACK_VIEW_SELECTED(sc, track) &&
- ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
- if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
- if (track->flag & TRACK_LOCKED) {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else if (track->search_flag & SELECT)
- UI_ThemeColorShade(TH_LOCK_MARKER, 64);
- else UI_ThemeColor(TH_LOCK_MARKER);
+ else if (marker->flag & MARKER_DISABLED) {
+ if (act) {
+ immUniformThemeColor(TH_ACT_MARKER);
}
- else if (marker->flag & MARKER_DISABLED) {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else if (track->search_flag & SELECT)
- UI_ThemeColorShade(TH_DIS_MARKER, 128);
- else UI_ThemeColor(TH_DIS_MARKER);
+ else if (track->pat_flag & SELECT) {
+ immUniformThemeColorShade(TH_DIS_MARKER, 128);
}
else {
- if (track->search_flag & SELECT)
- glColor3fv(scol);
- else
- glColor3fv(col);
+ immUniformThemeColor(TH_DIS_MARKER);
}
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(marker->search_min[0], marker->search_min[1]);
- glVertex2f(marker->search_max[0], marker->search_min[1]);
- glVertex2f(marker->search_max[0], marker->search_max[1]);
- glVertex2f(marker->search_min[0], marker->search_max[1]);
- glEnd();
+ }
+ else {
+ immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
}
if (tiny) {
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
}
else {
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE);
+ immUniform1f("dash_factor", 2.0f); /* Solid line */
+ }
+
+ if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2fv(shdr_pos, marker->pattern_corners[0]);
+ immVertex2fv(shdr_pos, marker->pattern_corners[1]);
+ immVertex2fv(shdr_pos, marker->pattern_corners[2]);
+ immVertex2fv(shdr_pos, marker->pattern_corners[3]);
+ immEnd();
+ }
+
+ /* search */
+ show_search = (TRACK_VIEW_SELECTED(sc, track) &&
+ ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
+
+ if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
+ imm_draw_line_box(shdr_pos, marker->search_min[0], marker->search_min[1],
+ marker->search_max[0], marker->search_max[1]);
}
- glPopMatrix();
+ gpuPopMatrix();
+
+ /* Restore default shader */
+ immUnbindProgram();
+
+ const uint pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ BLI_assert(pos == shdr_pos);
+ UNUSED_VARS_NDEBUG(pos);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
}
static float get_shortest_pattern_side(MovieTrackingMarker *marker)
@@ -746,7 +815,7 @@ static float get_shortest_pattern_side(MovieTrackingMarker *marker)
return sqrtf(len_sq);
}
-static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2])
+static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos)
{
float tdx, tdy;
@@ -758,15 +827,10 @@ static void draw_marker_slide_square(float x, float y, float dx, float dy, int o
tdy += px[1];
}
- glBegin(GL_QUADS);
- glVertex3f(x - tdx, y + tdy, 0.0f);
- glVertex3f(x + tdx, y + tdy, 0.0f);
- glVertex3f(x + tdx, y - tdy, 0.0f);
- glVertex3f(x - tdx, y - tdy, 0.0f);
- glEnd();
+ immRectf(pos, x - tdx, y - tdy, x + tdx, y + tdy);
}
-static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2])
+static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos)
{
float tdx, tdy;
@@ -778,15 +842,16 @@ static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int
tdy += px[1];
}
- glBegin(GL_TRIANGLES);
- glVertex3f(x, y, 0.0f);
- glVertex3f(x - tdx, y, 0.0f);
- glVertex3f(x, y + tdy, 0.0f);
- glEnd();
+ immBegin(PRIM_TRIANGLES, 3);
+ immVertex2f(pos, x, y);
+ immVertex2f(pos, x - tdx, y);
+ immVertex2f(pos, x, y + tdy);
+ immEnd();
}
static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- const float marker_pos[2], int outline, int sel, int act, int width, int height)
+ const float marker_pos[2], int outline, int sel, int act,
+ int width, int height, unsigned int pos)
{
float dx, dy, patdx, patdy, searchdx, searchdy;
int tiny = sc->flag & SC_SHOW_TINY_MARKER;
@@ -801,11 +866,11 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
track_colors(track, act, col, scol);
if (outline) {
- UI_ThemeColor(TH_MARKER_OUTLINE);
+ immUniformThemeColor(TH_MARKER_OUTLINE);
}
- glPushMatrix();
- glTranslate2fv(marker_pos);
+ gpuPushMatrix();
+ gpuTranslate2fv(marker_pos);
dx = 6.0f / width / sc->zoom;
dy = 6.0f / height / sc->zoom;
@@ -822,17 +887,14 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
if (!outline) {
- if (track->search_flag & SELECT)
- glColor3fv(scol);
- else
- glColor3fv(col);
+ immUniformColor3fv((track->search_flag & SELECT) ? scol : col);
}
/* search offset square */
- draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px);
+ draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px, pos);
/* search re-sizing triangle */
- draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px);
+ draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px, pos);
}
if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
@@ -842,16 +904,13 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
float tilt_ctrl[2];
if (!outline) {
- if (track->pat_flag & SELECT)
- glColor3fv(scol);
- else
- glColor3fv(col);
+ immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
}
/* pattern's corners sliding squares */
for (i = 0; i < 4; i++) {
draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
- patdx / 1.5f, patdy / 1.5f, outline, px);
+ patdx / 1.5f, patdy / 1.5f, outline, px, pos);
}
/* ** sliders to control overall pattern ** */
@@ -861,18 +920,16 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
glLineWidth(outline ? 3.0f : 1.0f);
- glBegin(GL_LINES);
- glVertex2f(0.0f, 0.0f);
- glVertex2fv(tilt_ctrl);
- glEnd();
-
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, 0.0f, 0.0f);
+ immVertex2fv(pos, tilt_ctrl);
+ immEnd();
/* slider to control pattern tilt */
- draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px);
+ draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px, pos);
}
- glPopMatrix();
+ gpuPopMatrix();
}
static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
@@ -890,16 +947,17 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
fontsize = BLF_height_max(fontid);
if (marker->flag & MARKER_DISABLED) {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else
- UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ if (act) {
+ UI_FontThemeColor(fontid, TH_ACT_MARKER);
+ }
+ else {
+ unsigned char color[4];
+ UI_GetThemeColorShade4ubv(TH_DIS_MARKER, 128, color);
+ BLF_color4ubv(fontid, color);
+ }
}
else {
- if (act)
- UI_ThemeColor(TH_ACT_MARKER);
- else
- UI_ThemeColor(TH_SEL_MARKER);
+ UI_FontThemeColor(fontid, act ? TH_ACT_MARKER : TH_SEL_MARKER);
}
if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
@@ -960,10 +1018,7 @@ static void plane_track_colors(bool is_active, float color[3], float selected_co
{
UI_GetThemeColor3fv(TH_MARKER, color);
- if (is_active)
- UI_GetThemeColor3fv(TH_ACT_MARKER, selected_color);
- else
- UI_GetThemeColor3fv(TH_SEL_MARKER, selected_color);
+ UI_GetThemeColor3fv(is_active ? TH_ACT_MARKER : TH_SEL_MARKER, selected_color);
}
static void getArrowEndPoint(const int width, const int height, const float zoom,
@@ -1060,9 +1115,6 @@ static void draw_plane_marker_image(Scene *scene,
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- glColor4f(1.0, 1.0, 1.0, plane_track->image_opacity);
-
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
glGenTextures(1, (GLuint *)&texid);
glBindTexture(GL_TEXTURE_2D, texid);
@@ -1073,20 +1125,38 @@ static void draw_plane_marker_image(Scene *scene,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA,
GL_UNSIGNED_BYTE, display_buffer);
- glPushMatrix();
- glMultMatrixf(gl_matrix);
+ gpuPushMatrix();
+ gpuMultMatrix(gl_matrix);
+
+ VertexFormat *imm_format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(imm_format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(imm_format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, plane_track->image_opacity);
+ immUniform1i("image", GL_TEXTURE0);
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, 1.0f, 0.0f);
+
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, 1.0f, 1.0f);
+
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, 0.0f, 1.0f);
+
+ immEnd();
- glBegin(GL_QUADS);
- glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f);
- glEnd();
+ immUnbindProgram();
- glPopMatrix();
+ gpuPopMatrix();
glBindTexture(GL_TEXTURE_2D, 0);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
if (transparent) {
glDisable(GL_BLEND);
@@ -1109,20 +1179,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
BKE_image_has_ibuf(plane_track->image, NULL);
const bool draw_plane_quad = !has_image || plane_track->image_opacity == 0.0f;
float px[2];
-
- if (draw_outline) {
- UI_ThemeColor(TH_MARKER_OUTLINE);
- }
- else {
- float color[3], selected_color[3];
- plane_track_colors(is_active_track, color, selected_color);
- if (is_selected_track) {
- glColor3fv(selected_color);
- }
- else {
- glColor3fv(color);
- }
- }
+ float color[3], selected_color[3];
px[0] = 1.0f / width / sc->zoom;
px[1] = 1.0f / height / sc->zoom;
@@ -1132,66 +1189,92 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
draw_plane_marker_image(scene, plane_track, plane_marker);
}
- if (draw_plane_quad) {
+ if (draw_plane_quad || is_selected_track) {
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- const bool stipple = !draw_outline && tiny;
- const bool thick = draw_outline && !tiny;
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
- if (stipple) {
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(3, 0xAAAA);
- }
- else {
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE);
- }
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- GPU_basic_shader_line_width(thick ? 3.0f : 1.0f);
+ immUniform1i("num_colors", 0); /* "simple" mode */
- /* Draw rectangle itself. */
- glBegin(GL_LINE_LOOP);
- glVertex2fv(plane_marker->corners[0]);
- glVertex2fv(plane_marker->corners[1]);
- glVertex2fv(plane_marker->corners[2]);
- glVertex2fv(plane_marker->corners[3]);
- glEnd();
+ if (draw_plane_quad) {
+ const bool stipple = !draw_outline && tiny;
+ const bool thick = draw_outline && !tiny;
- /* Draw axis. */
- if (!draw_outline) {
- float end_point[2];
- glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
+ glLineWidth(thick ? 3.0f : 1.0f);
- glBegin(GL_LINES);
+ if (stipple) {
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+ }
+ else {
+ immUniform1f("dash_factor", 2.0f); /* Solid line */
+ }
- getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
- glColor3f(1.0, 0.0, 0.0f);
- glVertex2fv(plane_marker->corners[0]);
- glVertex2fv(end_point);
+ if (draw_outline) {
+ immUniformThemeColor(TH_MARKER_OUTLINE);
+ }
+ else {
+ plane_track_colors(is_active_track, color, selected_color);
+ immUniformColor3fv(is_selected_track ? selected_color : color);
+ }
- getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
- glColor3f(0.0, 1.0, 0.0f);
- glVertex2fv(plane_marker->corners[0]);
- glVertex2fv(end_point);
+ /* Draw rectangle itself. */
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2fv(shdr_pos, plane_marker->corners[0]);
+ immVertex2fv(shdr_pos, plane_marker->corners[1]);
+ immVertex2fv(shdr_pos, plane_marker->corners[2]);
+ immVertex2fv(shdr_pos, plane_marker->corners[3]);
+ immEnd();
- glEnd();
+ /* Draw axis. */
+ if (!draw_outline) {
+ float end_point[2];
- glPopAttrib();
- }
+ immUniformColor3f(1.0f, 0.0f, 0.0f);
- if (stipple) {
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- }
- else {
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE);
+ immBegin(PRIM_LINES, 2);
+
+ getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
+ immVertex2fv(shdr_pos, plane_marker->corners[0]);
+ immVertex2fv(shdr_pos, end_point);
+
+ immEnd();
+
+ immUniformColor3f(0.0f, 1.0f, 0.0f);
+
+ immBegin(PRIM_LINES, 2);
+
+ getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
+ immVertex2fv(shdr_pos, plane_marker->corners[0]);
+ immVertex2fv(shdr_pos, end_point);
+
+ immEnd();
+ }
}
- }
- /* Draw sliders. */
- if (is_selected_track) {
- int i;
- for (i = 0; i < 4; i++) {
- draw_marker_slide_square(plane_marker->corners[i][0], plane_marker->corners[i][1],
- 3.0f * px[0], 3.0f * px[1], draw_outline, px);
+ /* Draw sliders. */
+ if (is_selected_track) {
+ immUniform1f("dash_factor", 2.0f); /* Solid line */
+
+ if (draw_outline) {
+ immUniformThemeColor(TH_MARKER_OUTLINE);
+ }
+ else {
+ immUniformColor3fv(selected_color);
+ }
+
+ int i;
+ for (i = 0; i < 4; i++) {
+ draw_marker_slide_square(plane_marker->corners[i][0], plane_marker->corners[i][1],
+ 3.0f * px[0], 3.0f * px[1], draw_outline, px, shdr_pos);
+ }
}
+
+ immUnbindProgram();
}
}
@@ -1243,13 +1326,13 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
- glPushMatrix();
- glTranslatef(x, y, 0);
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
- glPushMatrix();
- glScalef(zoomx, zoomy, 0);
- glMultMatrixf(sc->stabmat);
- glScalef(width, height, 0);
+ gpuPushMatrix();
+ gpuScale2f(zoomx, zoomy);
+ gpuMultMatrix(sc->stabmat);
+ gpuScale2f(width, height);
act_track = BKE_tracking_track_get_active(tracking);
@@ -1315,6 +1398,10 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
}
}
+ unsigned int position = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* markers outline and non-selected areas */
track = tracksbase->first;
fp = marker_pos;
@@ -1325,10 +1412,10 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
if (MARKER_VISIBLE(sc, track, marker)) {
copy_v2_v2(cur_pos, fp ? fp : marker->pos);
- draw_marker_outline(sc, track, marker, cur_pos, width, height);
- draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
- draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
- draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);
+ draw_marker_outline(sc, track, marker, cur_pos, width, height, position);
+ draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0, position);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height, position);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height, position);
if (fp)
fp += 2;
@@ -1351,8 +1438,8 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
if (!act) {
copy_v2_v2(cur_pos, fp ? fp : marker->pos);
- draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
- draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
+ draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1, position);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height, position);
}
if (fp)
@@ -1371,8 +1458,8 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
if (MARKER_VISIBLE(sc, act_track, marker)) {
copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
- draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
- draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
+ draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1, position);
+ draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height, position);
}
}
}
@@ -1381,7 +1468,6 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
float pos[4], vec[4], mat[4][4], aspy;
- glEnable(GL_POINT_SMOOTH);
glPointSize(3.0f);
aspy = 1.0f / clip->tracking.camera.pixel_aspect;
@@ -1410,28 +1496,34 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
sub_v2_v2(vec, npos);
- if (len_squared_v2(vec) < (3.0f * 3.0f))
- glColor3f(0.0f, 1.0f, 0.0f);
- else
- glColor3f(1.0f, 0.0f, 0.0f);
+ if (len_squared_v2(vec) < (3.0f * 3.0f)) {
+ immUniformColor3f(0.0f, 1.0f, 0.0f);
+ }
+ else {
+ immUniformColor3f(1.0f, 0.0f, 0.0f);
+ }
- glBegin(GL_POINTS);
- if (undistort)
- glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0);
- else
- glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+
+ if (undistort) {
+ immVertex2f(position, pos[0] / width, pos[1] / (height * aspy));
+ }
+ else {
+ immVertex2f(position, npos[0] / width, npos[1] / (height * aspy));
+ }
+
+ immEnd();
}
}
}
track = track->next;
}
-
- glDisable(GL_POINT_SMOOTH);
}
- glPopMatrix();
+ immUnbindProgram();
+
+ gpuPopMatrix();
if (sc->flag & SC_SHOW_NAMES) {
/* scaling should be cleared before drawing texts, otherwise font would also be scaled */
@@ -1457,7 +1549,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
}
}
- glPopMatrix();
+ gpuPopMatrix();
if (marker_pos)
MEM_freeN(marker_pos);
@@ -1484,11 +1576,15 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
- glPushMatrix();
- glTranslatef(x, y, 0);
- glScalef(zoomx, zoomy, 0);
- glMultMatrixf(sc->stabmat);
- glScalef(width, height, 0);
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+ gpuScale2f(zoomx, zoomy);
+ gpuMultMatrix(sc->stabmat);
+ gpuScale2f(width, height);
+
+ unsigned int position = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* grid */
if (sc->flag & SC_SHOW_GRID) {
@@ -1560,22 +1656,26 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
pos[1] += dy;
}
- glColor3f(1.0f, 0.0f, 0.0f);
+ immUniformColor3f(1.0f, 0.0f, 0.0f);
for (i = 0; i <= n; i++) {
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, n + 1);
+
for (j = 0; j <= n; j++) {
- glVertex2fv(grid[i][j]);
+ immVertex2fv(position, grid[i][j]);
}
- glEnd();
+
+ immEnd();
}
for (j = 0; j <= n; j++) {
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, n + 1);
+
for (i = 0; i <= n; i++) {
- glVertex2fv(grid[i][j]);
+ immVertex2fv(position, grid[i][j]);
}
- glEnd();
+
+ immEnd();
}
}
@@ -1594,7 +1694,8 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
continue;
}
- glColor4fv(layer->color);
+ immUniformColor4fv(layer->color);
+
glLineWidth(layer->thickness);
glPointSize((float)(layer->thickness + 2));
@@ -1604,7 +1705,6 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
while (stroke) {
if (stroke->flag & GP_STROKE_2DSPACE) {
if (stroke->totpoints > 1) {
- glBegin(GL_LINE_STRIP);
for (i = 0; i < stroke->totpoints - 1; i++) {
float npos[2], dpos[2], len;
int steps;
@@ -1627,19 +1727,22 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
sub_v2_v2v2(dpos, npos, pos);
mul_v2_fl(dpos, 1.0f / steps);
+ immBegin(PRIM_LINE_STRIP, steps + 1);
+
for (j = 0; j <= steps; j++) {
BKE_tracking_distort_v2(tracking, pos, tpos);
- glVertex2f(tpos[0] / width, tpos[1] / (height * aspy));
+ immVertex2f(position, tpos[0] / width, tpos[1] / (height * aspy));
add_v2_v2(pos, dpos);
}
+
+ immEnd();
}
- glEnd();
}
else if (stroke->totpoints == 1) {
- glBegin(GL_POINTS);
- glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(position, stroke->points[0].x + offsx, stroke->points[0].y + offsy);
+ immEnd();
}
}
@@ -1653,7 +1756,9 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
}
}
- glPopMatrix();
+ immUnbindProgram();
+
+ gpuPopMatrix();
}
void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
@@ -1750,8 +1855,8 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
* associated with the clip is already drawn in draw_distortion
*/
if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || is_track_source) {
- glPushMatrix();
- glMultMatrixf(sc->unistabmat);
+ gpuPushMatrix();
+ gpuMultMatrix(sc->unistabmat);
if (is_track_source) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
@@ -1760,13 +1865,13 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
int framenr = ED_space_clip_get_clip_frame_number(sc);
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
- glTranslate2fv(marker->pos);
+ gpuTranslate2fv(marker->pos);
}
}
ED_gpencil_draw_2dimage(C);
- glPopMatrix();
+ gpuPopMatrix();
}
}
else {
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
index 424d25defdd..c9db5d4a328 100644
--- a/source/blender/editors/space_clip/clip_graph_draw.c
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -42,7 +42,9 @@
#include "ED_screen.h"
#include "ED_clip.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "WM_types.h"
@@ -53,52 +55,30 @@
#include "clip_intern.h" // own include
-static void draw_curve_knot(float x, float y, float xscale, float yscale, float hsize)
-{
- static GLuint displist = 0;
-
- /* initialize round circle shape */
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0, 0.7, 8, 1);
- gluDeleteQuadric(qobj);
-
- glEndList();
- }
-
- glPushMatrix();
-
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
- glCallList(displist);
-
- glPopMatrix();
-}
+typedef struct TrackMotionCurveUserData {
+ MovieTrackingTrack *act_track;
+ bool sel;
+ float xscale, yscale, hsize;
+ unsigned int pos;
+} TrackMotionCurveUserData;
-static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track),
+static void tracking_segment_point_cb(void *userdata, MovieTrackingTrack *UNUSED(track),
MovieTrackingMarker *UNUSED(marker), int UNUSED(coord),
int scene_framenr, float val)
{
- glVertex2f(scene_framenr, val);
+ TrackMotionCurveUserData *data = (TrackMotionCurveUserData *) userdata;
+
+ immVertex2f(data->pos, scene_framenr, val);
}
-static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
+static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord, bool is_point)
{
- const float colors[2][3] = {
- {1.0f, 0.0f, 0.0f},
- {0.0f, 1.0f, 0.0f},
- };
- float col[4];
+ TrackMotionCurveUserData *data = (TrackMotionCurveUserData *) userdata;
+ float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- copy_v3_v3(col, colors[coord]);
+ col[coord] = 1.0f;
- if (track == userdata) {
+ if (track == data->act_track) {
col[3] = 1.0f;
glLineWidth(2.0f);
}
@@ -107,22 +87,22 @@ static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track,
glLineWidth(1.0f);
}
- glColor4fv(col);
+ immUniformColor4fv(col);
- glBegin(GL_LINE_STRIP);
+ if (is_point) {
+ immBeginAtMost(PRIM_POINTS, 1);
+ }
+ else {
+ /* Graph can be composed of smaller segments, if any marker is disabled */
+ immBeginAtMost(PRIM_LINE_STRIP, track->markersnr);
+ }
}
static void tracking_segment_end_cb(void *UNUSED(userdata), int UNUSED(coord))
{
- glEnd();
+ immEnd();
}
-typedef struct TrackMotionCurveUserData {
- MovieTrackingTrack *act_track;
- bool sel;
- float xscale, yscale, hsize;
-} TrackMotionCurveUserData;
-
static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
MovieTrackingMarker *marker, int coord, int scene_framenr, float val)
{
@@ -136,16 +116,19 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
sel = (marker->flag & sel_flag) ? 1 : 0;
if (sel == data->sel) {
- if (sel)
- UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
- else
- UI_ThemeColor(TH_HANDLE_VERTEX);
+ immUniformThemeColor(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX);
+
+ gpuPushMatrix();
+ gpuTranslate2f(scene_framenr, val);
+ gpuScale2f(1.0f / data->xscale * data->hsize, 1.0f / data->yscale * data->hsize);
- draw_curve_knot(scene_framenr, val, data->xscale, data->yscale, data->hsize);
+ imm_draw_circle_wire(data->pos, 0, 0, 0.7, 8);
+
+ gpuPopMatrix();
}
}
-static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc)
+static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc, unsigned int pos)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
@@ -162,18 +145,18 @@ static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc)
userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
userdata.sel = false;
userdata.act_track = act_track;
+ userdata.pos = pos;
UI_view2d_scale_get(v2d, &userdata.xscale, &userdata.yscale);
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
&userdata, tracking_segment_knot_cb, NULL, NULL);
-
/* draw graph lines */
glEnable(GL_BLEND);
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
- act_track, tracking_segment_point_cb, tracking_segment_start_cb,
+ &userdata, tracking_segment_point_cb, tracking_segment_start_cb,
tracking_segment_end_cb);
glDisable(GL_BLEND);
@@ -195,6 +178,7 @@ typedef struct TrackErrorCurveUserData {
float projection_matrix[4][4];
int width, height;
float aspy;
+ unsigned int pos;
} TrackErrorCurveUserData;
static void tracking_error_segment_point_cb(void *userdata,
@@ -230,11 +214,11 @@ static void tracking_error_segment_point_cb(void *userdata,
sub_v2_v2v2(delta, reprojected_position, marker_position);
reprojection_error = len_v2(delta) * weight;
- glVertex2f(scene_framenr, reprojection_error);
+ immVertex2f(data->pos, scene_framenr, reprojection_error);
}
}
-static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
+static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord, bool is_point)
{
if (coord == 1) {
TrackErrorCurveUserData *data = (TrackErrorCurveUserData *) userdata;
@@ -249,20 +233,26 @@ static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack *
glLineWidth(1.0f);
}
- glColor4fv(col);
+ immUniformColor4fv(col);
- glBegin(GL_LINE_STRIP);
+ if (is_point) { /* This probably never happens here, but just in case... */
+ immBeginAtMost(PRIM_POINTS, 1);
+ }
+ else {
+ /* Graph can be composed of smaller segments, if any marker is disabled */
+ immBeginAtMost(PRIM_LINE_STRIP, track->markersnr);
+ }
}
}
static void tracking_error_segment_end_cb(void *UNUSED(userdata), int coord)
{
if (coord == 1) {
- glEnd();
+ immEnd();
}
}
-static void draw_tracks_error_curves(SpaceClip *sc)
+static void draw_tracks_error_curves(SpaceClip *sc, unsigned int pos)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
@@ -273,6 +263,7 @@ static void draw_tracks_error_curves(SpaceClip *sc)
data.tracking_object = BKE_tracking_object_get_active(tracking);
data.active_track = BKE_tracking_track_get_active(tracking);
data.matrix_initialized = false;
+ data.pos = pos;
BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height);
data.aspy = 1.0f / tracking->camera.pixel_aspect;
@@ -289,37 +280,38 @@ static void draw_tracks_error_curves(SpaceClip *sc)
tracking_error_segment_end_cb);
}
-static void draw_frame_curves(SpaceClip *sc)
+static void draw_frame_curves(SpaceClip *sc, unsigned int pos)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
int i, lines = 0, prevfra = 0;
- glColor3f(0.0f, 0.0f, 1.0f);
+ immUniformColor3f(0.0f, 0.0f, 1.0f);
for (i = 0; i < reconstruction->camnr; i++) {
MovieReconstructedCamera *camera = &reconstruction->cameras[i];
int framenr;
if (lines && camera->framenr != prevfra + 1) {
- glEnd();
+ immEnd();
lines = 0;
}
if (!lines) {
- glBegin(GL_LINE_STRIP);
+ immBeginAtMost(PRIM_LINE_STRIP, reconstruction->camnr);
lines = 1;
}
framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, camera->framenr);
- glVertex2f(framenr, camera->error);
+ immVertex2f(pos, framenr, camera->error);
prevfra = camera->framenr;
}
- if (lines)
- glEnd();
+ if (lines) {
+ immEnd();
+ }
}
void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
@@ -335,14 +327,24 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
UI_view2d_grid_free(grid);
if (clip) {
- if (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION)
- draw_tracks_motion_curves(v2d, sc);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ glPointSize(3.0f);
- if (sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR)
- draw_tracks_error_curves(sc);
+ if (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) {
+ draw_tracks_motion_curves(v2d, sc, pos);
+ }
+
+ if (sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR) {
+ draw_tracks_error_curves(sc, pos);
+ }
+
+ if (sc->flag & SC_SHOW_GRAPH_FRAMES) {
+ draw_frame_curves(sc, pos);
+ }
- if (sc->flag & SC_SHOW_GRAPH_FRAMES)
- draw_frame_curves(sc);
+ immUnbindProgram();
}
/* frame range */
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 14393c6968b..ffc7a41f0aa 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -125,12 +125,12 @@ void ED_clip_tool_props_register(struct ARegionType *art);
/* clip_utils.c */
void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata,
void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val),
- void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord),
+ void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord, bool is_point),
void (*segment_end)(void *userdata, int coord));
void clip_graph_tracking_values_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata,
void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val),
- void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord),
+ void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord, bool is_point),
void (*segment_end)(void *userdata, int coord));
void clip_graph_tracking_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata,
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index e901b9f8026..272d99c2b0e 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -43,8 +43,8 @@
#include "BKE_tracking.h"
#include "BKE_depsgraph.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -52,7 +52,6 @@
#include "ED_screen.h"
#include "ED_clip.h"
-
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -63,7 +62,7 @@ void clip_graph_tracking_values_iterate_track(
SpaceClip *sc, MovieTrackingTrack *track, void *userdata,
void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord,
int scene_framenr, float val),
- void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord),
+ void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord, bool is_point),
void (*segment_end)(void *userdata, int coord))
{
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -92,8 +91,14 @@ void clip_graph_tracking_values_iterate_track(
}
if (!open) {
- if (segment_start)
- segment_start(userdata, track, coord);
+ if (segment_start) {
+ if ((i + 1) == track->markersnr) {
+ segment_start(userdata, track, coord, true);
+ }
+ else {
+ segment_start(userdata, track, coord, (track->markers[i + 1].flag & MARKER_DISABLED));
+ }
+ }
open = true;
prevval = marker->pos[coord];
@@ -124,7 +129,7 @@ void clip_graph_tracking_values_iterate(
SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata,
void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker,
int coord, int scene_framenr, float val),
- void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord),
+ void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord, bool is_point),
void (*segment_end)(void *userdata, int coord))
{
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -238,31 +243,35 @@ void clip_view_center_to_point(SpaceClip *sc, float x, float y)
void clip_draw_cfra(SpaceClip *sc, ARegion *ar, Scene *scene)
{
+ /* Draw a light green line to indicate current frame */
View2D *v2d = &ar->v2d;
- float xscale, yscale;
+ float x = (float)(sc->user.framenr * scene->r.framelen);
- /* Draw a light green line to indicate current frame */
- UI_ThemeColor(TH_CFRAME);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- float x = (float)(sc->user.framenr * scene->r.framelen);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CFRAME);
+ glLineWidth(2.0f);
- glLineWidth(2.0);
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, x, v2d->cur.ymin);
+ immVertex2f(pos, x, v2d->cur.ymax);
+ immEnd();
- glBegin(GL_LINES);
- glVertex2f(x, v2d->cur.ymin);
- glVertex2f(x, v2d->cur.ymax);
- glEnd();
+ immUnbindProgram();
UI_view2d_view_orthoSpecial(ar, v2d, 1);
/* because the frame number text is subject to the same scaling as the contents of the view */
- UI_view2d_scale_get(v2d, &xscale, &yscale);
- glScalef(1.0f / xscale, 1.0f, 1.0f);
+ float xscale;
+ UI_view2d_scale_get(v2d, &xscale, NULL);
+ gpuPushMatrix();
+ gpuScale2f(1.0f / xscale, 1.0f);
ED_region_cache_draw_curfra_label(sc->user.framenr, (float)sc->user.framenr * xscale, 18);
/* restore view transform */
- glScalef(xscale, 1.0, 1.0);
+ gpuPopMatrix();
}
void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
@@ -272,15 +281,27 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
/* currently clip editor supposes that editing clip length is equal to scene frame range */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
- glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
+ immRectf(pos, (float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+
glDisable(GL_BLEND);
- UI_ThemeColorShade(TH_BACK, -60);
+ immUniformThemeColorShade(TH_BACK, -60);
/* thin lines where the actual frames are */
- fdrawline((float)SFRA, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
- fdrawline((float)EFRA, v2d->cur.ymin, (float)EFRA, v2d->cur.ymax);
+ glLineWidth(1.0f);
+
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, (float)SFRA, v2d->cur.ymin);
+ immVertex2f(pos, (float)SFRA, v2d->cur.ymax);
+ immVertex2f(pos, (float)EFRA, v2d->cur.ymin);
+ immVertex2f(pos, (float)EFRA, v2d->cur.ymax);
+ immEnd();
+
+ immUnbindProgram();
}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 237082f948b..eed2acbfc68 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -60,7 +60,7 @@
#include "IMB_imbuf.h"
-#include "BIF_gl.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -329,7 +329,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
return (SpaceLink *)scn;
}
-static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1213,13 +1213,13 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar)
show_cursor |= sc->around == V3D_AROUND_CURSOR;
if (show_cursor) {
- glPushMatrix();
- glTranslatef(x, y, 0);
- glScalef(zoomx, zoomy, 0);
- glMultMatrixf(sc->stabmat);
- glScalef(width, height, 0);
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+ gpuScale2f(zoomx, zoomy);
+ gpuMultMatrix(sc->stabmat);
+ gpuScale2f(width, height);
ED_image_draw_cursor(ar, sc->cursor);
- glPopMatrix();
+ gpuPopMatrix();
}
clip_draw_cache_and_notes(C, sc, ar);
@@ -1238,7 +1238,9 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar)
}
}
-static void clip_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void clip_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1349,7 +1351,9 @@ static void clip_preview_region_draw(const bContext *C, ARegion *ar)
dopesheet_region_draw(C, ar);
}
-static void clip_preview_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void clip_preview_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
+ wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
{
}
@@ -1390,7 +1394,9 @@ static void clip_channels_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
}
-static void clip_channels_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void clip_channels_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
+ wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
{
}
@@ -1407,7 +1413,9 @@ static void clip_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void clip_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void clip_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1447,7 +1455,9 @@ static void clip_tools_region_draw(const bContext *C, ARegion *ar)
/****************** tool properties region ******************/
-static void clip_props_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void clip_props_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1492,7 +1502,9 @@ static void clip_properties_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void clip_properties_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void clip_properties_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_clip/tracking_ops_orient.c b/source/blender/editors/space_clip/tracking_ops_orient.c
index f81180d65a9..7b44e9317ba 100644
--- a/source/blender/editors/space_clip/tracking_ops_orient.c
+++ b/source/blender/editors/space_clip/tracking_ops_orient.c
@@ -44,6 +44,7 @@
#include "BKE_tracking.h"
#include "BKE_global.h"
#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -69,17 +70,16 @@ static Object *get_camera_with_movieclip(Scene *scene, MovieClip *clip)
return camera;
}
- for (Base *base = scene->base.first;
- base != NULL;
- base = base->next)
+ FOREACH_SCENE_OBJECT(scene, ob)
{
- if (base->object->type == OB_CAMERA) {
- if (BKE_object_movieclip_get(scene, base->object, false) == clip) {
- camera = base->object;
+ if (ob->type == OB_CAMERA) {
+ if (BKE_object_movieclip_get(scene, ob, false) == clip) {
+ camera = ob;
break;
}
}
}
+ FOREACH_SCENE_OBJECT_END
return camera;
}
@@ -87,6 +87,7 @@ static Object *get_camera_with_movieclip(Scene *scene, MovieClip *clip)
static Object *get_orientation_object(bContext *C)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
@@ -97,7 +98,7 @@ static Object *get_orientation_object(bContext *C)
object = get_camera_with_movieclip(scene, clip);
}
else {
- object = OBACT;
+ object = OBACT_NEW;
}
if (object != NULL && object->parent != NULL) {
@@ -111,7 +112,7 @@ static int set_orientation_poll(bContext *C)
{
SpaceClip *sc = CTX_wm_space_clip(C);
if (sc != NULL) {
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
if (clip != NULL) {
MovieTracking *tracking = &clip->tracking;
@@ -120,7 +121,7 @@ static int set_orientation_poll(bContext *C)
return true;
}
else {
- return OBACT != NULL;
+ return OBACT_NEW != NULL;
}
}
}
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 6396b390ca0..e813557f9e8 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -40,6 +40,7 @@
#include "MEM_guardedalloc.h"
#include "BIF_gl.h"
+#include "GPU_immediate.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -157,6 +158,8 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
int offl = 0, offc = 0;
int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
int pen[2];
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
xy[1] += tvc->lheight / 6;
console_cursor_wrap_offset(sc->prompt, tvc->console_width, &offl, &offc, NULL);
@@ -168,14 +171,17 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
pen[1] += tvc->lheight * offl;
/* cursor */
- UI_GetThemeColor3ubv(TH_CONSOLE_CURSOR, fg);
- glColor3ubv(fg);
-
- glRecti((xy[0] + pen[0]) - 1,
- (xy[1] + pen[1]),
- (xy[0] + pen[0]) + 1,
- (xy[1] + pen[1] + tvc->lheight)
- );
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CONSOLE_CURSOR);
+
+ immRectf(pos,
+ (xy[0] + pen[0]) - 1,
+ (xy[1] + pen[1]),
+ (xy[0] + pen[0]) + 1,
+ (xy[1] + pen[1] + tvc->lheight)
+ );
+
+ immUnbindProgram();
}
console_line_color(fg, cl_iter->type);
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 97a85bce006..9a2f4b5d431 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -368,7 +368,9 @@ static void console_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void console_main_region_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, wmNotifier *wmn)
+static void console_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
// SpaceInfo *sinfo = sa->spacedata.first;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 52d01063175..61f33d72b71 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -42,7 +42,6 @@
# include "BLI_winstuff.h"
#endif
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BKE_context.h"
@@ -71,6 +70,9 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "filelist.h"
#include "file_intern.h" // own include
@@ -258,9 +260,10 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade)
{
- UI_ThemeColorShade(colorid, shade);
+ float color[4];
+ UI_GetThemeColorShade4fv(colorid, shade, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f);
+ UI_draw_roundbox_aa(true, (float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f, color);
}
@@ -285,7 +288,8 @@ static void file_draw_icon(uiBlock *block, const char *path, int sx, int sy, int
}
-static void file_draw_string(int sx, int sy, const char *string, float width, int height, short align)
+static void file_draw_string(int sx, int sy, const char *string, float width, int height, short align,
+ const unsigned char col[4])
{
uiStyle *style;
uiFontStyle fs;
@@ -310,7 +314,7 @@ static void file_draw_string(int sx, int sy, const char *string, float width, in
rect.ymin = sy - height;
rect.ymax = sy;
- UI_fontstyle_draw(&fs, &rect, fname);
+ UI_fontstyle_draw(&fs, &rect, fname, col);
}
void file_calc_previews(const bContext *C, ARegion *ar)
@@ -335,6 +339,7 @@ static void file_draw_preview(
float scale;
int ex, ey;
bool use_dropshadow = !is_icon && (typeflags & FILE_TYPE_IMAGE);
+ float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
BLI_assert(imb != NULL);
@@ -381,12 +386,12 @@ static void file_draw_preview(
/* the image */
if (!is_icon && typeflags & FILE_TYPE_FTFONT) {
- UI_ThemeColor(TH_TEXT);
- }
- else {
- glColor4f(1.0, 1.0, 1.0, 1.0);
+ UI_GetThemeColor4fv(TH_TEXT, col);
}
- glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTexScaled(&state, (float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect,
+ scale, scale, 1.0f, 1.0f, col);
if (icon) {
UI_icon_draw_aspect((float)xco, (float)yco, icon, icon_aspect, 1.0f);
@@ -394,8 +399,13 @@ static void file_draw_preview(
/* border */
if (use_dropshadow) {
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- fdrawbox((float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2,KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ imm_draw_line_box(pos, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
+ immUnbindProgram();
}
but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, NULL);
@@ -451,49 +461,70 @@ static void draw_background(FileLayout *layout, View2D *v2d)
int i;
int sy;
- UI_ThemeColorShade(TH_BACK, -7);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShade(TH_BACK, -7);
/* alternating flat shade background */
for (i = 0; (i <= layout->rows); i += 2) {
sy = (int)v2d->cur.ymax - i * (layout->tile_h + 2 * layout->tile_border_y) - layout->tile_border_y;
- glRectf(v2d->cur.xmin, (float)sy, v2d->cur.xmax, (float)(sy + layout->tile_h + 2 * layout->tile_border_y));
-
+ immRectf(pos, v2d->cur.xmin, (float)sy, v2d->cur.xmax, (float)(sy + layout->tile_h + 2 * layout->tile_border_y));
}
+
+ immUnbindProgram();
}
static void draw_dividers(FileLayout *layout, View2D *v2d)
{
+ /* vertical column dividers */
+
const int step = (layout->tile_w + 2 * layout->tile_border_x);
- int v1[2], v2[2];
- int sx;
- unsigned char col_hi[3], col_lo[3];
- UI_GetThemeColorShade3ubv(TH_BACK, 30, col_hi);
- UI_GetThemeColorShade3ubv(TH_BACK, -30, col_lo);
+ unsigned int vertex_ct = 0;
+ int sx = (int)v2d->tot.xmin;
+ while (sx < v2d->cur.xmax) {
+ sx += step;
+ vertex_ct += 4; /* vertex_count = 2 points per line * 2 lines per divider */
+ }
- v1[1] = v2d->cur.ymax - layout->tile_border_y;
- v2[1] = v2d->cur.ymin;
+ if (vertex_ct > 0) {
+ int v1[2], v2[2];
+ unsigned char col_hi[3], col_lo[3];
- glBegin(GL_LINES);
+ UI_GetThemeColorShade3ubv(TH_BACK, 30, col_hi);
+ UI_GetThemeColorShade3ubv(TH_BACK, -30, col_lo);
- /* vertical column dividers */
- sx = (int)v2d->tot.xmin;
- while (sx < v2d->cur.xmax) {
- sx += step;
+ v1[1] = v2d->cur.ymax - layout->tile_border_y;
+ v2[1] = v2d->cur.ymin;
- glColor3ubv(col_lo);
- v1[0] = v2[0] = sx;
- glVertex2iv(v1);
- glVertex2iv(v2);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
- glColor3ubv(col_hi);
- v1[0] = v2[0] = sx + 1;
- glVertex2iv(v1);
- glVertex2iv(v2);
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINES, vertex_ct);
+
+ sx = (int)v2d->tot.xmin;
+ while (sx < v2d->cur.xmax) {
+ sx += step;
+
+ v1[0] = v2[0] = sx;
+ immSkipAttrib(color);
+ immVertex2iv(pos, v1);
+ immAttrib3ubv(color, col_lo);
+ immVertex2iv(pos, v2);
- glEnd();
+ v1[0] = v2[0] = sx + 1;
+ immSkipAttrib(color);
+ immVertex2iv(pos, v1);
+ immAttrib3ubv(color, col_hi);
+ immVertex2iv(pos, v2);
+ }
+
+ immEnd();
+ immUnbindProgram();
+ }
}
void file_draw_list(const bContext *C, ARegion *ar)
@@ -517,6 +548,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
short align;
bool do_drag;
int column_space = 0.6f * UI_UNIT_X;
+ unsigned char text_col[4];
const bool small_size = SMALL_SIZE_CHECK(params->thumbnail_size);
const bool update_stat_strings = small_size != SMALL_SIZE_CHECK(layout->curr_size);
const float thumb_icon_aspect = sqrtf(64.0f / (float)(params->thumbnail_size));
@@ -587,9 +619,6 @@ void file_draw_list(const bContext *C, ARegion *ar)
BLI_join_dirfile(path, sizeof(path), root, file->relpath);
- UI_ThemeColor4(TH_TEXT);
-
-
if (!(file_selflag & FILE_SEL_EDITING)) {
if ((params->highlight_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ||
(file_selflag & FILE_SEL_SELECTED))
@@ -625,7 +654,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
sx += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
}
- UI_ThemeColor4(TH_TEXT);
+ UI_GetThemeColor4ubv(TH_TEXT, text_col);
if (file_selflag & FILE_SEL_EDITING) {
uiBut *but;
@@ -656,7 +685,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
if (!(file_selflag& FILE_SEL_EDITING)) {
int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight : sy;
- file_draw_string(sx + 1, tpos, file->name, (float)textwidth, textheight, align);
+ file_draw_string(sx + 1, tpos, file->name, (float)textwidth, textheight, align, text_col);
}
sx += (int)layout->column_widths[COLUMN_NAME] + column_space;
@@ -668,7 +697,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
BLI_filelist_entry_size_to_string(NULL, file->entry->size, small_size, file->entry->size_str);
}
file_draw_string(
- sx, sy, file->entry->size_str, layout->column_widths[COLUMN_SIZE], layout->tile_h, align);
+ sx, sy, file->entry->size_str, layout->column_widths[COLUMN_SIZE], layout->tile_h,
+ align, text_col);
}
sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
}
@@ -679,10 +709,12 @@ void file_draw_list(const bContext *C, ARegion *ar)
NULL, file->entry->time, small_size, file->entry->time_str, file->entry->date_str);
}
file_draw_string(
- sx, sy, file->entry->date_str, layout->column_widths[COLUMN_DATE], layout->tile_h, align);
+ sx, sy, file->entry->date_str, layout->column_widths[COLUMN_DATE], layout->tile_h,
+ align, text_col);
sx += (int)layout->column_widths[COLUMN_DATE] + column_space;
file_draw_string(
- sx, sy, file->entry->time_str, layout->column_widths[COLUMN_TIME], layout->tile_h, align);
+ sx, sy, file->entry->time_str, layout->column_widths[COLUMN_TIME], layout->tile_h,
+ align, text_col);
sx += (int)layout->column_widths[COLUMN_TIME] + column_space;
}
else {
@@ -697,7 +729,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
BLI_filelist_entry_size_to_string(NULL, file->entry->size, small_size, file->entry->size_str);
}
file_draw_string(
- sx, sy, file->entry->size_str, layout->column_widths[COLUMN_SIZE], layout->tile_h, align);
+ sx, sy, file->entry->size_str, layout->column_widths[COLUMN_SIZE], layout->tile_h,
+ align, text_col);
}
sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 7abe5ff5070..c2700233cf5 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -228,7 +228,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
if (params->type == FILE_LOADLIB) {
params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0;
params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0;
- params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0;
+ params->flag |= RNA_boolean_get(op->ptr, "active_collection") ? FILE_ACTIVE_COLLECTION : 0;
}
if ((prop = RNA_struct_find_property(op->ptr, "display_type"))) {
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 374db92297d..269b1146ba0 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -291,7 +291,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
}
}
-static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
@@ -333,7 +333,9 @@ static void file_main_region_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
-static void file_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void file_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -597,7 +599,9 @@ static void file_tools_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void file_tools_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void file_tools_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
+ wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
{
#if 0
/* context changes */
@@ -659,7 +663,9 @@ static void file_ui_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
}
-static void file_ui_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void file_ui_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 96a078b2817..e8d033b7a06 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -46,10 +46,12 @@
#include "BKE_curve.h"
#include "BKE_fcurve.h"
-
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "ED_anim_api.h"
#include "graph_intern.h"
@@ -82,38 +84,59 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
FCM_EnvelopeData *fed;
const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
int i;
-
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ glLineWidth(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ immUniform1f("dash_width", 10.0f);
+ immUniform1f("dash_factor", 0.5f);
+
/* draw two black lines showing the standard reference levels */
- glColor3f(0.0f, 0.0f, 0.0f);
- glLineWidth(1);
- setlinestyle(5);
-
- glBegin(GL_LINES);
- glVertex2f(v2d->cur.xmin, env->midval + env->min);
- glVertex2f(v2d->cur.xmax, env->midval + env->min);
-
- glVertex2f(v2d->cur.xmin, env->midval + env->max);
- glVertex2f(v2d->cur.xmax, env->midval + env->max);
- glEnd();
- setlinestyle(0);
-
- /* set size of vertices (non-adjustable for now) */
- glPointSize(2.0f);
-
- /* for now, point color is fixed, and is white */
- glColor3f(1.0f, 1.0f, 1.0f);
-
- glBegin(GL_POINTS);
- for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
- /* only draw if visible
- * - min/max here are fixed, not relative
- */
- if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
- glVertex2f(fed->time, fed->min);
- glVertex2f(fed->time, fed->max);
+
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->min);
+ immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->min);
+
+ immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->max);
+ immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->max);
+ immEnd();
+
+ immUnbindProgram();
+
+ if (env->totvert > 0) {
+ /* set size of vertices (non-adjustable for now) */
+ glPointSize(2.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* for now, point color is fixed, and is white */
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+
+ immBeginAtMost(PRIM_POINTS, env->totvert * 2);
+
+ for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
+ /* only draw if visible
+ * - min/max here are fixed, not relative
+ */
+ if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
+ immVertex2f(shdr_pos, fed->time, fed->min);
+ immVertex2f(shdr_pos, fed->time, fed->max);
+ }
}
+
+ immEnd();
+
+ immUnbindProgram();
}
- glEnd();
}
/* *************************** */
@@ -121,16 +144,37 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
/* Points ---------------- */
-/* helper func - draw keyframe vertices only for an F-Curve */
-static void draw_fcurve_vertices_keyframes(FCurve *fcu, SpaceIpo *UNUSED(sipo), View2D *v2d, short edit, short sel)
+/* helper func - set color to draw F-Curve data with */
+static void set_fcurve_vertex_color(FCurve *fcu, bool sel)
+{
+ /* Fade the 'intensity' of the vertices based on the selection of the curves too */
+ int alphaOffset = (int)((fcurve_display_alpha(fcu) - 1.0f) * 255);
+
+ float color[4];
+
+ /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
+ if ((fcu->flag & FCURVE_PROTECTED) == 0) {
+ /* Curve's points ARE BEING edited */
+ UI_GetThemeColorShadeAlpha4fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, 0, alphaOffset, color);
+ }
+ else {
+ /* Curve's points CANNOT BE edited */
+ UI_GetThemeColorShadeAlpha4fv(sel ? TH_TEXT_HI : TH_TEXT, 0, alphaOffset, color);
+ }
+
+ immUniformColor4fv(color);
+}
+
+static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, bool sel, unsigned pos)
{
- BezTriple *bezt = fcu->bezt;
const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
- int i;
-
- glBegin(GL_POINTS);
-
- for (i = 0; i < fcu->totvert; i++, bezt++) {
+
+ set_fcurve_vertex_color(fcu, sel);
+
+ immBeginAtMost(PRIM_POINTS, fcu->totvert);
+
+ BezTriple *bezt = fcu->bezt;
+ for (int i = 0; i < fcu->totvert; i++, bezt++) {
/* as an optimization step, only draw those in view
* - we apply a correction factor to ensure that points don't pop in/out due to slight twitches of view size
*/
@@ -141,80 +185,50 @@ static void draw_fcurve_vertices_keyframes(FCurve *fcu, SpaceIpo *UNUSED(sipo),
* -
*/
if ((bezt->f2 & SELECT) == sel)
- glVertex3fv(bezt->vec[1]);
+ immVertex2fv(pos, bezt->vec[1]);
}
else {
/* no check for selection here, as curve is not editable... */
/* XXX perhaps we don't want to even draw points? maybe add an option for that later */
- glVertex3fv(bezt->vec[1]);
+ immVertex2fv(pos, bezt->vec[1]);
}
}
}
-
- glEnd();
-}
+ immEnd();
+}
-/* helper func - draw handle vertex for an F-Curve as a round unfilled circle
- * NOTE: the caller MUST HAVE GL_LINE_SMOOTH & GL_BLEND ENABLED, otherwise, the controls don't
- * have a consistent appearance (due to off-pixel alignments)...
- */
-static void draw_fcurve_handle_control(float x, float y, float xscale, float yscale, float hsize)
+/* helper func - draw keyframe vertices only for an F-Curve */
+static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, unsigned pos)
{
- static GLuint displist = 0;
-
- /* initialize round circle shape */
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0, 0.7, 8, 1);
- gluDeleteQuadric(qobj);
-
- glEndList();
- }
-
- /* adjust view transform before starting */
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
-
- /* draw! */
- glCallList(displist);
-
- /* restore view transform */
- glScalef(xscale / hsize, yscale / hsize, 1.0);
- glTranslatef(-x, -y, 0.0f);
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+
+ immUniform1f("size", UI_GetThemeValuef(TH_VERTEX_SIZE) * U.pixelsize);
+
+ draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, false, pos);
+ draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, true, pos);
+
+ immUnbindProgram();
}
+
/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */
-static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2d, short sel, short sel_handle_only, float units_scale)
+static void draw_fcurve_selected_handle_vertices(FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, unsigned pos)
{
- BezTriple *bezt = fcu->bezt;
- BezTriple *prevbezt = NULL;
- float hsize, xscale, yscale;
- int i;
-
- /* get view settings */
- hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
- UI_view2d_scale_get(v2d, &xscale, &yscale);
+ (void) v2d; /* TODO: use this to draw only points in view */
- /* Compensate OGL scale sued for unit mapping, so circle will be circle, not ellipse */
- yscale *= units_scale;
-
/* set handle color */
- if (sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
- else UI_ThemeColor(TH_HANDLE_VERTEX);
-
- /* anti-aliased lines for more consistent appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
-
- for (i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
- /* Draw the editmode handles for a bezier curve (others don't have handles)
+ float hcolor[3];
+ UI_GetThemeColor3fv(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX, hcolor);
+ immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f);
+ immUniformColor3fvAlpha(hcolor, 0.4f);
+
+ immBeginAtMost(PRIM_POINTS, fcu->totvert * 2);
+
+ BezTriple *bezt = fcu->bezt;
+ BezTriple *prevbezt = NULL;
+ for (int i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
+ /* Draw the editmode handles for a bezier curve (others don't have handles)
* if their selection status matches the selection status we're drawing for
* - first handle only if previous beztriple was bezier-mode
* - second handle only if current beztriple is bezier-mode
@@ -225,68 +239,61 @@ static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2
if (!sel_handle_only || BEZT_ISSEL_ANY(bezt)) {
if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
if ((bezt->f1 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax)*/
- draw_fcurve_handle_control(bezt->vec[0][0], bezt->vec[0][1], xscale, yscale, hsize);
+ immVertex2fv(pos, bezt->vec[0]);
}
-
+
if (bezt->ipo == BEZT_IPO_BEZ) {
if ((bezt->f3 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax)*/
- draw_fcurve_handle_control(bezt->vec[2][0], bezt->vec[2][1], xscale, yscale, hsize);
+ immVertex2fv(pos, bezt->vec[2]);
}
}
}
-
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+
+ immEnd();
}
-/* helper func - set color to draw F-Curve data with */
-static void set_fcurve_vertex_color(FCurve *fcu, short sel)
+/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */
+static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handle_only, unsigned pos)
{
- /* Fade the 'intensity' of the vertices based on the selection of the curves too */
- int alphaOffset = (int)((fcurve_display_alpha(fcu) - 1.0f) * 255);
-
- /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
- if ((fcu->flag & FCURVE_PROTECTED) == 0) {
- /* Curve's points ARE BEING edited */
- if (sel) UI_ThemeColorShadeAlpha(TH_VERTEX_SELECT, 0, alphaOffset);
- else UI_ThemeColorShadeAlpha(TH_VERTEX, 0, alphaOffset);
- }
- else {
- /* Curve's points CANNOT BE edited */
- if (sel) UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, alphaOffset);
- else UI_ThemeColorShadeAlpha(TH_TEXT, 0, alphaOffset);
- }
+ /* smooth outlines for more consistent appearance */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+
+ /* set handle size */
+ immUniform1f("size", (UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) + 1.0f) * U.pixelsize);
+ immUniform1f("outlineWidth", 1.0f * U.pixelsize);
+
+ draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos);
+ draw_fcurve_selected_handle_vertices(fcu, v2d, true, sel_handle_only, pos);
+
+ immUnbindProgram();
}
-static void draw_fcurve_vertices(SpaceIpo *sipo, ARegion *ar, FCurve *fcu, short do_handles, short sel_handle_only, float units_scale)
+static void draw_fcurve_vertices(ARegion *ar, FCurve *fcu, bool do_handles, bool sel_handle_only)
{
View2D *v2d = &ar->v2d;
-
+
/* only draw points if curve is visible
- * - draw unselected points before selected points as separate passes to minimize color-changing overhead
- * (XXX dunno if this is faster than drawing all in one pass though)
- * and also to make sure in the case of overlapping points that the selected is always visible
+ * - draw unselected points before selected points as separate passes
+ * to make sure in the case of overlapping points that the selected is always visible
* - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users)
*/
-
- glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ glEnable(GL_BLEND);
+ GPU_enable_program_point_size();
+
/* draw the two handles first (if they're shown, the curve doesn't have just a single keyframe, and the curve is being edited) */
if (do_handles) {
- set_fcurve_vertex_color(fcu, 0);
- draw_fcurve_vertices_handles(fcu, sipo, v2d, 0, sel_handle_only, units_scale);
-
- set_fcurve_vertex_color(fcu, 1);
- draw_fcurve_vertices_handles(fcu, sipo, v2d, 1, sel_handle_only, units_scale);
+ draw_fcurve_handle_vertices(fcu, v2d, sel_handle_only, pos);
}
-
+
/* draw keyframes over the handles */
- set_fcurve_vertex_color(fcu, 0);
- draw_fcurve_vertices_keyframes(fcu, sipo, v2d, !(fcu->flag & FCURVE_PROTECTED), 0);
-
- set_fcurve_vertex_color(fcu, 1);
- draw_fcurve_vertices_keyframes(fcu, sipo, v2d, !(fcu->flag & FCURVE_PROTECTED), 1);
+ draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos);
+
+ GPU_disable_program_point_size();
+ glDisable(GL_BLEND);
}
/* Handles ---------------- */
@@ -303,10 +310,10 @@ static bool draw_fcurve_handles_check(SpaceIpo *sipo, FCurve *fcu)
(fcu->totvert <= 1) /* do not show handles if there is only 1 keyframe, otherwise they all clump together in an ugly ball */
)
{
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
@@ -315,13 +322,10 @@ static bool draw_fcurve_handles_check(SpaceIpo *sipo, FCurve *fcu)
static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
{
int sel, b;
-
- /* a single call to GL_LINES here around these calls should be sufficient to still
- * get separate line segments, but which aren't wrapped with GL_LINE_STRIP every time we
- * want a single line
- */
- glBegin(GL_LINES);
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* slightly hacky, but we want to draw unselected points before selected ones
* so that selected points are clearly visible
*/
@@ -348,18 +352,24 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
UI_GetThemeColor3ubv(basecol + bezt->h1, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp); glVertex2fv(fp + 3);
+ immUniformColor4ubv(col);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, fp);
+ immVertex2fv(pos, fp + 3);
+ immEnd();
}
/* only draw second handle if this segment is bezier */
if (bezt->ipo == BEZT_IPO_BEZ) {
UI_GetThemeColor3ubv(basecol + bezt->h2, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp + 3); glVertex2fv(fp + 6);
+ immUniformColor4ubv(col);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, fp + 3);
+ immVertex2fv(pos, fp + 6);
+ immEnd();
}
}
else {
@@ -370,9 +380,12 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
fp = bezt->vec[0];
UI_GetThemeColor3ubv(basecol + bezt->h1, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp); glVertex2fv(fp + 3);
+ immUniformColor4ubv(col);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, fp);
+ immVertex2fv(pos, fp + 3);
+ immEnd();
}
/* only draw second handle if this segment is bezier, and selection is ok */
@@ -382,15 +395,18 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
fp = bezt->vec[1];
UI_GetThemeColor3ubv(basecol + bezt->h2, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp); glVertex2fv(fp + 3);
+ immUniformColor4ubv(col);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, fp);
+ immVertex2fv(pos, fp + 3);
+ immEnd();
}
}
}
}
-
- glEnd(); /* GL_LINES */
+
+ immUnbindProgram();
}
/* Samples ---------------- */
@@ -399,36 +415,24 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
* NOTE: the caller MUST HAVE GL_LINE_SMOOTH & GL_BLEND ENABLED, otherwise, the controls don't
* have a consistent appearance (due to off-pixel alignments)...
*/
-static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize)
+static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize, unsigned int pos)
{
- static GLuint displist = 0;
-
- /* initialize X shape */
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glBegin(GL_LINES);
- glVertex2f(-0.7f, -0.7f);
- glVertex2f(+0.7f, +0.7f);
-
- glVertex2f(-0.7f, +0.7f);
- glVertex2f(+0.7f, -0.7f);
- glEnd(); /* GL_LINES */
-
- glEndList();
- }
-
/* adjust view transform before starting */
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
-
- /* draw! */
- glCallList(displist);
-
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+ gpuScale2f(1.0f / xscale * hsize, 1.0f / yscale * hsize);
+
+ /* draw X shape */
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, -0.7f, -0.7f);
+ immVertex2f(pos, +0.7f, +0.7f);
+
+ immVertex2f(pos, -0.7f, +0.7f);
+ immVertex2f(pos, +0.7f, -0.7f);
+ immEnd();
+
/* restore view transform */
- glScalef(xscale / hsize, yscale / hsize, 1.0);
- glTranslatef(-x, -y, 0.0f);
+ gpuPopMatrix();
}
/* helper func - draw keyframe vertices only for an F-Curve */
@@ -441,10 +445,6 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
hsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
- /* set vertex color */
- if (fcu->flag & (FCURVE_ACTIVE | FCURVE_SELECTED)) UI_ThemeColor(TH_TEXT_HI);
- else UI_ThemeColor(TH_TEXT);
-
/* get verts */
first = fcu->fpt;
last = (first) ? (first + (fcu->totvert - 1)) : (NULL);
@@ -454,10 +454,17 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* anti-aliased lines for more consistent appearance */
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
-
- draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize);
- draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize);
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor((fcu->flag & FCURVE_SELECTED) ? TH_TEXT_HI : TH_TEXT);
+
+ draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize, pos);
+ draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize, pos);
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
}
@@ -466,7 +473,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* Curve ---------------- */
/* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */
-static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid)
+static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid, unsigned int pos)
{
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
ChannelDriver *driver;
@@ -536,37 +543,50 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
* - apply the unit correction factor to the calculated values so that
* the displayed values appear correctly in the viewport
*/
- glBegin(GL_LINE_STRIP);
-
+
n = (etime - stime) / samplefreq + 0.5f;
- for (i = 0; i <= n; i++) {
- float ctime = stime + i * samplefreq;
- glVertex2f(ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac);
+
+ if (n > 0) {
+ immBegin(PRIM_LINE_STRIP, (n + 1));
+
+ for (i = 0; i <= n; i++) {
+ float ctime = stime + i * samplefreq;
+ immVertex2f(pos, ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac);
+ }
+
+ immEnd();
}
-
- glEnd();
-
+
/* restore driver */
fcu->driver = driver;
}
/* helper func - draw a samples-based F-Curve */
-static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
+static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, const uint shdr_pos)
{
FPoint *prevfpt = fcu->fpt;
FPoint *fpt = prevfpt + 1;
float fac, v[2];
- int b = fcu->totvert - 1;
+ int b = fcu->totvert;
float unit_scale, offset;
short mapping_flag = ANIM_get_normalization_flags(ac);
+ int count = fcu->totvert;
+
+ if (prevfpt->vec[0] > v2d->cur.xmin) {
+ count++;
+ }
+
+ if ((prevfpt + b - 1)->vec[0] < v2d->cur.xmax) {
+ count++;
+ }
/* apply unit mapping */
- glPushMatrix();
+ gpuPushMatrix();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- glScalef(1.0f, unit_scale, 1.0f);
- glTranslatef(0.0f, offset, 0.0f);
+ gpuScale2f(1.0f, unit_scale);
+ gpuTranslate2f(0.0f, offset);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, count);
/* extrapolate to left? - left-side of view comes before first keyframe? */
if (prevfpt->vec[0] > v2d->cur.xmin) {
@@ -584,26 +604,19 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
}
- glVertex2fv(v);
+ immVertex2fv(shdr_pos, v);
}
- /* if only one sample, add it now */
- if (fcu->totvert == 1)
- glVertex2fv(prevfpt->vec);
-
/* loop over samples, drawing segments */
/* draw curve between first and last keyframe (if there are enough to do so) */
while (b--) {
/* Linear interpolation: just add one point (which should add a new line segment) */
- glVertex2fv(prevfpt->vec);
+ immVertex2fv(shdr_pos, prevfpt->vec);
/* get next pointers */
- prevfpt = fpt;
- fpt++;
-
- /* last point? */
- if (b == 0)
- glVertex2fv(prevfpt->vec);
+ if (b > 0) {
+ prevfpt++;
+ }
}
/* extrapolate to right? (see code for left-extrapolation above too) */
@@ -623,11 +636,12 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
}
- glVertex2fv(v);
+ immVertex2fv(shdr_pos, v);
}
- glEnd();
- glPopMatrix();
+ immEnd();
+
+ gpuPopMatrix();
}
/* helper func - check if the F-Curve only contains easily drawable segments
@@ -648,7 +662,7 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
}
/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */
-static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
+static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, unsigned int pos)
{
BezTriple *prevbezt = fcu->bezt;
BezTriple *bezt = prevbezt + 1;
@@ -661,12 +675,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
short mapping_flag = ANIM_get_normalization_flags(ac);
/* apply unit mapping */
- glPushMatrix();
+ gpuPushMatrix();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- glScalef(1.0f, unit_scale, 1.0f);
- glTranslatef(0.0f, offset, 0.0f);
+ gpuScale2f(1.0f, unit_scale);
+ gpuTranslate2f(0.0f, offset);
- glBegin(GL_LINE_STRIP);
+ /* For now, this assumes the worst case scenario, where all the keyframes have
+ * bezier interpolation, and are drawn at full res.
+ * This is tricky to optimize, but maybe can be improved at some point... */
+ immBeginAtMost(PRIM_LINE_STRIP, (b * 32 + 3));
/* extrapolate to left? */
if (prevbezt->vec[1][0] > v2d->cur.xmin) {
@@ -691,14 +708,14 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
}
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
/* if only one keyframe, add it now */
if (fcu->totvert == 1) {
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
/* draw curve between first and last keyframe (if there are enough to do so) */
@@ -708,17 +725,17 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
/* Constant-Interpolation: draw segment between previous keyframe and next, but holding same value */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
v1[0] = bezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
else if (prevbezt->ipo == BEZT_IPO_LIN) {
/* Linear interpolation: just add one point (which should add a new line segment) */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
else if (prevbezt->ipo == BEZT_IPO_BEZ) {
/* Bezier-Interpolation: draw curve as series of segments between keyframes
@@ -738,7 +755,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
/* only draw one */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
else {
/* clamp resolution to max of 32 */
@@ -760,8 +777,9 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
- for (fp = data; resol; resol--, fp += 3)
- glVertex2fv(fp);
+ for (fp = data; resol; resol--, fp += 3) {
+ immVertex2fv(pos, fp);
+ }
}
}
@@ -773,7 +791,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
if (b == 0) {
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
}
@@ -800,11 +818,12 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
}
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
- glEnd();
- glPopMatrix();
+ immEnd();
+
+ gpuPopMatrix();
}
/* Debugging -------------------------------- */
@@ -825,7 +844,16 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
/* for now, only show when debugging driver... */
//if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
// return;
-
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+
/* No curve to modify/visualize the result?
* => We still want to show the 1-1 default...
*/
@@ -833,26 +861,24 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
float t;
/* draw with thin dotted lines in style of what curve would have been */
- glColor3fv(fcu->color);
+ immUniformColor3fv(fcu->color);
- setlinestyle(20);
+ immUniform1f("dash_width", 40.0f);
+ immUniform1f("dash_factor", 0.5f);
glLineWidth(2.0f);
/* draw 1-1 line, stretching just past the screen limits
* NOTE: we need to scale the y-values to be valid for the units
*/
- glBegin(GL_LINES);
- {
- t = v2d->cur.xmin;
- glVertex2f(t, (t + offset) * unitfac);
-
- t = v2d->cur.xmax;
- glVertex2f(t, (t + offset) * unitfac);
- }
- glEnd();
-
- /* cleanup line drawing */
- setlinestyle(0);
+ immBegin(PRIM_LINES, 2);
+
+ t = v2d->cur.xmin;
+ immVertex2f(shdr_pos, t, (t + offset) * unitfac);
+
+ t = v2d->cur.xmax;
+ immVertex2f(shdr_pos, t, (t + offset) * unitfac);
+
+ immEnd();
}
/* draw driver only if actually functional */
@@ -866,53 +892,59 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
float co[2];
/* draw dotted lines leading towards this point from both axes ....... */
- glColor3f(0.9f, 0.9f, 0.9f);
- setlinestyle(5);
-
- glBegin(GL_LINES);
- {
- /* x-axis lookup */
- co[0] = x;
-
- if (y >= v2d->cur.ymin) {
- co[1] = v2d->cur.ymin - 1.0f;
- glVertex2fv(co);
-
- co[1] = y;
- glVertex2fv(co);
- }
-
- /* y-axis lookup */
+ immUniformColor3f(0.9f, 0.9f, 0.9f);
+ immUniform1f("dash_width", 10.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2);
+
+ /* x-axis lookup */
+ co[0] = x;
+
+ if (y >= v2d->cur.ymin) {
+ co[1] = v2d->cur.ymin - 1.0f;
+ immVertex2fv(shdr_pos, co);
+
co[1] = y;
-
- co[0] = v2d->cur.xmin - 1.0f;
- glVertex2fv(co);
-
- co[0] = x;
- glVertex2fv(co);
+ immVertex2fv(shdr_pos, co);
}
- glEnd();
-
- setlinestyle(0);
+
+ /* y-axis lookup */
+ co[1] = y;
+
+ co[0] = v2d->cur.xmin - 1.0f;
+ immVertex2fv(shdr_pos, co);
+
+ co[0] = x;
+ immVertex2fv(shdr_pos, co);
+
+ immEnd();
+ immUnbindProgram();
+
+ /* PRIM_POINTS do not survive dashed line geometry shader... */
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* x marks the spot .................................................... */
/* -> outer frame */
- glColor3f(0.9f, 0.9f, 0.9f);
+ immUniformColor3f(0.9f, 0.9f, 0.9f);
glPointSize(7.0);
- glBegin(GL_POINTS);
- glVertex2f(x, y);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, x, y);
+ immEnd();
/* inner frame */
- glColor3f(0.9f, 0.0f, 0.0f);
+ immUniformColor3f(0.9f, 0.0f, 0.0f);
glPointSize(3.0);
- glBegin(GL_POINTS);
- glVertex2f(x, y);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, x, y);
+ immEnd();
}
}
+
+ immUnbindProgram();
}
/* Public Curve-Drawing API ---------------- */
@@ -925,29 +957,43 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
FCurve *fcu;
/* draw with thick dotted lines */
- setlinestyle(10);
glLineWidth(3.0f);
/* anti-aliased lines for less jagged appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glEnable(GL_LINE_SMOOTH);
+ }
glEnable(GL_BLEND);
-
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniform1f("dash_width", 20.0f);
+ immUniform1f("dash_factor", 0.5f);
+
/* the ghost curves are simply sampled F-Curves stored in sipo->ghostCurves */
for (fcu = sipo->ghostCurves.first; fcu; fcu = fcu->next) {
/* set whatever color the curve has set
* - this is set by the function which creates these
* - draw with a fixed opacity of 2
*/
- glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], 0.5f);
+ immUniformColor3fvAlpha(fcu->color, 0.5f);
/* simply draw the stored samples */
- draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d);
+ draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d, shdr_pos);
+ }
+
+ immUnbindProgram();
+
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glDisable(GL_LINE_SMOOTH);
}
-
- /* restore settings */
- setlinestyle(0);
-
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
@@ -975,9 +1021,10 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
/* map keyframes for drawing if scaled F-Curve */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
-
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ }
+
/* draw curve:
* - curve line may be result of one or more destructive modifiers or just the raw data,
* so we need to check which method should be used
@@ -986,60 +1033,82 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
*/
/* 1) draw curve line */
+ if (((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) ||
+ (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)))
{
/* set color/drawing style for curve itself */
+ /* draw active F-Curve thicker than the rest to make it stand out */
+ if (fcu->flag & FCURVE_ACTIVE) {
+ glLineWidth(2.0);
+ }
+ else {
+ glLineWidth(1.0);
+ }
+
+ /* anti-aliased lines for less jagged appearance */
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glEnable(GL_LINE_SMOOTH);
+ }
+ glEnable(GL_BLEND);
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+
if (BKE_fcurve_is_protected(fcu)) {
/* protected curves (non editable) are drawn with dotted lines */
- setlinestyle(2);
+ immUniform1f("dash_width", 4.0f);
+ immUniform1f("dash_factor", 0.5f);
+ }
+ else {
+ immUniform1f("dash_factor", 2.0f); /* solid line */
}
+
if (((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) || (fcu->flag & FCURVE_MUTED)) {
/* muted curves are drawn in a grayish hue */
/* XXX should we have some variations? */
- UI_ThemeColorShade(TH_HEADER, 50);
+ immUniformThemeColorShade(TH_HEADER, 50);
}
else {
- /* set whatever color the curve has set
+ /* set whatever color the curve has set
* - unselected curves draw less opaque to help distinguish the selected ones
*/
- glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], fcurve_display_alpha(fcu));
+ immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu));
}
-
- /* draw active F-Curve thicker than the rest to make it stand out */
- if (fcu->flag & FCURVE_ACTIVE) {
- glLineWidth(2.0);
- }
- else {
- glLineWidth(1.0);
- }
-
- /* anti-aliased lines for less jagged appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
-
+
/* draw F-Curve */
if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
/* draw a curve affected by modifiers or only allowed to have integer values
* by sampling it at various small-intervals over the visible region
*/
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid);
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
}
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
/* just draw curve based on defined data (i.e. no modifiers) */
if (fcu->bezt) {
- if (fcurve_can_use_simple_bezt_drawing(fcu))
- draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
- else
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid);
+ if (fcurve_can_use_simple_bezt_drawing(fcu)) {
+ draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d, shdr_pos);
+ }
+ else {
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
+ }
}
else if (fcu->fpt) {
- draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d);
+ draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d, shdr_pos);
}
}
-
- /* restore settings */
- setlinestyle(0);
-
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
+
+ immUnbindProgram();
+
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glDisable(GL_LINE_SMOOTH);
+ }
glDisable(GL_BLEND);
}
@@ -1047,7 +1116,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
* - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
*/
if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
- if (fcurve_are_keyframes_usable(fcu) == 0) {
+ if (!fcurve_are_keyframes_usable(fcu) && !(fcu->fpt && fcu->totvert)) {
/* only draw controls if this is the active modifier */
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
switch (fcm->type) {
@@ -1063,9 +1132,9 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
/* apply unit-scaling to all values via OpenGL */
- glPushMatrix();
- glScalef(1.0f, unit_scale, 1.0f);
- glTranslatef(0.0f, offset, 0.0f);
+ gpuPushMatrix();
+ gpuScale2f(1.0f, unit_scale);
+ gpuTranslate2f(0.0f, offset);
/* set this once and for all - all handles and handle-verts should use the same thickness */
glLineWidth(1.0);
@@ -1080,14 +1149,14 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
glDisable(GL_BLEND);
}
- draw_fcurve_vertices(sipo, ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY), unit_scale);
+ draw_fcurve_vertices(ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY));
}
else {
/* samples: only draw two indicators at either end as indicators */
draw_fcurve_samples(sipo, ar, fcu);
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index f12db310856..980ee5aeffe 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -53,7 +53,7 @@
#include "ED_anim_api.h"
#include "ED_markers.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -265,43 +265,52 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
/* only free grid after drawing data, as we need to use it to determine sampling rate */
UI_view2d_grid_free(grid);
-
- /* horizontal component of value-cursor (value line before the current frame line) */
- if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
- float y = sipo->cursorVal;
-
- /* Draw a green line to indicate the cursor value */
- UI_ThemeColorShadeAlpha(TH_CFRAME, -10, -50);
- glEnable(GL_BLEND);
- glLineWidth(2.0);
+ if (((sipo->flag & SIPO_NODRAWCURSOR) == 0) || (sipo->mode == SIPO_MODE_DRIVERS)) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- glBegin(GL_LINES);
- glVertex2f(v2d->cur.xmin, y);
- glVertex2f(v2d->cur.xmax, y);
- glEnd();
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glDisable(GL_BLEND);
- }
-
- /* current frame or vertical component of vertical component of the cursor */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- /* cursor x-value */
- float x = sipo->cursorTime;
-
- /* to help differentiate this from the current frame, draw slightly darker like the horizontal one */
- UI_ThemeColorShadeAlpha(TH_CFRAME, -40, -50);
- glEnable(GL_BLEND);
- glLineWidth(2.0);
-
- glBegin(GL_LINES);
- glVertex2f(x, v2d->cur.ymin);
- glVertex2f(x, v2d->cur.ymax);
- glEnd();
+ /* horizontal component of value-cursor (value line before the current frame line) */
+ if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
+
+ float y = sipo->cursorVal;
+
+ /* Draw a green line to indicate the cursor value */
+ immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50);
+ glEnable(GL_BLEND);
+ glLineWidth(2.0);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, v2d->cur.xmin, y);
+ immVertex2f(pos, v2d->cur.xmax, y);
+ immEnd();
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
+ }
+
+ /* current frame or vertical component of vertical component of the cursor */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ /* cursor x-value */
+ float x = sipo->cursorTime;
+
+ /* to help differentiate this from the current frame, draw slightly darker like the horizontal one */
+ immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50);
+ glEnable(GL_BLEND);
+ glLineWidth(2.0);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, x, v2d->cur.ymin);
+ immVertex2f(pos, x, v2d->cur.ymax);
+ immEnd();
+
+ glDisable(GL_BLEND);
+ }
+
+ immUnbindProgram();
}
- else {
+
+ if (sipo->mode != SIPO_MODE_DRIVERS) {
/* current frame */
if (sipo->flag & SIPO_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS;
if ((sipo->flag & SIPO_NODRAWCFRANUM) == 0) flag |= DRAWCFRA_SHOW_NUMBOX;
@@ -404,7 +413,9 @@ static void graph_buttons_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void graph_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -459,7 +470,7 @@ static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg
}
/* editor level listener */
-static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index c60d194b620..0bc09981ba5 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -25,6 +25,7 @@ set(INC
../../blenlib
../../blentranslation
../../bmesh
+ ../../depsgraph
../../imbuf
../../gpu
../../makesdna
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index e810f4db7dd..259dc124d37 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -60,9 +60,12 @@
#include "BKE_image.h"
#include "BKE_paint.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
#include "BLF_api.h"
#include "ED_gpencil.h"
@@ -87,7 +90,6 @@ static void draw_render_info(const bContext *C,
float zoomx,
float zoomy)
{
- RenderResult *rr;
Render *re = RE_GetRender(scene->id.name);
RenderData *rd = RE_engine_get_render_data(re);
Scene *stats_scene = ED_render_job_get_scene(C);
@@ -95,7 +97,7 @@ static void draw_render_info(const bContext *C,
stats_scene = CTX_data_scene(C);
}
- rr = BKE_image_acquire_renderresult(stats_scene, ima);
+ RenderResult *rr = BKE_image_acquire_renderresult(stats_scene, ima);
if (rr && rr->text) {
float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
@@ -107,39 +109,41 @@ static void draw_render_info(const bContext *C,
if (re) {
int total_tiles;
bool need_free_tiles;
- rcti *tiles;
-
- tiles = RE_engine_get_current_tiles(re, &total_tiles, &need_free_tiles);
+ rcti *tiles = RE_engine_get_current_tiles(re, &total_tiles, &need_free_tiles);
if (total_tiles) {
- int i, x, y;
- rcti *tile;
-
/* find window pixel coordinates of origin */
+ int x, y;
UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
- glPushMatrix();
- glTranslatef(x, y, 0.0f);
- glScalef(zoomx, zoomy, 1.0f);
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+ gpuScale2f(zoomx, zoomy);
if (rd->mode & R_BORDER) {
- glTranslatef((int)(-rd->border.xmin * rd->xsch * rd->size / 100.0f),
- (int)(-rd->border.ymin * rd->ysch * rd->size / 100.0f),
- 0.0f);
+ /* TODO: round or floor instead of casting to int */
+ gpuTranslate2f((int)(-rd->border.xmin * rd->xsch * rd->size * 0.01f),
+ (int)(-rd->border.ymin * rd->ysch * rd->size * 0.01f));
}
- UI_ThemeColor(TH_FACE_SELECT);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_FACE_SELECT);
glLineWidth(1.0f);
- for (i = 0, tile = tiles; i < total_tiles; i++, tile++) {
- glaDrawBorderCorners(tile, zoomx, zoomy);
+
+ rcti *tile = tiles;
+ for (int i = 0; i < total_tiles; i++, tile++) {
+ immDrawBorderCorners(pos, tile, zoomx, zoomy);
}
+ immUnbindProgram();
+
if (need_free_tiles) {
MEM_freeN(tiles);
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -169,28 +173,34 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* noisy, high contrast make impossible to read if lower alpha is used. */
- glColor4ub(0, 0, 0, 190);
- glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, UI_UNIT_Y);
+ immUniformColor4ub(0, 0, 0, 190);
+ immRecti(pos, 0, 0, BLI_rcti_size_x(&ar->winrct) + 1, UI_UNIT_Y);
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi);
- glColor3ub(255, 255, 255);
+ BLF_color3ub(blf_mono_font, 255, 255, 255);
BLI_snprintf(str, sizeof(str), "X:%-4d Y:%-4d |", x, y);
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
if (zp) {
- glColor3ub(255, 255, 255);
+ BLF_color3ub(blf_mono_font, 255, 255, 255);
BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff));
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
}
if (zpf) {
- glColor3ub(255, 255, 255);
+ BLF_color3ub(blf_mono_font, 255, 255, 255);
BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
@@ -204,14 +214,14 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
else if (cp != NULL) {
BLI_snprintf(str, sizeof(str), " Val:%-.3f |", cp[0] / 255.0f);
}
- glColor3ub(255, 255, 255);
+ BLF_color3ub(blf_mono_font, 255, 255, 255);
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
}
if (channels >= 3) {
- glColor3ubv(red);
+ BLF_color3ubv(blf_mono_font, red);
if (fp)
BLI_snprintf(str, sizeof(str), " R:%-.5f", fp[0]);
else if (cp)
@@ -222,7 +232,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
- glColor3ubv(green);
+ BLF_color3ubv(blf_mono_font, green);
if (fp)
BLI_snprintf(str, sizeof(str), " G:%-.5f", fp[1]);
else if (cp)
@@ -233,7 +243,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
- glColor3ubv(blue);
+ BLF_color3ubv(blf_mono_font, blue);
if (fp)
BLI_snprintf(str, sizeof(str), " B:%-.5f", fp[2]);
else if (cp)
@@ -245,7 +255,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
dx += BLF_width(blf_mono_font, str, sizeof(str));
if (channels == 4) {
- glColor3ub(255, 255, 255);
+ BLF_color3ub(blf_mono_font, 255, 255, 255);
if (fp)
BLI_snprintf(str, sizeof(str), " A:%-.4f", fp[3]);
else if (cp)
@@ -267,9 +277,9 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
rgba[3] = linearcol[3];
if (use_default_view)
- IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, NULL, &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, NULL, &scene->display_settings);
else
- IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, &scene->view_settings, &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, &scene->view_settings, &scene->display_settings);
BLI_snprintf(str, sizeof(str), " | CM R:%-.4f G:%-.4f B:%-.4f", rgba[0], rgba[1], rgba[2]);
BLF_position(blf_mono_font, dx, dy, 0);
@@ -305,9 +315,9 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
if (color_manage) {
if (use_default_view)
- IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, NULL, &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, NULL, &scene->display_settings);
else
- IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, &scene->view_settings, &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, &scene->view_settings, &scene->display_settings);
}
else {
copy_v4_v4(finalcol, col);
@@ -318,13 +328,18 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y);
+ /* BLF uses immediate mode too, so we must reset our vertex format */
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
if (channels == 4) {
rcti color_rect_half;
int color_quater_x, color_quater_y;
color_rect_half = color_rect;
color_rect_half.xmax = BLI_rcti_cent_x(&color_rect);
- glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
+ /* what color ??? */
+ immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
color_rect_half = color_rect;
color_rect_half.xmin = BLI_rcti_cent_x(&color_rect);
@@ -332,31 +347,34 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
color_quater_x = BLI_rcti_cent_x(&color_rect_half);
color_quater_y = BLI_rcti_cent_y(&color_rect_half);
- glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255);
- glRecti(color_rect_half.xmin, color_rect_half.ymin, color_rect_half.xmax, color_rect_half.ymax);
+ immUniformColor3ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK);
+ immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_rect_half.xmax, color_rect_half.ymax);
- glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255);
- glRecti(color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax);
- glRecti(color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y);
+ immUniformColor3ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT);
+ immRecti(pos, color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax);
+ immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(UNPACK3(finalcol), fp ? fp[3] : (cp[3] / 255.0f));
- glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
+ immUniformColor3fvAlpha(finalcol, fp ? fp[3] : (cp[3] / 255.0f));
+ immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
glDisable(GL_BLEND);
}
else {
- glColor3fv(finalcol);
- glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
+ immUniformColor3fv(finalcol);
+ immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
}
+ immUnbindProgram();
/* draw outline */
- glColor3ub(128, 128, 128);
- sdrawbox(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ub(128, 128, 128);
+ imm_draw_line_box(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
+ immUnbindProgram();
dx += 1.75f * UI_UNIT_X;
- glColor3ub(255, 255, 255);
+ BLF_color3ub(blf_mono_font, 255, 255, 255);
if (channels == 1) {
if (fp) {
rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
@@ -375,7 +393,6 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLI_snprintf(str, sizeof(str), " L:%-.4f", lum);
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
- dx += BLF_width(blf_mono_font, str, sizeof(str));
}
else if (channels >= 3) {
rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val);
@@ -399,70 +416,37 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLI_snprintf(str, sizeof(str), " L:%-.4f", lum);
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
- dx += BLF_width(blf_mono_font, str, sizeof(str));
}
-
- (void)dx;
}
/* image drawing */
-
-static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti)
+static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *rect,
+ float zoomx, float zoomy)
{
-
- /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
- if (ENDIAN_ORDER == B_ENDIAN)
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
- glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_UNSIGNED_INT, recti);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
-}
+ /* Slowwww */
+ int *recti = MEM_mallocN(rectx * recty * sizeof(int), "temp");
+ for (int a = rectx * recty - 1; a >= 0; a--) {
+ /* zbuffer values are signed, so we need to shift color range */
+ recti[a] = rect[a] * 0.5f + 0.5f;
+ }
-static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, float *rectf)
-{
- float *trectf = MEM_mallocN(rectx * recty * 4, "temp");
- int a, b;
-
- for (a = rectx * recty - 1, b = 4 * a + 3; a >= 0; a--, b -= 4)
- trectf[a] = rectf[b];
-
- glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, trectf);
- MEM_freeN(trectf);
- /* ogl trick below is slower... (on ATI 9600) */
-// glColorMask(1, 0, 0, 0);
-// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf + 3);
-// glColorMask(0, 1, 0, 0);
-// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf + 2);
-// glColorMask(0, 0, 1, 0);
-// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf + 1);
-// glColorMask(1, 1, 1, 1);
-}
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
-static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti)
-{
- /* zbuffer values are signed, so we need to shift color range */
- glPixelTransferf(GL_RED_SCALE, 0.5f);
- glPixelTransferf(GL_GREEN_SCALE, 0.5f);
- glPixelTransferf(GL_BLUE_SCALE, 0.5f);
- glPixelTransferf(GL_RED_BIAS, 0.5f);
- glPixelTransferf(GL_GREEN_BIAS, 0.5f);
- glPixelTransferf(GL_BLUE_BIAS, 0.5f);
-
- glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_INT, recti);
-
- glPixelTransferf(GL_RED_SCALE, 1.0f);
- glPixelTransferf(GL_GREEN_SCALE, 1.0f);
- glPixelTransferf(GL_BLUE_SCALE, 1.0f);
- glPixelTransferf(GL_RED_BIAS, 0.0f);
- glPixelTransferf(GL_GREEN_BIAS, 0.0f);
- glPixelTransferf(GL_BLUE_BIAS, 0.0f);
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_RED, GL_INT, GL_NEAREST, recti, zoomx, zoomy, NULL);
+
+ MEM_freeN(recti);
}
-static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rectx, int recty, float *rect_float)
+static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rectx, int recty,
+ float *rect_float, float zoomx, float zoomy)
{
float bias, scale, *rectf, clipend;
int a;
-
+ float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+
if (scene->camera && scene->camera->type == OB_CAMERA) {
bias = ((Camera *)scene->camera->data)->clipsta;
clipend = ((Camera *)scene->camera->data)->clipend;
@@ -473,8 +457,8 @@ static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rec
scale = 0.01f;
clipend = 100.0f;
}
-
- rectf = MEM_mallocN(rectx * recty * 4, "temp");
+
+ rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp");
for (a = rectx * recty - 1; a >= 0; a--) {
if (rect_float[a] > clipend)
rectf[a] = 0.0f;
@@ -485,92 +469,85 @@ static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rec
rectf[a] *= rectf[a];
}
}
- glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, rectf);
-
- MEM_freeN(rectf);
-}
-static int draw_image_channel_offset(SpaceImage *sima)
-{
-#ifdef __BIG_ENDIAN__
- if (sima->flag & SI_SHOW_R) return 0;
- else if (sima->flag & SI_SHOW_G) return 1;
- else return 2;
-#else
- if (sima->flag & SI_SHOW_R) return 1;
- else if (sima->flag & SI_SHOW_G) return 2;
- else return 3;
-#endif
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
+
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_RED, GL_FLOAT, GL_NEAREST, rectf, zoomx, zoomy, NULL);
+
+ MEM_freeN(rectf);
}
static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
{
int x, y;
- /* set zoom */
- glPixelZoom(zoomx, zoomy);
-
glaDefine2DArea(&ar->winrct);
/* find window pixel coordinates of origin */
UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y);
/* this part is generic image display */
- if (sima->flag & SI_SHOW_ALPHA) {
- if (ibuf->rect)
- sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect);
- else if (ibuf->rect_float && ibuf->channels == 4)
- sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float);
- }
- else if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
+ if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
if (ibuf->zbuf)
- sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf);
+ sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf, zoomx, zoomy);
else if (ibuf->zbuf_float)
- sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float);
+ sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float, zoomx, zoomy);
else if (ibuf->channels == 1)
- sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float);
+ sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float, zoomx, zoomy);
}
else {
+ int clip_max_x, clip_max_y;
+ UI_view2d_view_to_region(&ar->v2d,
+ ar->v2d.cur.xmax, ar->v2d.cur.ymax,
+ &clip_max_x, &clip_max_y);
+
if (sima->flag & SI_USE_ALPHA) {
+ imm_draw_checker_box(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
}
- if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) == 0) {
- int clip_max_x, clip_max_y;
- UI_view2d_view_to_region(&ar->v2d,
- ar->v2d.cur.xmax, ar->v2d.cur.ymax,
- &clip_max_x, &clip_max_y);
+ /* If RGBA display with color management */
+ if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
+
glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, GL_NEAREST,
- 0, 0, clip_max_x, clip_max_y);
+ 0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
}
else {
+ float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
unsigned char *display_buffer;
void *cache_handle;
-
- /* TODO(sergey): Ideally GLSL shading should be capable of either
- * disabling some channels or displaying buffer with custom offset.
- */
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
- if (display_buffer != NULL) {
- int channel_offset = draw_image_channel_offset(sima);
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT,
- display_buffer - (4 - channel_offset));
- }
- if (cache_handle != NULL) {
- IMB_display_buffer_release(cache_handle);
+ ColorManagedViewSettings *view_settings;
+ ColorManagedDisplaySettings *display_settings;
+
+ if (sima->flag & SI_SHOW_R)
+ shuffle[0] = 1.0f;
+ else if (sima->flag & SI_SHOW_G)
+ shuffle[1] = 1.0f;
+ else if (sima->flag & SI_SHOW_B)
+ shuffle[2] = 1.0f;
+ else if (sima->flag & SI_SHOW_ALPHA)
+ shuffle[3] = 1.0f;
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, shuffle);
+
+ IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
+ display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);
+
+ if (display_buffer) {
+ immDrawPixelsTex_clipping(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer,
+ 0, 0, clip_max_x, clip_max_y, zoomx, zoomy, NULL);
}
+
+ IMB_display_buffer_release(cache_handle);
}
if (sima->flag & SI_USE_ALPHA)
glDisable(GL_BLEND);
}
-
- /* reset zoom */
- glPixelZoom(1.0f, 1.0f);
}
static unsigned int *get_part_from_buffer(unsigned int *buffer, int width, short startx, short starty, short endx, short endy)
@@ -601,7 +578,7 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
unsigned int *rect;
int dx, dy, sx, sy, x, y;
void *cache_handle;
- int channel_offset = -1;
+ float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* verify valid values, just leave this a while */
if (ima->xrep < 1) return;
@@ -615,8 +592,6 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
if (!display_buffer)
return;
- glPixelZoom(zoomx, zoomy);
-
if (sima->curtile >= ima->xrep * ima->yrep)
sima->curtile = ima->xrep * ima->yrep - 1;
@@ -628,24 +603,34 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
rect = get_part_from_buffer((unsigned int *)display_buffer, ibuf->x, sx, sy, sx + dx, sy + dy);
/* draw repeated */
- if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) != 0) {
- channel_offset = draw_image_channel_offset(sima);
+ if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) != 0) {
+ if (sima->flag & SI_SHOW_R)
+ shuffle[0] = 1.0f;
+ else if (sima->flag & SI_SHOW_G)
+ shuffle[1] = 1.0f;
+ else if (sima->flag & SI_SHOW_B)
+ shuffle[2] = 1.0f;
+ else if (sima->flag & SI_SHOW_ALPHA)
+ shuffle[3] = 1.0f;
}
+
for (sy = 0; sy + dy <= ibuf->y; sy += dy) {
for (sx = 0; sx + dx <= ibuf->x; sx += dx) {
UI_view2d_view_to_region(&ar->v2d, fx + (float)sx / (float)ibuf->x, fy + (float)sy / (float)ibuf->y, &x, &y);
- if (channel_offset == -1) {
- glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+
+ if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, x, y, dx, dy, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect, zoomx, zoomy, NULL);
}
else {
- glaDrawPixelsSafe(x, y, dx, dy, dx, GL_LUMINANCE, GL_UNSIGNED_INT,
- (unsigned char *)rect - (4 - channel_offset));
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, shuffle);
+
+ immDrawPixelsTex(&state, x, y, dx, dy, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect, zoomx, zoomy, NULL);
}
}
}
- glPixelZoom(1.0f, 1.0f);
-
IMB_display_buffer_release(cache_handle);
MEM_freeN(rect);
@@ -701,134 +686,62 @@ void draw_image_sample_line(SpaceImage *sima)
if (sima->sample_line_hist.flag & HISTO_FLAG_SAMPLELINE) {
Histogram *hist = &sima->sample_line_hist;
- glBegin(GL_LINES);
- glColor3ub(0, 0, 0);
- glVertex2fv(hist->co[0]);
- glVertex2fv(hist->co[1]);
- glEnd();
-
- setlinestyle(1);
- glBegin(GL_LINES);
- glColor3ub(255, 255, 255);
- glVertex2fv(hist->co[0]);
- glVertex2fv(hist->co[1]);
- glEnd();
- setlinestyle(0);
-
- }
-}
-
-/* XXX becomes WM paint cursor */
-#if 0
-static void draw_image_view_tool(Scene *scene)
-{
- ToolSettings *settings = scene->toolsettings;
- Brush *brush = settings->imapaint.brush;
- int mval[2];
- float radius;
- int draw = 0;
-
- if (brush) {
- if (settings->imapaint.flag & IMAGEPAINT_DRAWING) {
- if (settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL_DRAWING)
- draw = 1;
- }
- else if (settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL)
- draw = 1;
-
- if (draw) {
- getmouseco_areawin(mval);
-
- radius = BKE_brush_size_get(brush) * G.sima->zoom;
- fdrawXORcirc(mval[0], mval[1], radius);
-
- if (brush->innerradius != 1.0) {
- radius *= brush->innerradius;
- fdrawXORcirc(mval[0], mval[1], radius);
- }
- }
- }
-}
-#endif
-
-static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int *width, int *height)
-{
- Brush *brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint);
- ImBuf *ibuf;
- unsigned int size, alpha;
- unsigned char *display_buffer;
- unsigned char *rect, *cp;
- void *cache_handle;
-
- if (!brush || !brush->clone.image)
- return NULL;
-
- ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL);
-
- if (!ibuf)
- return NULL;
-
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+ VertexFormat *format = immVertexFormat();
+ unsigned int shdr_dashed_pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
- if (!display_buffer) {
- BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
- IMB_display_buffer_release(cache_handle);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
- return NULL;
- }
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- rect = MEM_dupallocN(display_buffer);
+ immUniform1i("num_colors", 2); /* Advanced dashes. */
+ immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 2.0f);
- IMB_display_buffer_release(cache_handle);
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(shdr_dashed_pos, hist->co[0]);
+ immVertex2fv(shdr_dashed_pos, hist->co[1]);
+ immEnd();
- if (!rect) {
- BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
- return NULL;
+ immUnbindProgram();
}
-
- *width = ibuf->x;
- *height = ibuf->y;
-
- size = (*width) * (*height);
- alpha = (unsigned char)255 * brush->clone.alpha;
- cp = rect;
-
- while (size-- > 0) {
- cp[3] = alpha;
- cp += 4;
- }
-
- BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
-
- return rect;
}
static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scene, float zoomx, float zoomy)
{
Brush *brush;
- int x, y, w, h;
- unsigned char *clonerect;
+ int x, y;
+ ImBuf *ibuf;
brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint);
- if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE)) {
- /* this is not very efficient, but glDrawPixels doesn't allow
- * drawing with alpha */
- clonerect = get_alpha_clone_image(C, scene, &w, &h);
+ if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE) && brush->clone.image) {
+ ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL);
- if (clonerect) {
+ if (ibuf) {
+ void *cache_handle = NULL;
+ float col[4] = {1.0f, 1.0f, 1.0f, brush->clone.alpha};
UI_view2d_view_to_region(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
- glPixelZoom(zoomx, zoomy);
+ unsigned char *display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+
+ if (!display_buffer) {
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
+ IMB_display_buffer_release(cache_handle);
+ return;
+ }
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, clonerect);
- glDisable(GL_BLEND);
- glPixelZoom(1.0, 1.0);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer, zoomx, zoomy, col);
- MEM_freeN(clonerect);
+ glDisable(GL_BLEND);
+
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
+ IMB_display_buffer_release(cache_handle);
}
}
}
@@ -924,23 +837,6 @@ void draw_image_main(const bContext *C, ARegion *ar)
if (show_paint)
draw_image_paint_helpers(C, ar, scene, zoomx, zoomy);
- /* XXX integrate this code */
-#if 0
- if (ibuf) {
- float xoffs = 0.0f, yoffs = 0.0f;
-
- if (image_preview_active(sa, &xim, &yim)) {
- xoffs = scene->r.disprect.xmin;
- yoffs = scene->r.disprect.ymin;
- glColor3ub(0, 0, 0);
- calc_image_view(sima, 'f');
- myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
- glRectf(0.0f, 0.0f, 1.0f, 1.0f);
- glLoadIdentity();
- }
- }
-#endif
-
if (show_viewer) {
BLI_unlock_thread(LOCK_DRAW_IMAGE);
}
@@ -1002,8 +898,12 @@ void draw_image_cache(const bContext *C, ARegion *ar)
/* Draw current frame. */
x = (cfra - sfra) / (efra - sfra + 1) * ar->winx;
- UI_ThemeColor(TH_CFRAME);
- glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CFRAME);
+ immRecti(pos, x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
+ immUnbindProgram();
+
ED_region_cache_draw_curfra_label(cfra, x, 8.0f * UI_DPI_FAC);
if (mask != NULL) {
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 8f2f6595408..a3a115b3e6a 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -365,7 +365,7 @@ bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool ret;
- ret = EDBM_mtexpoly_check(em);
+ ret = EDBM_uv_check(em);
return ret;
}
@@ -374,10 +374,10 @@ bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
}
/* matches clip function */
-bool ED_space_image_check_show_maskedit(Scene *scene, SpaceImage *sima)
+bool ED_space_image_check_show_maskedit(SceneLayer *sl, SpaceImage *sima)
{
/* check editmode - this is reserved for UV editing */
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
if (ob && ob->mode & OB_MODE_EDIT && ED_space_image_show_uvedit(sima, ob)) {
return false;
}
@@ -390,8 +390,8 @@ int ED_space_image_maskedit_poll(bContext *C)
SpaceImage *sima = CTX_wm_space_image(C);
if (sima) {
- Scene *scene = CTX_data_scene(C);
- return ED_space_image_check_show_maskedit(scene, sima);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ return ED_space_image_check_show_maskedit(sl, sima);
}
return false;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index c2cfca295a4..69597a390d6 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -792,6 +792,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
SpaceImage *sima;
ARegion *ar;
Scene *scene;
+ SceneLayer *sl;
Object *obedit;
Image *ima;
@@ -799,6 +800,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
sima = CTX_wm_space_image(C);
ar = CTX_wm_region(C);
scene = CTX_data_scene(C);
+ sl = CTX_data_scene_layer(C);
obedit = CTX_data_edit_object(C);
ima = ED_space_image(sima);
@@ -810,7 +812,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
}
- else if (ED_space_image_check_show_maskedit(scene, sima)) {
+ else if (ED_space_image_check_show_maskedit(sl, sima)) {
if (!ED_mask_selected_minmax(C, min, max)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 6ddf78290aa..baa1dcdffd9 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -44,10 +44,15 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
+#include "BKE_editmesh.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_material.h"
+
+#include "DEG_depsgraph.h"
#include "IMB_imbuf_types.h"
@@ -422,27 +427,23 @@ static void image_refresh(const bContext *C, ScrArea *sa)
}
else {
/* old shading system, we set texface */
- MTexPoly *tf;
-
- if (em && EDBM_mtexpoly_check(em)) {
- tf = EDBM_mtexpoly_active_get(em, NULL, sloppy, selected);
+ if (em && EDBM_uv_check(em)) {
+ BMFace *efa = BM_mesh_active_face_get(em->bm, sloppy, selected);
- if (tf) {
+ if (efa) {
/* don't need to check for pin here, see above */
- sima->image = tf->tpage;
-
- if ((sima->flag & SI_EDITTILE) == 0) {
- sima->curtile = tf->tile;
- }
+ Image *image = BKE_object_material_edit_image_get(obedit, efa->mat_nr);
+
+ sima->image = image;
}
}
}
}
}
-static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
+static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *scene)
{
- Scene *scene = sc->scene;
+ SceneLayer *sl = BKE_scene_layer_context_active(scene);
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
/* context changes */
@@ -535,7 +536,7 @@ static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
case ND_TRANSFORM:
case ND_MODIFIER:
{
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
ED_area_tag_refresh(sa);
@@ -684,9 +685,11 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
SpaceImage *sima = CTX_wm_space_image(C);
Object *obact = CTX_data_active_object(C);
Object *obedit = CTX_data_edit_object(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
Mask *mask = NULL;
bool curve = false;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
View2D *v2d = &ar->v2d;
//View2DScrollers *scrollers;
float col[3];
@@ -722,7 +725,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
- ED_uvedit_draw_main(sima, ar, scene, obedit, obact);
+ ED_uvedit_draw_main(sima, ar, scene, sl, obedit, obact, depsgraph);
/* check for mask (delay draw) */
if (ED_space_image_show_uvedit(sima, obedit)) {
@@ -801,7 +804,9 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
#endif
}
-static void image_main_region_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, wmNotifier *wmn)
+static void image_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -845,7 +850,9 @@ static void image_buttons_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void image_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void image_buttons_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -918,7 +925,9 @@ static void image_tools_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void image_tools_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void image_tools_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -964,7 +973,9 @@ static void image_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void image_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void image_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 8dc6c4229b2..bd1bdb952d6 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -49,6 +49,7 @@
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_editmesh.h"
@@ -271,7 +272,7 @@ static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
{
- if (base->flag & SELECT) stats->totobjsel++;
+ if (base->flag & BASE_SELECTED) stats->totobjsel++;
if (ob->transflag & OB_DUPLIPARTS) {
/* Dupli Particles */
@@ -300,7 +301,7 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
}
}
- stats_object(ob, base->flag & SELECT, 1, stats);
+ stats_object(ob, base->flag_legacy & SELECT, 1, stats);
stats->totobj++;
}
else if (ob->parent && (ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES))) {
@@ -316,23 +317,23 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
}
stats->totobj += tot;
- stats_object(ob, base->flag & SELECT, tot, stats);
+ stats_object(ob, base->flag_legacy & SELECT, tot, stats);
}
else if (ob->transflag & OB_DUPLIFRAMES) {
/* Dupli Frames */
int tot = count_duplilist(ob);
stats->totobj += tot;
- stats_object(ob, base->flag & SELECT, tot, stats);
+ stats_object(ob, base->flag_legacy & SELECT, tot, stats);
}
else if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
/* Dupli Group */
int tot = count_duplilist(ob);
stats->totobj += tot;
- stats_object(ob, base->flag & SELECT, tot, stats);
+ stats_object(ob, base->flag_legacy & SELECT, tot, stats);
}
else {
/* No Dupli */
- stats_object(ob, base->flag & SELECT, 1, stats);
+ stats_object(ob, base->flag_legacy & SELECT, 1, stats);
stats->totobj++;
}
}
@@ -344,10 +345,10 @@ static bool stats_is_object_dynamic_topology_sculpt(Object *ob)
}
/* Statistics displayed in info header. Called regularly on scene changes. */
-static void stats_update(Scene *scene)
+static void stats_update(Scene *scene, SceneLayer *sl)
{
SceneStats stats = {0};
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
+ Object *ob = (sl->basact) ? sl->basact->object : NULL;
Base *base;
if (scene->obedit) {
@@ -364,23 +365,25 @@ static void stats_update(Scene *scene)
}
else {
/* Objects */
- for (base = scene->base.first; base; base = base->next)
- if (scene->lay & base->lay)
+ for (base = sl->object_bases.first; base; base = base->next)
+ if (base->flag & BASE_VISIBLED) {
stats_dupli_object(base, base->object, &stats);
+ }
}
- if (!scene->stats)
- scene->stats = MEM_callocN(sizeof(SceneStats), "SceneStats");
+ if (!sl->stats) {
+ sl->stats = MEM_callocN(sizeof(SceneStats), "SceneStats");
+ }
- *(scene->stats) = stats;
+ *(sl->stats) = stats;
}
-static void stats_string(Scene *scene)
+static void stats_string(Scene *scene, SceneLayer *sl)
{
#define MAX_INFO_MEM_LEN 64
- SceneStats *stats = scene->stats;
+ SceneStats *stats = sl->stats;
SceneStatsFmt stats_fmt;
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
+ Object *ob = (sl->basact) ? sl->basact->object : NULL;
uintptr_t mem_in_use, mmap_in_use;
char memstr[MAX_INFO_MEM_LEN];
char gpumemstr[MAX_INFO_MEM_LEN] = "";
@@ -487,19 +490,20 @@ static void stats_string(Scene *scene)
#undef MAX_INFO_LEN
-void ED_info_stats_clear(Scene *scene)
+void ED_info_stats_clear(SceneLayer *sl)
{
- if (scene->stats) {
- MEM_freeN(scene->stats);
- scene->stats = NULL;
+ if (sl->stats) {
+ MEM_freeN(sl->stats);
+ sl->stats = NULL;
}
}
-const char *ED_info_stats_string(Scene *scene)
+const char *ED_info_stats_string(Scene *scene, SceneLayer *sl)
{
- if (!scene->stats)
- stats_update(scene);
- stats_string(scene);
+ if (!sl->stats) {
+ stats_update(scene, sl);
+ }
+ stats_string(scene, sl);
- return scene->stats->infostr;
+ return sl->stats->infostr;
}
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 21777fd8afa..ab08b288470 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -236,7 +236,9 @@ static void info_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void info_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void info_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
// SpaceInfo *sinfo = sa->spacedata.first;
@@ -251,7 +253,9 @@ static void info_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
}
}
-static void info_header_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void info_header_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index c801a736e31..33c0565c12c 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -39,6 +39,8 @@
#include "BLI_utildefines.h"
#include "BLI_string_utf8.h"
+#include "GPU_immediate.h"
+
#include "BIF_gl.h"
#include "BKE_text.h"
@@ -81,9 +83,15 @@ static void console_draw_sel(const char *str, const int sel[2], const int xy[2],
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ubv(bg_sel);
- glRecti(xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4ubv(bg_sel);
+ immRecti(pos, xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2);
+
+ immUnbindProgram();
glDisable(GL_BLEND);
}
@@ -182,21 +190,25 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
cdc->sel[1] = str_len - sel_orig[0];
if (bg) {
- glColor3ubv(bg);
- glRecti(0, cdc->xy[1], cdc->winx, (cdc->xy[1] + (cdc->lheight * tot_lines)));
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glColor3ubv(fg);
+ immUniformColor3ubv(bg);
+ immRecti(pos, 0, cdc->xy[1], cdc->winx, (cdc->xy[1] + (cdc->lheight * tot_lines)));
+
+ immUnbindProgram();
+ }
/* last part needs no clipping */
BLF_position(cdc->font_id, cdc->xy[0], cdc->lofs + cdc->xy[1], 0);
+ BLF_color3ubv(cdc->font_id, fg);
BLF_draw_mono(cdc->font_id, s, len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
console_step_sel(cdc, -initial_offset);
- // glColor4ub(255, 0, 0, 96); // debug
+ /* BLF_color3ub(cdc->font_id, 255, 0, 0); // debug */
console_draw_sel(s, cdc->sel, cdc->xy, len, cdc->cwidth, cdc->lheight, bg_sel);
- glColor3ubv(fg);
}
cdc->xy[1] += cdc->lheight;
@@ -210,9 +222,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
if (cdc->sel[0] != cdc->sel[1]) {
console_step_sel(cdc, len);
- // glColor4ub(0, 255, 0, 96); // debug
+ /* BLF_color3ub(cdc->font_id, 0, 255, 0); // debug */
console_draw_sel(s, cdc->sel, cdc->xy, len, cdc->cwidth, cdc->lheight, bg_sel);
- glColor3ubv(fg);
}
cdc->xy[1] += cdc->lheight;
@@ -230,12 +241,17 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
else { /* simple, no wrap */
if (bg) {
- glColor3ubv(bg);
- glRecti(0, cdc->xy[1], cdc->winx, cdc->xy[1] + cdc->lheight);
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glColor3ubv(fg);
+ immUniformColor3ubv(bg);
+ immRecti(pos, 0, cdc->xy[1], cdc->winx, cdc->xy[1] + cdc->lheight);
+
+ immUnbindProgram();
+ }
+ BLF_color3ubv(cdc->font_id, fg);
BLF_position(cdc->font_id, cdc->xy[0], cdc->lofs + cdc->xy[1], 0);
BLF_draw_mono(cdc->font_id, str, str_len, cdc->cwidth);
@@ -245,7 +261,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
isel[0] = str_len - cdc->sel[1];
isel[1] = str_len - cdc->sel[0];
- // glColor4ub(255, 255, 0, 96); // debug
+ /* BLF_color3ub(cdc->font_id, 255, 255, 0); // debug */
console_draw_sel(str, isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight, bg_sel);
console_step_sel(cdc, -(str_len + 1));
}
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 3de44174d6a..04790f54057 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -461,13 +461,13 @@ static void set_sca_ob(Object *ob)
static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag)
{
Base *base;
- Main *bmain= CTX_data_main(C);
- Scene *scene= CTX_data_scene(C);
- Object *ob, *obt, *obact= CTX_data_active_object(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob, *obt, *obact = CTX_data_active_object(C);
ID **idar;
bSensor *sens;
bController *cont;
- unsigned int lay;
int a, nr, do_it;
/* we need a sorted object list */
@@ -485,19 +485,12 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
ob= ob->id.next;
}
- /* XXX here it checked 3d lay */
- lay= scene->lay;
-
- base= FIRSTBASE;
- while (base) {
- if (base->lay & lay) {
- if (base->flag & SELECT) {
- if (scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS;
- if (scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT;
- if (scavisflag & BUTS_ACT_SEL) base->object->scavisflag |= OB_VIS_ACT;
- }
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) && (base->flag & SELECT)) {
+ if (scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS;
+ if (scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT;
+ if (scavisflag & BUTS_ACT_SEL) base->object->scavisflag |= OB_VIS_ACT;
}
- base= base->next;
}
if (obact) {
diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c
index 12ca141128b..af90ef487e0 100644
--- a/source/blender/editors/space_logic/space_logic.c
+++ b/source/blender/editors/space_logic/space_logic.c
@@ -198,7 +198,9 @@ static void logic_refresh(const bContext *UNUSED(C), ScrArea *UNUSED(sa))
}
-static void logic_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void logic_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index e9c46e9d04b..48e822ef876 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -45,6 +45,7 @@
#include "BKE_nla.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_report.h"
@@ -125,7 +126,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
{
bDopeSheet *ads = (bDopeSheet *)ac->data;
Scene *sce = (Scene *)ads->source;
- Base *base = (Base *)ale->data;
+ BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
AnimData *adt = ob->adt;
@@ -133,24 +134,24 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
- base->flag ^= SELECT;
- ob->flag = base->flag;
+ base->flag_legacy ^= SELECT;
+ BKE_scene_base_flag_sync_from_base(base);
if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
- Base *b;
+ BaseLegacy *b;
/* deselect all */
/* TODO: should this deselect all other types of channels too? */
for (b = sce->base.first; b; b = b->next) {
- b->flag &= ~SELECT;
- b->object->flag = b->flag;
+ b->flag_legacy &= ~SELECT;
+ BKE_scene_base_flag_sync_from_base(b);
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}
/* select object now */
- base->flag |= SELECT;
+ base->flag_legacy |= SELECT;
ob->flag |= SELECT;
if (adt) adt->flag |= ADT_UI_SELECTED;
}
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 255fc0d6f8f..561c29b68cc 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -53,9 +53,11 @@
#include "ED_anim_api.h"
#include "ED_keyframes_draw.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+
#include "WM_types.h"
#include "UI_interface.h"
@@ -97,50 +99,70 @@ void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
}
/* draw the keyframes in the specified Action */
-static void nla_action_draw_keyframes(AnimData *adt, bAction *act, View2D *v2d, float y, float ymin, float ymax)
+static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, float ymin, float ymax)
{
- DLRBT_Tree keys;
- ActKeyColumn *ak;
- float xscale, f1, f2;
- float color[4];
-
/* get a list of the keyframes with NLA-scaling applied */
+ DLRBT_Tree keys;
BLI_dlrbTree_init(&keys);
action_to_keylist(adt, act, &keys, NULL);
BLI_dlrbTree_linkedlist_sync(&keys);
-
- if (ELEM(NULL, act, keys.first))
+
+ if (!(act && keys.first))
return;
-
+
/* draw a darkened region behind the strips
* - get and reset the background color, this time without the alpha to stand out better
* (amplified alpha is used instead)
*/
+ float color[4];
nla_action_get_color(adt, act, color);
color[3] *= 2.5f;
-
- glColor4fv(color);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4fv(color);
+
/* - draw a rect from the first to the last frame (no extra overlaps for now)
* that is slightly stumpier than the track background (hardcoded 2-units here)
*/
- f1 = ((ActKeyColumn *)keys.first)->cfra;
- f2 = ((ActKeyColumn *)keys.last)->cfra;
-
- glRectf(f1, ymin + 2, f2, ymax - 2);
-
-
- /* get View2D scaling factor */
- UI_view2d_scale_get(v2d, &xscale, NULL);
-
- /* for now, color is hardcoded to be black */
- glColor3f(0.0f, 0.0f, 0.0f);
-
- /* just draw each keyframe as a simple dot (regardless of the selection status)
- * - size is 3.0f which is smaller than the editable keyframes, so that there is a distinction
- */
- for (ak = keys.first; ak; ak = ak->next)
- draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, ak->key_type, KEYFRAME_SHAPE_FRAME, 1.0f);
-
+ float f1 = ((ActKeyColumn *)keys.first)->cfra;
+ float f2 = ((ActKeyColumn *)keys.last)->cfra;
+
+ immRectf(pos_id, f1, ymin + 2, f2, ymax - 2);
+ immUnbindProgram();
+
+ /* count keys before drawing */
+ unsigned int key_ct = 0;
+ for (ActKeyColumn *ak = keys.first; ak; ak = ak->next) {
+ key_ct++;
+ }
+
+ if (key_ct > 0) {
+ format = immVertexFormat();
+ pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int size_id = VertexFormat_add_attrib(format, "size", COMP_F32, 1, KEEP_FLOAT);
+ unsigned int color_id = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ unsigned int outline_color_id = VertexFormat_add_attrib(format, "outlineColor", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ immBegin(PRIM_POINTS, key_ct);
+
+ /* - disregard the selection status of keyframes so they draw a certain way
+ * - size is 6.0f which is smaller than the editable keyframes, so that there is a distinction
+ */
+ for (ActKeyColumn *ak = keys.first; ak; ak = ak->next) {
+ draw_keyframe_shape(ak->cfra, y, 6.0f, false, ak->key_type, KEYFRAME_SHAPE_FRAME, 1.0f,
+ pos_id, size_id, color_id, outline_color_id);
+ }
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
+ }
+
/* free icons */
BLI_dlrbTree_free(&keys);
}
@@ -148,57 +170,68 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, View2D *v2d,
/* Strip Markers ------------------------ */
/* Markers inside an action strip */
-static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
+static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymaxc, int shade, const bool dashed)
{
- bAction *act = strip->act;
- TimeMarker *marker;
-
- if (ELEM(NULL, strip->act, strip->act->markers.first))
+ const bAction *act = strip->act;
+
+ if (!(act && act->markers.first))
return;
-
- for (marker = act->markers.first; marker; marker = marker->next) {
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ if (dashed) {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ }
+ immUniformThemeColorShade(TH_STRIP_SELECT, shade);
+
+ immBeginAtMost(PRIM_LINES, BLI_listbase_count(&act->markers) * 2);
+ for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) {
if ((marker->frame > strip->actstart) && (marker->frame < strip->actend)) {
float frame = nlastrip_get_frame(strip, marker->frame, NLATIME_CONVERT_MAP);
-
+
/* just a simple line for now */
- // XXX: draw a triangle instead...
- fdrawline(frame, yminc + 1, frame, ymaxc - 1);
+ /* XXX: draw a triangle instead... */
+ immVertex2f(shdr_pos, frame, yminc + 1);
+ immVertex2f(shdr_pos, frame, ymaxc - 1);
}
}
+ immEnd();
+
+ immUnbindProgram();
}
/* Markers inside a NLA-Strip */
static void nla_strip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
{
- glLineWidth(2.0);
+ glLineWidth(2.0f);
if (strip->type == NLASTRIP_TYPE_CLIP) {
/* try not to be too conspicuous, while being visible enough when transforming */
- if (strip->flag & NLASTRIP_FLAG_SELECT)
- UI_ThemeColorShade(TH_STRIP_SELECT, -60);
- else
- UI_ThemeColorShade(TH_STRIP_SELECT, -40);
-
- setlinestyle(3);
-
+ int shade = (strip->flag & NLASTRIP_FLAG_SELECT) ? -60 : -40;
+
/* just draw the markers in this clip */
- nla_actionclip_draw_markers(strip, yminc, ymaxc);
-
- setlinestyle(0);
+ nla_actionclip_draw_markers(strip, yminc, ymaxc, shade, true);
}
else if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
/* just a solid color, so that it is very easy to spot */
- UI_ThemeColorShade(TH_STRIP_SELECT, 20);
-
+ int shade = 20;
/* draw the markers in the first level of strips only (if they are actions) */
for (NlaStrip *nls = strip->strips.first; nls; nls = nls->next) {
if (nls->type == NLASTRIP_TYPE_CLIP) {
- nla_actionclip_draw_markers(nls, yminc, ymaxc);
+ nla_actionclip_draw_markers(nls, yminc, ymaxc, shade, false);
}
}
}
-
- glLineWidth(1.0);
}
/* Strips (Proper) ---------------------- */
@@ -266,15 +299,12 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col
}
/* helper call for drawing influence/time control curves for a given NLA-strip */
-static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc)
+static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, unsigned int pos)
{
+ immUniformColor3f(0.7f, 0.7f, 0.7f);
+
const float yheight = ymaxc - yminc;
-
- /* drawing color is simply a light-gray */
- // TODO: is this color suitable?
- // XXX nasty hacked color for now... which looks quite bad too...
- glColor3f(0.7f, 0.7f, 0.7f);
-
+
/* draw with AA'd line */
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
@@ -285,43 +315,44 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc)
float cfra;
/* plot the curve (over the strip's main region) */
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1));
+
/* sample at 1 frame intervals, and draw
* - min y-val is yminc, max is y-maxc, so clamp in those regions
*/
for (cfra = strip->start; cfra <= strip->end; cfra += 1.0f) {
- float y = evaluate_fcurve(fcu, cfra);
+ float y = evaluate_fcurve(fcu, cfra); /* assume this to be in 0-1 range */
CLAMP(y, 0.0f, 1.0f);
- glVertex2f(cfra, ((y * yheight) + yminc));
+ immVertex2f(pos, cfra, ((y * yheight) + yminc));
}
- glEnd(); // GL_LINE_STRIP
+
+ immEnd();
}
else {
/* use blend in/out values only if both aren't zero */
if ((IS_EQF(strip->blendin, 0.0f) && IS_EQF(strip->blendout, 0.0f)) == 0) {
- glBegin(GL_LINE_STRIP);
+ immBeginAtMost(PRIM_LINE_STRIP, 4);
+
/* start of strip - if no blendin, start straight at 1, otherwise from 0 to 1 over blendin frames */
if (IS_EQF(strip->blendin, 0.0f) == 0) {
- glVertex2f(strip->start, yminc);
- glVertex2f(strip->start + strip->blendin, ymaxc);
+ immVertex2f(pos, strip->start, yminc);
+ immVertex2f(pos, strip->start + strip->blendin, ymaxc);
}
else
- glVertex2f(strip->start, ymaxc);
+ immVertex2f(pos, strip->start, ymaxc);
/* end of strip */
if (IS_EQF(strip->blendout, 0.0f) == 0) {
- glVertex2f(strip->end - strip->blendout, ymaxc);
- glVertex2f(strip->end, yminc);
+ immVertex2f(pos, strip->end - strip->blendout, ymaxc);
+ immVertex2f(pos, strip->end, yminc);
}
else
- glVertex2f(strip->end, ymaxc);
- glEnd(); // GL_LINE_STRIP
+ immVertex2f(pos, strip->end, ymaxc);
+
+ immEnd();
}
}
-
- /* time -------------------------- */
- // XXX do we want to draw this curve? in a different color too?
-
+
/* turn off AA'd lines */
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -331,11 +362,14 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc)
static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc)
{
const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) && (nlt->flag & NLATRACK_SOLO) == 0);
- float color[3];
-
+ float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
/* get color of strip */
nla_strip_get_color_inside(adt, strip, color);
-
+
+ uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* draw extrapolation info first (as backdrop)
* - but this should only be drawn if track has some contribution
*/
@@ -343,7 +377,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
/* enable transparency... */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
switch (strip->extendmode) {
/* since this does both sides, only do the 'before' side, and leave the rest to the next case */
case NLASTRIP_EXTEND_HOLD:
@@ -352,15 +386,10 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
*/
if (strip->prev == NULL) {
/* set the drawing color to the color of the strip, but with very faint alpha */
- glColor4f(color[0], color[1], color[2], 0.15f);
-
+ immUniformColor3fvAlpha(color, 0.15f);
+
/* draw the rect to the edge of the screen */
- glBegin(GL_QUADS);
- glVertex2f(v2d->cur.xmin, yminc);
- glVertex2f(v2d->cur.xmin, ymaxc);
- glVertex2f(strip->start, ymaxc);
- glVertex2f(strip->start, yminc);
- glEnd();
+ immRectf(shdr_pos, v2d->cur.xmin, yminc, strip->start, ymaxc);
}
ATTR_FALLTHROUGH;
@@ -369,118 +398,141 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
/* only need to try and draw if the next strip doesn't occur immediately after */
if ((strip->next == NULL) || (IS_EQF(strip->next->start, strip->end) == 0)) {
/* set the drawing color to the color of the strip, but this time less faint */
- glColor4f(color[0], color[1], color[2], 0.3f);
+ immUniformColor3fvAlpha(color, 0.3f);
/* draw the rect to the next strip or the edge of the screen */
- glBegin(GL_QUADS);
- glVertex2f(strip->end, yminc);
- glVertex2f(strip->end, ymaxc);
-
- if (strip->next) {
- glVertex2f(strip->next->start, ymaxc);
- glVertex2f(strip->next->start, yminc);
- }
- else {
- glVertex2f(v2d->cur.xmax, ymaxc);
- glVertex2f(v2d->cur.xmax, yminc);
- }
- glEnd();
+ float x2 = strip->next ? strip->next->start : v2d->cur.xmax;
+ immRectf(shdr_pos, strip->end, yminc, x2, ymaxc);
}
break;
}
-
+
glDisable(GL_BLEND);
}
-
-
+
+
/* draw 'inside' of strip itself */
if (non_solo == 0) {
+ immUnbindProgram();
+
/* strip is in normal track */
- glColor3fv(color);
UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
-
- UI_draw_roundbox_shade_x(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1);
+ UI_draw_roundbox_shade_x(true, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1, color);
+
+ /* restore current vertex format & program (roundbox trashes it) */
+ shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
}
else {
/* strip is in disabled track - make less visible */
- glColor4f(color[0], color[1], color[2], 0.1f);
+ immUniformColor3fvAlpha(color, 0.1f);
glEnable(GL_BLEND);
- glRectf(strip->start, yminc, strip->end, ymaxc);
+ immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc);
glDisable(GL_BLEND);
}
-
-
+
+
/* draw strip's control 'curves'
* - only if user hasn't hidden them...
*/
if ((snla->flag & SNLA_NOSTRIPCURVES) == 0)
- nla_draw_strip_curves(strip, yminc, ymaxc);
-
-
+ nla_draw_strip_curves(strip, yminc, ymaxc, shdr_pos);
+
+ immUnbindProgram();
+
/* draw markings indicating locations of local markers (useful for lining up different actions) */
if ((snla->flag & SNLA_NOLOCALMARKERS) == 0)
nla_strip_draw_markers(strip, yminc, ymaxc);
-
- /* draw strip outline
+
+ /* draw strip outline
* - color used here is to indicate active vs non-active
*/
if (strip->flag & NLASTRIP_FLAG_ACTIVE) {
/* strip should appear 'sunken', so draw a light border around it */
- glColor3f(0.9f, 1.0f, 0.9f); // FIXME: hardcoded temp-hack colors
+ color[0] = 0.9f; /* FIXME: hardcoded temp-hack colors */
+ color[1] = 1.0f;
+ color[2] = 0.9f;
}
else {
/* strip should appear to stand out, so draw a dark border around it */
- glColor3f(0.0f, 0.0f, 0.0f);
+ color[0] = color[1] = color[2] = 0.0f; /* FIXME: or 1.0f ?? */
}
-
- /* - line style: dotted for muted */
- if ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED))
- setlinestyle(4);
-
+
/* draw outline */
- UI_draw_roundbox_shade_x(GL_LINE_LOOP, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1);
-
+ /* XXX TODO Was dashed like code below, not implemented for now so kept solid... */
+ UI_draw_roundbox_shade_x(false, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1, color);
+
+ /* restore current vertex format & program (roundbox trashes it) */
+ /* Note that we use dahsed shader here, and make it draw solid lines if not muted... */
+ shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniformColor3fv(color);
+
+ /* - line style: dotted for muted */
+ if ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED)) {
+ immUniform1f("dash_width", 4.0f);
+ immUniform1f("dash_factor", 0.5f);
+ }
+ else {
+ immUniform1f("dash_factor", 2.0f); /* solid line */
+ }
+
/* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */
if ((strip->type == NLASTRIP_TYPE_CLIP) && IS_EQF(strip->repeat, 1.0f) == 0) {
float repeatLen = (strip->actend - strip->actstart) * strip->scale;
- int i;
-
+
/* only draw lines for whole-numbered repeats, starting from the first full-repeat
* up to the last full repeat (but not if it lies on the end of the strip)
*/
- for (i = 1; i < strip->repeat; i++) {
+ immBeginAtMost(PRIM_LINES, 2 * (strip->repeat - 1));
+ for (int i = 1; i < strip->repeat; i++) {
float repeatPos = strip->start + (repeatLen * i);
-
+
/* don't draw if line would end up on or after the end of the strip */
- if (repeatPos < strip->end)
- fdrawline(repeatPos, yminc + 4, repeatPos, ymaxc - 4);
+ if (repeatPos < strip->end) {
+ immVertex2f(shdr_pos, repeatPos, yminc + 4);
+ immVertex2f(shdr_pos, repeatPos, ymaxc - 4);
+ }
}
+ immEnd();
}
/* or if meta-strip, draw lines delimiting extents of sub-strips (in same color as outline, if more than 1 exists) */
else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) {
- NlaStrip *cs;
- float y = (ymaxc - yminc) / 2.0f + yminc;
-
+ float y = (ymaxc - yminc) * 0.5f + yminc;
+
+ immBeginAtMost(PRIM_LINES, 4 * BLI_listbase_count(&strip->strips)); /* up to 2 lines per strip */
+
/* only draw first-level of child-strips, but don't draw any lines on the endpoints */
- for (cs = strip->strips.first; cs; cs = cs->next) {
+ for (NlaStrip *cs = strip->strips.first; cs; cs = cs->next) {
/* draw start-line if not same as end of previous (and only if not the first strip)
* - on upper half of strip
*/
- if ((cs->prev) && IS_EQF(cs->prev->end, cs->start) == 0)
- fdrawline(cs->start, y, cs->start, ymaxc);
-
+ if ((cs->prev) && IS_EQF(cs->prev->end, cs->start) == 0) {
+ immVertex2f(shdr_pos, cs->start, y);
+ immVertex2f(shdr_pos, cs->start, ymaxc);
+ }
+
/* draw end-line if not the last strip
* - on lower half of strip
*/
- if (cs->next)
- fdrawline(cs->end, yminc, cs->end, y);
+ if (cs->next) {
+ immVertex2f(shdr_pos, cs->end, yminc);
+ immVertex2f(shdr_pos, cs->end, y);
+ }
}
+
+ immEnd();
}
-
- /* reset linestyle */
- setlinestyle(0);
-}
+
+ immUnbindProgram();
+}
/* add the relevant text to the cache of text-strings to draw in pixelspace */
static void nla_draw_strip_text(
@@ -491,7 +543,6 @@ static void nla_draw_strip_text(
char str[256];
size_t str_len;
char col[4];
- rctf rect;
/* just print the name and the range */
if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
@@ -518,12 +569,14 @@ static void nla_draw_strip_text(
/* set bounding-box for text
* - padding of 2 'units' on either side
*/
- // TODO: make this centered?
- rect.xmin = xminc;
- rect.ymin = yminc;
- rect.xmax = xmaxc;
- rect.ymax = ymaxc;
-
+ /* TODO: make this centered? */
+ rctf rect = {
+ .xmin = xminc,
+ .ymin = yminc,
+ .xmax = xmaxc,
+ .ymax = ymaxc
+ };
+
/* add this string to the cache of texts to draw */
UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
}
@@ -536,9 +589,7 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */
const char col[4] = {220, 220, 220, 255}; /* light gray */
char numstr[32];
- size_t numstr_len;
-
-
+
/* Always draw times above the strip, whereas sequencer drew below + above.
* However, we should be fine having everything on top, since these tend to be
* quite spaced out.
@@ -546,9 +597,9 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
* while also preserving some accuracy, since we do use floats
*/
/* start frame */
- numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start);
+ size_t numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start);
UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col);
-
+
/* end frame */
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->end);
UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, numstr_len, col);
@@ -558,20 +609,14 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
View2D *v2d = &ar->v2d;
- float y = 0.0f;
- size_t items;
- int height;
const float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
const float text_margin_x = (8 * UI_DPI_FAC) * pixelx;
/* build list of channels to draw */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ ListBase anim_data = {NULL, NULL};
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
@@ -579,16 +624,16 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
* - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
- height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
+ int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
/* loop through channels, and set up drawing depending on their type */
- y = (float)(-NLACHANNEL_HEIGHT(snla));
+ float y = (float)(-NLACHANNEL_HEIGHT(snla));
- for (ale = anim_data.first; ale; ale = ale->next) {
+ for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) {
const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
@@ -602,11 +647,10 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
AnimData *adt = ale->adt;
NlaTrack *nlt = (NlaTrack *)ale->data;
- NlaStrip *strip;
- int index;
/* draw each strip in the track (if visible) */
- for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) {
+ int index = 1;
+ for (NlaStrip *strip = nlt->strips.first; strip; strip = strip->next, index++) {
if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
const float xminc = strip->start + text_margin_x;
const float xmaxc = strip->end + text_margin_x;
@@ -631,45 +675,60 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
case ANIMTYPE_NLAACTION:
{
AnimData *adt = ale->adt;
- float color[4];
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
* and a second darker rect within which we draw keyframe indicator dots if there's data
*/
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
/* get colors for drawing */
+ float color[4];
nla_action_get_color(adt, ale->data, color);
- glColor4fv(color);
-
+ immUniformColor4fv(color);
+
/* draw slightly shifted up for greater separation from standard channels,
* but also slightly shorter for some more contrast when viewing the strips
*/
- glRectf(v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
-
- /* draw keyframes in the action */
- nla_action_draw_keyframes(adt, ale->data, v2d, y, yminc + NLACHANNEL_SKIP, ymaxc - NLACHANNEL_SKIP);
+ immRectf(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
/* draw 'embossed' lines above and below the strip for effect */
/* white base-lines */
glLineWidth(2.0f);
- glColor4f(1.0f, 1.0f, 1.0f, 0.3);
- fdrawline(v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
- fdrawline(v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
-
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.3f);
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP);
+ immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
+ immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP);
+ immVertex2f(pos, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
+ immEnd();
+
/* black top-lines */
glLineWidth(1.0f);
- glColor3f(0.0f, 0.0f, 0.0f);
- fdrawline(v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
- fdrawline(v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
-
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP);
+ immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
+ immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP);
+ immVertex2f(pos, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
+ immEnd();
+
+ /* TODO: these lines but better --^ */
+
+ immUnbindProgram();
+
+ /* draw keyframes in the action */
+ nla_action_draw_keyframes(adt, ale->data, y, yminc + NLACHANNEL_SKIP, ymaxc - NLACHANNEL_SKIP);
+
glDisable(GL_BLEND);
break;
}
}
}
-
+
/* adjust y-position for next one */
y -= NLACHANNEL_STEP(snla);
}
@@ -685,17 +744,14 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
- int filter;
SpaceNla *snla = (SpaceNla *)ac->sl;
View2D *v2d = &ar->v2d;
float y = 0.0f;
- size_t items;
- int height;
/* build list of channels to draw */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
@@ -703,7 +759,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
* - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
- height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
+ int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 3b5604087b9..a71f2f20a3f 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -353,7 +353,9 @@ static void nla_buttons_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void nla_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void nla_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -386,7 +388,9 @@ static void nla_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegio
}
-static void nla_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void nla_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -431,7 +435,9 @@ static void nla_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), A
}
}
-static void nla_channel_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void nla_channel_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -466,7 +472,7 @@ static void nla_channel_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa)
}
/* editor level listener */
-static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index cde818333e4..41843927587 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -53,6 +53,7 @@ set(SRC
node_templates.c
node_toolbar.c
node_view.c
+ node_widgets.c
space_node.c
node_intern.h
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index f58b4050834..500abfe6c63 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -50,9 +50,12 @@
#include "BLF_api.h"
#include "BLT_translation.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -62,6 +65,7 @@
#include "WM_types.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
@@ -80,49 +84,6 @@ static void node_socket_button_label(bContext *UNUSED(C), uiLayout *layout, Poin
uiItemL(layout, text, 0);
}
-
-/* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */
-
-#if 0 /* UNUSED */
-static void node_draw_socket_new(bNodeSocket *sock, float size)
-{
- float x = sock->locx, y = sock->locy;
-
- /* 16 values of sin function */
- static float si[16] = {
- 0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
- 0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
- -0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
- -0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f
- };
- /* 16 values of cos function */
- static float co[16] = {
- 1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
- -0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
- -0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
- 0.15142777f, 0.52896401f, 0.82076344f, 0.97952994f,
- };
- int a;
-
- glColor3ub(180, 180, 180);
-
- glBegin(GL_POLYGON);
- for (a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
-
- glColor4ub(0, 0, 0, 150);
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINE_LOOP);
- for (a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
-}
-#endif
-
/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -392,6 +353,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
const int font_size = data->label_size / aspect;
const float margin = (float)(NODE_DY / 4);
int label_height;
+ unsigned char color[3];
nodeLabel(ntree, node, label, sizeof(label));
@@ -400,7 +362,8 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
BLF_size(fontid, MIN2(24, font_size), U.dpi); /* clamp otherwise it can suck up a LOT of memory */
/* title color */
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
+ UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color);
+ BLF_color3ubv(fontid, color);
width = BLF_width(fontid, label, sizeof(label));
ascender = BLF_ascender(fontid);
@@ -465,7 +428,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
{
rctf *rct = &node->totr;
int color_id = node_get_colorid(node);
- unsigned char color[4];
+ float color[4];
float alpha;
/* skip if out of view */
@@ -475,40 +438,32 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
return;
}
- UI_GetThemeColor4ubv(TH_NODE_FRAME, color);
- alpha = (float)(color[3]) / 255.0f;
+ UI_GetThemeColor4fv(TH_NODE_FRAME, color);
+ alpha = color[3];
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD, alpha);
/* body */
- if (node->flag & NODE_CUSTOM_COLOR)
- glColor4f(node->color[0], node->color[1], node->color[2], alpha);
+ if (node->flag & NODE_CUSTOM_COLOR) {
+ rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], alpha);
+ }
else
- UI_ThemeColor4(TH_NODE_FRAME);
- glEnable(GL_BLEND);
+ UI_GetThemeColor4fv(TH_NODE_FRAME, color);
+
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
- glDisable(GL_BLEND);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
-
if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
+ UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color);
else
- UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP,
- rct->xmin, rct->ymin,
- rct->xmax, rct->ymax, BASIS_RAD);
-
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color);
+
+ UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
}
-
+
/* label */
node_draw_frame_label(ntree, node, snode->aspect);
@@ -580,15 +535,9 @@ static void node_draw_reroute_prepare(const bContext *UNUSED(C), bNodeTree *UNUS
static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(snode),
bNodeTree *ntree, bNode *node, bNodeInstanceKey UNUSED(key))
{
- bNodeSocket *sock;
char showname[128]; /* 128 used below */
rctf *rct = &node->totr;
-#if 0 /* UNUSED */
- float size = NODE_REROUTE_SIZE;
-#endif
- float socket_size = NODE_SOCKSIZE;
-
/* skip if out of view */
if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax ||
node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax)
@@ -602,23 +551,26 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
* selection state is indicated by socket outline below!
*/
#if 0
+ float size = NODE_REROUTE_SIZE;
+
/* body */
+ float debug_color[4];
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_ThemeColor4(TH_NODE);
- glEnable(GL_BLEND);
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
- glDisable(GL_BLEND);
+ UI_GetThemeColor4fv(TH_NODE, debug_color);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
/* using different shades of TH_TEXT_HI for the empasis, like triangle */
- if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
- else
- UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
+ if (node->flag & NODE_ACTIVE) {
+ UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, 0, -40, debug_color);
+ }
+ else {
+ UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, -20, -120, debug_color);
+ }
+ UI_draw_roundbox_4fv(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -637,9 +589,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
/* only draw input socket. as they all are placed on the same position.
* highlight also if node itself is selected, since we don't display the node body separately!
*/
- for (sock = node->inputs.first; sock; sock = sock->next) {
- node_socket_circle_draw(C, ntree, node, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT));
- }
+ node_draw_sockets(&ar->v2d, C, ntree, node, false, node->flag & SELECT);
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
@@ -798,7 +748,7 @@ static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_layers", "", ICON_NONE);
uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NONE);
}
else {
@@ -1016,7 +966,7 @@ static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *pt
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
}
}
}
@@ -1035,7 +985,7 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
}
else
uiItemR(layout, ptr, "uv_map", 0, "", 0);
@@ -1057,7 +1007,7 @@ static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
}
else
uiItemR(row, ptr, "uv_map", 0, "", 0);
@@ -2207,14 +2157,21 @@ static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNo
const float cx = x + snode->zoom * backdropWidth * node->custom3;
const float cy = y + snode->zoom * backdropHeight * node->custom4;
- glColor3f(1.0, 1.0, 1.0);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
- glBegin(GL_LINES);
- glVertex2f(cx - 25, cy - 25);
- glVertex2f(cx + 25, cy + 25);
- glVertex2f(cx + 25, cy - 25);
- glVertex2f(cx - 25, cy + 25);
- glEnd();
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, cx - 25, cy - 25);
+ immVertex2f(pos, cx + 25, cy + 25);
+ immVertex2f(pos, cx + 25, cy - 25);
+ immVertex2f(pos, cx - 25, cy + 25);
+ immEnd();
+
+ immUnbindProgram();
}
}
@@ -2233,9 +2190,6 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN
float cx, cy, x1, x2, x3, x4;
float y1, y2, y3, y4;
-
- glColor3f(1.0, 1.0, 1.0);
-
cx = x + snode->zoom * backdropWidth * boxmask->x;
cy = y + snode->zoom * backdropHeight * boxmask->y;
@@ -2248,12 +2202,21 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN
y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
- glBegin(GL_LINE_LOOP);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glVertex2f(x3, y3);
- glVertex2f(x4, y4);
- glEnd();
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x3, y3);
+ immVertex2f(pos, x4, y4);
+ immEnd();
+
+ immUnbindProgram();
}
static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
@@ -2271,9 +2234,6 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop
float cx, cy, x1, x2, x3, x4;
float y1, y2, y3, y4;
-
- glColor3f(1.0, 1.0, 1.0);
-
cx = x + snode->zoom * backdropWidth * ellipsemask->x;
cy = y + snode->zoom * backdropHeight * ellipsemask->y;
@@ -2286,13 +2246,21 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop
y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
- glBegin(GL_LINE_LOOP);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glVertex2f(x3, y3);
- glVertex2f(x4, y4);
- glEnd();
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x3, y3);
+ immVertex2f(pos, x4, y4);
+ immEnd();
+
+ immUnbindProgram();
}
static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -3198,6 +3166,7 @@ void ED_init_node_socket_type_virtual(bNodeSocketType *stype)
void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeInstanceKey parent_key)
{
bNodeInstanceKey active_viewer_key = (snode->nodetree ? snode->nodetree->active_viewer_key : NODE_INSTANCE_KEY_NONE);
+ float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
Image *ima;
void *lock;
ImBuf *ibuf;
@@ -3212,12 +3181,10 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (ibuf) {
float x, y;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
+
+ gpuPushProjectionMatrix();
+ gpuPushMatrix();
+
/* somehow the offset has to be calculated inverse */
glaDefine2DArea(&ar->winrct);
@@ -3230,60 +3197,37 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
unsigned char *display_buffer = NULL;
void *cache_handle = NULL;
- if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B)) {
- int ofs;
-
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
-#ifdef __BIG_ENDIAN__
- if (snode->flag & SNODE_SHOW_R) ofs = 0;
- else if (snode->flag & SNODE_SHOW_G) ofs = 1;
- else ofs = 2;
-#else
- if (snode->flag & SNODE_SHOW_R) ofs = 1;
- else if (snode->flag & SNODE_SHOW_G) ofs = 2;
- else ofs = 3;
-#endif
+ if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B | SNODE_SHOW_ALPHA)) {
- glPixelZoom(snode->zoom, snode->zoom);
- /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
-
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT,
- display_buffer - (4 - ofs));
-
- glPixelZoom(1.0f, 1.0f);
- }
- else if (snode->flag & SNODE_SHOW_ALPHA) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
- glPixelZoom(snode->zoom, snode->zoom);
- /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
-#ifdef __BIG_ENDIAN__
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
-#endif
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, display_buffer);
-
-#ifdef __BIG_ENDIAN__
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
-#endif
- glPixelZoom(1.0f, 1.0f);
+
+ if (snode->flag & SNODE_SHOW_R)
+ shuffle[0] = 1.0f;
+ else if (snode->flag & SNODE_SHOW_G)
+ shuffle[1] = 1.0f;
+ else if (snode->flag & SNODE_SHOW_B)
+ shuffle[2] = 1.0f;
+ else
+ shuffle[3] = 1.0f;
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, shuffle);
+
+ immDrawPixelsTex(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST,
+ display_buffer, snode->zoom, snode->zoom, NULL);
+
+ GPU_shader_unbind();
}
else if (snode->flag & SNODE_USE_ALPHA) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPixelZoom(snode->zoom, snode->zoom);
-
- glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
-
- glPixelZoom(1.0f, 1.0f);
+
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
+
glDisable(GL_BLEND);
}
else {
- glPixelZoom(snode->zoom, snode->zoom);
-
- glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
-
- glPixelZoom(1.0f, 1.0f);
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
}
if (cache_handle)
@@ -3308,20 +3252,24 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
viewer_border->ymin < viewer_border->ymax)
{
rcti pixel_border;
- UI_ThemeColor(TH_ACTIVE);
BLI_rcti_init(&pixel_border,
x + snode->zoom * viewer_border->xmin * ibuf->x,
x + snode->zoom * viewer_border->xmax * ibuf->x,
y + snode->zoom * viewer_border->ymin * ibuf->y,
y + snode->zoom * viewer_border->ymax * ibuf->y);
- glaDrawBorderCorners(&pixel_border, 1.0f, 1.0f);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE);
+
+ immDrawBorderCorners(pos, &pixel_border, 1.0f, 1.0f);
+
+ immUnbindProgram();
}
}
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
}
BKE_image_release_ibuf(ima, ibuf, lock);
@@ -3433,6 +3381,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
float linew;
float arrow[2], arrow1[2], arrow2[2];
glGetFloatv(GL_LINE_WIDTH, &linew);
+ unsigned int pos;
/* we can reuse the dist variable here to increment the GL curve eval amount*/
dist = 1.0f / (float)LINK_RESOL;
@@ -3456,141 +3405,89 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
arrow[0] = coord_array[LINK_ARROW][0];
arrow[1] = coord_array[LINK_ARROW][1];
}
+
+ if (do_triple || drawarrow || (!do_shaded)) {
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ }
+
if (do_triple) {
- UI_ThemeColorShadeAlpha(th_col3, -80, -120);
+ immUniformThemeColorShadeAlpha(th_col3, -80, -120);
glLineWidth(4.0f);
-
- glBegin(GL_LINE_STRIP);
+
+ immBegin(PRIM_LINE_STRIP, (LINK_RESOL + 1));
+
for (i = 0; i <= LINK_RESOL; i++) {
- glVertex2fv(coord_array[i]);
+ immVertex2fv(pos, coord_array[i]);
}
- glEnd();
+
+ immEnd();
+
if (drawarrow) {
- glBegin(GL_LINE_STRIP);
- glVertex2fv(arrow1);
- glVertex2fv(arrow);
- glVertex2fv(arrow2);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2fv(pos, arrow1);
+ immVertex2fv(pos, arrow);
+ immVertex2fv(pos, arrow2);
+ immEnd();
}
}
-
- /* XXX using GL_LINES for shaded node lines is a workaround
- * for Intel hardware, this breaks with GL_LINE_STRIP and
- * changing color in begin/end blocks.
- */
+
glLineWidth(1.5f);
- if (do_shaded) {
- glBegin(GL_LINES);
- for (i = 0; i < LINK_RESOL; i++) {
- UI_ThemeColorBlend(th_col1, th_col2, spline_step);
- glVertex2fv(coord_array[i]);
-
- UI_ThemeColorBlend(th_col1, th_col2, spline_step + dist);
- glVertex2fv(coord_array[i + 1]);
-
- spline_step += dist;
- }
- glEnd();
+
+ if (drawarrow) {
+ immUniformThemeColorBlend(th_col1, th_col2, 0.5f);
+
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex2fv(pos, arrow1);
+ immVertex2fv(pos, arrow);
+ immVertex2fv(pos, arrow2);
+ immEnd();
}
- else {
- UI_ThemeColor(th_col1);
- glBegin(GL_LINE_STRIP);
+
+ if (!do_shaded) {
+ immUniformThemeColor(th_col1);
+
+ immBegin(PRIM_LINE_STRIP, (LINK_RESOL + 1));
+
for (i = 0; i <= LINK_RESOL; i++) {
- glVertex2fv(coord_array[i]);
+ immVertex2fv(pos, coord_array[i]);
}
- glEnd();
+
+ immEnd();
}
-
- if (drawarrow) {
- glBegin(GL_LINE_STRIP);
- glVertex2fv(arrow1);
- glVertex2fv(arrow);
- glVertex2fv(arrow2);
- glEnd();
+
+ if (do_triple || drawarrow || (!do_shaded)) {
+ immUnbindProgram();
}
-
- glDisable(GL_LINE_SMOOTH);
- }
-}
-#if 0 /* not used in 2.5x yet */
-static void node_link_straight_points(View2D *UNUSED(v2d), SpaceNode *snode, bNodeLink *link, float coord_array[][2])
-{
- if (link->fromsock) {
- coord_array[0][0] = link->fromsock->locx;
- coord_array[0][1] = link->fromsock->locy;
- }
- else {
- if (snode == NULL) return;
- coord_array[0][0] = snode->mx;
- coord_array[0][1] = snode->my;
- }
- if (link->tosock) {
- coord_array[1][0] = link->tosock->locx;
- coord_array[1][1] = link->tosock->locy;
- }
- else {
- if (snode == NULL) return;
- coord_array[1][0] = snode->mx;
- coord_array[1][1] = snode->my;
- }
-}
+ if (do_shaded) {
+ unsigned char col[3];
-void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link,
- int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3)
-{
- float coord_array[2][2];
- int i;
-
- node_link_straight_points(v2d, snode, link, coord_array);
-
- glEnable(GL_LINE_SMOOTH);
-
- if (do_triple) {
- UI_ThemeColorShadeAlpha(th_col3, -80, -120);
- glLineWidth(4.0f);
-
- glBegin(GL_LINES);
- glVertex2fv(coord_array[0]);
- glVertex2fv(coord_array[1]);
- glEnd();
- }
-
- UI_ThemeColor(th_col1);
- glLineWidth(1.5f);
-
- /* XXX using GL_LINES for shaded node lines is a workaround
- * for Intel hardware, this breaks with GL_LINE_STRIP and
- * changing color in begin/end blocks.
- */
- if (do_shaded) {
- glBegin(GL_LINES);
- for (i = 0; i < LINK_RESOL - 1; ++i) {
- float t = (float)i / (float)(LINK_RESOL - 1);
- UI_ThemeColorBlend(th_col1, th_col2, t);
- glVertex2f((1.0f - t) * coord_array[0][0] + t * coord_array[1][0],
- (1.0f - t) * coord_array[0][1] + t * coord_array[1][1]);
-
- t = (float)(i + 1) / (float)(LINK_RESOL - 1);
- UI_ThemeColorBlend(th_col1, th_col2, t);
- glVertex2f((1.0f - t) * coord_array[0][0] + t * coord_array[1][0],
- (1.0f - t) * coord_array[0][1] + t * coord_array[1][1]);
- }
- glEnd();
- }
- else {
- glBegin(GL_LINE_STRIP);
- for (i = 0; i < LINK_RESOL; ++i) {
- float t = (float)i / (float)(LINK_RESOL - 1);
- glVertex2f((1.0f - t) * coord_array[0][0] + t * coord_array[1][0],
- (1.0f - t) * coord_array[0][1] + t * coord_array[1][1]);
+ VertexFormat *format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ immBegin(PRIM_LINE_STRIP, (LINK_RESOL + 1));
+
+ for (i = 0; i <= LINK_RESOL; i++) {
+ UI_GetThemeColorBlend3ubv(th_col1, th_col2, spline_step, col);
+ immAttrib3ubv(color, col);
+
+ immVertex2fv(pos, coord_array[i]);
+
+ spline_step += dist;
+ }
+
+ immEnd();
+
+ immUnbindProgram();
}
- glEnd();
+
+ glDisable(GL_LINE_SMOOTH);
}
-
- glDisable(GL_LINE_SMOOTH);
}
-#endif
/* note; this is used for fake links in groups too */
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
@@ -3638,27 +3535,27 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
// node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
}
-void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border)
+void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos)
{
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, 4);
if (border & (NODE_LEFT | NODE_RIGHT)) {
- glVertex2f(cent[0], v2d->cur.ymin);
- glVertex2f(cent[0], v2d->cur.ymax);
+ immVertex2f(pos, cent[0], v2d->cur.ymin);
+ immVertex2f(pos, cent[0], v2d->cur.ymax);
}
else {
- glVertex2f(cent[0], cent[1] - size);
- glVertex2f(cent[0], cent[1] + size);
+ immVertex2f(pos, cent[0], cent[1] - size);
+ immVertex2f(pos, cent[0], cent[1] + size);
}
if (border & (NODE_TOP | NODE_BOTTOM)) {
- glVertex2f(v2d->cur.xmin, cent[1]);
- glVertex2f(v2d->cur.xmax, cent[1]);
+ immVertex2f(pos, v2d->cur.xmin, cent[1]);
+ immVertex2f(pos, v2d->cur.xmax, cent[1]);
}
else {
- glVertex2f(cent[0] - size, cent[1]);
- glVertex2f(cent[0] + size, cent[1]);
+ immVertex2f(pos, cent[0] - size, cent[1]);
+ immVertex2f(pos, cent[0] + size, cent[1]);
}
- glEnd();
+ immEnd();
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 6e25c87d274..4fc9f08ff02 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -51,9 +51,13 @@
#include "BLF_api.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -617,60 +621,16 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
glDisable(GL_LINE_SMOOTH);
}
-/* this might have some more generic use */
-static void node_circle_draw(float x, float y, float size, const float col[4], int highlight)
+static void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, PointerRNA node_ptr, bNodeSocket *sock, unsigned pos, unsigned col)
{
- /* 16 values of sin function */
- static const float si[16] = {
- 0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
- 0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
- -0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
- -0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f
- };
- /* 16 values of cos function */
- static const float co[16] = {
- 1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
- -0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
- -0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
- 0.15142777f, 0.52896401f, 0.82076344f, 0.97952994f,
- };
- int a;
-
- glColor4fv(col);
-
- glEnable(GL_BLEND);
- glBegin(GL_POLYGON);
- for (a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
- glDisable(GL_BLEND);
-
- if (highlight) {
- UI_ThemeColor(TH_TEXT_HI);
- glLineWidth(1.5f);
- }
- else {
- glColor4ub(0, 0, 0, 150);
- }
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINE_LOOP);
- for (a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
-}
-
-void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *sock, float size, int highlight)
-{
- PointerRNA ptr, node_ptr;
+ PointerRNA ptr;
float color[4];
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
- RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
sock->typeinfo->draw_color((bContext *)C, &ptr, &node_ptr, color);
- node_circle_draw(sock->locx, sock->locy, size, color, highlight);
+
+ immAttrib4fv(col, color);
+ immVertex2f(pos, sock->locx, sock->locy);
}
/* ************** Socket callbacks *********** */
@@ -679,10 +639,15 @@ static void node_draw_preview_background(float tile, rctf *rect)
{
float x, y;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* draw checkerboard backdrop to show alpha */
- glColor3ub(120, 120, 120);
- glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- glColor3ub(160, 160, 160);
+ immUniformColor3ub(120, 120, 120);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformColor3ub(160, 160, 160);
for (y = rect->ymin; y < rect->ymax; y += tile * 2) {
for (x = rect->xmin; x < rect->xmax; x += tile * 2) {
@@ -693,7 +658,7 @@ static void node_draw_preview_background(float tile, rctf *rect)
if (y + tile > rect->ymax)
tiley = rect->ymax - y;
- glRectf(x, y, x + tilex, y + tiley);
+ immRectf(pos, x, y, x + tilex, y + tiley);
}
}
for (y = rect->ymin + tile; y < rect->ymax; y += tile * 2) {
@@ -705,9 +670,10 @@ static void node_draw_preview_background(float tile, rctf *rect)
if (y + tile > rect->ymax)
tiley = rect->ymax - y;
- glRectf(x, y, x + tilex, y + tiley);
+ immRectf(pos, x, y, x + tilex, y + tiley);
}
}
+ immUnbindProgram();
}
/* not a callback */
@@ -740,15 +706,17 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
- glColor4f(1.0, 1.0, 1.0, 1.0);
- glPixelZoom(scale, scale);
- glaDrawPixelsTex(draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect);
- glPixelZoom(1.0f, 1.0f);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect,
+ scale, scale, NULL);
glDisable(GL_BLEND);
- UI_ThemeColorShadeAlpha(TH_BACK, -15, +100);
- fdrawbox(draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -15, +100);
+ imm_draw_line_box(pos, draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax);
+ immUnbindProgram();
}
/* common handle function for operator buttons that need to select the node first */
@@ -773,23 +741,134 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
else {
const float margin = 3.0f;
- glColor4f(0.0f, 0.0f, 0.0f, 0.33f);
- glEnable(GL_BLEND);
- UI_draw_roundbox(rct->xmin - margin, rct->ymin - margin,
- rct->xmax + margin, rct->ymax + margin, radius + margin);
- glDisable(GL_BLEND);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.33f};
+ UI_draw_roundbox_aa(true, rct->xmin - margin, rct->ymin - margin,
+ rct->xmax + margin, rct->ymax + margin, radius + margin, color);
+ }
+}
+
+void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *node, bool draw_outputs, bool select_all)
+{
+ const unsigned int total_input_ct = BLI_listbase_count(&node->inputs);
+ const unsigned int total_output_ct = BLI_listbase_count(&node->outputs);
+
+ if (total_input_ct + total_output_ct == 0) {
+ return;
+ }
+
+ PointerRNA node_ptr;
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
+
+ float scale;
+ UI_view2d_scale_get(v2d, &scale, NULL);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_F32, 4, KEEP_FLOAT);
+
+ glEnable(GL_BLEND);
+ GPU_enable_program_point_size();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA);
+
+ /* set handle size */
+ immUniform1f("size", 2.0f * NODE_SOCKSIZE * scale); /* 2 * size to have diameter */
+
+ if (!select_all) {
+ /* outline for unselected sockets */
+ immUniform1f("outlineWidth", 1.0f);
+ immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 0.6f);
+
+ immBeginAtMost(PRIM_POINTS, total_input_ct + total_output_ct);
+ }
+
+ /* socket inputs */
+ short selected_input_ct = 0;
+ bNodeSocket *sock;
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ ++selected_input_ct;
+ continue;
+ }
+
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ }
+
+ /* socket outputs */
+ short selected_output_ct = 0;
+ if (draw_outputs) {
+ for (sock = node->outputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ ++selected_output_ct;
+ continue;
+ }
+
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ }
+ }
+
+ if (!select_all) {
+ immEnd();
+ }
+
+ /* go back and draw selected sockets */
+ if (selected_input_ct + selected_output_ct > 0) {
+ /* outline for selected sockets */
+ float c[3];
+ UI_GetThemeColor3fv(TH_TEXT_HI, c);
+ immUniform4f("outlineColor", c[0], c[1], c[2], 1.0f);
+ immUniform1f("outlineWidth", 1.5f);
+
+ immBegin(PRIM_POINTS, selected_input_ct + selected_output_ct);
+
+ if (selected_input_ct) {
+ /* socket inputs */
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ if (--selected_input_ct == 0)
+ break; /* stop as soon as last one is drawn */
+ }
+ }
+ }
+
+ if (selected_output_ct) {
+ /* socket outputs */
+ for (sock = node->outputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ if (--selected_output_ct == 0)
+ break; /* stop as soon as last one is drawn */
+ }
+ }
+ }
+
+ immEnd();
}
+
+ immUnbindProgram();
+
+ GPU_disable_program_point_size();
+ glDisable(GL_BLEND);
}
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey key)
{
bNodeInstanceHash *previews = CTX_data_pointer_get(C, "node_previews").data;
- bNodeSocket *sock;
rctf *rct = &node->totr;
float iconofs;
/* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */
float iconbutw = 0.8f * UI_UNIT_X;
int color_id = node_get_colorid(node);
+ float color[4];
char showname[128]; /* 128 used below */
View2D *v2d = &ar->v2d;
@@ -798,7 +877,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
nodeSynchronizeID(node, false);
/* skip if out of view */
- if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
+ if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) {
UI_block_end(C, node->block);
node->block = NULL;
return;
@@ -807,23 +886,24 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
- /* header uses color from backdrop, but we make it opaqie */
- if (color_id == TH_NODE) {
- float col[3];
- UI_GetThemeColorShade3fv(color_id, -20, col);
- glColor4f(col[0], col[1], col[2], 1.0f);
+ if (node->flag & NODE_MUTED) {
+ UI_GetThemeColorBlendShade4fv(color_id, TH_REDALERT, 0.5f, 0, color);
+ }
+ else {
+ /* header uses color from backdrop, but we make it opaque */
+ if (color_id == TH_NODE) {
+ UI_GetThemeColorShade3fv(color_id, -20, color);
+ color[3] = 1.0f;
+ }
+ else {
+ UI_GetThemeColor4fv(color_id, color);
+ }
}
- else
- UI_ThemeColor(color_id);
-
- if (node->flag & NODE_MUTED)
- UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
-
glLineWidth(1.0f);
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
- UI_draw_roundbox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD, color);
/* show/hide icons */
iconofs = rct->xmax - 0.35f * U.widget_unit;
@@ -856,10 +936,12 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
}
/* title */
- if (node->flag & SELECT)
- UI_ThemeColor(TH_SELECT);
- else
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
+ if (node->flag & SELECT) {
+ UI_GetThemeColor4fv(TH_SELECT, color);
+ }
+ else {
+ UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
+ }
/* open/close entirely? */
{
@@ -874,17 +956,9 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_block_emboss_set(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v');
+ UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color);
}
- /* this isn't doing anything for the label, so commenting out */
-#if 0
- if (node->flag & SELECT)
- UI_ThemeColor(TH_TEXT_HI);
- else
- UI_ThemeColor(TH_TEXT);
-#endif
-
nodeLabel(ntree, node, showname, sizeof(showname));
//if (node->flag & NODE_MUTED)
@@ -897,55 +971,30 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* body */
if (!nodeIsRegistered(node))
- UI_ThemeColor4(TH_REDALERT); /* use warning color to indicate undefined types */
- else if (node->flag & NODE_CUSTOM_COLOR)
- glColor3fv(node->color);
+ UI_GetThemeColor4fv(TH_REDALERT, color); /* use warning color to indicate undefined types */
+ else if (node->flag & NODE_CUSTOM_COLOR) {
+ rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], 1.0f);
+ }
else
- UI_ThemeColor4(TH_NODE);
- glEnable(GL_BLEND);
+ UI_GetThemeColor4fv(TH_NODE, color);
+
UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD);
- glDisable(GL_BLEND);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
-
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
-
- if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
- else
- UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
-
+ UI_GetThemeColorShadeAlpha4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
+
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
-
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
}
/* disable lines */
if (node->flag & NODE_MUTED)
node_draw_mute_line(v2d, snode, node);
-
- /* socket inputs, buttons */
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (nodeSocketIsHidden(sock))
- continue;
-
- node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE, sock->flag & SELECT);
- }
-
- /* socket outputs */
- for (sock = node->outputs.first; sock; sock = sock->next) {
- if (nodeSocketIsHidden(sock))
- continue;
-
- node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE, sock->flag & SELECT);
- }
-
+ node_draw_sockets(v2d, C, ntree, node, true, false);
+
/* preview */
if (node->flag & NODE_PREVIEW && previews) {
bNodePreview *preview = BKE_node_instance_hash_lookup(previews, key);
@@ -965,37 +1014,33 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey UNUSED(key))
{
- bNodeSocket *sock;
rctf *rct = &node->totr;
float dx, centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- float socket_size = NODE_SOCKSIZE;
int color_id = node_get_colorid(node);
+ float color[4];
char showname[128]; /* 128 is used below */
+ View2D *v2d = &ar->v2d;
+ float scale;
+
+ UI_view2d_scale_get(v2d, &scale, NULL);
/* shadow */
node_draw_shadow(snode, node, hiddenrad, 1.0f);
/* body */
- UI_ThemeColor(color_id);
if (node->flag & NODE_MUTED)
- UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
-
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
+ UI_GetThemeColorBlendShade4fv(color_id, TH_REDALERT, 0.5f, 0, color);
+ else
+ UI_GetThemeColor4fv(color_id, color);
+
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
-
- if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
- else
- UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
-
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ UI_GetThemeColorShadeAlpha4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
+
+ UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
}
/* custom color inline */
@@ -1003,18 +1048,19 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glColor3fv(node->color);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad);
+ UI_draw_roundbox_3fvAlpha(false, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad, node->color, 1.0f);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
/* title */
- if (node->flag & SELECT)
- UI_ThemeColor(TH_SELECT);
- else
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
+ if (node->flag & SELECT) {
+ UI_GetThemeColor4fv(TH_SELECT, color);
+ }
+ else {
+ UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
+ }
/* open entirely icon */
{
@@ -1029,18 +1075,13 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
UI_block_emboss_set(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h');
+ UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h', color);
}
/* disable lines */
if (node->flag & NODE_MUTED)
node_draw_mute_line(&ar->v2d, snode, node);
-
- if (node->flag & SELECT)
- UI_ThemeColor(TH_SELECT);
- else
- UI_ThemeColor(TH_TEXT);
-
+
if (node->miniwidth > 0.0f) {
nodeLabel(ntree, node, showname, sizeof(showname));
@@ -1054,27 +1095,35 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
}
/* scale widget thing */
- UI_ThemeColorShade(color_id, -10);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColorShade(color_id, -10);
dx = 10.0f;
- fdrawline(rct->xmax - dx, centy - 4.0f, rct->xmax - dx, centy + 4.0f);
- fdrawline(rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
-
- UI_ThemeColorShade(color_id, +30);
+
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
+
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immEnd();
+
+ immUniformThemeColorShade(color_id, 30);
dx -= snode->aspect;
- fdrawline(rct->xmax - dx, centy - 4.0f, rct->xmax - dx, centy + 4.0f);
- fdrawline(rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
- /* sockets */
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (!nodeSocketIsHidden(sock))
- node_socket_circle_draw(C, ntree, node, sock, socket_size, sock->flag & SELECT);
- }
-
- for (sock = node->outputs.first; sock; sock = sock->next) {
- if (!nodeSocketIsHidden(sock))
- node_socket_circle_draw(C, ntree, node, sock, socket_size, sock->flag & SELECT);
- }
-
+ immBegin(PRIM_LINES, 4);
+ immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
+
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ node_draw_sockets(v2d, C, ntree, node, true, false);
+
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
node->block = NULL;
@@ -1215,7 +1264,7 @@ static void draw_tree_path(SpaceNode *snode)
ED_node_tree_path_get_fixedbuf(snode, info, sizeof(info));
- UI_ThemeColor(TH_TEXT_HI);
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
BLF_draw_default(1.5f * UI_UNIT_X, 1.5f * UI_UNIT_Y, 0.0f, info, sizeof(info));
}
@@ -1248,12 +1297,14 @@ static void draw_group_overlay(const bContext *C, ARegion *ar)
View2D *v2d = &ar->v2d;
rctf rect = v2d->cur;
uiBlock *block;
-
+ float color[4];
+
/* shade node groups to separate them visually */
- UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70);
glEnable(GL_BLEND);
+
+ UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, -70, color);
UI_draw_roundbox_corner_set(UI_CNR_NONE);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0);
+ UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color);
glDisable(GL_BLEND);
/* set the block bounds to clip mouse events from underlying nodes */
@@ -1285,7 +1336,6 @@ void drawnodespace(const bContext *C, ARegion *ar)
/* only set once */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_MAP1_VERTEX_3);
/* nodes */
snode_set_context(C);
@@ -1345,7 +1395,23 @@ void drawnodespace(const bContext *C, ARegion *ar)
/* backdrop */
draw_nodespace_back_pix(C, ar, snode, path->parent_key);
-
+
+ {
+ float original_proj[4][4];
+ gpuGetProjectionMatrix(original_proj);
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ glaDefine2DArea(&ar->winrct);
+ wmOrtho2_pixelspace(ar->winx, ar->winy);
+
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
+
+ gpuPopMatrix();
+ gpuLoadProjectionMatrix(original_proj);
+ }
+
draw_nodetree(C, ar, ntree, path->parent_key);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 9dc39b1839b..3cb5fd94ea9 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -397,6 +397,14 @@ void ED_node_shader_default(const bContext *C, ID *id)
Material *ma = (Material *)id;
ma->nodetree = ntree;
+ if (BKE_scene_uses_blender_eevee(scene)) {
+ out = nodeAddStaticNode(C, ntree, SH_NODE_OUTPUT_METALLIC);
+ out->locx = 300.0f; out->locy = 300.0f;
+ nodeSetActive(ntree, out);
+ ntreeUpdateTree(CTX_data_main(C), ntree);
+ return;
+ }
+
if (BKE_scene_use_new_shading_nodes(scene)) {
output_type = SH_NODE_OUTPUT_MATERIAL;
shader_type = SH_NODE_BSDF_DIFFUSE;
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 6b8fa0b88fe..b425a92f601 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -67,12 +67,11 @@ void snode_group_offset(struct SpaceNode *snode, float *x, float *y); /* transfo
/* node_draw.c */
int node_get_colorid(struct bNode *node);
-void node_socket_circle_draw(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node,
- struct bNodeSocket *sock, float size, int highlight);
int node_get_resize_cursor(int directions);
void node_draw_shadow(struct SpaceNode *snode, struct bNode *node, float radius, float alpha);
void node_draw_default(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode,
struct bNodeTree *ntree, struct bNode *node, bNodeInstanceKey key);
+void node_draw_sockets(struct View2D *v2d, const struct bContext *C, struct bNodeTree *ntree, struct bNode *node, bool draw_outputs, bool select_all);
void node_update_default(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node);
int node_select_area_default(struct bNode *node, int x, int y);
int node_tweak_area_default(struct bNode *node, int x, int y);
@@ -220,6 +219,10 @@ void NODE_OT_shader_script_update(struct wmOperatorType *ot);
void NODE_OT_viewer_border(struct wmOperatorType *ot);
void NODE_OT_clear_viewer_border(struct wmOperatorType *ot);
+/* node_widgets.c */
+void NODE_WGT_backdrop_transform(struct wmManipulatorGroupType *wgt);
+
+
extern const char *node_context_dir[];
// XXXXXX
diff --git a/source/blender/editors/space_node/node_widgets.c b/source/blender/editors/space_node/node_widgets.c
new file mode 100644
index 00000000000..9e7445b8566
--- /dev/null
+++ b/source/blender/editors/space_node/node_widgets.c
@@ -0,0 +1,114 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_node/node_widgets.c
+ * \ingroup spnode
+ */
+
+#include "BKE_context.h"
+#include "BKE_image.h"
+
+#include "DNA_manipulator_types.h"
+
+#include "ED_screen.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "node_intern.h"
+
+
+static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgrouptype))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && node->type == CMP_NODE_VIEWER) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_transform_init(const bContext *UNUSED(C), wmManipulatorGroup *wgroup)
+{
+ wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
+
+ wwrapper->manipulator = MANIPULATOR_rect_transform_new(
+ wgroup, "backdrop_cage",
+ MANIPULATOR_RECT_TRANSFORM_STYLE_TRANSLATE | MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM);
+ wgroup->customdata = wwrapper;
+
+}
+
+static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmManipulatorGroup *wgroup)
+{
+ wmManipulator *cage = ((wmManipulatorWrapper *)wgroup->customdata)->manipulator;
+ const ARegion *ar = CTX_wm_region(C);
+ /* center is always at the origin */
+ const float origin[3] = {ar->winx / 2, ar->winy / 2};
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ const float w = (ibuf->x > 0) ? ibuf->x : 64.0f;
+ const float h = (ibuf->y > 0) ? ibuf->y : 64.0f;
+
+ MANIPULATOR_rect_transform_set_dimensions(cage, w, h);
+ WM_manipulator_set_origin(cage, origin);
+ WM_manipulator_set_flag(cage, WM_MANIPULATOR_HIDDEN, false);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ SpaceNode *snode = CTX_wm_space_node(C);
+ PointerRNA nodeptr;
+ RNA_pointer_create(snode->id, &RNA_SpaceNodeEditor, snode, &nodeptr);
+ WM_manipulator_set_property(cage, RECT_TRANSFORM_SLOT_OFFSET, &nodeptr, "backdrop_offset");
+ WM_manipulator_set_property(cage, RECT_TRANSFORM_SLOT_SCALE, &nodeptr, "backdrop_zoom");
+ }
+ else {
+ WM_manipulator_set_flag(cage, WM_MANIPULATOR_HIDDEN, true);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_transform(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Backdrop Transform Widgets";
+
+ wgt->poll = WIDGETGROUP_node_transform_poll;
+ wgt->init = WIDGETGROUP_node_transform_init;
+ wgt->refresh = WIDGETGROUP_node_transform_refresh;
+}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index bbdf6feef01..4eeb4d02d8c 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -57,6 +57,8 @@
#include "RNA_access.h"
+#include "WM_api.h"
+
#include "node_intern.h" /* own include */
@@ -381,12 +383,12 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
}
-static void node_area_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
+static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *scene)
{
/* note, ED_area_tag_refresh will re-execute compositor */
SpaceNode *snode = sa->spacedata.first;
/* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
- short shader_type = BKE_scene_use_new_shading_nodes(sc->scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT;
+ short shader_type = BKE_scene_use_new_shading_nodes(scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT;
/* preview renders */
switch (wmn->category) {
@@ -643,6 +645,14 @@ static void node_main_region_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
+ /* manipulators stay in the background for now - quick patchjob to make sure nodes themselves work */
+ if (!ar->manipulator_map) {
+ ar->manipulator_map = WM_manipulatormap_new_from_type(&(const struct wmManipulatorMapType_Params) {
+ "Node_Canvas", SPACE_NODE, RGN_TYPE_WINDOW});
+ }
+
+ WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
+
/* own keymaps */
keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -737,15 +747,28 @@ static void node_header_region_draw(const bContext *C, ARegion *ar)
}
/* used for header + main region */
-static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void node_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
+ wmManipulatorMap *mmap = ar->manipulator_map;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
- if (wmn->data == ND_SPACE_NODE)
- ED_region_tag_redraw(ar);
+ switch (wmn->data) {
+ case ND_SPACE_NODE:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_SPACE_NODE_VIEW:
+ WM_manipulatormap_tag_refresh(mmap);
+ break;
+ }
break;
case NC_SCREEN:
+ if (wmn->data == ND_SCREENSET || wmn->action == NA_EDITED) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
switch (wmn->data) {
case ND_SCREENCAST:
case ND_ANIMPLAY:
@@ -754,10 +777,20 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi
}
break;
case NC_SCENE:
+ ED_region_tag_redraw(ar);
+ if (wmn->data == ND_RENDER_RESULT) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
+ break;
+ case NC_NODE:
+ ED_region_tag_redraw(ar);
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
+ break;
case NC_MATERIAL:
case NC_TEXTURE:
case NC_WORLD:
- case NC_NODE:
case NC_LINESTYLE:
ED_region_tag_redraw(ar);
break;
@@ -822,6 +855,14 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
return 0;
}
+static void node_widgets(void)
+{
+ /* create the widgetmap for the area here */
+ wmManipulatorMapType *wmaptype = WM_manipulatormaptype_ensure(&(const struct wmManipulatorMapType_Params) {
+ "Node_Canvas", SPACE_NODE, RGN_TYPE_WINDOW});
+ WM_manipulatorgrouptype_append(wmaptype, NODE_WGT_backdrop_transform);
+}
+
static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
SpaceNode *snode = (SpaceNode *)slink;
@@ -912,6 +953,7 @@ void ED_spacetype_node(void)
st->refresh = node_area_refresh;
st->context = node_context;
st->dropboxes = node_dropboxes;
+ st->manipulators = node_widgets;
st->id_remap = node_id_remap;
/* regions: main window */
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 289d6e715e1..a9d630c31e5 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -37,12 +37,14 @@ set(INC_SYS
)
set(SRC
+ outliner_collections.c
outliner_draw.c
outliner_edit.c
outliner_ops.c
outliner_select.c
outliner_tools.c
outliner_tree.c
+ outliner_utils.c
space_outliner.c
outliner_intern.h
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
new file mode 100644
index 00000000000..97b03693ca6
--- /dev/null
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -0,0 +1,462 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Blender Foundation, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_outliner/outliner_collections.c
+ * \ingroup spoutliner
+ */
+
+#include "BKE_context.h"
+#include "BKE_collection.h"
+#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
+#include "BKE_report.h"
+
+#include "BLI_listbase.h"
+
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "UI_resources.h"
+
+#include "outliner_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+
+static LayerCollection *outliner_collection_active(bContext *C)
+{
+ TODO_LAYER_OPERATORS;
+ /* consider that we may have overrides or objects active
+ * leading to no active collections */
+ return CTX_data_layer_collection(C);
+}
+
+SceneCollection *outliner_scene_collection_from_tree_element(TreeElement *te)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (tselem->type == TSE_SCENE_COLLECTION) {
+ return te->directdata;
+ }
+ else if (tselem->type == TSE_LAYER_COLLECTION) {
+ LayerCollection *lc = te->directdata;
+ return lc->scene_collection;
+ }
+
+ return NULL;
+}
+
+#if 0
+static CollectionOverride *outliner_override_active(bContext *UNUSED(C))
+{
+ TODO_LAYER_OPERATORS;
+ TODO_LAYER_OVERRIDE;
+ return NULL;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* collection manager operators */
+
+/**
+ * Recursively get the collection for a given index
+ */
+static SceneCollection *scene_collection_from_index(ListBase *lb, const int number, int *i)
+{
+ for (SceneCollection *sc = lb->first; sc; sc = sc->next) {
+ if (*i == number) {
+ return sc;
+ }
+
+ (*i)++;
+
+ SceneCollection *sc_nested = scene_collection_from_index(&sc->scene_collections, number, i);
+ if (sc_nested) {
+ return sc_nested;
+ }
+ }
+ return NULL;
+}
+
+static int collection_link_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc;
+
+ int scene_collection_index = RNA_enum_get(op->ptr, "scene_collection");
+ if (scene_collection_index == 0) {
+ sc = sc_master;
+ }
+ else {
+ int index = 1;
+ sc = scene_collection_from_index(&sc_master->scene_collections, scene_collection_index, &index);
+ BLI_assert(sc);
+ }
+
+ BKE_collection_link(sl, sc);
+
+ DAG_relations_tag_update(CTX_data_main(C));
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ return OPERATOR_FINISHED;
+}
+
+static int collection_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ if (BKE_collection_master(CTX_data_scene(C))->scene_collections.first == NULL) {
+ RNA_enum_set(op->ptr, "scene_collection", 0);
+ return collection_link_exec(C, op);
+ }
+ else {
+ return WM_enum_search_invoke(C, op, event);
+ }
+}
+
+static void collection_scene_collection_itemf_recursive(
+ EnumPropertyItem *tmp, EnumPropertyItem **item, int *totitem, int *value, SceneCollection *sc)
+{
+ tmp->value = *value;
+ tmp->icon = ICON_COLLAPSEMENU;
+ tmp->identifier = sc->name;
+ tmp->name = sc->name;
+ RNA_enum_item_add(item, totitem, tmp);
+
+ (*value)++;
+
+ for (SceneCollection *ncs = sc->scene_collections.first; ncs; ncs = ncs->next) {
+ collection_scene_collection_itemf_recursive(tmp, item, totitem, value, ncs);
+ }
+}
+
+static EnumPropertyItem *collection_scene_collection_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ EnumPropertyItem *item = NULL;
+ int value = 0, totitem = 0;
+
+ Scene *scene = CTX_data_scene(C);
+ SceneCollection *sc = BKE_collection_master(scene);
+
+ collection_scene_collection_itemf_recursive(&tmp, &item, &totitem, &value, sc);
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+void OUTLINER_OT_collection_link(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Add Collection";
+ ot->idname = "OUTLINER_OT_collection_link";
+ ot->description = "Link a new collection to the active layer";
+
+ /* api callbacks */
+ ot->exec = collection_link_exec;
+ ot->invoke = collection_link_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ prop = RNA_def_enum(ot->srna, "scene_collection", DummyRNA_NULL_items, 0, "Scene Collection", "");
+ RNA_def_enum_funcs(prop, collection_scene_collection_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
+}
+
+/**
+ * Returns true if selected element is a collection directly
+ * linked to the active SceneLayer (not a nested collection)
+ */
+static int collection_unlink_poll(bContext *C)
+{
+ LayerCollection *lc = outliner_collection_active(C);
+
+ if (lc == NULL) {
+ return 0;
+ }
+
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ return BLI_findindex(&sl->layer_collections, lc) != -1 ? 1 : 0;
+}
+
+static int collection_unlink_exec(bContext *C, wmOperator *op)
+{
+ LayerCollection *lc = outliner_collection_active(C);
+
+ if (lc == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Active element is not a collection");
+ return OPERATOR_CANCELLED;
+ }
+
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ BKE_collection_unlink(sl, lc);
+
+ DAG_relations_tag_update(CTX_data_main(C));
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&CTX_data_scene(C)->id, 0);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_unlink(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Collection";
+ ot->idname = "OUTLINER_OT_collection_unlink";
+ ot->description = "Unlink collection from the active layer";
+
+ /* api callbacks */
+ ot->exec = collection_unlink_exec;
+ ot->poll = collection_unlink_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int collection_new_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+
+ SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
+ BKE_collection_link(sl, sc);
+
+ DAG_relations_tag_update(CTX_data_main(C));
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "New Collection";
+ ot->idname = "OUTLINER_OT_collection_new";
+ ot->description = "Add a new collection to the scene, and link it to the active layer";
+
+ /* api callbacks */
+ ot->exec = collection_new_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/**
+ * Returns true is selected element is a collection
+ */
+static int collection_override_new_poll(bContext *(C))
+{
+#ifdef TODO_LAYER_OVERRIDE
+ /* disable for now, since it's not implemented */
+ (void) C;
+ return 0;
+#else
+ return outliner_collection_active(C) ? 1 : 0;
+#endif
+}
+
+static int collection_override_new_invoke(bContext *UNUSED(C), wmOperator *op, const wmEvent *UNUSED(event))
+{
+ TODO_LAYER_OPERATORS;
+ TODO_LAYER_OVERRIDE;
+ BKE_report(op->reports, RPT_ERROR, "OUTLINER_OT_collections_override_new not implemented yet");
+ return OPERATOR_CANCELLED;
+}
+
+/* in the middle of renames remove s */
+void OUTLINER_OT_collection_override_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "New Override";
+ ot->idname = "OUTLINER_OT_collection_override_new";
+ ot->description = "Add a new override to the active collection";
+
+ /* api callbacks */
+ ot->invoke = collection_override_new_invoke;
+ ot->poll = collection_override_new_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+struct CollectionDeleteData {
+ Scene *scene;
+ SpaceOops *soops;
+};
+
+static TreeTraversalAction collection_delete_cb(TreeElement *te, void *customdata)
+{
+ struct CollectionDeleteData *data = customdata;
+ SceneCollection *scene_collection = outliner_scene_collection_from_tree_element(te);
+
+ if (!scene_collection) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
+
+ if (scene_collection == BKE_collection_master(data->scene)) {
+ /* skip - showing warning/error message might be missleading
+ * when deleting multiple collections, so just do nothing */
+ }
+ else {
+ BKE_collection_remove(data->scene, scene_collection);
+ }
+
+ return TRAVERSE_CONTINUE;
+}
+
+static int collection_delete_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ struct CollectionDeleteData data = {.scene = scene, .soops = soops};
+
+ TODO_LAYER_OVERRIDE; /* handle overrides */
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_delete_cb, &data);
+
+ DAG_relations_tag_update(CTX_data_main(C));
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collections_delete(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Delete";
+ ot->idname = "OUTLINER_OT_collections_delete";
+ ot->description = "Delete selected overrides or collections";
+
+ /* api callbacks */
+ ot->exec = collection_delete_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int collection_select_exec(bContext *C, wmOperator *op)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ const int collection_index = RNA_int_get(op->ptr, "collection_index");
+ sl->active_collection = collection_index;
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select";
+ ot->idname = "OUTLINER_OT_collection_select";
+ ot->description = "Change active collection or override";
+
+ /* api callbacks */
+ ot->exec = collection_select_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_int(ot->srna, "collection_index", 0, 0, INT_MAX, "Index",
+ "Index of collection to select", 0, INT_MAX);
+}
+
+/* -------------------------------------------------------------------- */
+
+static int stubs_invoke(bContext *UNUSED(C), wmOperator *op, const wmEvent *UNUSED(event))
+{
+ TODO_LAYER_OPERATORS;
+ BKE_report(op->reports, RPT_ERROR, "Operator not implemented yet");
+ return OPERATOR_CANCELLED;
+}
+
+void OUTLINER_OT_collection_objects_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Objects";
+ ot->idname = "OUTLINER_OT_collection_objects_add";
+ ot->description = "Add selected objects to collection";
+
+ /* api callbacks */
+ ot->invoke = stubs_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_objects_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Object";
+ ot->idname = "OUTLINER_OT_collection_objects_remove";
+ ot->description = "Remove objects from collection";
+
+ /* api callbacks */
+ ot->invoke = stubs_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_objects_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Objects";
+ ot->idname = "OUTLINER_OT_collection_objects_select";
+ ot->description = "Select collection objects";
+
+ /* api callbacks */
+ ot->invoke = stubs_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_objects_deselect(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Deselect Objects";
+ ot->idname = "OUTLINER_OT_collection_objects_deselect";
+ ot->description = "Deselect collection objects";
+
+ /* api callbacks */
+ ot->invoke = stubs_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 121fe812016..1755370a5d6 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -51,6 +51,7 @@
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
@@ -66,8 +67,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "GPU_immediate.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
@@ -172,116 +172,6 @@ static void restrictbutton_recursive_bone(Bone *bone_parent, int flag, bool set_
}
-static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob_parent, char flag,
- bool state, bool deselect, const char *rnapropname)
-{
- Main *bmain = CTX_data_main(C);
- Object *ob;
-
- for (ob = bmain->object.first; ob; ob = ob->id.next) {
- if (BKE_object_is_child_recursive(ob_parent, ob)) {
- /* only do if child object is selectable */
- if ((flag == OB_RESTRICT_SELECT) || (ob->restrictflag & OB_RESTRICT_SELECT) == 0) {
- if (state) {
- ob->restrictflag |= flag;
- if (deselect) {
- ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
- }
- }
- else {
- ob->restrictflag &= ~flag;
- }
- }
-
- if (rnapropname) {
- PointerRNA ptr;
- PropertyRNA *prop;
- ID *id;
- bAction *action;
- FCurve *fcu;
- bool driven, special;
-
- RNA_id_pointer_create(&ob->id, &ptr);
- prop = RNA_struct_find_property(&ptr, rnapropname);
- fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, NULL, &action, &driven, &special);
-
- if (fcu && !driven) {
- id = ptr.id.data;
- if (autokeyframe_cfra_can_key(scene, id)) {
- ReportList *reports = CTX_wm_reports(C);
- ToolSettings *ts = scene->toolsettings;
- eInsertKeyFlags key_flag = ANIM_get_keyframing_flags(scene, 1);
-
- fcu->flag &= ~FCURVE_SELECTED;
- insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path, fcu->array_index, CFRA, ts->keyframe_type, key_flag);
- /* Assuming this is not necessary here, since 'ancestor' object button will do it anyway. */
- /* WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); */
- }
- }
- }
- }
- }
-}
-
-static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2)
-{
- Scene *scene = (Scene *)poin;
- Object *ob = (Object *)poin2;
-
- if (!common_restrict_check(C, ob)) return;
-
- /* deselect objects that are invisible */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
- /* Ouch! There is no backwards pointer from Object to Base,
- * so have to do loop to find it. */
- ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
- }
-
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_child(C, scene, ob, OB_RESTRICT_VIEW,
- (ob->restrictflag & OB_RESTRICT_VIEW) != 0, true, "hide");
- }
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-
-}
-
-static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2)
-{
- Scene *scene = (Scene *)poin;
- Object *ob = (Object *)poin2;
-
- if (!common_restrict_check(C, ob)) return;
-
- /* if select restriction has just been turned on */
- if (ob->restrictflag & OB_RESTRICT_SELECT) {
- /* Ouch! There is no backwards pointer from Object to Base,
- * so have to do loop to find it. */
- ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
- }
-
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_child(C, scene, ob, OB_RESTRICT_SELECT,
- (ob->restrictflag & OB_RESTRICT_SELECT) != 0, true, NULL);
- }
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-
-}
-
-static void restrictbutton_rend_cb(bContext *C, void *poin, void *poin2)
-{
- Object *ob = (Object *)poin2;
-
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_child(C, (Scene *)poin, ob, OB_RESTRICT_RENDER,
- (ob->restrictflag & OB_RESTRICT_RENDER) != 0, false, "hide_render");
- }
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, poin);
-}
-
static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
@@ -355,96 +245,14 @@ static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), voi
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
-static int group_restrict_flag(Group *gr, int flag)
+static void restrictbutton_collection_flag_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
- GroupObject *gob;
-
-#ifdef USE_GROUP_SELECT
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if ((gob->ob->restrictflag & flag) == 0)
- return 0;
- }
- return 1;
-#else
- /* weak but fast */
- if ((gob = gr->gobject.first))
- if ((gob->ob->restrictflag & flag) == 0)
- return 0;
- return 1;
-#endif
-}
-
-static int group_select_flag(Group *gr)
-{
- GroupObject *gob;
-
-#ifdef USE_GROUP_SELECT
- for (gob = gr->gobject.first; gob; gob = gob->next)
- if ((gob->ob->flag & SELECT))
- return 1;
-
- return 0;
-#else
- /* weak but fast */
- if ((gob = gr->gobject.first))
- if (gob->ob->flag & SELECT)
- return 1;
- return 0;
-#endif
-}
-
-void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag)
-{
- Scene *scene = (Scene *)poin;
- GroupObject *gob;
- Group *gr = (Group *)poin2;
-
- if (group_restrict_flag(gr, flag)) {
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if (ID_IS_LINKED_DATABLOCK(gob->ob))
- continue;
-
- gob->ob->restrictflag &= ~flag;
-
- if (flag == OB_RESTRICT_VIEW)
- if (gob->ob->flag & SELECT)
- ED_base_object_select(BKE_scene_base_find(scene, gob->ob), BA_DESELECT);
- }
- }
- else {
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if (ID_IS_LINKED_DATABLOCK(gob->ob))
- continue;
-
- /* not in editmode */
- if (scene->obedit != gob->ob) {
- gob->ob->restrictflag |= flag;
-
- if (ELEM(flag, OB_RESTRICT_SELECT, OB_RESTRICT_VIEW)) {
- if ((gob->ob->flag & SELECT)) {
- ED_base_object_select(BKE_scene_base_find(scene, gob->ob), BA_DESELECT);
- }
- }
- }
- }
- }
-}
-
-static void restrictbutton_gr_restrict_view(bContext *C, void *poin, void *poin2)
-{
- restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_VIEW);
- WM_event_add_notifier(C, NC_GROUP, NULL);
- DAG_id_type_tag(CTX_data_main(C), ID_OB);
-}
-static void restrictbutton_gr_restrict_select(bContext *C, void *poin, void *poin2)
-{
- restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_SELECT);
- WM_event_add_notifier(C, NC_GROUP, NULL);
-}
-static void restrictbutton_gr_restrict_render(bContext *C, void *poin, void *poin2)
-{
- restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_RENDER);
- WM_event_add_notifier(C, NC_GROUP, NULL);
+ Scene *scene = poin;
+ /* hide and deselect bases that are directly influenced by this LayerCollection */
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL);
}
static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
@@ -466,6 +274,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
BLI_mempool *ts = soops->treestore;
TreeStoreElem *tselem = tsep;
@@ -527,7 +336,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
BLI_strncpy(newname, ebone->name, sizeof(ebone->name));
BLI_strncpy(ebone->name, oldname, sizeof(ebone->name));
ED_armature_bone_rename(obedit->data, oldname, newname);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, OBACT);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, OBACT_NEW);
}
break;
}
@@ -539,8 +348,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
char newname[sizeof(bone->name)];
/* always make current object active */
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
- ob = OBACT;
+ tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NORMAL, true);
+ ob = OBACT_NEW;
/* restore bone name */
BLI_strncpy(newname, bone->name, sizeof(bone->name));
@@ -556,8 +365,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
char newname[sizeof(pchan->name)];
/* always make current pose-bone active */
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
- ob = OBACT;
+ tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NORMAL, true);
+ ob = OBACT_NEW;
BLI_assert(ob->type == OB_ARMATURE);
@@ -591,6 +400,13 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
}
case TSE_R_LAYER:
break;
+ case TSE_SCENE_COLLECTION:
+ case TSE_LAYER_COLLECTION:
+ {
+ SceneCollection *sc = outliner_scene_collection_from_tree_element(te);
+ BKE_collection_rename(scene, sc, te->name);
+ break;
+ }
}
}
tselem->flag &= ~TSE_TEXTBUT;
@@ -603,7 +419,6 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
TreeElement *te;
TreeStoreElem *tselem;
Object *ob = NULL;
- Group *gr = NULL;
PropertyRNA *object_prop_hide, *object_prop_hide_select, *object_prop_hide_render;
@@ -617,73 +432,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
- /* objects have toggle-able restriction flags */
- if (tselem->type == 0 && te->idcode == ID_OB) {
- PointerRNA ptr;
-
- ob = (Object *)tselem->id;
- RNA_pointer_create((ID *)ob, &RNA_Object, ob, &ptr);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, object_prop_hide, -1, 0, 0, -1, -1,
- TIP_("Restrict viewport visibility (Ctrl - Recursive)"));
- UI_but_func_set(bt, restrictbutton_view_cb, scene, ob);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, object_prop_hide_select, -1, 0, 0, -1, -1,
- TIP_("Restrict viewport selection (Ctrl - Recursive)"));
- UI_but_func_set(bt, restrictbutton_sel_cb, scene, ob);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, object_prop_hide_render, -1, 0, 0, -1, -1,
- TIP_("Restrict rendering (Ctrl - Recursive)"));
- UI_but_func_set(bt, restrictbutton_rend_cb, scene, ob);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- UI_block_emboss_set(block, UI_EMBOSS);
-
- }
- if (tselem->type == 0 && te->idcode == ID_GR) {
- int restrict_bool;
- int but_flag = UI_BUT_DRAG_LOCK;
- gr = (Group *)tselem->id;
-
- if (ID_IS_LINKED_DATABLOCK(gr))
- but_flag |= UI_BUT_DISABLED;
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW);
- bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_gr_restrict_view, scene, gr);
- UI_but_flag_enable(bt, but_flag);
-
- restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT);
- bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_gr_restrict_select, scene, gr);
- UI_but_flag_enable(bt, but_flag);
-
- restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER);
- bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
- UI_but_func_set(bt, restrictbutton_gr_restrict_render, scene, gr);
- UI_but_flag_enable(bt, but_flag);
-
- UI_block_emboss_set(block, UI_EMBOSS);
- }
/* scene render layers and passes have toggle-able flags too! */
- else if (tselem->type == TSE_R_LAYER) {
+ if (tselem->type == TSE_R_LAYER) {
UI_block_emboss_set(block, UI_EMBOSS_NONE);
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
@@ -805,6 +555,27 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
UI_block_emboss_set(block, UI_EMBOSS);
}
+ else if (tselem->type == TSE_LAYER_COLLECTION) {
+ LayerCollection *collection = te->directdata;
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_VISIBLE, 0, ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
+ TIP_("Restrict/Allow 3D View visibility of objects in the collection"));
+ UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_SELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
+ TIP_("Restrict/Allow 3D View selection of objects in the collection"));
+ UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
}
if (TSELEM_OPEN(tselem, soops)) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
@@ -878,18 +649,23 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
float miny = v2d->cur.ymin;
if (miny < v2d->tot.ymin) miny = v2d->tot.ymin;
- UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
+ glLineWidth(1.0f);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- /* draw column separator lines */
- fdrawline((float)sizex,
- v2d->cur.ymax,
- (float)sizex,
- miny);
+ immBegin(PRIM_LINES, 4);
- fdrawline((float)sizex + OL_RNA_COL_SIZEX,
- v2d->cur.ymax,
- (float)sizex + OL_RNA_COL_SIZEX,
- miny);
+ immVertex2f(pos, sizex, v2d->cur.ymax);
+ immVertex2f(pos, sizex, miny);
+
+ immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, v2d->cur.ymax);
+ immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, miny);
+
+ immEnd();
+
+ immUnbindProgram();
}
static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb)
@@ -987,7 +763,7 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
/* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */
if (arg->x >= arg->xmax) {
glEnable(GL_BLEND);
- UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_FAC, arg->alpha);
+ UI_icon_draw_alpha(arg->x, arg->y, icon, arg->alpha);
glDisable(GL_BLEND);
}
else {
@@ -1047,7 +823,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
arg.xb = x; /* for ui buttons */
arg.yb = y;
arg.alpha = alpha;
-
+
/* placement of icons, copied from interface_widgets.c */
aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
x += 2.0f * aspect;
@@ -1055,184 +831,253 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
arg.x = x;
arg.y = y;
+#define ICON_DRAW(_icon) UI_icon_draw_alpha(x, y, _icon, alpha)
+
if (tselem->type) {
switch (tselem->type) {
case TSE_ANIM_DATA:
- UI_icon_draw(x, y, ICON_ANIM_DATA); break; // xxx
+ ICON_DRAW(ICON_ANIM_DATA); /* XXX */
+ break;
case TSE_NLA:
- UI_icon_draw(x, y, ICON_NLA); break;
+ ICON_DRAW(ICON_NLA);
+ break;
case TSE_NLA_TRACK:
- UI_icon_draw(x, y, ICON_NLA); break; // XXX
+ ICON_DRAW(ICON_NLA); /* XXX */
+ break;
case TSE_NLA_ACTION:
- UI_icon_draw(x, y, ICON_ACTION); break;
+ ICON_DRAW(ICON_ACTION);
+ break;
case TSE_DRIVER_BASE:
- UI_icon_draw(x, y, ICON_DRIVER); break;
+ ICON_DRAW(ICON_DRIVER);
+ break;
case TSE_DEFGROUP_BASE:
- UI_icon_draw(x, y, ICON_GROUP_VERTEX); break;
+ ICON_DRAW(ICON_GROUP_VERTEX);
+ break;
case TSE_BONE:
case TSE_EBONE:
- UI_icon_draw(x, y, ICON_BONE_DATA); break;
+ ICON_DRAW(ICON_BONE_DATA);
+ break;
case TSE_CONSTRAINT_BASE:
- UI_icon_draw(x, y, ICON_CONSTRAINT); break;
+ ICON_DRAW(ICON_CONSTRAINT);
+ break;
case TSE_MODIFIER_BASE:
- UI_icon_draw(x, y, ICON_MODIFIER); break;
+ ICON_DRAW(ICON_MODIFIER);
+ break;
case TSE_LINKED_OB:
- UI_icon_draw(x, y, ICON_OBJECT_DATA); break;
+ ICON_DRAW(ICON_OBJECT_DATA);
+ break;
case TSE_LINKED_PSYS:
- UI_icon_draw(x, y, ICON_PARTICLES); break;
+ ICON_DRAW(ICON_PARTICLES);
+ break;
case TSE_MODIFIER:
{
Object *ob = (Object *)tselem->id;
ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
switch ((ModifierType)md->type) {
- case eModifierType_Subsurf:
- UI_icon_draw(x, y, ICON_MOD_SUBSURF); break;
- case eModifierType_Armature:
- UI_icon_draw(x, y, ICON_MOD_ARMATURE); break;
- case eModifierType_Lattice:
- UI_icon_draw(x, y, ICON_MOD_LATTICE); break;
- case eModifierType_Curve:
- UI_icon_draw(x, y, ICON_MOD_CURVE); break;
- case eModifierType_Build:
- UI_icon_draw(x, y, ICON_MOD_BUILD); break;
- case eModifierType_Mirror:
- UI_icon_draw(x, y, ICON_MOD_MIRROR); break;
- case eModifierType_Decimate:
- UI_icon_draw(x, y, ICON_MOD_DECIM); break;
- case eModifierType_Wave:
- UI_icon_draw(x, y, ICON_MOD_WAVE); break;
- case eModifierType_Hook:
- UI_icon_draw(x, y, ICON_HOOK); break;
- case eModifierType_Softbody:
- UI_icon_draw(x, y, ICON_MOD_SOFT); break;
- case eModifierType_Boolean:
- UI_icon_draw(x, y, ICON_MOD_BOOLEAN); break;
- case eModifierType_ParticleSystem:
- UI_icon_draw(x, y, ICON_MOD_PARTICLES); break;
+ case eModifierType_Subsurf:
+ ICON_DRAW(ICON_MOD_SUBSURF);
+ break;
+ case eModifierType_Armature:
+ ICON_DRAW(ICON_MOD_ARMATURE);
+ break;
+ case eModifierType_Lattice:
+ ICON_DRAW(ICON_MOD_LATTICE);
+ break;
+ case eModifierType_Curve:
+ ICON_DRAW(ICON_MOD_CURVE);
+ break;
+ case eModifierType_Build:
+ ICON_DRAW(ICON_MOD_BUILD);
+ break;
+ case eModifierType_Mirror:
+ ICON_DRAW(ICON_MOD_MIRROR);
+ break;
+ case eModifierType_Decimate:
+ ICON_DRAW(ICON_MOD_DECIM);
+ break;
+ case eModifierType_Wave:
+ ICON_DRAW(ICON_MOD_WAVE);
+ break;
+ case eModifierType_Hook:
+ ICON_DRAW(ICON_HOOK);
+ break;
+ case eModifierType_Softbody:
+ ICON_DRAW(ICON_MOD_SOFT);
+ break;
+ case eModifierType_Boolean:
+ ICON_DRAW(ICON_MOD_BOOLEAN);
+ break;
+ case eModifierType_ParticleSystem:
+ ICON_DRAW(ICON_MOD_PARTICLES);
+ break;
case eModifierType_ParticleInstance:
- UI_icon_draw(x, y, ICON_MOD_PARTICLES); break;
+ ICON_DRAW(ICON_MOD_PARTICLES);
+ break;
case eModifierType_EdgeSplit:
- UI_icon_draw(x, y, ICON_MOD_EDGESPLIT); break;
+ ICON_DRAW(ICON_MOD_EDGESPLIT);
+ break;
case eModifierType_Array:
- UI_icon_draw(x, y, ICON_MOD_ARRAY); break;
+ ICON_DRAW(ICON_MOD_ARRAY);
+ break;
case eModifierType_UVProject:
case eModifierType_UVWarp: /* TODO, get own icon */
- UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break;
+ ICON_DRAW(ICON_MOD_UVPROJECT);
+ break;
case eModifierType_Displace:
- UI_icon_draw(x, y, ICON_MOD_DISPLACE); break;
+ ICON_DRAW(ICON_MOD_DISPLACE);
+ break;
case eModifierType_Shrinkwrap:
- UI_icon_draw(x, y, ICON_MOD_SHRINKWRAP); break;
+ ICON_DRAW(ICON_MOD_SHRINKWRAP);
+ break;
case eModifierType_Cast:
- UI_icon_draw(x, y, ICON_MOD_CAST); break;
+ ICON_DRAW(ICON_MOD_CAST);
+ break;
case eModifierType_MeshDeform:
case eModifierType_SurfaceDeform:
- UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break;
+ ICON_DRAW(ICON_MOD_MESHDEFORM);
+ break;
case eModifierType_Bevel:
- UI_icon_draw(x, y, ICON_MOD_BEVEL); break;
+ ICON_DRAW(ICON_MOD_BEVEL);
+ break;
case eModifierType_Smooth:
case eModifierType_LaplacianSmooth:
case eModifierType_CorrectiveSmooth:
- UI_icon_draw(x, y, ICON_MOD_SMOOTH); break;
+ ICON_DRAW(ICON_MOD_SMOOTH);
+ break;
case eModifierType_SimpleDeform:
- UI_icon_draw(x, y, ICON_MOD_SIMPLEDEFORM); break;
+ ICON_DRAW(ICON_MOD_SIMPLEDEFORM);
+ break;
case eModifierType_Mask:
- UI_icon_draw(x, y, ICON_MOD_MASK); break;
+ ICON_DRAW(ICON_MOD_MASK);
+ break;
case eModifierType_Cloth:
- UI_icon_draw(x, y, ICON_MOD_CLOTH); break;
+ ICON_DRAW(ICON_MOD_CLOTH);
+ break;
case eModifierType_Explode:
- UI_icon_draw(x, y, ICON_MOD_EXPLODE); break;
+ ICON_DRAW(ICON_MOD_EXPLODE);
+ break;
case eModifierType_Collision:
case eModifierType_Surface:
- UI_icon_draw(x, y, ICON_MOD_PHYSICS); break;
+ ICON_DRAW(ICON_MOD_PHYSICS);
+ break;
case eModifierType_Fluidsim:
- UI_icon_draw(x, y, ICON_MOD_FLUIDSIM); break;
+ ICON_DRAW(ICON_MOD_FLUIDSIM);
+ break;
case eModifierType_Multires:
- UI_icon_draw(x, y, ICON_MOD_MULTIRES); break;
+ ICON_DRAW(ICON_MOD_MULTIRES);
+ break;
case eModifierType_Smoke:
- UI_icon_draw(x, y, ICON_MOD_SMOKE); break;
+ ICON_DRAW(ICON_MOD_SMOKE);
+ break;
case eModifierType_Solidify:
- UI_icon_draw(x, y, ICON_MOD_SOLIDIFY); break;
+ ICON_DRAW(ICON_MOD_SOLIDIFY);
+ break;
case eModifierType_Screw:
- UI_icon_draw(x, y, ICON_MOD_SCREW); break;
+ ICON_DRAW(ICON_MOD_SCREW);
+ break;
case eModifierType_Remesh:
- UI_icon_draw(x, y, ICON_MOD_REMESH); break;
+ ICON_DRAW(ICON_MOD_REMESH);
+ break;
case eModifierType_WeightVGEdit:
case eModifierType_WeightVGMix:
case eModifierType_WeightVGProximity:
- UI_icon_draw(x, y, ICON_MOD_VERTEX_WEIGHT); break;
+ ICON_DRAW(ICON_MOD_VERTEX_WEIGHT);
+ break;
case eModifierType_DynamicPaint:
- UI_icon_draw(x, y, ICON_MOD_DYNAMICPAINT); break;
+ ICON_DRAW(ICON_MOD_DYNAMICPAINT);
+ break;
case eModifierType_Ocean:
- UI_icon_draw(x, y, ICON_MOD_OCEAN); break;
+ ICON_DRAW(ICON_MOD_OCEAN);
+ break;
case eModifierType_Warp:
- UI_icon_draw(x, y, ICON_MOD_WARP); break;
+ ICON_DRAW(ICON_MOD_WARP);
+ break;
case eModifierType_Skin:
- UI_icon_draw(x, y, ICON_MOD_SKIN); break;
+ ICON_DRAW(ICON_MOD_SKIN);
+ break;
case eModifierType_Triangulate:
- UI_icon_draw(x, y, ICON_MOD_TRIANGULATE); break;
+ ICON_DRAW(ICON_MOD_TRIANGULATE);
+ break;
case eModifierType_MeshCache:
- UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; /* XXX, needs own icon */
+ ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
+ break;
case eModifierType_MeshSequenceCache:
- UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; /* XXX, needs own icon */
+ ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
+ break;
case eModifierType_Wireframe:
- UI_icon_draw(x, y, ICON_MOD_WIREFRAME); break;
+ ICON_DRAW(ICON_MOD_WIREFRAME);
+ break;
case eModifierType_LaplacianDeform:
- UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; /* XXX, needs own icon */
+ ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
+ break;
case eModifierType_DataTransfer:
- UI_icon_draw(x, y, ICON_MOD_DATA_TRANSFER); break;
+ ICON_DRAW(ICON_MOD_DATA_TRANSFER);
+ break;
case eModifierType_NormalEdit:
- UI_icon_draw(x, y, ICON_MOD_NORMALEDIT); break;
+ ICON_DRAW(ICON_MOD_NORMALEDIT);
+ break;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
case NUM_MODIFIER_TYPES:
- UI_icon_draw(x, y, ICON_DOT); break;
+ ICON_DRAW(ICON_DOT);
+ break;
}
break;
}
case TSE_POSE_BASE:
- UI_icon_draw(x, y, ICON_ARMATURE_DATA); break;
+ ICON_DRAW(ICON_ARMATURE_DATA);
+ break;
case TSE_POSE_CHANNEL:
- UI_icon_draw(x, y, ICON_BONE_DATA); break;
+ ICON_DRAW(ICON_BONE_DATA);
+ break;
case TSE_PROXY:
- UI_icon_draw(x, y, ICON_GHOST); break;
+ ICON_DRAW(ICON_GHOST);
+ break;
case TSE_R_LAYER_BASE:
- UI_icon_draw(x, y, ICON_RENDERLAYERS); break;
+ ICON_DRAW(ICON_RENDERLAYERS);
+ break;
case TSE_R_LAYER:
- UI_icon_draw(x, y, ICON_RENDERLAYERS); break;
+ ICON_DRAW(ICON_RENDERLAYERS);
+ break;
case TSE_LINKED_LAMP:
- UI_icon_draw(x, y, ICON_LAMP_DATA); break;
+ ICON_DRAW(ICON_LAMP_DATA);
+ break;
case TSE_LINKED_MAT:
- UI_icon_draw(x, y, ICON_MATERIAL_DATA); break;
+ ICON_DRAW(ICON_MATERIAL_DATA);
+ break;
case TSE_POSEGRP_BASE:
- UI_icon_draw(x, y, ICON_GROUP_BONE); break;
+ ICON_DRAW(ICON_GROUP_BONE);
+ break;
case TSE_SEQUENCE:
if (te->idcode == SEQ_TYPE_MOVIE)
- UI_icon_draw(x, y, ICON_SEQUENCE);
+ ICON_DRAW(ICON_SEQUENCE);
else if (te->idcode == SEQ_TYPE_META)
- UI_icon_draw(x, y, ICON_DOT);
+ ICON_DRAW(ICON_DOT);
else if (te->idcode == SEQ_TYPE_SCENE)
- UI_icon_draw(x, y, ICON_SCENE);
+ ICON_DRAW(ICON_SCENE);
else if (te->idcode == SEQ_TYPE_SOUND_RAM)
- UI_icon_draw(x, y, ICON_SOUND);
+ ICON_DRAW(ICON_SOUND);
else if (te->idcode == SEQ_TYPE_IMAGE)
- UI_icon_draw(x, y, ICON_IMAGE_COL);
+ ICON_DRAW(ICON_IMAGE_COL);
else
- UI_icon_draw(x, y, ICON_PARTICLES);
+ ICON_DRAW(ICON_PARTICLES);
break;
case TSE_SEQ_STRIP:
- UI_icon_draw(x, y, ICON_LIBRARY_DATA_DIRECT);
+ ICON_DRAW(ICON_LIBRARY_DATA_DIRECT);
break;
case TSE_SEQUENCE_DUP:
- UI_icon_draw(x, y, ICON_OBJECT_DATA);
+ ICON_DRAW(ICON_OBJECT_DATA);
break;
case TSE_RNA_STRUCT:
if (RNA_struct_is_ID(te->rnaptr.type)) {
arg.id = (ID *)te->rnaptr.data;
tselem_draw_icon_uibut(&arg, RNA_struct_ui_icon(te->rnaptr.type));
}
- else
- UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type));
+ else {
+ int icon = RNA_struct_ui_icon(te->rnaptr.type);
+ ICON_DRAW(icon);
+ }
break;
/* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */
#if 0
@@ -1241,7 +1086,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
break;
#endif
default:
- UI_icon_draw(x, y, ICON_DOT); break;
+ ICON_DRAW(ICON_DOT);
+ break;
}
}
else if (tselem->id) {
@@ -1346,17 +1192,18 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
}
}
}
+
+#undef ICON_DRAW
}
-static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level,
- int xmax, int *offsx, int ys)
+static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SceneLayer *sl, SpaceOops *soops,
+ ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
{
TreeElement *te;
TreeStoreElem *tselem;
eOLDrawState active;
for (te = lb->first; te; te = te->next) {
-
/* exit drawing early */
if ((*offsx) - UI_UNIT_X > xmax)
break;
@@ -1369,34 +1216,38 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
/* active blocks get white circle */
if (tselem->type == 0) {
if (te->idcode == ID_OB) {
- active = (OBACT == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
+ active = (OBACT_NEW == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
}
else if (scene->obedit && scene->obedit->data == tselem->id) {
active = OL_DRAWSEL_NORMAL;
}
else {
- active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false);
+ active = tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NONE, false);
}
}
else {
- active = tree_element_type_active(NULL, scene, soops, te, tselem, OL_SETSEL_NONE, false);
+ active = tree_element_type_active(C, scene, sl, soops, te, tselem, OL_SETSEL_NONE, false);
}
if (active != OL_DRAWSEL_NONE) {
float ufac = UI_UNIT_X / 20.0f;
+ float color[4] = {1.0f, 1.0f, 1.0f, 0.4f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- glColor4ub(255, 255, 255, 100);
- UI_draw_roundbox(
+ color[3] *= alpha_fac;
+
+ UI_draw_roundbox_aa(
+ true,
(float) *offsx + 1.0f * ufac,
(float)ys + 1.0f * ufac,
(float)*offsx + UI_UNIT_X - 1.0f * ufac,
(float)ys + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac);
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
glEnable(GL_BLEND); /* roundbox disables */
}
- tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f);
+ tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac);
te->xs = *offsx;
te->ys = ys;
te->xend = (short)*offsx + UI_UNIT_X;
@@ -1407,7 +1258,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
/* this tree element always has same amount of branches, so don't draw */
if (tselem->type != TSE_R_LAYER)
- outliner_draw_iconrow(C, block, scene, soops, &te->subtree, level + 1, xmax, offsx, ys);
+ outliner_draw_iconrow(C, block, scene, sl, soops, &te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
}
}
@@ -1416,11 +1267,14 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
static void outliner_set_coord_tree_element(TreeElement *te, int startx, int starty)
{
TreeElement *ten;
-
- /* store coord and continue, we need coordinates for elements outside view too */
- te->xs = startx;
- te->ys = starty;
-
+
+ /* closed items may be displayed in row of parent, don't change their coordinate! */
+ if ((te->flag & TE_ICONROW) == 0) {
+ /* store coord and continue, we need coordinates for elements outside view too */
+ te->xs = startx;
+ te->ys = starty;
+ }
+
for (ten = te->subtree.first; ten; ten = ten->next) {
outliner_set_coord_tree_element(ten, startx + UI_UNIT_X, starty);
}
@@ -1428,24 +1282,28 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta
static void outliner_draw_tree_element(
- bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, int startx, int *starty, TreeElement **te_edit)
+ bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, SceneLayer *sl,
+ ARegion *ar, SpaceOops *soops, TreeElement *te, bool draw_grayed_out,
+ int startx, int *starty, TreeElement **te_edit, TreeElement **te_floating)
{
- TreeElement *ten;
TreeStoreElem *tselem;
float ufac = UI_UNIT_X / 20.0f;
int offsx = 0;
eOLDrawState active = OL_DRAWSEL_NONE;
-
+ float color[4];
tselem = TREESTORE(te);
if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) {
+ const float alpha_fac = draw_grayed_out ? 0.5f : 1.0f;
+ const float alpha = 0.5f * alpha_fac;
int xmax = ar->v2d.cur.xmax;
- unsigned char alpha = 128;
-
+
if ((tselem->flag & TSE_TEXTBUT) && (*te_edit == NULL)) {
*te_edit = te;
}
+ if ((te->drag_data != NULL) && (*te_floating == NULL)) {
+ *te_floating = te;
+ }
/* icons can be ui buts, we don't want it to overlap with restrict */
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
@@ -1453,50 +1311,24 @@ static void outliner_draw_tree_element(
glEnable(GL_BLEND);
- /* start by highlighting search matches
- * we don't expand items when searching in the datablocks but we
- * still want to highlight any filter matches.
- */
- if ((SEARCHING_OUTLINER(soops) || (soops->outlinevis == SO_DATABLOCKS && soops->search_string[0] != 0)) &&
- (tselem->flag & TSE_SEARCHMATCH))
- {
- char col[4];
- UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col);
- col[3] = alpha;
- glColor4ubv((GLubyte *)col);
- glRecti(startx, *starty + 1, ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
- }
-
/* colors for active/selected data */
if (tselem->type == 0) {
-
if (te->idcode == ID_SCE) {
if (tselem->id == (ID *)scene) {
- glColor4ub(255, 255, 255, alpha);
- active = OL_DRAWSEL_ACTIVE;
- }
- }
- else if (te->idcode == ID_GR) {
- Group *gr = (Group *)tselem->id;
- if (group_select_flag(gr)) {
- char col[4];
- UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
- col[3] = alpha;
- glColor4ubv((GLubyte *)col);
-
+ rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
active = OL_DRAWSEL_ACTIVE;
}
}
else if (te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
- if (ob == OBACT || (ob->flag & SELECT)) {
+ if (ob == OBACT_NEW || (ob->flag & SELECT)) {
char col[4] = {0, 0, 0, 0};
/* outliner active ob: always white text, circle color now similar to view3d */
active = OL_DRAWSEL_ACTIVE;
- if (ob == OBACT) {
+ if (ob == OBACT_NEW) {
if (ob->flag & SELECT) {
UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
col[3] = alpha;
@@ -1508,38 +1340,36 @@ static void outliner_draw_tree_element(
UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
col[3] = alpha;
}
-
- glColor4ubv((GLubyte *)col);
+ rgba_float_args_set(color, (float)col[0] / 255, (float)col[1] / 255, (float)col[2] / 255, alpha);
}
}
else if (scene->obedit && scene->obedit->data == tselem->id) {
- glColor4ub(255, 255, 255, alpha);
+ rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
active = OL_DRAWSEL_ACTIVE;
}
else {
- if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false)) {
- glColor4ub(220, 220, 255, alpha);
+ if (tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NONE, false)) {
+ rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
active = OL_DRAWSEL_ACTIVE;
}
}
}
else {
- if (tree_element_type_active(NULL, scene, soops, te, tselem, OL_SETSEL_NONE, false) != OL_DRAWSEL_NONE) {
- active = OL_DRAWSEL_ACTIVE;
- }
- glColor4ub(220, 220, 255, alpha);
+ active = tree_element_type_active(C, scene, sl, soops, te, tselem, OL_SETSEL_NONE, false);
+ rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
}
/* active circle */
if (active != OL_DRAWSEL_NONE) {
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(
+ UI_draw_roundbox_aa(
+ true,
(float)startx + UI_UNIT_X + 1.0f * ufac,
(float)*starty + 1.0f * ufac,
(float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac,
(float)*starty + UI_UNIT_Y - 1.0f * ufac,
- UI_UNIT_Y / 2.0f - 1.0f * ufac);
+ UI_UNIT_Y / 2.0f - 1.0f * ufac, color);
glEnable(GL_BLEND); /* roundbox disables it */
te->flag |= TE_ACTIVE; // for lookup in display hierarchies
@@ -1548,56 +1378,64 @@ static void outliner_draw_tree_element(
/* open/close icon, only when sublevels, except for scene */
if (te->subtree.first || (tselem->type == 0 && te->idcode == ID_SCE) || (te->flag & TE_LAZY_CLOSED)) {
int icon_x;
- icon_x = startx;
-
+ if (tselem->type == 0 && ELEM(te->idcode, ID_OB, ID_SCE))
+ icon_x = startx;
+ else
+ icon_x = startx + 5 * ufac;
+
// icons a bit higher
if (TSELEM_OPEN(tselem, soops))
- UI_icon_draw((float)icon_x + 2 * ufac, (float)*starty + 1 * ufac, ICON_DISCLOSURE_TRI_DOWN);
+ UI_icon_draw_alpha((float)icon_x + 2 * ufac, (float)*starty + 1 * ufac, ICON_DISCLOSURE_TRI_DOWN,
+ alpha_fac);
else
- UI_icon_draw((float)icon_x + 2 * ufac, (float)*starty + 1 * ufac, ICON_DISCLOSURE_TRI_RIGHT);
+ UI_icon_draw_alpha((float)icon_x + 2 * ufac, (float)*starty + 1 * ufac, ICON_DISCLOSURE_TRI_RIGHT,
+ alpha_fac);
}
offsx += UI_UNIT_X;
/* datatype icon */
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) {
-
- tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, 1.0f);
-
+ tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac);
offsx += UI_UNIT_X + 2 * ufac;
}
else
offsx += 2 * ufac;
if (tselem->type == 0 && ID_IS_LINKED_DATABLOCK(tselem->id)) {
- glPixelTransferf(GL_ALPHA_SCALE, 0.5f);
if (tselem->id->tag & LIB_TAG_MISSING) {
- UI_icon_draw((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_BROKEN);
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_BROKEN,
+ alpha_fac);
}
else if (tselem->id->tag & LIB_TAG_INDIRECT) {
- UI_icon_draw((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_INDIRECT);
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_INDIRECT,
+ alpha_fac);
}
else {
- UI_icon_draw((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_DIRECT);
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_DIRECT,
+ alpha_fac);
}
- glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
offsx += UI_UNIT_X + 2 * ufac;
}
glDisable(GL_BLEND);
/* name */
if ((tselem->flag & TSE_TEXTBUT) == 0) {
+ unsigned char text_col[4];
+
if (active == OL_DRAWSEL_NORMAL) {
- UI_ThemeColor(TH_TEXT_HI);
+ UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
}
else if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f);
+ UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.75f, text_col);
+ text_col[3] = 255;
}
else {
- UI_ThemeColor(TH_TEXT);
+ UI_GetThemeColor4ubv(TH_TEXT, text_col);
}
+ text_col[3] *= alpha_fac;
- UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name);
+ UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name, text_col);
}
offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
@@ -1608,24 +1446,33 @@ static void outliner_draw_tree_element(
if (tselem->type == 0 && te->idcode == ID_SCE) {
/* pass */
}
+ /* this tree element always has same amount of branches, so don't draw */
else if (tselem->type != TSE_R_LAYER) {
- /* this tree element always has same amount of branches, so don't draw */
-
int tempx = startx + offsx;
-
- /* divider */
- UI_ThemeColorShade(TH_BACK, -40);
- glRecti(tempx - 10.0f * ufac,
- *starty + 4.0f * ufac,
- tempx - 8.0f * ufac,
- *starty + UI_UNIT_Y - 4.0f * ufac);
-
+
glEnable(GL_BLEND);
- glPixelTransferf(GL_ALPHA_SCALE, 0.5);
-
- outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty);
-
- glPixelTransferf(GL_ALPHA_SCALE, 1.0);
+
+ /* divider */
+ {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ unsigned char col[4];
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ UI_GetThemeColorShade4ubv(TH_BACK, -40, col);
+ col[3] *= alpha_fac;
+
+ immUniformColor4ubv(col);
+ immRecti(pos, tempx - 10.0f * ufac,
+ *starty + 4.0f * ufac,
+ tempx - 8.0f * ufac,
+ *starty + UI_UNIT_Y - 4.0f * ufac);
+ immUnbindProgram();
+ }
+
+ outliner_draw_iconrow(C, block, scene, sl, soops, &te->subtree, 0, xmax, &tempx,
+ *starty, alpha_fac);
+
glDisable(GL_BLEND);
}
}
@@ -1635,16 +1482,20 @@ static void outliner_draw_tree_element(
te->xs = startx;
te->ys = *starty;
te->xend = startx + offsx;
-
+
if (TSELEM_OPEN(tselem, soops)) {
*starty -= UI_UNIT_Y;
- for (ten = te->subtree.first; ten; ten = ten->next) {
- outliner_draw_tree_element(C, block, fstyle, scene, ar, soops, ten, startx + UI_UNIT_X, starty, te_edit);
+ for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
+ /* check if element needs to be drawn grayed out, but also gray out
+ * childs of a grayed out parent (pass on draw_grayed_out to childs) */
+ bool draw_childs_grayed_out = draw_grayed_out || (ten->drag_data != NULL);
+ outliner_draw_tree_element(C, block, fstyle, scene, sl, ar, soops, ten, draw_childs_grayed_out,
+ startx + UI_UNIT_X, starty, te_edit, te_floating);
}
}
else {
- for (ten = te->subtree.first; ten; ten = ten->next) {
+ for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
outliner_set_coord_tree_element(ten, startx, *starty);
}
@@ -1652,115 +1503,277 @@ static void outliner_draw_tree_element(
}
}
-static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, int *starty)
+static void outliner_draw_tree_element_floating(
+ const ARegion *ar, const TreeElement *te_floating)
+{
+ const TreeElement *te_insert = te_floating->drag_data->insert_handle;
+ const int line_width = 2;
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ int coord_y = te_insert->ys;
+ int coord_x = te_insert->xs;
+ float col[4];
+
+ if (te_insert == te_floating) {
+ /* don't draw anything */
+ return;
+ }
+
+ UI_GetThemeColorShade4fv(TH_BACK, -40, col);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ glEnable(GL_BLEND);
+
+ if (ELEM(te_floating->drag_data->insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) {
+ if (te_floating->drag_data->insert_type == TE_INSERT_BEFORE) {
+ coord_y += UI_UNIT_Y;
+ }
+ immUniformColor4fv(col);
+ glLineWidth(line_width);
+
+ immBegin(PRIM_LINE_STRIP, 2);
+ immVertex2f(pos, coord_x, coord_y);
+ immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
+ immEnd();
+ }
+ else {
+ BLI_assert(te_floating->drag_data->insert_type == TE_INSERT_INTO);
+ immUniformColor3fvAlpha(col, col[3] * 0.5f);
+
+ immBegin(PRIM_TRIANGLE_STRIP, 4);
+ immVertex2f(pos, coord_x, coord_y + UI_UNIT_Y);
+ immVertex2f(pos, coord_x, coord_y);
+ immVertex2f(pos, ar->v2d.cur.xmax, coord_y + UI_UNIT_Y);
+ immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
+ immEnd();
+ }
+
+ glDisable(GL_BLEND);
+ immUnbindProgram();
+}
+
+static void outliner_draw_hierarchy_lines_recursive(unsigned pos, SpaceOops *soops, ListBase *lb, int startx,
+ const unsigned char col[4], bool draw_grayed_out,
+ int *starty)
{
TreeElement *te;
TreeStoreElem *tselem;
int y1, y2;
-
- if (BLI_listbase_is_empty(lb)) return;
-
+
+ if (BLI_listbase_is_empty(lb)) {
+ return;
+ }
+
+ const unsigned char grayed_alpha = col[3] / 2;
+
y1 = y2 = *starty; /* for vertical lines between objects */
for (te = lb->first; te; te = te->next) {
+ bool draw_childs_grayed_out = draw_grayed_out || (te->drag_data != NULL);
y2 = *starty;
tselem = TREESTORE(te);
-
+
+ if (draw_childs_grayed_out) {
+ immUniformColor3ubvAlpha(col, grayed_alpha);
+ }
+ else {
+ immUniformColor4ubv(col);
+ }
+
/* horizontal line? */
if (tselem->type == 0 && (te->idcode == ID_OB || te->idcode == ID_SCE))
- glRecti(startx, *starty, startx + UI_UNIT_X, *starty - 1);
+ immRecti(pos, startx, *starty, startx + UI_UNIT_X, *starty - 1);
*starty -= UI_UNIT_Y;
if (TSELEM_OPEN(tselem, soops))
- outliner_draw_hierarchy(soops, &te->subtree, startx + UI_UNIT_X, starty);
+ outliner_draw_hierarchy_lines_recursive(pos, soops, &te->subtree, startx + UI_UNIT_X,
+ col, draw_childs_grayed_out, starty);
}
-
+
+ if (draw_grayed_out) {
+ immUniformColor3ubvAlpha(col, grayed_alpha);
+ }
+ else {
+ immUniformColor4ubv(col);
+ }
+
/* vertical line */
te = lb->last;
if (te->parent || lb->first != lb->last) {
tselem = TREESTORE(te);
- if (tselem->type == 0 && te->idcode == ID_OB) {
-
- glRecti(startx, y1 + UI_UNIT_Y, startx + 1, y2);
- }
+ if (tselem->type == 0 && te->idcode == ID_OB)
+ immRecti(pos, startx, y1 + UI_UNIT_Y, startx + 1, y2);
}
}
+static void outliner_draw_hierarchy_lines(SpaceOops *soops, ListBase *lb, int startx, int *starty)
+{
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ unsigned char col[4];
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col);
+ col[3] = 255;
+
+ glEnable(GL_BLEND);
+ outliner_draw_hierarchy_lines_recursive(pos, soops, lb, startx, col, false, starty);
+ glDisable(GL_BLEND);
+
+ immUnbindProgram();
+}
+
static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty)
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
/* selection status */
if (TSELEM_OPEN(tselem, soops))
- if (tselem->type == TSE_RNA_STRUCT)
- glRecti(0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
+ if (tselem->type == TSE_RNA_STRUCT) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immThemeColorShadeAlpha(TH_BACK, -15, -200);
+ immRecti(pos, 0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
+ immUnbindProgram();
+ }
*starty -= UI_UNIT_Y;
if (TSELEM_OPEN(tselem, soops)) {
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
- if (tselem->type == TSE_RNA_STRUCT)
- fdrawline(0, (float)*starty + UI_UNIT_Y, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
+ if (tselem->type == TSE_RNA_STRUCT) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immThemeColorShadeAlpha(TH_BACK, -15, -200);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y);
+ immVertex2f(pos, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
+ immEnd();
+
+ immUnbindProgram();
+ }
}
}
}
-static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty)
+static void outliner_draw_highlights_recursive(
+ unsigned pos, const ARegion *ar, const SpaceOops *soops, const ListBase *lb,
+ const float col_selection[4], const float col_highlight[4], const float col_searchmatch[4],
+ int start_x, int *io_start_y)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
-
+ const bool is_searching = SEARCHING_OUTLINER(soops) ||
+ (soops->outlinevis == SO_DATABLOCKS && soops->search_string[0] != 0);
+
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ const TreeStoreElem *tselem = TREESTORE(te);
+ const int start_y = *io_start_y;
+
/* selection status */
if (tselem->flag & TSE_SELECTED) {
- glRecti(0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
+ immUniformColor4fv(col_selection);
+ immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
+ }
+
+ /* search match highlights
+ * we don't expand items when searching in the datablocks but we
+ * still want to highlight any filter matches. */
+ if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) {
+ immUniformColor4fv(col_searchmatch);
+ immRecti(pos, start_x, start_y + 1, ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
+ }
+
+ /* mouse hover highlights */
+ if ((tselem->flag & TSE_HIGHLIGHTED) || (te->drag_data != NULL)) {
+ immUniformColor4fv(col_highlight);
+ immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
+ }
+
+ *io_start_y -= UI_UNIT_Y;
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_highlights_recursive(
+ pos, ar, soops, &te->subtree, col_selection, col_highlight, col_searchmatch,
+ start_x + UI_UNIT_X, io_start_y);
}
- *starty -= UI_UNIT_Y;
- if (TSELEM_OPEN(tselem, soops)) outliner_draw_selection(ar, soops, &te->subtree, starty);
}
}
+static void outliner_draw_highlights(ARegion *ar, SpaceOops *soops, int startx, int *starty)
+{
+ const float col_highlight[4] = {1.0f, 1.0f, 1.0f, 0.13f};
+ float col_selection[4], col_searchmatch[4];
+
+ UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col_selection);
+ col_selection[3] = 1.0f; /* no alpha */
+ UI_GetThemeColor4fv(TH_MATCH, col_searchmatch);
+ col_searchmatch[3] = 0.5f;
+
+ glEnable(GL_BLEND);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ outliner_draw_highlights_recursive(pos, ar, soops, &soops->tree, col_selection, col_highlight, col_searchmatch,
+ startx, starty);
+ immUnbindProgram();
+ glDisable(GL_BLEND);
+}
-static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegion *ar,
- SpaceOops *soops, TreeElement **te_edit)
+static void outliner_draw_tree(
+ bContext *C, uiBlock *block, Scene *scene, SceneLayer *sl, ARegion *ar,
+ SpaceOops *soops, const bool has_restrict_icons,
+ TreeElement **te_edit)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- TreeElement *te;
+ TreeElement *te_floating = NULL;
int starty, startx;
- float col[3];
-
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once
-
+
if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
/* struct marks */
- UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
- //UI_ThemeColorShade(TH_BACK, -20);
starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
outliner_draw_struct_marks(ar, soops, &soops->tree, &starty);
}
-
- /* always draw selection fill before hierarchy */
- UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col);
- glColor3fv(col);
+
+ /* draw highlights before hierarchy */
starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
- outliner_draw_selection(ar, soops, &soops->tree, &starty);
-
+ startx = 0;
+ outliner_draw_highlights(ar, soops, startx, &starty);
+
+ /* set scissor so tree elements or lines can't overlap restriction icons */
+ GLfloat scissor[4] = {0};
+ if (has_restrict_icons) {
+ int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)OL_TOGW + 1;
+ CLAMP_MIN(mask_x, 0);
+
+ glGetFloatv(GL_SCISSOR_BOX, scissor);
+ glScissor(ar->winrct.xmin, ar->winrct.ymin, mask_x, ar->winy);
+ }
+
// gray hierarchy lines
- UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.4f);
- starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
- startx = UI_UNIT_X / 2 - 1.0f;
- outliner_draw_hierarchy(soops, &soops->tree, startx, &starty);
+ starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
+ startx = 6;
+ outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty);
+
// items themselves
starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
startx = 0;
- for (te = soops->tree.first; te; te = te->next) {
- outliner_draw_tree_element(C, block, fstyle, scene, ar, soops, te, startx, &starty, te_edit);
+ for (TreeElement *te = soops->tree.first; te; te = te->next) {
+ outliner_draw_tree_element(C, block, fstyle, scene, sl, ar, soops, te, te->drag_data != NULL,
+ startx, &starty, te_edit, &te_floating);
+ }
+ if (te_floating && te_floating->drag_data->insert_handle) {
+ outliner_draw_tree_element_floating(ar, te_floating);
+ }
+
+ if (has_restrict_icons) {
+ /* reset scissor */
+ glScissor(UNPACK4(scissor));
}
}
@@ -1769,53 +1782,60 @@ static void outliner_back(ARegion *ar)
{
int ystart;
- UI_ThemeColorShade(TH_BACK, 6);
ystart = (int)ar->v2d.tot.ymax;
ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
-
- while (ystart + 2 * UI_UNIT_Y > ar->v2d.cur.ymin) {
- glRecti(0, ystart, (int)ar->v2d.cur.xmax, ystart + UI_UNIT_Y);
- ystart -= 2 * UI_UNIT_Y;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShade(TH_BACK, 6);
+
+ const float x1 = 0.0f, x2 = ar->v2d.cur.xmax;
+ float y1 = ystart, y2;
+ int tot = (int)floor(ystart - ar->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y);
+
+ if (tot > 0) {
+ immBegin(PRIM_TRIANGLES, 6 * tot);
+ while (tot--) {
+ y1 -= 2 * UI_UNIT_Y;
+ y2 = y1 + UI_UNIT_Y;
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y2);
+
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x1, y2);
+ }
+ immEnd();
}
+ immUnbindProgram();
}
static void outliner_draw_restrictcols(ARegion *ar)
{
- int ystart;
-
- /* background underneath */
- UI_ThemeColor(TH_BACK);
- glRecti((int)(ar->v2d.cur.xmax - OL_TOGW),
- (int)(ar->v2d.cur.ymin - 1), (int)ar->v2d.cur.xmax, (int)ar->v2d.cur.ymax);
-
- UI_ThemeColorShade(TH_BACK, 6);
- ystart = (int)ar->v2d.tot.ymax;
- ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
-
- while (ystart + 2 * UI_UNIT_Y > ar->v2d.cur.ymin) {
- glRecti((int)ar->v2d.cur.xmax - OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart + UI_UNIT_Y);
- ystart -= 2 * UI_UNIT_Y;
- }
-
- UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
+ glLineWidth(1.0f);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
+ immBegin(PRIM_LINES, 6);
/* view */
- sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- (int)ar->v2d.cur.ymax,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- (int)ar->v2d.cur.ymin);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymin);
/* render */
- sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- (int)ar->v2d.cur.ymax,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- (int)ar->v2d.cur.ymin);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)ar->v2d.cur.ymin);
/* render */
- sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
- (int)ar->v2d.cur.ymax,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
- (int)ar->v2d.cur.ymin);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)ar->v2d.cur.ymin);
+
+ immEnd();
+ immUnbindProgram();
}
/* ****************************************************** */
@@ -1825,14 +1845,16 @@ void draw_outliner(const bContext *C)
{
Main *mainvar = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
SpaceOops *soops = CTX_wm_space_outliner(C);
uiBlock *block;
int sizey = 0, sizex = 0, sizex_rna = 0;
TreeElement *te_edit = NULL;
+ bool has_restrict_icons;
- outliner_build_tree(mainvar, scene, soops); // always
+ outliner_build_tree(mainvar, scene, sl, soops); // always
/* get extents of data */
outliner_height(soops, &soops->tree, &sizey);
@@ -1852,6 +1874,7 @@ void draw_outliner(const bContext *C)
/* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
+ has_restrict_icons = false;
}
else {
/* width must take into account restriction columns (if visible) so that entries will still be visible */
@@ -1863,7 +1886,8 @@ void draw_outliner(const bContext *C)
// XXX this isn't that great yet...
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
sizex += OL_TOGW * 3;
-
+
+ has_restrict_icons = !(soops->flag & SO_HIDE_RESTRICTCOLS);
}
/* adds vertical offset */
@@ -1880,19 +1904,19 @@ void draw_outliner(const bContext *C)
/* draw outliner stuff (background, hierarchy lines and names) */
outliner_back(ar);
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
- outliner_draw_tree((bContext *)C, block, scene, ar, soops, &te_edit);
+ outliner_draw_tree((bContext *)C, block, scene, sl, ar, soops, has_restrict_icons, &te_edit);
if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
/* draw rna buttons */
outliner_draw_rnacols(ar, sizex_rna);
outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree);
}
- else if ((soops->outlinevis == SO_ID_ORPHANS) && !(soops->flag & SO_HIDE_RESTRICTCOLS)) {
+ else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
/* draw user toggle columns */
outliner_draw_restrictcols(ar);
outliner_draw_userbuts(block, ar, soops, &soops->tree);
}
- else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
+ else if (has_restrict_icons) {
/* draw restriction columns */
outliner_draw_restrictcols(ar);
outliner_draw_restrictbuts(block, scene, ar, soops, &soops->tree);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 335eb95da0e..6a3e53281da 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -54,6 +54,7 @@
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_idcode.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
@@ -148,8 +149,46 @@ TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2]
return NULL;
}
+
/* ************************************************************** */
-/* Click Activated */
+
+/* Highlight --------------------------------------------------- */
+
+static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
+
+ TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, my);
+ bool changed = false;
+
+ if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
+ changed = outliner_set_flag(&soops->tree, TSE_HIGHLIGHTED, false);
+ if (hovered_te) {
+ hovered_te->store_elem->flag |= TSE_HIGHLIGHTED;
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
+ ED_region_tag_redraw(ar);
+ }
+
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+}
+
+void OUTLINER_OT_highlight_update(wmOperatorType *ot)
+{
+ ot->name = "Update Highlight";
+ ot->idname = "OUTLINER_OT_highlight_update";
+ ot->description = "Update the item highlight based on the current mouse position";
+
+ ot->invoke = outliner_highlight_update;
+
+ ot->poll = ED_operator_outliner_active;
+}
/* Toggle Open/Closed ------------------------------------------- */
@@ -216,8 +255,11 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
/* Rename --------------------------------------------------- */
-static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, ReportList *reports)
+static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
+ ReportList *reports)
{
+ bool add_textbut = false;
+
/* can't rename rna datablocks entries or listbases */
if (ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE)) {
/* do nothing */;
@@ -230,6 +272,18 @@ static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
else if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
BKE_report(reports, RPT_WARNING, "Cannot edit sequence name");
}
+ else if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
+ SceneCollection *master = BKE_collection_master(scene);
+
+ if ((tselem->type == TSE_SCENE_COLLECTION && te->directdata == master) ||
+ (((LayerCollection *)te->directdata)->scene_collection == master))
+ {
+ BKE_report(reports, RPT_WARNING, "Cannot edit name of master collection");
+ }
+ else {
+ add_textbut = true;
+ }
+ }
else if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
}
@@ -237,34 +291,39 @@ static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
BKE_report(reports, RPT_WARNING, "Cannot edit the path of an indirectly linked library");
}
else {
+ add_textbut = true;
+ }
+
+ if (add_textbut) {
tselem->flag |= TSE_TEXTBUT;
ED_region_tag_redraw(ar);
}
}
void item_rename_cb(
- bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *te,
+ bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
ARegion *ar = CTX_wm_region(C);
- do_item_rename(ar, te, tselem, reports);
+ do_item_rename(scene, ar, te, tselem, reports);
}
-static int do_outliner_item_rename(ReportList *reports, ARegion *ar, TreeElement *te, const float mval[2])
+static int do_outliner_item_rename(const Scene *scene, ReportList *reports, ARegion *ar, TreeElement *te,
+ const float mval[2])
{
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
TreeStoreElem *tselem = TREESTORE(te);
/* click on name */
if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
- do_item_rename(ar, te, tselem, reports);
+ do_item_rename(scene, ar, te, tselem, reports);
return 1;
}
return 0;
}
for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_rename(reports, ar, te, mval)) return 1;
+ if (do_outliner_item_rename(scene, reports, ar, te, mval)) return 1;
}
return 0;
}
@@ -280,7 +339,7 @@ static int outliner_item_rename(bContext *C, wmOperator *op, const wmEvent *even
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_rename(op->reports, ar, te, fmval)) {
+ if (do_outliner_item_rename(CTX_data_scene(C), op->reports, ar, te, fmval)) {
changed = true;
break;
}
@@ -744,17 +803,34 @@ int outliner_has_one_flag(ListBase *lb, short flag, const int curlevel)
return 0;
}
-void outliner_set_flag(ListBase *lb, short flag, short set)
+/**
+ * Set or unset \a flag for all outliner elements in \a lb and sub-trees.
+ * \return if any flag was modified.
+ */
+bool outliner_set_flag(ListBase *lb, short flag, short set)
{
TreeElement *te;
TreeStoreElem *tselem;
-
+ bool changed = false;
+ bool has_flag;
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
- if (set == 0) tselem->flag &= ~flag;
- else tselem->flag |= flag;
- outliner_set_flag(&te->subtree, flag, set);
+ has_flag = (tselem->flag & flag);
+ if (set == 0) {
+ if (has_flag) {
+ tselem->flag &= ~flag;
+ changed = true;
+ }
+ }
+ else if (!has_flag) {
+ tselem->flag |= flag;
+ changed = true;
+ }
+ changed |= outliner_set_flag(&te->subtree, flag, set);
}
+
+ return changed;
}
/* Restriction Columns ------------------------------- */
@@ -782,181 +858,6 @@ int common_restrict_check(bContext *C, Object *ob)
}
/* =============================================== */
-/* Restriction toggles */
-
-/* Toggle Visibility ---------------------------------------- */
-
-void object_toggle_visibility_cb(
- bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Base *base = (Base *)te->directdata;
- Object *ob = (Object *)tselem->id;
-
- if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
- BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
- return;
- }
-
- /* add check for edit mode */
- if (!common_restrict_check(C, ob)) return;
-
- if (base || (base = BKE_scene_base_find(scene, ob))) {
- if ((base->object->restrictflag ^= OB_RESTRICT_VIEW)) {
- ED_base_object_select(base, BA_DESELECT);
- }
- }
-}
-
-void group_toggle_visibility_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Group *group = (Group *)tselem->id;
- restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_VIEW);
-}
-
-static int outliner_toggle_visibility_exec(bContext *C, wmOperator *op)
-{
- Main *bmain = CTX_data_main(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
-
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_visibility_cb);
-
- DAG_id_type_tag(bmain, ID_OB);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
- ED_region_tag_redraw(ar);
-
- return OPERATOR_FINISHED;
-}
-
-void OUTLINER_OT_visibility_toggle(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Toggle Visibility";
- ot->idname = "OUTLINER_OT_visibility_toggle";
- ot->description = "Toggle the visibility of selected items";
-
- /* callbacks */
- ot->exec = outliner_toggle_visibility_exec;
- ot->poll = ED_operator_outliner_active_no_editobject;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* Toggle Selectability ---------------------------------------- */
-
-void object_toggle_selectability_cb(
- bContext *UNUSED(C), ReportList *reports, Scene *scene, TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Base *base = (Base *)te->directdata;
-
- if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
- BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
- return;
- }
-
- if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id);
- if (base) {
- base->object->restrictflag ^= OB_RESTRICT_SELECT;
- }
-}
-
-void group_toggle_selectability_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Group *group = (Group *)tselem->id;
- restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_SELECT);
-}
-
-static int outliner_toggle_selectability_exec(bContext *C, wmOperator *op)
-{
- SpaceOops *soops = CTX_wm_space_outliner(C);
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
-
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_selectability_cb);
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- ED_region_tag_redraw(ar);
-
- return OPERATOR_FINISHED;
-}
-
-void OUTLINER_OT_selectability_toggle(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Toggle Selectability";
- ot->idname = "OUTLINER_OT_selectability_toggle";
- ot->description = "Toggle the selectability";
-
- /* callbacks */
- ot->exec = outliner_toggle_selectability_exec;
- ot->poll = ED_operator_outliner_active_no_editobject;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* Toggle Renderability ---------------------------------------- */
-
-void object_toggle_renderability_cb(
- bContext *UNUSED(C), ReportList *reports, Scene *scene, TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Base *base = (Base *)te->directdata;
-
- if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
- BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
- return;
- }
-
- if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id);
- if (base) {
- base->object->restrictflag ^= OB_RESTRICT_RENDER;
- }
-}
-
-void group_toggle_renderability_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Group *group = (Group *)tselem->id;
- restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_RENDER);
-}
-
-static int outliner_toggle_renderability_exec(bContext *C, wmOperator *op)
-{
- Main *bmain = CTX_data_main(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- Scene *scene = CTX_data_scene(C);
-
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_renderability_cb);
-
- DAG_id_type_tag(bmain, ID_OB);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
-
- return OPERATOR_FINISHED;
-}
-
-void OUTLINER_OT_renderability_toggle(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Toggle Renderability";
- ot->idname = "OUTLINER_OT_renderability_toggle";
- ot->description = "Toggle the renderability of selected items";
-
- /* callbacks */
- ot->exec = outliner_toggle_renderability_exec;
- ot->poll = ED_operator_outliner_active;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* =============================================== */
/* Outliner setting toggles */
/* Toggle Expanded (Outliner) ---------------------------------------- */
@@ -1077,14 +978,14 @@ static int outliner_open_back(TreeElement *te)
static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceOops *so = CTX_wm_space_outliner(C);
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
TreeElement *te;
int xdelta, ytop;
- Object *obact = OBACT;
+ Object *obact = OBACT_NEW;
if (!obact)
return OPERATOR_CANCELLED;
@@ -2019,6 +1920,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Main *bmain = CTX_data_main(C);
Scene *scene = NULL;
TreeElement *te = NULL;
+ TreeStoreElem *tselem;
char childname[MAX_ID_NAME];
char parname[MAX_ID_NAME];
int partype = 0;
@@ -2028,8 +1930,21 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Find object hovered over */
te = outliner_dropzone_find(soops, fmval, true);
+ tselem = te ? TREESTORE(te) : NULL;
- if (te) {
+ if (tselem && ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
+ SceneCollection *sc = outliner_scene_collection_from_tree_element(te);
+
+ scene = BKE_scene_find_from_collection(bmain, sc);
+ BLI_assert(scene);
+ RNA_string_get(op->ptr, "child", childname);
+ ob = (Object *)BKE_libblock_find_name(ID_OB, childname);
+ BKE_collection_object_add(scene, sc, ob);
+
+ DAG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ }
+ else if (te) {
RNA_string_set(op->ptr, "parent", te->name);
/* Identify parent and child */
RNA_string_get(op->ptr, "child", childname);
@@ -2233,8 +2148,6 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
te = outliner_dropzone_find(soops, fmval, false);
if (te) {
- Base *base;
-
RNA_string_set(op->ptr, "scene", te->name);
scene = (Scene *)BKE_libblock_find_name(ID_SCE, te->name);
@@ -2245,16 +2158,26 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
- base = ED_object_scene_link(scene, ob);
-
- if (base == NULL) {
+ if (BKE_scene_has_object(scene, ob)) {
return OPERATOR_CANCELLED;
}
- if (scene == CTX_data_scene(C)) {
- /* when linking to an inactive scene don't touch the layer */
- ob->lay = base->lay;
- ED_base_object_select(base, BA_SELECT);
+ SceneCollection *sc;
+ if (scene != CTX_data_scene(C)) {
+ /* when linking to an inactive scene link to the master collection */
+ sc = BKE_collection_master(scene);
+ }
+ else {
+ sc = CTX_data_scene_collection(C);
+ }
+
+ BKE_collection_object_add(scene, sc, ob);
+
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+ if (base) {
+ ED_object_base_select(base, BA_SELECT);
+ }
}
DAG_relations_tag_update(bmain);
@@ -2349,7 +2272,6 @@ static int group_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Main *bmain = CTX_data_main(C);
Group *group = NULL;
Object *ob = NULL;
- Scene *scene = CTX_data_scene(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
ARegion *ar = CTX_wm_region(C);
TreeElement *te = NULL;
@@ -2379,7 +2301,7 @@ static int group_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
- BKE_group_object_add(group, ob, scene, NULL);
+ BKE_group_object_add(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index ccc52f2dba8..06b37377535 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -37,13 +37,50 @@
/* internal exports only */
struct wmOperatorType;
+struct TreeElement;
struct TreeStoreElem;
+struct Main;
struct bContext;
struct Scene;
+struct SceneLayer;
struct ID;
struct Object;
struct bPoseChannel;
struct EditBone;
+struct wmKeyConfig;
+
+
+typedef enum TreeElementInsertType {
+ TE_INSERT_BEFORE,
+ TE_INSERT_AFTER,
+ TE_INSERT_INTO,
+} TreeElementInsertType;
+
+typedef enum TreeTraversalAction {
+ /* Continue traversal regularly, don't skip children. */
+ TRAVERSE_CONTINUE = 0,
+ /* Stop traversal */
+ TRAVERSE_BREAK,
+ /* Continue traversal, but skip childs of traversed element */
+ TRAVERSE_SKIP_CHILDS,
+} TreeTraversalAction;
+
+/**
+ * Callback type for reinserting elements at a different position, used to allow user customizable element order.
+ * Passing scene right now, may be better to allow some custom data.
+ */
+typedef void (*TreeElementReinsertFunc)(struct Main *bmain, const struct Scene *scene,
+ struct TreeElement *insert_element,
+ struct TreeElement *insert_handle, TreeElementInsertType action);
+/**
+ * Executed on (almost) each mouse move while dragging. It's supposed to give info
+ * if reinserting insert_element before/after/into insert_handle would be allowed.
+ * It's allowed to change the reinsert info here for non const pointers.
+ */
+typedef bool (*TreeElementReinsertPollFunc)(const struct Scene *scene, const struct TreeElement *insert_element,
+ struct TreeElement **io_insert_handle, TreeElementInsertType *io_action);
+typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata);
+
typedef struct TreeElement {
struct TreeElement *next, *prev, *parent;
@@ -57,7 +94,17 @@ typedef struct TreeElement {
const char *name;
void *directdata; // Armature Bones, Base, Sequence, Strip...
PointerRNA rnaptr; // RNA Pointer
-} TreeElement;
+
+ /* callbacks - TODO should be moved into a type (like TreeElementType) */
+ TreeElementReinsertFunc reinsert;
+ TreeElementReinsertPollFunc reinsert_poll;
+
+ struct {
+ TreeElementInsertType insert_type;
+ /* the element before/after/into which we may insert the dragged one (NULL to insert at top) */
+ struct TreeElement *insert_handle;
+ } *drag_data;
+} TreeElement;
#define TREESTORE_ID_TYPE(_id) \
(ELEM(GS((_id)->name), ID_SCE, ID_LI, ID_OB, ID_ME, ID_CU, ID_MB, ID_NT, ID_MA, ID_TE, ID_IM, ID_LT, ID_LA, ID_CA) || \
@@ -65,10 +112,14 @@ typedef struct TreeElement {
ELEM(GS((_id)->name), ID_SCR, ID_WM, ID_TXT, ID_VF, ID_SO, ID_CF, ID_PAL)) /* Only in 'blendfile' mode ... :/ */
/* TreeElement->flag */
-#define TE_ACTIVE 1
-#define TE_ICONROW 2
-#define TE_LAZY_CLOSED 4
-#define TE_FREE_NAME 8
+enum {
+ TE_ACTIVE = (1 << 0),
+ /* Closed items display their children as icon within the row. TE_ICONROW is for
+ * these child-items that are visible but only within the row of the closed parent. */
+ TE_ICONROW = (1 << 1),
+ TE_LAZY_CLOSED = (1 << 2),
+ TE_FREE_NAME = (1 << 3),
+};
/* button events */
#define OL_NAMEBUTTON 1
@@ -129,15 +180,9 @@ typedef enum {
void outliner_free_tree(ListBase *lb);
void outliner_cleanup_tree(struct SpaceOops *soops);
+void outliner_remove_treestore_element(struct SpaceOops *soops, TreeStoreElem *tselem);
-TreeElement *outliner_find_tse(struct SpaceOops *soops, const TreeStoreElem *tse);
-TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem);
-TreeElement *outliner_find_id(struct SpaceOops *soops, ListBase *lb, const struct ID *id);
-TreeElement *outliner_find_posechannel(ListBase *lb, const struct bPoseChannel *pchan);
-TreeElement *outliner_find_editbone(ListBase *lb, const struct EditBone *ebone);
-struct ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode);
-
-void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct SpaceOops *soops);
+void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct SceneLayer *sl, struct SpaceOops *soops);
/* outliner_draw.c ---------------------------------------------- */
@@ -146,11 +191,11 @@ void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
/* outliner_select.c -------------------------------------------- */
eOLDrawState tree_element_type_active(
- struct bContext *C, struct Scene *scene, struct SpaceOops *soops,
+ struct bContext *C, struct Scene *scene, struct SceneLayer *sl, struct SpaceOops *soops,
TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive);
-eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops,
+eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, struct SceneLayer *sl, SpaceOops *soops,
TreeElement *te, const eOLSetState set, const bool handle_all_types);
-int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive);
+int outliner_item_activate_or_toggle_closed(struct bContext *C, int x, int y, bool extend, bool recursive);
/* outliner_edit.c ---------------------------------------------- */
typedef void (*outliner_operation_cb)(
@@ -158,16 +203,16 @@ typedef void (*outliner_operation_cb)(
struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *, void *);
void outliner_do_object_operation_ex(
- struct bContext *C, ReportList *reports, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
- outliner_operation_cb operation_cb, bool recurse_selected);
+ struct bContext *C, struct ReportList *reports, struct Scene *scene, struct SpaceOops *soops,
+ struct ListBase *lb, outliner_operation_cb operation_cb, bool recurse_selected);
void outliner_do_object_operation(
- struct bContext *C, ReportList *reports, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
- outliner_operation_cb operation_cb);
+ struct bContext *C, struct ReportList *reports, struct Scene *scene, struct SpaceOops *soops,
+ struct ListBase *lb, outliner_operation_cb operation_cb);
int common_restrict_check(struct bContext *C, struct Object *ob);
int outliner_has_one_flag(ListBase *lb, short flag, const int curlevel);
-void outliner_set_flag(ListBase *lb, short flag, short set);
+bool outliner_set_flag(ListBase *lb, short flag, short set);
void object_toggle_visibility_cb(
struct bContext *C, struct ReportList *reports, struct Scene *scene,
@@ -208,8 +253,11 @@ void id_remap_cb(
struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const bool children);
+
/* ...................................................... */
+void OUTLINER_OT_highlight_update(struct wmOperatorType *ot);
+
void OUTLINER_OT_item_activate(struct wmOperatorType *ot);
void OUTLINER_OT_item_openclose(struct wmOperatorType *ot);
void OUTLINER_OT_item_rename(struct wmOperatorType *ot);
@@ -229,10 +277,6 @@ void OUTLINER_OT_expanded_toggle(struct wmOperatorType *ot);
void OUTLINER_OT_scroll_page(struct wmOperatorType *ot);
-void OUTLINER_OT_renderability_toggle(struct wmOperatorType *ot);
-void OUTLINER_OT_selectability_toggle(struct wmOperatorType *ot);
-void OUTLINER_OT_visibility_toggle(struct wmOperatorType *ot);
-
void OUTLINER_OT_keyingset_add_selected(struct wmOperatorType *ot);
void OUTLINER_OT_keyingset_remove_selected(struct wmOperatorType *ot);
@@ -261,10 +305,40 @@ void OUTLINER_OT_animdata_operation(struct wmOperatorType *ot);
void OUTLINER_OT_action_set(struct wmOperatorType *ot);
void OUTLINER_OT_constraint_operation(struct wmOperatorType *ot);
void OUTLINER_OT_modifier_operation(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_operation(struct wmOperatorType *ot);
/* ---------------------------------------------------------------- */
/* outliner_ops.c */
void outliner_operatortypes(void);
void outliner_keymap(struct wmKeyConfig *keyconf);
+/* outliner_collections.c */
+
+struct SceneCollection *outliner_scene_collection_from_tree_element(TreeElement *te);
+
+void OUTLINER_OT_collections_delete(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_select(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_link(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_unlink(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_new(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_override_new(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_objects_add(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_objects_remove(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_objects_select(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_objects_deselect(struct wmOperatorType *ot);
+
+/* outliner_utils.c ---------------------------------------------- */
+
+TreeElement *outliner_find_item_at_y(const SpaceOops *soops, const ListBase *tree, float view_co_y);
+TreeElement *outliner_find_item_at_x_in_row(const SpaceOops *soops, const TreeElement *parent_te, float view_co_x);
+TreeElement *outliner_find_tse(struct SpaceOops *soops, const TreeStoreElem *tse);
+TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem);
+TreeElement *outliner_find_id(struct SpaceOops *soops, ListBase *lb, const struct ID *id);
+TreeElement *outliner_find_posechannel(ListBase *lb, const struct bPoseChannel *pchan);
+TreeElement *outliner_find_editbone(ListBase *lb, const struct EditBone *ebone);
+struct ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode);
+bool outliner_tree_traverse(const SpaceOops *soops, ListBase *tree, int filter_te_flag, int filter_tselem_flag,
+ TreeTraversalFunc func, void *customdata);
+
+
#endif /* __OUTLINER_INTERN_H__ */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 776717c8443..5466ef1a9ed 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -28,25 +28,265 @@
* \ingroup spoutliner
*/
-#include "DNA_space_types.h"
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "ED_screen.h"
+
+#include "MEM_guardedalloc.h"
#include "RNA_access.h"
+#include "UI_interface.h"
+#include "UI_view2d.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "outliner_intern.h"
+enum {
+ OUTLINER_ITEM_DRAG_CANCEL,
+ OUTLINER_ITEM_DRAG_CONFIRM,
+};
+
+static int outliner_item_drag_drop_poll(bContext *C)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ return ED_operator_outliner_active(C) &&
+ /* Only collection display modes supported for now. Others need more design work */
+ ELEM(soops->outlinevis, SO_ACT_LAYER, SO_COLLECTIONS);
+}
+
+static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event)
+{
+ /* note: using EVT_TWEAK_ events to trigger dragging is fine,
+ * it sends coordinates from where dragging was started */
+ const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
+ return outliner_find_item_at_y(soops, &soops->tree, my);
+}
+
+static void outliner_item_drag_end(TreeElement *dragged_te)
+{
+ MEM_SAFE_FREE(dragged_te->drag_data);
+}
+
+static void outliner_item_drag_get_insert_data(
+ const SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged,
+ TreeElement **r_te_insert_handle, TreeElementInsertType *r_insert_type)
+{
+ TreeElement *te_hovered;
+ float view_mval[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+ te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+
+ if (te_hovered) {
+ /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */
+
+ if (te_hovered == te_dragged) {
+ *r_te_insert_handle = te_dragged;
+ }
+ else if (te_hovered != te_dragged) {
+ const float margin = UI_UNIT_Y * (1.0f / 4);
+
+ *r_te_insert_handle = te_hovered;
+ if (view_mval[1] < (te_hovered->ys + margin)) {
+ if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) {
+ /* inserting after a open item means we insert into it, but as first child */
+ if (BLI_listbase_is_empty(&te_hovered->subtree)) {
+ *r_insert_type = TE_INSERT_INTO;
+ }
+ else {
+ *r_insert_type = TE_INSERT_BEFORE;
+ *r_te_insert_handle = te_hovered->subtree.first;
+ }
+ }
+ else {
+ *r_insert_type = TE_INSERT_AFTER;
+ }
+ }
+ else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
+ *r_insert_type = TE_INSERT_BEFORE;
+ }
+ else {
+ *r_insert_type = TE_INSERT_INTO;
+ }
+ }
+ }
+ else {
+ /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */
+
+ TreeElement *first = soops->tree.first;
+ TreeElement *last = soops->tree.last;
+
+ if (view_mval[1] < last->ys) {
+ *r_te_insert_handle = last;
+ *r_insert_type = TE_INSERT_AFTER;
+ }
+ else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
+ *r_te_insert_handle = first;
+ *r_insert_type = TE_INSERT_BEFORE;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+}
+
+static void outliner_item_drag_handle(
+ const Scene *scene, SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
+{
+ TreeElement *te_insert_handle;
+ TreeElementInsertType insert_type;
+
+ outliner_item_drag_get_insert_data(soops, ar, event, te_dragged, &te_insert_handle, &insert_type);
+
+ if (!te_dragged->reinsert_poll &&
+ /* there is no reinsert_poll, so we do some generic checks (same types and reinsert callback is available) */
+ (TREESTORE(te_dragged)->type == TREESTORE(te_insert_handle)->type) &&
+ te_dragged->reinsert)
+ {
+ /* pass */
+ }
+ else if (te_dragged == te_insert_handle) {
+ /* nothing will happen anyway, no need to do poll check */
+ }
+ else if (!te_dragged->reinsert_poll ||
+ !te_dragged->reinsert_poll(scene, te_dragged, &te_insert_handle, &insert_type))
+ {
+ te_insert_handle = NULL;
+ }
+ te_dragged->drag_data->insert_type = insert_type;
+ te_dragged->drag_data->insert_handle = te_insert_handle;
+}
+
+static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeElement *dragged_te)
+{
+ TreeElement *insert_handle = dragged_te->drag_data->insert_handle;
+ TreeElementInsertType insert_type = dragged_te->drag_data->insert_type;
+
+ if ((insert_handle == dragged_te) || !insert_handle) {
+ /* No need to do anything */
+ }
+ else if (dragged_te->reinsert) {
+ BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(scene, dragged_te, &insert_handle,
+ &insert_type));
+ /* call of assert above should not have changed insert_handle and insert_type at this point */
+ BLI_assert(dragged_te->drag_data->insert_handle == insert_handle &&
+ dragged_te->drag_data->insert_type == insert_type);
+ dragged_te->reinsert(bmain, scene, dragged_te, insert_handle, insert_type);
+ return true;
+ }
+
+ return false;
+}
+
+static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ TreeElement *te_dragged = op->customdata;
+ int retval = OPERATOR_RUNNING_MODAL;
+ bool redraw = false;
+ bool skip_rebuild = true;
+
+ switch (event->type) {
+ case EVT_MODAL_MAP:
+ if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) {
+ if (outliner_item_drag_drop_apply(bmain, scene, te_dragged)) {
+ skip_rebuild = false;
+ }
+ retval = OPERATOR_FINISHED;
+ }
+ else if (event->val == OUTLINER_ITEM_DRAG_CANCEL) {
+ retval = OPERATOR_CANCELLED;
+ }
+ else {
+ BLI_assert(0);
+ }
+ WM_event_add_mousemove(C); /* update highlight */
+ outliner_item_drag_end(te_dragged);
+ redraw = true;
+ break;
+ case MOUSEMOVE:
+ outliner_item_drag_handle(scene, soops, ar, event, te_dragged);
+ redraw = true;
+ break;
+ }
+
+ if (skip_rebuild) {
+ soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
+ }
+ if (redraw) {
+ ED_region_tag_redraw(ar);
+ }
+
+ return retval;
+}
+
+static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ TreeElement *te_dragged = outliner_item_drag_element_find(soops, ar, event);
+
+ if (!te_dragged) {
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+ }
+
+ op->customdata = te_dragged;
+ te_dragged->drag_data = MEM_callocN(sizeof(*te_dragged->drag_data), __func__);
+ /* by default we don't change the item position */
+ te_dragged->drag_data->insert_handle = te_dragged;
+ /* unset highlighted tree element, dragged one will be highlighted instead */
+ outliner_set_flag(&soops->tree, TSE_HIGHLIGHTED, false);
+
+ soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
+ ED_region_tag_redraw(ar);
+
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/**
+ * Notes about Outliner Item Drag 'n Drop:
+ * Right now only collections display mode is supported. But ideally all/most modes would support this. There are
+ * just some open design questions that have to be answered: do we want to allow mixing order of different data types
+ * (like render-layers and objects)? Would that be a purely visual change or would that have any other effect? ...
+ */
+static void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
+{
+ ot->name = "Drag and Drop Item";
+ ot->idname = "OUTLINER_OT_item_drag_drop";
+ ot->description = "Change the hierarchical position of an item by repositioning it using drag and drop";
+
+ ot->invoke = outliner_item_drag_drop_invoke;
+ ot->modal = outliner_item_drag_drop_modal;
+
+ ot->poll = outliner_item_drag_drop_poll;
+
+ ot->flag = OPTYPE_UNDO;
+}
+
+
/* ************************** registration **********************************/
void outliner_operatortypes(void)
{
+ WM_operatortype_append(OUTLINER_OT_highlight_update);
WM_operatortype_append(OUTLINER_OT_item_activate);
WM_operatortype_append(OUTLINER_OT_select_border);
WM_operatortype_append(OUTLINER_OT_item_openclose);
WM_operatortype_append(OUTLINER_OT_item_rename);
+ WM_operatortype_append(OUTLINER_OT_item_drag_drop);
WM_operatortype_append(OUTLINER_OT_operation);
WM_operatortype_append(OUTLINER_OT_scene_operation);
WM_operatortype_append(OUTLINER_OT_object_operation);
@@ -61,6 +301,7 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_action_set);
WM_operatortype_append(OUTLINER_OT_constraint_operation);
WM_operatortype_append(OUTLINER_OT_modifier_operation);
+ WM_operatortype_append(OUTLINER_OT_collection_operation);
WM_operatortype_append(OUTLINER_OT_show_one_level);
WM_operatortype_append(OUTLINER_OT_show_active);
@@ -70,10 +311,6 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_selected_toggle);
WM_operatortype_append(OUTLINER_OT_expanded_toggle);
- WM_operatortype_append(OUTLINER_OT_renderability_toggle);
- WM_operatortype_append(OUTLINER_OT_selectability_toggle);
- WM_operatortype_append(OUTLINER_OT_visibility_toggle);
-
WM_operatortype_append(OUTLINER_OT_keyingset_add_selected);
WM_operatortype_append(OUTLINER_OT_keyingset_remove_selected);
@@ -87,13 +324,57 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_scene_drop);
WM_operatortype_append(OUTLINER_OT_material_drop);
WM_operatortype_append(OUTLINER_OT_group_link);
+
+ /* collections */
+ WM_operatortype_append(OUTLINER_OT_collections_delete);
+ WM_operatortype_append(OUTLINER_OT_collection_select);
+ WM_operatortype_append(OUTLINER_OT_collection_link);
+ WM_operatortype_append(OUTLINER_OT_collection_unlink);
+ WM_operatortype_append(OUTLINER_OT_collection_new);
+ WM_operatortype_append(OUTLINER_OT_collection_override_new);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_add);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_remove);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_select);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_deselect);
+}
+
+static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf)
+{
+ static EnumPropertyItem modal_items[] = {
+ {OUTLINER_ITEM_DRAG_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {OUTLINER_ITEM_DRAG_CONFIRM, "CONFIRM", 0, "Confirm/Drop", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+ const char *map_name = "Outliner Item Drap 'n Drop Modal Map";
+
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, map_name);
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items)
+ return NULL;
+
+ keymap = WM_modalkeymap_add(keyconf, map_name, modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL);
+
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
+ WM_modalkeymap_add_item(keymap, RETKEY, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
+ WM_modalkeymap_add_item(keymap, PADENTER, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
+
+ WM_modalkeymap_assign(keymap, "OUTLINER_OT_item_drag_drop");
+
+ return keymap;
}
void outliner_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Outliner", SPACE_OUTLINER, 0);
wmKeyMapItem *kmi;
-
+
+ WM_keymap_add_item(keymap, "OUTLINER_OT_highlight_update", MOUSEMOVE, KM_ANY, KM_ANY, 0);
+
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, 0, 0);
@@ -123,6 +404,8 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_operation", RIGHTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_item_drag_drop", EVT_TWEAK_L, KM_ANY, 0, 0);
+
WM_keymap_add_item(keymap, "OUTLINER_OT_show_hierarchy", HOMEKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_show_active", PERIODKEY, KM_PRESS, 0, 0);
@@ -140,11 +423,6 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "OUTLINER_OT_selected_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_expanded_toggle", AKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "OUTLINER_OT_renderability_toggle", RKEY, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "OUTLINER_OT_selectability_toggle", SKEY, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "OUTLINER_OT_visibility_toggle", VKEY, KM_PRESS, 0, 0);
-
-
/* keying sets - only for databrowse */
WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_add_selected", KKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_remove_selected", KKEY, KM_PRESS, KM_ALT, 0);
@@ -154,5 +432,7 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "OUTLINER_OT_drivers_add_selected", DKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_drivers_delete_selected", DKEY, KM_PRESS, KM_ALT, 0);
+
+ outliner_item_drag_drop_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 7e05c76b35b..931af08c717 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -46,6 +46,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_object.h"
+#include "BKE_layer.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_armature.h"
@@ -68,61 +69,12 @@
#include "outliner_intern.h"
-/* ****************************************************** */
-/* Outliner Selection (gray-blue highlight for rows) */
-
-static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selecting)
-{
- TreeElement *te;
- TreeStoreElem *tselem;
- bool changed = false;
-
- for (te = lb->first; te && *index >= 0; te = te->next, (*index)--) {
- tselem = TREESTORE(te);
-
- /* if we've encountered the right item, set its 'Outliner' selection status */
- if (*index == 0) {
- /* this should be the last one, so no need to do anything with index */
- if ((te->flag & TE_ICONROW) == 0) {
- /* -1 value means toggle testing for now... */
- if (*selecting == -1) {
- if (tselem->flag & TSE_SELECTED)
- *selecting = 0;
- else
- *selecting = 1;
- }
-
- /* set selection */
- if (*selecting)
- tselem->flag |= TSE_SELECTED;
- else
- tselem->flag &= ~TSE_SELECTED;
-
- changed |= true;
- }
- }
- else if (TSELEM_OPEN(tselem, soops)) {
- /* Only try selecting sub-elements if we haven't hit the right element yet
- *
- * Hack warning:
- * Index must be reduced before supplying it to the sub-tree to try to do
- * selection, however, we need to increment it again for the next loop to
- * function correctly
- */
- (*index)--;
- changed |= outliner_select(soops, &te->subtree, index, selecting);
- (*index)++;
- }
- }
-
- return changed;
-}
/* ****************************************************** */
/* Outliner Element Selection/Activation on Click */
static eOLDrawState tree_element_active_renderlayer(
- bContext *C, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, Scene *UNUSED(scene), SceneLayer *UNUSED(sl), TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
Scene *sce;
@@ -146,14 +98,14 @@ static eOLDrawState tree_element_active_renderlayer(
* CTRL+LMB: Select/Deselect object and all cildren
* CTRL+SHIFT+LMB: Add/Remove object and all children
*/
-static void do_outliner_object_select_recursive(Scene *scene, Object *ob_parent, bool select)
+static void do_outliner_object_select_recursive(SceneLayer *sl, Object *ob_parent, bool select)
{
Base *base;
- for (base = FIRSTBASE; base; base = base->next) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
Object *ob = base->object;
- if ((((ob->restrictflag & OB_RESTRICT_VIEW) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ if ((((base->flag & BASE_VISIBLED) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
}
}
@@ -184,7 +136,7 @@ static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_p
}
static eOLDrawState tree_element_set_active_object(
- bContext *C, Scene *scene, SpaceOops *soops,
+ bContext *C, Scene *scene, SceneLayer *sl, SpaceOops *soops,
TreeElement *te, const eOLSetState set, bool recursive)
{
TreeStoreElem *tselem = TREESTORE(te);
@@ -198,7 +150,7 @@ static eOLDrawState tree_element_set_active_object(
}
else {
ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == OBACT) {
+ if (ob == OBACT_NEW) {
return OL_DRAWSEL_NONE;
}
}
@@ -213,29 +165,29 @@ static eOLDrawState tree_element_set_active_object(
}
/* find associated base in current scene */
- base = BKE_scene_base_find(scene, ob);
+ base = BKE_scene_layer_base_find(sl, ob);
if (base) {
if (set == OL_SETSEL_EXTEND) {
/* swap select */
- if (base->flag & SELECT)
- ED_base_object_select(base, BA_DESELECT);
+ if (base->flag & BASE_SELECTED)
+ ED_object_base_select(base, BA_DESELECT);
else
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_select(base, BA_SELECT);
}
else {
/* deleselect all */
- BKE_scene_base_deselect_all(scene);
- ED_base_object_select(base, BA_SELECT);
+ BKE_scene_layer_base_deselect_all(sl);
+ ED_object_base_select(base, BA_SELECT);
}
if (recursive) {
/* Recursive select/deselect for Object hierarchies */
- do_outliner_object_select_recursive(scene, ob, (ob->flag & SELECT) != 0);
+ do_outliner_object_select_recursive(sl, ob, (ob->flag & SELECT) != 0);
}
- if (C) {
- ED_base_object_activate(C, base); /* adds notifier */
+ if (set != OL_SETSEL_NONE) {
+ ED_object_base_activate(C, base); /* adds notifier */
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
}
@@ -247,7 +199,7 @@ static eOLDrawState tree_element_set_active_object(
}
static eOLDrawState tree_element_active_material(
- bContext *C, Scene *scene, SpaceOops *soops,
+ bContext *C, Scene *UNUSED(scene), SceneLayer *sl, SpaceOops *soops,
TreeElement *te, const eOLSetState set)
{
TreeElement *tes;
@@ -256,7 +208,7 @@ static eOLDrawState tree_element_active_material(
/* we search for the object parent */
ob = (Object *)outliner_search_back(soops, te, ID_OB);
// note: ob->matbits can be NULL when a local object points to a library mesh.
- if (ob == NULL || ob != OBACT || ob->matbits == NULL) {
+ if (ob == NULL || ob != OBACT_NEW || ob->matbits == NULL) {
return OL_DRAWSEL_NONE; /* just paranoia */
}
@@ -300,12 +252,12 @@ static eOLDrawState tree_element_active_material(
}
static eOLDrawState tree_element_active_texture(
- bContext *C, Scene *scene, SpaceOops *UNUSED(soops),
+ bContext *C, Scene *scene, SceneLayer *sl, SpaceOops *UNUSED(soops),
TreeElement *te, const eOLSetState set)
{
TreeElement *tep;
TreeStoreElem /* *tselem,*/ *tselemp;
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
SpaceButs *sbuts = NULL;
if (ob == NULL) {
@@ -387,14 +339,14 @@ static eOLDrawState tree_element_active_texture(
static eOLDrawState tree_element_active_lamp(
- bContext *UNUSED(C), Scene *scene, SpaceOops *soops,
+ bContext *UNUSED(C), Scene *UNUSED(scene), SceneLayer *sl, SpaceOops *soops,
TreeElement *te, const eOLSetState set)
{
Object *ob;
/* we search for the object parent */
ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == NULL || ob != OBACT) {
+ if (ob == NULL || ob != OBACT_NEW) {
/* just paranoia */
return OL_DRAWSEL_NONE;
}
@@ -410,7 +362,7 @@ static eOLDrawState tree_element_active_lamp(
}
static eOLDrawState tree_element_active_camera(
- bContext *UNUSED(C), Scene *scene, SpaceOops *soops,
+ bContext *UNUSED(C), Scene *scene, SceneLayer *UNUSED(sl), SpaceOops *soops,
TreeElement *te, const eOLSetState set)
{
Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
@@ -423,7 +375,7 @@ static eOLDrawState tree_element_active_camera(
}
static eOLDrawState tree_element_active_world(
- bContext *C, Scene *scene, SpaceOops *UNUSED(soops),
+ bContext *C, Scene *scene, SceneLayer *UNUSED(sl), SpaceOops *UNUSED(soops),
TreeElement *te, const eOLSetState set)
{
TreeElement *tep;
@@ -456,7 +408,7 @@ static eOLDrawState tree_element_active_world(
}
static eOLDrawState tree_element_active_defgroup(
- bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, SceneLayer *sl, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
Object *ob;
@@ -470,17 +422,16 @@ static eOLDrawState tree_element_active_defgroup(
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
}
else {
- if (ob == OBACT) {
+ if (ob == OBACT_NEW)
if (ob->actdef == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
- }
}
return OL_DRAWSEL_NONE;
}
static eOLDrawState tree_element_active_posegroup(
- bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, Scene *UNUSED(scene), SceneLayer *sl, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
Object *ob = (Object *)tselem->id;
@@ -491,7 +442,7 @@ static eOLDrawState tree_element_active_posegroup(
}
}
else {
- if (ob == OBACT && ob->pose) {
+ if (ob == OBACT_NEW && ob->pose) {
if (ob->pose->active_group == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
@@ -501,7 +452,7 @@ static eOLDrawState tree_element_active_posegroup(
}
static eOLDrawState tree_element_active_posechannel(
- bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
+ bContext *C, Scene *UNUSED(scene), SceneLayer *sl, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
{
Object *ob = (Object *)tselem->id;
bArmature *arm = ob->data;
@@ -535,7 +486,7 @@ static eOLDrawState tree_element_active_posechannel(
}
}
else {
- if (ob == OBACT && ob->pose) {
+ if (ob == OBACT_NEW && ob->pose) {
if (pchan->bone->flag & BONE_SELECTED) {
return OL_DRAWSEL_NORMAL;
}
@@ -545,14 +496,14 @@ static eOLDrawState tree_element_active_posechannel(
}
static eOLDrawState tree_element_active_bone(
- bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
+ bContext *C, SceneLayer *sl, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
{
bArmature *arm = (bArmature *)tselem->id;
Bone *bone = te->directdata;
if (set != OL_SETSEL_NONE) {
if (!(bone->flag & BONE_HIDDEN_P)) {
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
if (ob) {
if (set != OL_SETSEL_EXTEND) {
/* single select forces all other bones to get unselected */
@@ -581,7 +532,7 @@ static eOLDrawState tree_element_active_bone(
}
}
else {
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
if (ob && ob->data == arm) {
if (bone->flag & BONE_SELECTED) {
@@ -654,7 +605,7 @@ static eOLDrawState tree_element_active_ebone(
}
static eOLDrawState tree_element_active_modifier(
- bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, Scene *UNUSED(scene), SceneLayer *UNUSED(sl), TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
@@ -682,7 +633,7 @@ static eOLDrawState tree_element_active_psys(
}
static int tree_element_active_constraint(
- bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, Scene *UNUSED(scene), SceneLayer *UNUSED(sl), TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
@@ -695,7 +646,7 @@ static int tree_element_active_constraint(
}
static eOLDrawState tree_element_active_text(
- bContext *UNUSED(C), Scene *UNUSED(scene), SpaceOops *UNUSED(soops),
+ bContext *UNUSED(C), Scene *UNUSED(scene), SceneLayer *UNUSED(sl), SpaceOops *UNUSED(soops),
TreeElement *UNUSED(te), int UNUSED(set))
{
// XXX removed
@@ -703,10 +654,10 @@ static eOLDrawState tree_element_active_text(
}
static eOLDrawState tree_element_active_pose(
- bContext *C, Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, Scene *scene, SceneLayer *sl, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
{
Object *ob = (Object *)tselem->id;
- Base *base = BKE_scene_base_find(scene, ob);
+ Base *base = BKE_scene_layer_base_find(sl, ob);
if (set != OL_SETSEL_NONE) {
if (scene->obedit)
@@ -787,7 +738,7 @@ static eOLDrawState tree_element_active_sequence_dup(
}
static eOLDrawState tree_element_active_keymap_item(
- bContext *UNUSED(C), TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
+ bContext *UNUSED(C), Scene *UNUSED(scene), SceneLayer *UNUSED(sl), TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
{
wmKeyMapItem *kmi = te->directdata;
@@ -803,10 +754,42 @@ static eOLDrawState tree_element_active_keymap_item(
return OL_DRAWSEL_NONE;
}
+static eOLDrawState tree_element_active_collection(
+ bContext *C, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+{
+ if (set == OL_SETSEL_NONE) {
+ LayerCollection *active = CTX_data_layer_collection(C);
+
+ /* sometimes the renderlayer has no LayerCollection at all */
+ if (active == NULL) {
+ return OL_DRAWSEL_NONE;
+ }
+
+ if ((tselem->type == TSE_SCENE_COLLECTION && active->scene_collection == te->directdata) ||
+ (tselem->type == TSE_LAYER_COLLECTION && active == te->directdata))
+ {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ /* don't allow selecting a scene collection, it can have multiple layer collection
+ * instances (which one would the user want to be selected then?) */
+ else if (tselem->type == TSE_LAYER_COLLECTION) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ LayerCollection *lc = te->directdata;
+ const int collection_index = BKE_layer_collection_findindex(sl, lc);
+
+ BLI_assert(collection_index >= 0);
+ sl->active_collection = collection_index;
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ }
+
+ return OL_DRAWSEL_NONE;
+}
+
/* ---------------------------------------------- */
/* generic call for ID data check or make/check active in UI */
-eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te,
+eOLDrawState tree_element_active(bContext *C, Scene *scene, SceneLayer *sl, SpaceOops *soops, TreeElement *te,
const eOLSetState set, const bool handle_all_types)
{
switch (te->idcode) {
@@ -814,236 +797,240 @@ eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, Tr
* selection. See do_outliner_item_activate. */
case ID_OB:
if (handle_all_types) {
- return tree_element_set_active_object(C, scene, soops, te, set, false);
+ return tree_element_set_active_object(C, scene, sl, soops, te, set, false);
}
break;
case ID_MA:
- return tree_element_active_material(C, scene, soops, te, set);
+ return tree_element_active_material(C, scene, sl, soops, te, set);
case ID_WO:
- return tree_element_active_world(C, scene, soops, te, set);
+ return tree_element_active_world(C, scene, sl, soops, te, set);
case ID_LA:
- return tree_element_active_lamp(C, scene, soops, te, set);
+ return tree_element_active_lamp(C, scene, sl, soops, te, set);
case ID_TE:
- return tree_element_active_texture(C, scene, soops, te, set);
+ return tree_element_active_texture(C, scene, sl, soops, te, set);
case ID_TXT:
- return tree_element_active_text(C, scene, soops, te, set);
+ return tree_element_active_text(C, scene, sl, soops, te, set);
case ID_CA:
- return tree_element_active_camera(C, scene, soops, te, set);
+ return tree_element_active_camera(C, scene, sl, soops, te, set);
}
return OL_DRAWSEL_NONE;
}
/**
* Generic call for non-id data to make/check active in UI
- *
- * \note Context can be NULL when ``(set == OL_SETSEL_NONE)``
*/
eOLDrawState tree_element_type_active(
- bContext *C, Scene *scene, SpaceOops *soops,
+ bContext *C, Scene *scene, SceneLayer *sl, SpaceOops *soops,
TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
{
switch (tselem->type) {
case TSE_DEFGROUP:
- return tree_element_active_defgroup(C, scene, te, tselem, set);
+ return tree_element_active_defgroup(C, sl, te, tselem, set);
case TSE_BONE:
- return tree_element_active_bone(C, scene, te, tselem, set, recursive);
+ return tree_element_active_bone(C, sl, te, tselem, set, recursive);
case TSE_EBONE:
return tree_element_active_ebone(C, scene, te, tselem, set, recursive);
case TSE_MODIFIER:
- return tree_element_active_modifier(C, te, tselem, set);
+ return tree_element_active_modifier(C, scene, sl, te, tselem, set);
case TSE_LINKED_OB:
if (set != OL_SETSEL_NONE) {
- tree_element_set_active_object(C, scene, soops, te, set, false);
+ tree_element_set_active_object(C, scene, sl, soops, te, set, false);
}
- else if (tselem->id == (ID *)OBACT) {
+ else if (tselem->id == (ID *)OBACT_NEW) {
return OL_DRAWSEL_NORMAL;
}
break;
case TSE_LINKED_PSYS:
return tree_element_active_psys(C, scene, te, tselem, set);
case TSE_POSE_BASE:
- return tree_element_active_pose(C, scene, te, tselem, set);
+ return tree_element_active_pose(C, scene, sl, te, tselem, set);
case TSE_POSE_CHANNEL:
- return tree_element_active_posechannel(C, scene, te, tselem, set, recursive);
+ return tree_element_active_posechannel(C, scene, sl, te, tselem, set, recursive);
case TSE_CONSTRAINT:
- return tree_element_active_constraint(C, te, tselem, set);
+ return tree_element_active_constraint(C, scene, sl, te, tselem, set);
case TSE_R_LAYER:
- return tree_element_active_renderlayer(C, te, tselem, set);
+ return tree_element_active_renderlayer(C, scene, sl, te, tselem, set);
case TSE_POSEGRP:
- return tree_element_active_posegroup(C, scene, te, tselem, set);
+ return tree_element_active_posegroup(C, scene, sl, te, tselem, set);
case TSE_SEQUENCE:
return tree_element_active_sequence(C, scene, te, tselem, set);
case TSE_SEQUENCE_DUP:
return tree_element_active_sequence_dup(scene, te, tselem, set);
case TSE_KEYMAP_ITEM:
- return tree_element_active_keymap_item(C, te, tselem, set);
+ return tree_element_active_keymap_item(C, scene, sl, te, tselem, set);
case TSE_GP_LAYER:
- //return tree_element_active_gplayer(C, scene, te, tselem, set);
+ //return tree_element_active_gplayer(C, scene, s, te, tselem, set);
break;
-
+ case TSE_SCENE_COLLECTION:
+ case TSE_LAYER_COLLECTION:
+ return tree_element_active_collection(C, te, tselem, set);
}
return OL_DRAWSEL_NONE;
}
/* ================================================ */
-static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, bool extend, bool recursive, const float mval[2])
+static void outliner_item_activate(
+ bContext *C, SpaceOops *soops, TreeElement *te,
+ const bool extend, const bool recursive)
{
-
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- TreeStoreElem *tselem = TREESTORE(te);
- bool openclose = false;
-
- /* open close icon */
- if ((te->flag & TE_ICONROW) == 0) { // hidden icon, no open/close
- if (mval[0] > te->xs && mval[0] < te->xs + UI_UNIT_X)
- openclose = true;
- }
-
- if (openclose) {
- /* all below close/open? */
- if (extend) {
- tselem->flag &= ~TSE_CLOSED;
- outliner_set_flag(&te->subtree, TSE_CLOSED, !outliner_has_one_flag(&te->subtree, TSE_CLOSED, 1));
- }
- else {
- if (tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED;
- else tselem->flag |= TSE_CLOSED;
-
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ /* always makes active object, except for some specific types.
+ * Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want
+ * to switch out of edit mode (see T48328 for details). */
+ if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_LAYER_COLLECTION)) {
+ tree_element_set_active_object(C, scene, sl, soops, te,
+ (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
+ recursive && tselem->type == 0);
+ }
+
+ if (tselem->type == 0) { // the lib blocks
+ /* editmode? */
+ if (te->idcode == ID_SCE) {
+ if (scene != (Scene *)tselem->id) {
+ ED_screen_set_scene(C, CTX_wm_screen(C), (Scene *)tselem->id);
}
-
- return true;
}
- /* name and first icon */
- else if (mval[0] > te->xs + UI_UNIT_X && mval[0] < te->xend) {
-
- /* always makes active object, except for some specific types.
- * Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want
- * to switch out of edit mode (see T48328 for details). */
- if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE)) {
- tree_element_set_active_object(C, scene, soops, te,
- (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
- recursive && tselem->type == 0);
- }
+ else if (te->idcode == ID_GR) {
+ Group *gr = (Group *)tselem->id;
+ GroupObject *gob;
- if (tselem->type == 0) { // the lib blocks
- /* editmode? */
- if (te->idcode == ID_SCE) {
- if (scene != (Scene *)tselem->id) {
- ED_screen_set_scene(C, CTX_wm_screen(C), (Scene *)tselem->id);
- }
- }
- else if (te->idcode == ID_GR) {
- Group *gr = (Group *)tselem->id;
- GroupObject *gob;
-
- if (extend) {
- int sel = BA_SELECT;
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if (gob->ob->flag & SELECT) {
- sel = BA_DESELECT;
- break;
- }
- }
-
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- ED_base_object_select(BKE_scene_base_find(scene, gob->ob), sel);
- }
- }
- else {
- BKE_scene_base_deselect_all(scene);
-
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if ((gob->ob->flag & SELECT) == 0)
- ED_base_object_select(BKE_scene_base_find(scene, gob->ob), BA_SELECT);
- }
+ if (extend) {
+ int sel = BA_SELECT;
+ for (gob = gr->gobject.first; gob; gob = gob->next) {
+ if (gob->ob->flag & SELECT) {
+ sel = BA_DESELECT;
+ break;
}
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else if (ELEM(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) {
- WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
- }
- else { // rest of types
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false);
}
+ for (gob = gr->gobject.first; gob; gob = gob->next) {
+ ED_object_base_select(BKE_scene_layer_base_find(sl, gob->ob), sel);
+ }
}
else {
- tree_element_type_active(C, scene, soops, te, tselem,
- extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
- recursive);
+ BKE_scene_layer_base_deselect_all(sl);
+
+ for (gob = gr->gobject.first; gob; gob = gob->next) {
+ Base *base = BKE_scene_layer_base_find(sl, gob->ob);
+ if ((base->flag & BASE_SELECTED) == 0) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
}
- return true;
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- }
-
- for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, mval)) {
- return true;
+ else if (ELEM(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) {
+ WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
+ else { // rest of types
+ tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NORMAL, false);
}
+
+ }
+ else {
+ tree_element_type_active(C, scene, sl, soops, te, tselem,
+ extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
+ recursive);
}
- return false;
}
-int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recursive)
+/**
+ * \param extend: Don't deselect other items, only modify \a te.
+ * \param toggle: Select \a te when not selected, deselect when selected.
+ */
+static void outliner_item_select(SpaceOops *soops, const TreeElement *te, const bool extend, const bool toggle)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+ const short new_flag = toggle ? (tselem->flag ^ TSE_SELECTED) : (tselem->flag | TSE_SELECTED);
+
+ if (extend == false) {
+ outliner_set_flag(&soops->tree, TSE_SELECTED, false);
+ }
+ tselem->flag = new_flag;
+}
+
+static void outliner_item_toggle_closed(TreeElement *te, const bool toggle_children)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (toggle_children) {
+ tselem->flag &= ~TSE_CLOSED;
+
+ const bool all_opened = !outliner_has_one_flag(&te->subtree, TSE_CLOSED, 1);
+ outliner_set_flag(&te->subtree, TSE_CLOSED, all_opened);
+ }
+ else {
+ tselem->flag ^= TSE_CLOSED;
+ }
+}
+
+static bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x)
+{
+ return ((te->flag & TE_ICONROW) == 0) && (view_co_x > te->xs) && (view_co_x < te->xs + UI_UNIT_X);
+}
+
+static bool outliner_is_co_within_restrict_columns(const SpaceOops *soops, const ARegion *ar, float view_co_x)
+{
+ return (!ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF) &&
+ !(soops->flag & SO_HIDE_RESTRICTCOLS) &&
+ (view_co_x > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX));
+}
+
+int outliner_item_activate_or_toggle_closed(bContext *C, int x, int y, bool extend, bool recursive)
{
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te;
- float fmval[2];
+ float view_mval[2];
+ bool changed = false, rebuild_tree = false;
- UI_view2d_region_to_view(&ar->v2d, x, y, &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, x, y, &view_mval[0], &view_mval[1]);
- if (!ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF) &&
- !(soops->flag & SO_HIDE_RESTRICTCOLS) &&
- (fmval[0] > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX))
- {
+ if (outliner_is_co_within_restrict_columns(soops, ar, view_mval[0])) {
return OPERATOR_CANCELLED;
}
- for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, fmval)) break;
+ if (!(te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]))) {
+ /* skip */
}
-
- if (te) {
- ED_undo_push(C, "Outliner click event");
+ else if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
+ outliner_item_toggle_closed(te, extend);
+ changed = true;
+ rebuild_tree = true;
}
else {
- short selecting = -1;
- int row;
-
- /* get row number - 100 here is just a dummy value since we don't need the column */
- UI_view2d_listview_view_to_cell(&ar->v2d, 1000, UI_UNIT_Y, 0.0f, OL_Y_OFFSET,
- fmval[0], fmval[1], NULL, &row);
-
- /* select relevant row */
- if (outliner_select(soops, &soops->tree, &row, &selecting)) {
-
+ /* the row may also contain children, if one is hovered we want this instead of current te */
+ TreeElement *activate_te = outliner_find_item_at_x_in_row(soops, te, view_mval[0]);
+
+ outliner_item_select(soops, activate_te, extend, extend);
+ outliner_item_activate(C, soops, activate_te, extend, recursive);
+ changed = true;
+ }
+
+ if (changed) {
+ if (!rebuild_tree) {
+ /* only needs to redraw, no rebuild */
soops->storeflag |= SO_TREESTORE_REDRAW;
-
- /* no need for undo push here, only changing outliner data which is
- * scene level - campbell */
- /* ED_undo_push(C, "Outliner selection event"); */
}
+ ED_undo_push(C, "Outliner selection change");
+ ED_region_tag_redraw(ar);
}
-
- ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
/* event can enterkey, then it opens/closes */
-static int outliner_item_activate(bContext *C, wmOperator *op, const wmEvent *event)
+static int outliner_item_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bool extend = RNA_boolean_get(op->ptr, "extend");
bool recursive = RNA_boolean_get(op->ptr, "recursive");
int x = event->mval[0];
int y = event->mval[1];
- return outliner_item_do_activate(C, x, y, extend, recursive);
+ return outliner_item_activate_or_toggle_closed(C, x, y, extend, recursive);
}
void OUTLINER_OT_item_activate(wmOperatorType *ot)
@@ -1052,7 +1039,7 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
ot->idname = "OUTLINER_OT_item_activate";
ot->description = "Handle mouse clicks to activate/select items";
- ot->invoke = outliner_item_activate;
+ ot->invoke = outliner_item_activate_invoke;
ot->poll = ED_operator_outliner_active;
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index d1392b6c07e..0591a8674d3 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -56,6 +56,7 @@
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_group.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
@@ -360,15 +361,15 @@ void OUTLINER_OT_scene_operation(wmOperatorType *ot)
/* ******************************************** */
static void object_select_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *te,
+ bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
- Base *base = (Base *)te->directdata;
-
- if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id);
- if (base && ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0)) {
- base->flag |= SELECT;
- base->object->flag |= SELECT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+
+ if (base && ((base->flag & BASE_VISIBLED) != 0)) {
+ base->flag |= BASE_SELECTED;
}
}
@@ -380,20 +381,20 @@ static void object_select_hierarchy_cb(
wmWindow *win = CTX_wm_window(C);
int x = win->eventstate->mval[0];
int y = win->eventstate->mval[1];
- outliner_item_do_activate(C, x, y, true, true);
+ outliner_item_activate_or_toggle_closed(C, x, y, true, true);
}
static void object_deselect_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *te,
+ bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
- Base *base = (Base *)te->directdata;
-
- if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+
if (base) {
- base->flag &= ~SELECT;
- base->object->flag &= ~SELECT;
+ base->flag &= ~BASE_SELECTED;
}
}
@@ -401,30 +402,27 @@ static void object_delete_cb(
bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
TreeStoreElem *tsep, TreeStoreElem *tselem, void *user_data)
{
- Base *base = (Base *)te->directdata;
-
- if (base == NULL)
- base = BKE_scene_base_find(scene, (Object *)tselem->id);
- if (base) {
+ Object *ob = (Object *)tselem->id;
+ if (ob) {
Main *bmain = CTX_data_main(C);
- if (base->object->id.tag & LIB_TAG_INDIRECT) {
- BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
+ if (ob->id.tag & LIB_TAG_INDIRECT) {
+ BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
return;
}
- else if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
- ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0)
+ else if (BKE_library_ID_is_indirectly_used(bmain, ob) &&
+ ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0)
{
BKE_reportf(reports, RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
- base->object->id.name + 2, scene->id.name + 2);
+ ob->id.name + 2, scene->id.name + 2);
return;
}
// check also library later
- if (scene->obedit == base->object)
+ if (scene->obedit == ob)
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
- ED_base_object_free_and_unlink(CTX_data_main(C), scene, base);
+ ED_base_object_free_and_unlink(CTX_data_main(C), scene, ob);
/* leave for ED_outliner_id_unref to handle */
#if 0
te->directdata = NULL;
@@ -522,22 +520,25 @@ static void singleuser_world_cb(
}
static void group_linkobs2scene_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
+ bContext *C, ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ SceneCollection *sc = CTX_data_scene_collection(C);
Group *group = (Group *)tselem->id;
GroupObject *gob;
Base *base;
for (gob = group->gobject.first; gob; gob = gob->next) {
- base = BKE_scene_base_find(scene, gob->ob);
+ base = BKE_scene_layer_base_find(sl, gob->ob);
if (!base) {
/* link to scene */
- base = BKE_scene_base_add(scene, gob->ob);
+ BKE_collection_object_add(scene, sc, gob->ob);
+ base = BKE_scene_layer_base_find(sl, gob->ob);
id_us_plus(&gob->ob->id);
}
- base->object->flag |= SELECT;
- base->flag |= SELECT;
+
+ base->flag |= BASE_SELECTED;
}
}
@@ -657,6 +658,14 @@ typedef enum eOutliner_PropModifierOps {
OL_MODIFIER_OP_DELETE
} eOutliner_PropModifierOps;
+typedef enum eOutliner_PropCollectionOps {
+ OL_COLLECTION_OP_OBJECTS_ADD = 1,
+ OL_COLLECTION_OP_OBJECTS_REMOVE,
+ OL_COLLECTION_OP_COLLECTION_NEW,
+ OL_COLLECTION_OP_COLLECTION_DEL,
+ OL_COLLECTION_OP_COLLECTION_UNLINK,
+} eOutliner_PropCollectionOps;
+
static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
@@ -807,6 +816,63 @@ static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem
}
}
+static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg)
+{
+ bContext *C = (bContext *)Carg;
+ Scene *scene = CTX_data_scene(C);
+ LayerCollection *lc = te->directdata;
+ SceneCollection *sc = lc->scene_collection;
+
+ if (event == OL_COLLECTION_OP_OBJECTS_ADD) {
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ BKE_collection_object_add(scene, sc, ob);
+ }
+ CTX_DATA_END;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ }
+ else if (event == OL_COLLECTION_OP_OBJECTS_REMOVE) {
+ Main *bmain = CTX_data_main(C);
+
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ BKE_collection_object_remove(bmain, scene, sc, ob, true);
+ }
+ CTX_DATA_END;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ te->store_elem->flag &= ~TSE_SELECTED;
+ }
+ else if (event == OL_COLLECTION_OP_COLLECTION_NEW) {
+ BKE_collection_add(scene, sc, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ }
+ else if (event == OL_COLLECTION_OP_COLLECTION_UNLINK) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+
+ if (BLI_findindex(&sl->layer_collections, lc) == -1) {
+ /* we can't unlink if the layer collection wasn't directly linked */
+ TODO_LAYER_OPERATORS; /* this shouldn't be in the menu in those cases */
+ }
+ else {
+ BKE_collection_unlink(sl, lc);
+ DAG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ }
+ }
+ else if (event == OL_COLLECTION_OP_COLLECTION_DEL) {
+ if (BKE_collection_remove(scene, sc)) {
+ DAG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ }
+ else {
+ /* we can't remove the master collection */
+ TODO_LAYER_OPERATORS; /* this shouldn't be in the menu in those cases */
+ }
+ }
+}
+
static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb,
void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *),
void *arg)
@@ -831,12 +897,13 @@ static Base *outline_delete_hierarchy(bContext *C, ReportList *reports, Scene *s
{
Base *child_base, *base_next;
Object *parent;
+ SceneLayer *scene_layer = CTX_data_scene_layer(C);
if (!base) {
return NULL;
}
- for (child_base = scene->base.first; child_base; child_base = base_next) {
+ for (child_base = scene_layer->object_bases.first; child_base; child_base = base_next) {
base_next = child_base->next;
for (parent = child_base->object->parent; parent && (parent != base->object); parent = parent->parent);
if (parent) {
@@ -859,7 +926,7 @@ static Base *outline_delete_hierarchy(bContext *C, ReportList *reports, Scene *s
base->object->id.name + 2, scene->id.name + 2);
return base_next;
}
- ED_base_object_free_and_unlink(CTX_data_main(C), scene, base);
+ ED_base_object_free_and_unlink(CTX_data_main(C), scene, base->object);
return base_next;
}
@@ -867,11 +934,12 @@ static void object_delete_hierarchy_cb(
bContext *C, ReportList *reports, Scene *scene,
TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base = (Base *)te->directdata;
Object *obedit = scene->obedit;
if (!base) {
- base = BKE_scene_base_find(scene, (Object *)tselem->id);
+ base = BKE_scene_layer_base_find(sl, (Object *)tselem->id);
}
if (base) {
/* Check also library later. */
@@ -992,21 +1060,6 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
str = "Localized Objects";
}
- else if (event == OL_OP_TOGVIS) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_visibility_cb);
- str = "Toggle Visibility";
- WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
- }
- else if (event == OL_OP_TOGSEL) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_selectability_cb);
- str = "Toggle Selectability";
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else if (event == OL_OP_TOGREN) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_renderability_cb);
- str = "Toggle Renderability";
- WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
- }
else if (event == OL_OP_RENAME) {
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb);
str = "Rename Object";
@@ -1102,15 +1155,6 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op)
case OL_GROUPOP_REMAP:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
break;
- case OL_GROUPOP_TOGVIS:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, group_toggle_visibility_cb, NULL);
- break;
- case OL_GROUPOP_TOGSEL:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, group_toggle_selectability_cb, NULL);
- break;
- case OL_GROUPOP_TOGREN:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, group_toggle_renderability_cb, NULL);
- break;
case OL_GROUPOP_RENAME:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
break;
@@ -1750,6 +1794,52 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
/* ******************** */
+static EnumPropertyItem prop_collection_op_types[] = {
+ {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
+ {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
+ {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
+ {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"},
+ {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_NEW", ICON_X, "Delete Collection", "Delete the collection"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_PropCollectionOps event;
+
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, collection_cb, C);
+
+ outliner_cleanup_tree(soops);
+
+ ED_undo_push(C, "Collection operation");
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_operation(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Outliner Collection Operation";
+ ot->idname = "OUTLINER_OT_collection_operation";
+ ot->description = "";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_collection_operation_exec;
+ ot->poll = ED_operator_outliner_active;
+
+ ot->flag = 0;
+
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_collection_op_types, 0, "Collection Operation", "");
+}
+
+/* ******************** */
+
// XXX: select linked is for RNA structs only
static EnumPropertyItem prop_data_op_types[] = {
{OL_DOP_SELECT, "SELECT", 0, "Select", ""},
@@ -1924,6 +2014,9 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop
else if (datalevel == TSE_MODIFIER) {
WM_operator_name_call(C, "OUTLINER_OT_modifier_operation", WM_OP_INVOKE_REGION_WIN, NULL);
}
+ else if (datalevel == TSE_LAYER_COLLECTION) {
+ WM_operator_name_call(C, "OUTLINER_OT_collection_operation", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
else {
WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL);
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index ec46c5df9a0..e7a866524fd 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -61,8 +61,10 @@
#include "BLT_translation.h"
+#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_main.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
#include "BKE_sequencer.h"
@@ -83,6 +85,9 @@
# include "BLI_math_base.h" /* M_PI */
#endif
+/* prototypes */
+static void outliner_make_hierarchy(ListBase *lb);
+
/* ********************************************************* */
/* Persistent Data */
@@ -199,105 +204,6 @@ void outliner_cleanup_tree(SpaceOops *soops)
outliner_storage_cleanup(soops);
}
-/* Find specific item from the treestore */
-TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem)
-{
- TreeElement *te, *tes;
- for (te = lb->first; te; te = te->next) {
- if (te->store_elem == store_elem) return te;
- tes = outliner_find_tree_element(&te->subtree, store_elem);
- if (tes) return tes;
- }
- return NULL;
-}
-
-/* tse is not in the treestore, we use its contents to find a match */
-TreeElement *outliner_find_tse(SpaceOops *soops, const TreeStoreElem *tse)
-{
- TreeStoreElem *tselem;
-
- if (tse->id == NULL) return NULL;
-
- /* check if 'tse' is in treestore */
- tselem = BKE_outliner_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id);
- if (tselem)
- return outliner_find_tree_element(&soops->tree, tselem);
-
- return NULL;
-}
-
-/* Find treestore that refers to given ID */
-TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, const ID *id)
-{
- for (TreeElement *te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
- if (tselem->type == 0) {
- if (tselem->id == id) {
- return te;
- }
- /* only deeper on scene or object */
- if (ELEM(te->idcode, ID_OB, ID_SCE) ||
- ((soops->outlinevis == SO_GROUPS) && (te->idcode == ID_GR)))
- {
- TreeElement *tes = outliner_find_id(soops, &te->subtree, id);
- if (tes) {
- return tes;
- }
- }
- }
- }
- return NULL;
-}
-
-TreeElement *outliner_find_posechannel(ListBase *lb, const bPoseChannel *pchan)
-{
- for (TreeElement *te = lb->first; te; te = te->next) {
- if (te->directdata == pchan) {
- return te;
- }
-
- TreeStoreElem *tselem = TREESTORE(te);
- if (ELEM(tselem->type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) {
- TreeElement *tes = outliner_find_posechannel(&te->subtree, pchan);
- if (tes) {
- return tes;
- }
- }
- }
- return NULL;
-}
-
-TreeElement *outliner_find_editbone(ListBase *lb, const EditBone *ebone)
-{
- for (TreeElement *te = lb->first; te; te = te->next) {
- if (te->directdata == ebone) {
- return te;
- }
-
- TreeStoreElem *tselem = TREESTORE(te);
- if (ELEM(tselem->type, 0, TSE_EBONE)) {
- TreeElement *tes = outliner_find_editbone(&te->subtree, ebone);
- if (tes) {
- return tes;
- }
- }
- }
- return NULL;
-}
-
-ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode)
-{
- TreeStoreElem *tselem;
- te = te->parent;
-
- while (te) {
- tselem = TREESTORE(te);
- if (tselem->type == 0 && te->idcode == idcode) return tselem->id;
- te = te->parent;
- }
- return NULL;
-}
-
/* ********************************************************* */
@@ -483,12 +389,57 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
#endif
}
+static void outliner_object_reorder(
+ Main *UNUSED(bmain), const Scene *scene,
+ TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
+{
+ TreeStoreElem *tselem_insert = TREESTORE(insert_element);
+ Object *ob = (Object *)tselem_insert->id;
+ SceneCollection *sc = outliner_scene_collection_from_tree_element(insert_handle);
+ SceneCollection *sc_ob_parent = NULL;
+
+ BLI_assert(action == TE_INSERT_INTO);
+ UNUSED_VARS_NDEBUG(action);
+
+ /* find parent scene-collection of object */
+ if (insert_element->parent) {
+ for (TreeElement *te_ob_parent = insert_element->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) {
+ if (ELEM(TREESTORE(te_ob_parent)->type, TSE_SCENE_COLLECTION, TSE_LAYER_COLLECTION)) {
+ sc_ob_parent = outliner_scene_collection_from_tree_element(te_ob_parent);
+ break;
+ }
+ }
+ }
+ else {
+ sc_ob_parent = BKE_collection_master(scene);
+ }
+ BKE_collection_object_move(scene, sc, sc_ob_parent, ob);
+}
+
+static bool outliner_object_reorder_poll(
+ const Scene *UNUSED(scene), const TreeElement *insert_element,
+ TreeElement **io_insert_handle, TreeElementInsertType *io_action)
+{
+ TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
+ if (ELEM(tselem_handle->type, TSE_SCENE_COLLECTION, TSE_LAYER_COLLECTION) &&
+ (insert_element->parent != *io_insert_handle))
+ {
+ *io_action = TE_INSERT_INTO;
+ return true;
+ }
+
+ return false;
+}
+
// can be inlined if necessary
static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob)
{
+ te->reinsert = outliner_object_reorder;
+ te->reinsert_poll = outliner_object_reorder_poll;
+
if (outliner_animdata_test(ob->adt))
outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
-
+
outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
if (ob->proxy && !ID_IS_LINKED_DATABLOCK(ob))
@@ -903,8 +854,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
id = TREESTORE(parent)->id;
}
- /* One exception */
- if (type == TSE_ID_BASE) {
+ /* exceptions */
+ if (ELEM(type, TSE_ID_BASE, TSE_LAYER_COLLECTION)) {
/* pass */
}
else if (id == NULL) {
@@ -941,6 +892,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if (type == TSE_GP_LAYER) {
/* pass */
}
+ else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
+ /* pass */
+ }
else if (type == TSE_ID_BASE) {
/* pass */
}
@@ -1233,6 +1187,15 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
return te;
}
+/**
+ * \note Really only removes \a tselem, not it's TreeElement instance or any children.
+ */
+void outliner_remove_treestore_element(SpaceOops *soops, TreeStoreElem *tselem)
+{
+ BKE_outliner_treehash_remove_element(soops->treehash, tselem);
+ BLI_mempool_free(soops->treestore, tselem);
+}
+
/* ======================================================= */
/* Sequencer mode tree building */
@@ -1370,6 +1333,141 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
}
}
+static void outliner_layer_collections_reorder(
+ Main *bmain, const Scene *scene,
+ TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
+{
+ LayerCollection *lc_insert = insert_element->directdata;
+ LayerCollection *lc_handle = insert_handle->directdata;
+
+ if (action == TE_INSERT_BEFORE) {
+ BKE_layer_collection_move_above(scene, lc_handle, lc_insert);
+ }
+ else if (action == TE_INSERT_AFTER) {
+ BKE_layer_collection_move_below(scene, lc_handle, lc_insert);
+ }
+ else if (action == TE_INSERT_INTO) {
+ BKE_layer_collection_move_into(scene, lc_handle, lc_insert);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ DAG_relations_tag_update(bmain);
+}
+static bool outliner_layer_collections_reorder_poll(
+ const Scene *UNUSED(scene), const TreeElement *UNUSED(insert_element),
+ TreeElement **io_insert_handle, TreeElementInsertType *UNUSED(io_action))
+{
+ const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
+ return ELEM(tselem_handle->type, TSE_LAYER_COLLECTION);
+}
+
+static void outliner_add_layer_collections_recursive(
+ SpaceOops *soops, ListBase *tree, ListBase *layer_collections, TreeElement *parent_ten)
+{
+ for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) {
+ TreeElement *ten = outliner_add_element(soops, tree, collection, parent_ten, TSE_LAYER_COLLECTION, 0);
+
+ ten->name = collection->scene_collection->name;
+ ten->directdata = collection;
+ ten->reinsert = outliner_layer_collections_reorder;
+ ten->reinsert_poll = outliner_layer_collections_reorder_poll;
+
+ outliner_add_layer_collections_recursive(soops, &ten->subtree, &collection->layer_collections, ten);
+ for (LinkData *link = collection->object_bases.first; link; link = link->next) {
+ Base *base = (Base *)link->data;
+ TreeElement *te_object = outliner_add_element(soops, &ten->subtree, base->object, ten, 0, 0);
+ te_object->directdata = base;
+ }
+ outliner_make_hierarchy(&ten->subtree);
+ }
+}
+static void outliner_add_collections_act_layer(SpaceOops *soops, SceneLayer *layer)
+{
+ outliner_add_layer_collections_recursive(soops, &soops->tree, &layer->layer_collections, NULL);
+}
+
+static void outliner_scene_collections_reorder(
+ Main *bmain, const Scene *scene,
+ TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
+{
+ SceneCollection *sc_insert = insert_element->directdata;
+ SceneCollection *sc_handle = insert_handle->directdata;
+
+ BLI_assert((action == TE_INSERT_INTO) || (sc_handle != BKE_collection_master(scene)));
+ if (action == TE_INSERT_BEFORE) {
+ BKE_collection_move_above(scene, sc_handle, sc_insert);
+ }
+ else if (action == TE_INSERT_AFTER) {
+ BKE_collection_move_below(scene, sc_handle, sc_insert);
+ }
+ else if (action == TE_INSERT_INTO) {
+ BKE_collection_move_into(scene, sc_handle, sc_insert);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ DAG_relations_tag_update(bmain);
+}
+static bool outliner_scene_collections_reorder_poll(
+ const Scene *scene, const TreeElement *UNUSED(insert_element),
+ TreeElement **io_insert_handle, TreeElementInsertType *io_action)
+{
+ const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_handle = (*io_insert_handle)->directdata;
+
+ if (!ELEM(tselem_handle->type, TSE_SCENE_COLLECTION)) {
+ return false;
+ }
+
+ if (sc_handle == sc_master) {
+ /* exception: Can't insert before/after master selection, has to be one of its childs */
+ TreeElement *te_master = *io_insert_handle;
+ if (*io_action == TE_INSERT_BEFORE) {
+ /* can't go higher than master collection, insert into it */
+ *io_action = TE_INSERT_INTO;
+ }
+ else if (*io_action == TE_INSERT_AFTER) {
+ *io_insert_handle = te_master->subtree.last;
+ }
+ }
+ return true;
+}
+
+static void outliner_add_scene_collection_objects(
+ SpaceOops *soops, ListBase *tree, SceneCollection *collection, TreeElement *parent)
+{
+ for (LinkData *link = collection->objects.first; link; link = link->next) {
+ outliner_add_element(soops, tree, link->data, parent, 0, 0);
+ }
+ outliner_make_hierarchy(tree);
+}
+
+static void outliner_add_scene_collections_recursive(
+ SpaceOops *soops, ListBase *tree, ListBase *scene_collections, TreeElement *parent_ten)
+{
+ for (SceneCollection *collection = scene_collections->first; collection; collection = collection->next) {
+ TreeElement *ten = outliner_add_element(soops, tree, collection, parent_ten, TSE_SCENE_COLLECTION, 0);
+
+ ten->name = collection->name;
+ ten->directdata = collection;
+ ten->reinsert = outliner_scene_collections_reorder;
+ ten->reinsert_poll = outliner_scene_collections_reorder_poll;
+
+ outliner_add_scene_collections_recursive(soops, &ten->subtree, &collection->scene_collections, ten);
+ outliner_add_scene_collection_objects(soops, &ten->subtree, collection, ten);
+ }
+}
+static void outliner_add_collections_master(SpaceOops *soops, Scene *scene)
+{
+ SceneCollection *master = BKE_collection_master(scene);
+ outliner_add_scene_collections_recursive(soops, &soops->tree, &master->scene_collections, NULL);
+ outliner_add_scene_collection_objects(soops, &soops->tree, master, NULL);
+}
+
/* ======================================================= */
/* Generic Tree Building helpers - order these are called is top to bottom */
@@ -1483,18 +1581,15 @@ static void outliner_sort(ListBase *lb)
{
TreeElement *te;
TreeStoreElem *tselem;
- int totelem = 0;
te = lb->last;
if (te == NULL) return;
tselem = TREESTORE(te);
-
+
/* sorting rules; only object lists, ID lists, or deformgroups */
- if ( ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) {
-
- /* count first */
- for (te = lb->first; te; te = te->next) totelem++;
-
+ if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) {
+ int totelem = BLI_listbase_count(lb);
+
if (totelem > 1) {
tTreeSort *tear = MEM_mallocN(totelem * sizeof(tTreeSort), "tree sort array");
tTreeSort *tp = tear;
@@ -1619,9 +1714,8 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
/* Main entry point for building the tree data-structure that the outliner represents */
// TODO: split each mode into its own function?
-void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
+void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops *soops)
{
- Base *base;
TreeElement *te = NULL, *ten;
TreeStoreElem *tselem;
int show_opened = !soops->treestore || !BLI_mempool_count(soops->treestore); /* on first view, we open scenes */
@@ -1702,31 +1796,42 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
tselem = TREESTORE(te);
if (sce == scene && show_opened)
tselem->flag &= ~TSE_CLOSED;
-
- for (base = sce->base.first; base; base = base->next) {
- ten = outliner_add_element(soops, &te->subtree, base->object, te, 0, 0);
- ten->directdata = base;
+
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ outliner_add_element(soops, &te->subtree, ob, te, 0, 0);
}
+ FOREACH_SCENE_OBJECT_END
+
outliner_make_hierarchy(&te->subtree);
+
/* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
- for (base = sce->base.first; base; base = base->next) base->object->id.newid = NULL;
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ ob->id.newid = NULL;
+ }
+ FOREACH_SCENE_OBJECT_END
}
}
else if (soops->outlinevis == SO_CUR_SCENE) {
outliner_add_scene_contents(soops, &soops->tree, scene, NULL);
-
- for (base = scene->base.first; base; base = base->next) {
- ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
- ten->directdata = base;
+
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0);
}
+ FOREACH_SCENE_OBJECT_END
outliner_make_hierarchy(&soops->tree);
}
else if (soops->outlinevis == SO_VISIBLE) {
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & scene->lay)
- outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
+ FOREACH_VISIBLE_BASE(sl, base)
+ {
+ ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
+ ten->directdata = base;
+
}
+ FOREACH_VISIBLE_BASE_END
outliner_make_hierarchy(&soops->tree);
}
else if (soops->outlinevis == SO_GROUPS) {
@@ -1738,8 +1843,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
for (go = group->gobject.first; go; go = go->next) {
- ten = outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0);
- ten->directdata = NULL; /* eh, why? */
+ outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0);
}
outliner_make_hierarchy(&te->subtree);
/* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
@@ -1748,26 +1852,25 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
}
}
else if (soops->outlinevis == SO_SAME_TYPE) {
- Object *ob = OBACT;
- if (ob) {
- for (base = scene->base.first; base; base = base->next) {
- if (base->object->type == ob->type) {
- ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
- ten->directdata = base;
+ Object *ob_active = OBACT_NEW;
+ if (ob_active) {
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ if (ob->type == ob_active->type) {
+ outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0);
}
}
+ FOREACH_SCENE_OBJECT_END
outliner_make_hierarchy(&soops->tree);
}
}
else if (soops->outlinevis == SO_SELECTED) {
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & scene->lay) {
- if (base->flag & SELECT) {
- ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
- ten->directdata = base;
- }
- }
+ FOREACH_SELECTED_BASE(sl, base)
+ {
+ ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
+ ten->directdata = base;
}
+ FOREACH_SELECTED_BASE_END
outliner_make_hierarchy(&soops->tree);
}
else if (soops->outlinevis == SO_SEQUENCE) {
@@ -1821,9 +1924,15 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
else if (soops->outlinevis == SO_ID_ORPHANS) {
outliner_add_orphaned_datablocks(mainvar, soops);
}
+ else if (soops->outlinevis == SO_ACT_LAYER) {
+ outliner_add_collections_act_layer(soops, BKE_scene_layer_context_active(scene));
+ }
+ else if (soops->outlinevis == SO_COLLECTIONS) {
+ outliner_add_collections_master(soops, scene);
+ }
else {
- ten = outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0);
- if (ten) ten->directdata = BASACT;
+ ten = outliner_add_element(soops, &soops->tree, OBACT_NEW, NULL, 0, 0);
+ ten->directdata = BASACT_NEW;
}
if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) {
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
new file mode 100644
index 00000000000..f123b240efc
--- /dev/null
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -0,0 +1,234 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_outliner/outliner_utils.c
+ * \ingroup spoutliner
+ */
+
+#include "BKE_outliner_treehash.h"
+
+#include "BLI_utildefines.h"
+
+#include "DNA_action_types.h"
+#include "DNA_space_types.h"
+
+#include "ED_armature.h"
+
+#include "UI_interface.h"
+
+#include "outliner_intern.h"
+
+
+/**
+ * Try to find an item under y-coordinate \a view_co_y (view-space).
+ * \note Recursive
+ */
+TreeElement *outliner_find_item_at_y(const SpaceOops *soops, const ListBase *tree, float view_co_y)
+{
+ for (TreeElement *te_iter = tree->first; te_iter; te_iter = te_iter->next) {
+ if (view_co_y < (te_iter->ys + UI_UNIT_Y)) {
+ if (view_co_y >= te_iter->ys) {
+ /* co_y is inside this element */
+ return te_iter;
+ }
+ else if (TSELEM_OPEN(te_iter->store_elem, soops)) {
+ /* co_y is lower than current element, possibly inside children */
+ TreeElement *te_sub = outliner_find_item_at_y(soops, &te_iter->subtree, view_co_y);
+ if (te_sub) {
+ return te_sub;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Collapsed items can show their children as click-able icons. This function tries to find
+ * such an icon that represents the child item at x-coordinate \a view_co_x (view-space).
+ *
+ * \return a hovered child item or \a parent_te (if no hovered child found).
+ */
+TreeElement *outliner_find_item_at_x_in_row(const SpaceOops *soops, const TreeElement *parent_te, float view_co_x)
+{
+ if (!TSELEM_OPEN(TREESTORE(parent_te), soops)) { /* if parent_te is opened, it doesn't show childs in row */
+ /* no recursion, items can only display their direct children in the row */
+ for (TreeElement *child_te = parent_te->subtree.first;
+ child_te && view_co_x >= child_te->xs; /* don't look further if co_x is smaller than child position*/
+ child_te = child_te->next)
+ {
+ if ((child_te->flag & TE_ICONROW) && (view_co_x > child_te->xs) && (view_co_x < child_te->xend)) {
+ return child_te;
+ }
+ }
+ }
+
+ /* return parent if no child is hovered */
+ return (TreeElement *)parent_te;
+}
+
+/* Find specific item from the treestore */
+TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem)
+{
+ TreeElement *te, *tes;
+ for (te = lb->first; te; te = te->next) {
+ if (te->store_elem == store_elem) return te;
+ tes = outliner_find_tree_element(&te->subtree, store_elem);
+ if (tes) return tes;
+ }
+ return NULL;
+}
+
+/* tse is not in the treestore, we use its contents to find a match */
+TreeElement *outliner_find_tse(SpaceOops *soops, const TreeStoreElem *tse)
+{
+ TreeStoreElem *tselem;
+
+ if (tse->id == NULL) return NULL;
+
+ /* check if 'tse' is in treestore */
+ tselem = BKE_outliner_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id);
+ if (tselem)
+ return outliner_find_tree_element(&soops->tree, tselem);
+
+ return NULL;
+}
+
+/* Find treestore that refers to given ID */
+TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, const ID *id)
+{
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (tselem->type == 0) {
+ if (tselem->id == id) {
+ return te;
+ }
+ /* only deeper on scene or object */
+ if (ELEM(te->idcode, ID_OB, ID_SCE) ||
+ ((soops->outlinevis == SO_GROUPS) && (te->idcode == ID_GR)))
+ {
+ TreeElement *tes = outliner_find_id(soops, &te->subtree, id);
+ if (tes) {
+ return tes;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+TreeElement *outliner_find_posechannel(ListBase *lb, const bPoseChannel *pchan)
+{
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ if (te->directdata == pchan) {
+ return te;
+ }
+
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (ELEM(tselem->type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) {
+ TreeElement *tes = outliner_find_posechannel(&te->subtree, pchan);
+ if (tes) {
+ return tes;
+ }
+ }
+ }
+ return NULL;
+}
+
+TreeElement *outliner_find_editbone(ListBase *lb, const EditBone *ebone)
+{
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ if (te->directdata == ebone) {
+ return te;
+ }
+
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (ELEM(tselem->type, 0, TSE_EBONE)) {
+ TreeElement *tes = outliner_find_editbone(&te->subtree, ebone);
+ if (tes) {
+ return tes;
+ }
+ }
+ }
+ return NULL;
+}
+
+ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode)
+{
+ TreeStoreElem *tselem;
+ te = te->parent;
+
+ while (te) {
+ tselem = TREESTORE(te);
+ if (tselem->type == 0 && te->idcode == idcode) return tselem->id;
+ te = te->parent;
+ }
+ return NULL;
+}
+
+/**
+ * Iterate over all tree elements (pre-order traversal), executing \a func callback for
+ * each tree element matching the optional filters.
+ *
+ * \param filter_te_flag: If not 0, only TreeElements with this flag will be visited.
+ * \param filter_tselem_flag: Same as \a filter_te_flag, but for the TreeStoreElem.
+ * \param func: Custom callback to execute for each visited item.
+ */
+bool outliner_tree_traverse(const SpaceOops *soops, ListBase *tree, int filter_te_flag, int filter_tselem_flag,
+ TreeTraversalFunc func, void *customdata)
+{
+ for (TreeElement *te = tree->first, *te_next; te; te = te_next) {
+ TreeTraversalAction func_retval = TRAVERSE_CONTINUE;
+ /* in case te is freed in callback */
+ TreeStoreElem *tselem = TREESTORE(te);
+ ListBase subtree = te->subtree;
+ te_next = te->next;
+
+ if (filter_te_flag && (te->flag & filter_te_flag) == 0) {
+ /* skip */
+ }
+ else if (filter_tselem_flag && (tselem->flag & filter_tselem_flag) == 0) {
+ /* skip */
+ }
+ else {
+ func_retval = func(te, customdata);
+ }
+ /* Don't access te or tselem from now on! Might've been freed... */
+
+ if (func_retval == TRAVERSE_BREAK) {
+ return false;
+ }
+
+ if (func_retval == TRAVERSE_SKIP_CHILDS) {
+ /* skip */
+ }
+ else if (!outliner_tree_traverse(soops, &subtree, filter_te_flag, filter_tselem_flag, func, customdata)) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 759ef4e78e4..b632db48caa 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -102,10 +102,14 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
if (GS(id->name) == ID_OB) {
/* Ensure item under cursor is valid drop target */
TreeElement *te = outliner_dropzone_find(soops, fmval, true);
+ TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
- if (te && te->idcode == ID_OB && TREESTORE(te)->type == 0) {
+ if (!te) {
+ /* pass */
+ }
+ else if (te->idcode == ID_OB && tselem->type == 0) {
Scene *scene;
- ID *te_id = TREESTORE(te)->id;
+ ID *te_id = tselem->id;
/* check if dropping self or parent */
if (te_id == id || (Object *)te_id == ((Object *)id)->parent)
@@ -122,6 +126,10 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
return 1;
}
}
+ else if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
+ /* support adding object from different scene to collection */
+ return 1;
+ }
}
}
return 0;
@@ -292,7 +300,9 @@ static void outliner_main_region_free(ARegion *UNUSED(ar))
}
-static void outliner_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void outliner_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -308,6 +318,7 @@ static void outliner_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(s
case ND_RENDER_OPTIONS:
case ND_SEQUENCER:
case ND_LAYER:
+ case ND_LAYER_CONTENT:
case ND_WORLD:
ED_region_tag_redraw(ar);
break;
@@ -414,7 +425,9 @@ static void outliner_header_region_free(ARegion *UNUSED(ar))
{
}
-static void outliner_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void outliner_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 4228635ccd6..fb8de02d3bd 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -176,7 +176,9 @@ static void script_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void script_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void script_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
+ wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
{
/* context changes */
// XXX - Todo, need the ScriptSpace accessible to get the python script to run.
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 70a6e6d83cb..4d1e878868a 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -55,10 +55,11 @@
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "ED_anim_api.h"
#include "ED_gpencil.h"
@@ -190,25 +191,35 @@ void color3ubv_from_seq(Scene *curscene, Sequence *seq, unsigned char col[3])
}
}
-static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
+static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq,
+ float x1, float y1, float x2, float y2, float stepsize, unsigned int pos)
{
/*
* x1 is the starting x value to draw the wave,
* x2 the end x value, same for y1 and y2
* stepsize is width of a pixel.
*/
+
+ /* offset x1 and x2 values, to match view min/max, if strip is out of bounds */
+ int x1_offset = max_ff(v2d->cur.xmin, x1);
+ int x2_offset = min_ff(v2d->cur.xmax + 1.0f, x2);
+
if (seq->sound && ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) {
- int i, j, pos;
- int length = floor((x2 - x1) / stepsize) + 1;
- float ymid = (y1 + y2) / 2;
- float yscale = (y2 - y1) / 2;
+ int i, j, p;
+ int length = floor((x2_offset - x1_offset) / stepsize) + 1;
+ float ymid = (y1 + y2) / 2.0f;
+ float yscale = (y2 - y1) / 2.0f;
float samplestep;
float startsample, endsample;
float value1, value2;
bSound *sound = seq->sound;
SoundWaveform *waveform;
-
+
+ if (length < 2) {
+ return;
+ }
+
if (!sound->spinlock) {
sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
BLI_spin_init(sound->spinlock);
@@ -241,21 +252,27 @@ static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequenc
endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
samplestep = (endsample - startsample) * stepsize / (x2 - x1);
- if (length > floor((waveform->length - startsample) / samplestep))
- length = floor((waveform->length - startsample) / samplestep);
+ length = min_ii(floor((waveform->length - startsample) / samplestep), length);
+
+ if (length < 2) {
+ return;
+ }
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
- glColor4f(1.0f, 1.0f, 1.0f, 0.5);
glEnable(GL_BLEND);
- glBegin(GL_TRIANGLE_STRIP);
+
+ immBegin(PRIM_TRIANGLE_STRIP, length * 2);
+
for (i = 0; i < length; i++) {
- float sampleoffset = startsample + i * samplestep;
- pos = sampleoffset;
+ float sampleoffset = startsample + ((x1_offset - x1) / stepsize + i) * samplestep;
+ p = sampleoffset;
- value1 = waveform->data[pos * 3];
- value2 = waveform->data[pos * 3 + 1];
+ value1 = waveform->data[p * 3];
+ value2 = waveform->data[p * 3 + 1];
if (samplestep > 1.0f) {
- for (j = pos + 1; (j < waveform->length) && (j < pos + samplestep); j++) {
+ for (j = p + 1; (j < waveform->length) && (j < p + samplestep); j++) {
if (value1 > waveform->data[j * 3])
value1 = waveform->data[j * 3];
@@ -265,34 +282,20 @@ static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequenc
}
else {
/* use simple linear interpolation */
- float f = sampleoffset - pos;
- value1 = (1.0f - f) * value1 + f * waveform->data[pos * 3 + 3];
- value2 = (1.0f - f) * value2 + f * waveform->data[pos * 3 + 4];
+ float f = sampleoffset - p;
+ value1 = (1.0f - f) * value1 + f * waveform->data[p * 3 + 3];
+ value2 = (1.0f - f) * value2 + f * waveform->data[p * 3 + 4];
}
- glVertex2f(x1 + i * stepsize, ymid + value1 * yscale);
- glVertex2f(x1 + i * stepsize, ymid + value2 * yscale);
+ immVertex2f(pos, x1_offset + i * stepsize, ymid + value1 * yscale);
+ immVertex2f(pos, x1_offset + i * stepsize, ymid + value2 * yscale);
}
- glEnd();
- glDisable(GL_BLEND);
- }
-}
-static void drawmeta_stipple(int value)
-{
- if (value) {
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_HALFTONE);
-
- glEnable(GL_LINE_STIPPLE);
- glLineStipple(1, 0x8888);
- }
- else {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- glDisable(GL_LINE_STIPPLE);
+ immEnd();
+
+ glDisable(GL_BLEND);
}
}
-
static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
{
/* note: this used to use SEQ_BEGIN/SEQ_END, but it messes up the
@@ -325,9 +328,6 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if (seqm->flag & SEQ_MUTE)
- drawmeta_stipple(1);
-
for (seq = seqbase->first; seq; seq = seq->next) {
chan_min = min_ii(chan_min, seq->machine);
chan_max = max_ii(chan_max, seq->machine);
@@ -338,6 +338,10 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
col[3] = 196; /* alpha, used for all meta children */
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
for (seq = seqbase->first; seq; seq = seq->next) {
const int startdisp = seq->startdisp + offset;
const int enddisp = seq->enddisp + offset;
@@ -348,12 +352,16 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
float x2_chan = enddisp;
float y1_chan, y2_chan;
- if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
- drawmeta_stipple(1);
-
color3ubv_from_seq(scene, seq, col);
- glColor4ubv(col);
+ if ((seqm->flag & SEQ_MUTE) || (seq->flag & SEQ_MUTE)) {
+ col[3] = 64;
+ }
+ else {
+ col[3] = 196;
+ }
+
+ immUniformColor4ubv(col);
/* clamp within parent sequence strip bounds */
if (x1_chan < x1) x1_chan = x1;
@@ -362,20 +370,12 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
y1_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
y2_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
- glRectf(x1_chan, y1_chan, x2_chan, y2_chan);
-
- UI_GetColorPtrShade3ubv(col, col, -30);
- glColor4ubv(col);
- fdrawbox(x1_chan, y1_chan, x2_chan, y2_chan);
-
- if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
- drawmeta_stipple(0);
+ immRectf(pos, x1_chan, y1_chan, x2_chan, y2_chan);
}
}
- if (seqm->flag & SEQ_MUTE)
- drawmeta_stipple(0);
-
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
@@ -391,7 +391,7 @@ static float draw_seq_handle_size_get_clamped(Sequence *seq, const float pixelx)
}
/* draw a handle, for each end of a sequence strip */
-static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_clamped, const short direction)
+static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_clamped, const short direction, unsigned int pos)
{
float v1[2], v2[2], v3[2], rx1 = 0, rx2 = 0; //for triangles and rect
float x1, x2, y1, y2;
@@ -433,21 +433,31 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if (seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
- else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
- else glColor4ub(0, 0, 0, 22);
-
- glRectf(rx1, y1, rx2, y2);
-
- if (seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
- else glColor4ub(0, 0, 0, 50);
+ if (seq->flag & whichsel) {
+ immUniformColor4ub(0, 0, 0, 80);
+ }
+ else if (seq->flag & SELECT) {
+ immUniformColor4ub(255, 255, 255, 30);
+ }
+ else {
+ immUniformColor4ub(0, 0, 0, 22);
+ }
- glEnable(GL_POLYGON_SMOOTH);
- glBegin(GL_TRIANGLES);
- glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
- glEnd();
+ immRectf(pos, rx1, y1, rx2, y2);
- glDisable(GL_POLYGON_SMOOTH);
+ if (seq->flag & whichsel) {
+ immUniformColor4ub(255, 255, 255, 200);
+ }
+ else {
+ immUniformColor4ub(0, 0, 0, 50);
+ }
+
+ immBegin(PRIM_TRIANGLES, 3);
+ immVertex2fv(pos, v1);
+ immVertex2fv(pos, v2);
+ immVertex2fv(pos, v3);
+ immEnd();
+
glDisable(GL_BLEND);
}
@@ -586,67 +596,10 @@ static void draw_seq_text(View2D *v2d, SpaceSeq *sseq, Sequence *seq, float x1,
UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
}
-/* draws a shaded strip, made from gradient + flat color + gradient */
-void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
+static void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq, unsigned int pos)
{
- float ymid1, ymid2;
-
- if (seq->flag & SEQ_MUTE) {
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_HALFTONE);
- }
-
- ymid1 = (y2 - y1) * 0.25f + y1;
- ymid2 = (y2 - y1) * 0.65f + y1;
-
- glBegin(GL_QUADS);
-
- if (seq->flag & SEQ_INVALID_EFFECT) { col[0] = 255; col[1] = 0; col[2] = 255; }
- else if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, -50);
- /* else UI_GetColorPtrShade3ubv(col, col, 0); */ /* DO NOTHING */
-
- glColor3ubv(col);
-
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
-
- if (seq->flag & SEQ_INVALID_EFFECT) { col[0] = 255; col[1] = 0; col[2] = 255; }
- else if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
- else UI_GetColorPtrShade3ubv(col, col, -5);
-
- glColor3ubv((GLubyte *)col);
-
- glVertex2f(x2, ymid1);
- glVertex2f(x1, ymid1);
-
- glEnd();
-
- glRectf(x1, ymid1, x2, ymid2);
-
- glBegin(GL_QUADS);
-
- glVertex2f(x1, ymid2);
- glVertex2f(x2, ymid2);
-
- if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, -15);
- else UI_GetColorPtrShade3ubv(col, col, 25);
-
- glColor3ubv((GLubyte *)col);
-
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
-
- glEnd();
-
- if (seq->flag & SEQ_MUTE) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- }
-}
-
-void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq)
-{
- float x1, x2, y1, y2, pixely, a;
- unsigned char col[3], blendcol[3];
+ float x1, x2, y1, y2, pixely;
+ unsigned char col[4], blendcol[3];
View2D *v2d = &ar->v2d;
x1 = seq->startdisp;
@@ -660,90 +613,82 @@ void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq)
if (pixely <= 0) return; /* can happen when the view is split/resized */
blendcol[0] = blendcol[1] = blendcol[2] = 120;
-
- if (seq->startofs) {
+
+ if (seq->startofs || seq->endofs) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
color3ubv_from_seq(scene, seq, col);
-
+
if (seq->flag & SELECT) {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
- glColor4ub(col[0], col[1], col[2], 170);
+ UI_GetColorPtrShade3ubv(col, col, -50);
+ }
+
+ if (seq->flag & SEQ_MUTE) {
+ col[3] = 64;
}
else {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
- glColor4ub(col[0], col[1], col[2], 110);
+ if (seq->flag & SELECT) {
+ col[3] = 170;
+ }
+ else {
+ col[3] = 80;
+ }
}
-
- glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
-
- if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
- else glColor4ub(col[0], col[1], col[2], 160);
-
- fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline
-
- glDisable(GL_BLEND);
+ }
+
+ if (seq->startofs) {
+ immUniformColor4ubv(col);
+ immRectf(pos, (float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
+
+ immUniformColor3ubvAlpha(col, col[3] + 50);
+
+ imm_draw_line_box(pos, (float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); /* outline */
}
if (seq->endofs) {
+ immUniformColor4ubv(col);
+ immRectf(pos, x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
+
+ immUniformColor3ubvAlpha(col, col[3] + 50);
+
+ imm_draw_line_box(pos, x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); /* outline */
+ }
+
+ if (seq->startofs || seq->endofs) {
+ glDisable(GL_BLEND);
+ }
+
+ if (seq->startstill || seq->endstill) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
+
color3ubv_from_seq(scene, seq, col);
-
- if (seq->flag & SELECT) {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
- glColor4ub(col[0], col[1], col[2], 170);
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5f, 60);
+
+ if (seq->flag & SEQ_MUTE) {
+ col[3] = 96;
}
else {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
- glColor4ub(col[0], col[1], col[2], 110);
+ if (seq->flag & SELECT) {
+ col[3] = 255;
+ }
+ else {
+ col[3] = 170;
+ }
}
-
- glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
-
- if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
- else glColor4ub(col[0], col[1], col[2], 160);
-
- fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
-
- glDisable(GL_BLEND);
+
+ immUniformColor4ubv(col);
}
+
if (seq->startstill) {
- color3ubv_from_seq(scene, seq, col);
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
- glColor3ubv((GLubyte *)col);
-
- draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
-
- /* feint pinstripes, helps see exactly which is extended and which isn't,
- * especially when the extension is very small */
- if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
- else UI_GetColorPtrShade3ubv(col, col, -16);
-
- glColor3ubv((GLubyte *)col);
-
- for (a = y1; a < y2; a += pixely * 2.0f) {
- fdrawline(x1, a, (float)(seq->start), a);
- }
+ immRectf(pos, x1, y1, (float)(seq->start), y2);
}
if (seq->endstill) {
- color3ubv_from_seq(scene, seq, col);
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
- glColor3ubv((GLubyte *)col);
-
- draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
-
- /* feint pinstripes, helps see exactly which is extended and which isn't,
- * especially when the extension is very small */
- if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
- else UI_GetColorPtrShade3ubv(col, col, -16);
-
- glColor3ubv((GLubyte *)col);
-
- for (a = y1; a < y2; a += pixely * 2.0f) {
- fdrawline((float)(seq->start + seq->len), a, x2, a);
- }
+ immRectf(pos, (float)(seq->start + seq->len), y1, x2, y2);
+ }
+
+ if (seq->startstill || seq->endstill) {
+ glDisable(GL_BLEND);
}
}
@@ -757,7 +702,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
{
View2D *v2d = &ar->v2d;
float x1, x2, y1, y2;
- unsigned char col[3], background_col[3], is_single_image;
+ unsigned char col[4], background_col[4], is_single_image;
const float handsize_clamped = draw_seq_handle_size_get_clamped(seq, pixelx);
/* we need to know if this is a single image/color or not for drawing */
@@ -769,72 +714,105 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* get the correct color per strip type*/
//color3ubv_from_seq(scene, seq, col);
color3ubv_from_seq(scene, seq, background_col);
-
+
+ if (seq->flag & SEQ_MUTE) {
+ background_col[3] = 128;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else {
+ background_col[3] = 255;
+ }
+
+ if (seq->flag & SELECT) {
+ UI_GetColorPtrShade3ubv(background_col, background_col, -50);
+ }
+
+ immUniformColor4ubv(background_col);
+
/* draw the main strip body */
if (is_single_image) { /* single image */
- draw_shadedstrip(seq, background_col,
- BKE_sequence_tx_get_final_left(seq, false), y1,
- BKE_sequence_tx_get_final_right(seq, false), y2);
+ immRectf(pos, BKE_sequence_tx_get_final_left(seq, false), y1,
+ BKE_sequence_tx_get_final_right(seq, false), y2);
}
else { /* normal operation */
- draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
+ immRectf(pos, x1, y1, x2, y2);
+ }
+
+ if (seq->flag & SEQ_MUTE) {
+ glDisable(GL_BLEND);
}
if (!is_single_image) {
if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) || (seq == special_seq_update)) {
- draw_sequence_extensions(scene, ar, seq);
+ draw_sequence_extensions(scene, ar, seq, pos);
}
}
- draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE);
- draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE);
-
- /* draw the strip outline */
+ draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos);
+ draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos);
+
x1 = seq->startdisp;
x2 = seq->enddisp;
/* draw sound wave */
if (seq->type == SEQ_TYPE_SOUND_RAM) {
if (!(sseq->flag & SEQ_NO_WAVEFORMS)) {
- drawseqwave(C, sseq, scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx);
+ drawseqwave(v2d, C, sseq, scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx, pos);
}
}
+ immUnbindProgram();
+
/* draw lock */
if (seq->flag & SEQ_LOCK) {
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
glEnable(GL_BLEND);
- /* light stripes */
- glColor4ub(255, 255, 255, 32);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_DIAG_STRIPES);
- glRectf(x1, y1, x2, y2);
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES);
+
+ immUniform4f("color1", 1.0f, 1.0f, 1.0f, 0.125f);
+ immUniform4f("color2", 0.0f, 0.0f, 0.0f, 0.125f);
+ immUniform1i("size1", 8);
+ immUniform1i("size2", 8);
+
+ immRectf(pos, x1, y1, x2, y2);
- /* dark stripes */
- glColor4ub(0, 0, 0, 32);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_DIAG_STRIPES_SWAP);
- glRectf(x1, y1, x2, y2);
+ immUnbindProgram();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
glDisable(GL_BLEND);
}
if (!BKE_sequence_is_valid_check(seq)) {
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
+ glEnable(GL_BLEND);
+
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES);
+
+ immUniform4f("color1", 1.0f, 0.0f, 0.0f, 1.0f);
+ immUniform4f("color2", 0.0f, 0.0f, 0.0f, 0.0f);
+ immUniform1i("size1", 8);
+ immUniform1i("size2", 8);
- /* panic! */
- glColor4ub(255, 0, 0, 255);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_DIAG_STRIPES);
- glRectf(x1, y1, x2, y2);
+ immRectf(pos, x1, y1, x2, y2);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immUnbindProgram();
+
+ glDisable(GL_BLEND);
}
color3ubv_from_seq(scene, seq, col);
+
+ /* draw the strip outline */
+ color3ubv_from_seq(scene, seq, col);
if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) {
if (seq->flag & SEQ_OVERLAP) {
col[0] = 255; col[1] = col[2] = 40;
@@ -851,19 +829,27 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
drawmeta_contents(scene, seq, x1, y1, x2, y2);
}
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ /* TODO: add back stippled line for muted strips? */
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
if (seq->flag & SEQ_MUTE) {
- glEnable(GL_LINE_STIPPLE);
- glLineStipple(1, 0x8888);
+ col[3] = 96;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ immUniformColor4ubv(col);
}
-
- glColor3ubv((GLubyte *)col);
-
- UI_draw_roundbox_shade_x(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
-
- if (seq->flag & SEQ_MUTE) {
- glDisable(GL_LINE_STIPPLE);
+ else {
+ immUniformColor3ubv(col);
}
-
+
+ imm_draw_line_box(pos, x1, y1, x2, y2); /* outline */
+
+ immUnbindProgram();
+
/* calculate if seq is long enough to print a name */
x1 = seq->startdisp + handsize_clamped;
x2 = seq->enddisp - handsize_clamped;
@@ -1047,33 +1033,39 @@ static void sequencer_draw_borders(const SpaceSeq *sseq, const View2D *v2d, cons
glLineWidth(1.0f);
/* border */
- setlinestyle(3);
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
- glBegin(GL_LINE_LOOP);
- glVertex2f(x1 - 0.5f, y1 - 0.5f);
- glVertex2f(x1 - 0.5f, y2 + 0.5f);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
- glVertex2f(x2 + 0.5f, y1 - 0.5f);
- glEnd();
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniformThemeColor(TH_BACK);
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ imm_draw_line_box(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
/* safety border */
if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) {
+ immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
+
UI_draw_safe_areas(
- x1, x2, y1, y2,
+ shdr_pos, x1, x2, y1, y2,
scene->safe_areas.title,
scene->safe_areas.action);
if (sseq->flag & SEQ_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(
- x1, x2, y1, y2,
+ shdr_pos, x1, x2, y1, y2,
scene->safe_areas.title_center,
scene->safe_areas.action_center);
}
}
- setlinestyle(0);
+ immUnbindProgram();
}
/* draws checkerboard background for transparent content */
@@ -1088,11 +1080,7 @@ static void sequencer_draw_background(
/* only draw alpha for main buffer */
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
if ((sseq->flag & SEQ_USE_ALPHA) && !draw_overlay) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
- glColor4f(1.0, 1.0, 1.0, 1.0);
+ imm_draw_checker_box(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
}
}
}
@@ -1136,9 +1124,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glClear(GL_COLOR_BUFFER_BIT);
}
- /* without this colors can flicker from previous opengl state */
- glColor4ub(255, 255, 255, 255);
-
/* only initialize the preview if a render is in progress */
if (G.is_rendering)
return;
@@ -1153,15 +1138,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if ((ibuf == NULL) ||
(ibuf->rect == NULL && ibuf->rect_float == NULL))
{
- /* gpencil can also be drawn without a valid imbuf */
- if ((draw_gpencil && is_imbuf) && !draw_overlay) {
- sequencer_display_size(scene, sseq, viewrect);
+ sequencer_display_size(scene, sseq, viewrect);
- sequencer_draw_background(sseq, v2d, viewrect, false);
- sequencer_draw_borders(sseq, v2d, scene);
+ sequencer_draw_background(sseq, v2d, viewrect, false);
+ sequencer_draw_borders(sseq, v2d, scene);
+ /* gpencil can also be drawn without a valid imbuf */
+ if ((draw_gpencil && is_imbuf) && !draw_overlay) {
sequencer_draw_gpencil(C);
}
+
return;
}
@@ -1230,6 +1216,18 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
sequencer_draw_background(sseq, v2d, viewrect, draw_overlay);
}
+ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ /* Format needs to be created prior to any immBindProgram call.
+ * Do it here because OCIO binds it's own shader.
+ */
+ VertexFormat *imm_format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(imm_format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(imm_format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+
if (scope) {
IMB_freeImBuf(ibuf);
ibuf = scope;
@@ -1302,9 +1300,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
}
}
- glColor4f(1.0, 1.0, 1.0, 1.0);
+ if (draw_backdrop) {
+ /* XXX: need to load identity projection too? */
+ gpuPushMatrix();
+ gpuLoadIdentity();
+ }
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
glGenTextures(1, (GLuint *)&texid);
glBindTexture(GL_TEXTURE_2D, texid);
@@ -1317,15 +1318,13 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer);
- if (draw_backdrop) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
+ if (!glsl_used) {
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+ immUniform1i("image", GL_TEXTURE0);
}
- glBegin(GL_QUADS);
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
if (draw_overlay) {
if (sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
@@ -1335,16 +1334,30 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
tot_clip.xmax = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmax);
tot_clip.ymax = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymax);
- glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymin); glVertex2f(tot_clip.xmin, tot_clip.ymin);
- glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymax); glVertex2f(tot_clip.xmin, tot_clip.ymax);
- glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymax); glVertex2f(tot_clip.xmax, tot_clip.ymax);
- glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymin); glVertex2f(tot_clip.xmax, tot_clip.ymin);
+ immAttrib2f(texCoord, scene->ed->over_border.xmin, scene->ed->over_border.ymin);
+ immVertex2f(pos, tot_clip.xmin, tot_clip.ymin);
+
+ immAttrib2f(texCoord, scene->ed->over_border.xmin, scene->ed->over_border.ymax);
+ immVertex2f(pos, tot_clip.xmin, tot_clip.ymax);
+
+ immAttrib2f(texCoord, scene->ed->over_border.xmax, scene->ed->over_border.ymax);
+ immVertex2f(pos, tot_clip.xmax, tot_clip.ymax);
+
+ immAttrib2f(texCoord, scene->ed->over_border.xmax, scene->ed->over_border.ymin);
+ immVertex2f(pos, tot_clip.xmax, tot_clip.ymin);
}
else if (sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) {
- glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymax);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymin);
+
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymax);
+
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymax);
+
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymin);
}
}
else if (draw_backdrop) {
@@ -1363,25 +1376,46 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
imagey = aspect / image_aspect;
}
- glTexCoord2f(0.0f, 0.0f); glVertex2f(-imagex, -imagey);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(-imagex, imagey);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(imagex, imagey);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(imagex, -imagey);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, -imagex, -imagey);
+
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, -imagex, imagey);
+
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, imagex, imagey);
+
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, imagex, -imagey);
}
else {
draw_metadata = ((sseq->flag & SEQ_SHOW_METADATA) != 0);
- glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymax);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymin);
+
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymax);
+
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymax);
+
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymin);
}
- glEnd();
+
+ immEnd();
glBindTexture(GL_TEXTURE_2D, 0);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA)
+
+ if (!glsl_used) {
+ immUnbindProgram();
+ }
+
+ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
glDisable(GL_BLEND);
+ }
+
glDeleteTextures(1, &texid);
if (glsl_used)
@@ -1398,10 +1432,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
}
if (draw_backdrop) {
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
+ gpuPopMatrix();
return;
}
@@ -1475,42 +1506,42 @@ void drawprefetchseqspace(Scene *scene, ARegion *UNUSED(ar), SpaceSeq *sseq)
static void draw_seq_backdrop(View2D *v2d)
{
int i;
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* darker gray overlay over the view backdrop */
- UI_ThemeColorShade(TH_BACK, -20);
- glRectf(v2d->cur.xmin, -1.0, v2d->cur.xmax, 1.0);
+ immUniformThemeColorShade(TH_BACK, -20);
+ immRectf(pos, v2d->cur.xmin, -1.0, v2d->cur.xmax, 1.0);
/* Alternating horizontal stripes */
i = max_ii(1, ((int)v2d->cur.ymin) - 1);
- glBegin(GL_QUADS);
while (i < v2d->cur.ymax) {
- if (((int)i) & 1)
- UI_ThemeColorShade(TH_BACK, -15);
- else
- UI_ThemeColorShade(TH_BACK, -25);
-
- glVertex2f(v2d->cur.xmax, i);
- glVertex2f(v2d->cur.xmin, i);
- glVertex2f(v2d->cur.xmin, i + 1);
- glVertex2f(v2d->cur.xmax, i + 1);
+ if (i & 1) {
+ immUniformThemeColorShade(TH_BACK, -15);
+ }
+ else {
+ immUniformThemeColorShade(TH_BACK, -25);
+ }
+
+ immRectf(pos, v2d->cur.xmin, i, v2d->cur.xmax, i + 1);
- i += 1.0;
+ i++;
}
- glEnd();
-
+
/* Darker lines separating the horizontal bands */
i = max_ii(1, ((int)v2d->cur.ymin) - 1);
- UI_ThemeColor(TH_GRID);
-
- glBegin(GL_LINES);
- while (i < v2d->cur.ymax) {
- glVertex2f(v2d->cur.xmax, i);
- glVertex2f(v2d->cur.xmin, i);
-
- i += 1.0;
+ int line_ct = (int)v2d->cur.ymax - i + 1;
+ immUniformThemeColor(TH_GRID);
+ immBegin(PRIM_LINES, line_ct * 2);
+ while (line_ct--) {
+ immVertex2f(pos, v2d->cur.xmax, i);
+ immVertex2f(pos, v2d->cur.xmin, i);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* draw the contents of the sequencer strips view */
@@ -1526,7 +1557,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
/* loop through twice, first unselected, then selected */
for (j = 0; j < 2; j++) {
Sequence *seq;
- int outline_tint = (j) ? -60 : -150; /* highlighting around strip edges indicating selection */
+ int outline_tint = (j) ? 40 : -40; /* highlighting around strip edges indicating selection */
/* loop through strips, checking for those that are visible */
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -1554,8 +1585,15 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
if (special_seq_update) {
const Sequence *seq = special_seq_update;
glEnable(GL_BLEND);
- glColor4ub(255, 255, 255, 48);
- glRectf(seq->startdisp, seq->machine + SEQ_STRIP_OFSBOTTOM, seq->enddisp, seq->machine + SEQ_STRIP_OFSTOP);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4ub(255, 255, 255, 48);
+ immRectf(pos, seq->startdisp, seq->machine + SEQ_STRIP_OFSBOTTOM, seq->enddisp, seq->machine + SEQ_STRIP_OFSTOP);
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
}
@@ -1567,36 +1605,56 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
const int frame_end = PEFRA + 1;
glEnable(GL_BLEND);
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* draw darkened area outside of active timeline
* frame range used is preview range or scene range */
- UI_ThemeColorShadeAlpha(TH_BACK, -25, -100);
+ immUniformThemeColorShadeAlpha(TH_BACK, -25, -100);
if (frame_sta < frame_end) {
- glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax);
- glRectf((float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax);
+ immRectf(pos, (float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
else {
- glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
- UI_ThemeColorShade(TH_BACK, -60);
+ immUniformThemeColorShade(TH_BACK, -60);
+
/* thin lines where the actual frames are */
- fdrawline(frame_sta, v2d->cur.ymin, frame_sta, v2d->cur.ymax);
- fdrawline(frame_end, v2d->cur.ymin, frame_end, v2d->cur.ymax);
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, frame_sta, v2d->cur.ymin);
+ immVertex2f(pos, frame_sta, v2d->cur.ymax);
+
+ immVertex2f(pos, frame_end, v2d->cur.ymin);
+ immVertex2f(pos, frame_end, v2d->cur.ymax);
+
+ immEnd();
if (ed && !BLI_listbase_is_empty(&ed->metastack)) {
MetaStack *ms = ed->metastack.last;
- glColor4ub(255, 255, 255, 8);
- glRectf(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax);
+ immUniformColor4ub(255, 255, 255, 8);
+ immRectf(pos, ms->disp_range[0], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax);
+
+ immUniformThemeColorShade(TH_BACK, -40);
- UI_ThemeColorShade(TH_BACK, -40);
+ immBegin(PRIM_LINES, 4);
- fdrawline(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[0], v2d->cur.ymax);
- fdrawline(ms->disp_range[1], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax);
+ immVertex2f(pos, ms->disp_range[0], v2d->cur.ymin);
+ immVertex2f(pos, ms->disp_range[0], v2d->cur.ymax);
+
+ immVertex2f(pos, ms->disp_range[1], v2d->cur.ymin);
+ immVertex2f(pos, ms->disp_range[1], v2d->cur.ymax);
+
+ immEnd();
}
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
@@ -1671,16 +1729,20 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
/* overlap playhead */
if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
int cfra_over = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? scene->ed->over_cfra : scene->r.cfra + scene->ed->over_ofs;
- glColor3f(0.2, 0.2, 0.2);
- // glRectf(cfra_over, v2d->cur.ymin, scene->ed->over_ofs + scene->r.cfra + 1, v2d->cur.ymax);
- glBegin(GL_LINES);
- glVertex2f(cfra_over, v2d->cur.ymin);
- glVertex2f(cfra_over, v2d->cur.ymax);
- glEnd();
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(0.2f, 0.2f, 0.2f);
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, cfra_over, v2d->cur.ymin);
+ immVertex2f(pos, cfra_over, v2d->cur.ymax);
+ immEnd();
+
+ immUnbindProgram();
}
-
+
/* callback */
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 3ae4a233353..35b54bfd097 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1256,7 +1256,6 @@ typedef struct SlipData {
int num_seq;
bool slow;
int slow_offset; /* offset at the point where offset was turned on */
- void *draw_handle;
NumInput num_input;
} SlipData;
@@ -1291,21 +1290,6 @@ static void transseq_restore(TransSeq *ts, Sequence *seq)
seq->len = ts->len;
}
-static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data)
-{
- Scene *scene = CTX_data_scene(C);
- SlipData *td = data;
- int i;
-
- for (i = 0; i < td->num_seq; i++) {
- Sequence *seq = td->seq_array[i];
-
- if ((seq->type != SEQ_TYPE_META) && td->trim[i]) {
- draw_sequence_extensions(scene, ar, seq);
- }
- }
-}
-
static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
{
Sequence *seq;
@@ -1354,7 +1338,6 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
SlipData *data;
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
- ARegion *ar = CTX_wm_region(C);
float mouseloc[2];
int num_seq, i;
View2D *v2d = UI_view2d_fromcontext(C);
@@ -1384,8 +1367,6 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
transseq_backup(data->ts + i, data->seq_array[i]);
}
- data->draw_handle = ED_region_draw_cb_activate(ar->type, draw_slip_extensions, data, REGION_DRAW_POST_VIEW);
-
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
copy_v2_v2_int(data->init_mouse, event->mval);
@@ -1527,7 +1508,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
Scene *scene = CTX_data_scene(C);
SlipData *data = (SlipData *)op->customdata;
ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
const bool has_numInput = hasNumInput(&data->num_input);
bool handled = true;
@@ -1585,7 +1565,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
case RETKEY:
case SPACEKEY:
{
- ED_region_draw_cb_exit(ar->type, data->draw_handle);
MEM_freeN(data->seq_array);
MEM_freeN(data->trim);
MEM_freeN(data->ts);
@@ -1614,8 +1593,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
BKE_sequence_calc(scene, seq);
}
- ED_region_draw_cb_exit(ar->type, data->draw_handle);
-
MEM_freeN(data->seq_array);
MEM_freeN(data->ts);
MEM_freeN(data->trim);
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index 730cc117287..7ce2f73cbef 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -56,8 +56,6 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
void draw_timeline_seq(const struct bContext *C, struct ARegion *ar);
void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop);
void color3ubv_from_seq(struct Scene *curscene, struct Sequence *seq, unsigned char col[3]);
-void draw_shadedstrip(struct Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
-void draw_sequence_extensions(struct Scene *scene, struct ARegion *ar, struct Sequence *seq);
void sequencer_special_update_set(Sequence *seq);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index a2a80297041..b3ec2948c8c 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -337,7 +337,8 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl)
return (SpaceLink *)sseqn;
}
-static void sequencer_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void sequencer_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -490,7 +491,9 @@ static void sequencer_main_region_draw(const bContext *C, ARegion *ar)
draw_timeline_seq(C, ar);
}
-static void sequencer_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void sequencer_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -596,7 +599,9 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *ar)
}
}
-static void sequencer_preview_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void sequencer_preview_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -662,7 +667,9 @@ static void sequencer_buttons_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void sequencer_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void sequencer_buttons_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index fcb46ced750..ed1ef080e0c 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -125,7 +125,7 @@ static SpaceLink *text_duplicate(SpaceLink *sl)
return (SpaceLink *)stextn;
}
-static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
SpaceText *st = sa->spacedata.first;
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 70b5feac280..79607bf88cb 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -49,6 +49,8 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -123,38 +125,38 @@ static void txt_format_text(SpaceText *st)
#endif
/* Sets the current drawing color based on the format character specified */
-static void format_draw_color(char formatchar)
+static void format_draw_color(const TextDrawContext *tdc, char formatchar)
{
switch (formatchar) {
case FMT_TYPE_WHITESPACE:
break;
case FMT_TYPE_SYMBOL:
- UI_ThemeColor(TH_SYNTAX_S);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_S);
break;
case FMT_TYPE_COMMENT:
- UI_ThemeColor(TH_SYNTAX_C);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_C);
break;
case FMT_TYPE_NUMERAL:
- UI_ThemeColor(TH_SYNTAX_N);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_N);
break;
case FMT_TYPE_STRING:
- UI_ThemeColor(TH_SYNTAX_L);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_L);
break;
case FMT_TYPE_DIRECTIVE:
- UI_ThemeColor(TH_SYNTAX_D);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_D);
break;
case FMT_TYPE_SPECIAL:
- UI_ThemeColor(TH_SYNTAX_V);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_V);
break;
case FMT_TYPE_RESERVED:
- UI_ThemeColor(TH_SYNTAX_R);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_R);
break;
case FMT_TYPE_KEYWORD:
- UI_ThemeColor(TH_SYNTAX_B);
+ UI_FontThemeColor(tdc->font_id, TH_SYNTAX_B);
break;
case FMT_TYPE_DEFAULT:
default:
- UI_ThemeColor(TH_TEXT);
+ UI_FontThemeColor(tdc->font_id, TH_TEXT);
break;
}
}
@@ -429,7 +431,7 @@ static int text_draw_wrapped(
/* Draw the visible portion of text on the overshot line */
for (a = fstart, ma = mstart; ma < mend; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (use_syntax) {
- if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
+ if (fmt_prev != format[a]) format_draw_color(tdc, fmt_prev = format[a]);
}
x += text_font_draw_character_utf8(tdc, x, y, str + ma);
fpos++;
@@ -452,7 +454,7 @@ static int text_draw_wrapped(
/* Draw the remaining text */
for (a = fstart, ma = mstart; str[ma] && y > clip_min_y; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (use_syntax) {
- if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
+ if (fmt_prev != format[a]) format_draw_color(tdc, fmt_prev = format[a]);
}
x += text_font_draw_character_utf8(tdc, x, y, str + ma);
@@ -505,7 +507,7 @@ static void text_draw(
char fmt_prev = 0xff;
for (a = 0; a < amount; a++) {
- if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
+ if (format[a] != fmt_prev) format_draw_color(tdc, fmt_prev = format[a]);
x += text_font_draw_character_utf8(tdc, x, y, in + str_shift);
str_shift += BLI_str_utf8_size_safe(in + str_shift);
}
@@ -906,22 +908,23 @@ static void draw_textscroll(const SpaceText *st, rcti *scroll, rcti *back)
{
bTheme *btheme = UI_GetTheme();
uiWidgetColors wcol = btheme->tui.wcol_scroll;
- unsigned char col[4];
+ float col[4];
float rad;
-
- UI_ThemeColor(TH_BACK);
- glRecti(back->xmin, back->ymin, back->xmax, back->ymax);
+
+ /* background so highlights don't go behind the scrollbar */
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_BACK);
+ immRecti(pos, back->xmin, back->ymin, back->xmax, back->ymax);
+ immUnbindProgram();
UI_draw_widget_scroll(&wcol, scroll, &st->txtbar, (st->flags & ST_SCROLL_SELECT) ? UI_SCROLL_PRESSED : 0);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
rad = 0.4f * min_ii(BLI_rcti_size_x(&st->txtscroll), BLI_rcti_size_y(&st->txtscroll));
- UI_GetThemeColor3ubv(TH_HILITE, col);
- col[3] = 48;
- glColor4ubv(col);
- glEnable(GL_BLEND);
- UI_draw_roundbox(st->txtscroll.xmin + 1, st->txtscroll.ymin, st->txtscroll.xmax - 1, st->txtscroll.ymax, rad);
- glDisable(GL_BLEND);
+ UI_GetThemeColor3fv(TH_HILITE, col);
+ col[3] = 0.18f;
+ UI_draw_roundbox_aa(true, st->txtscroll.xmin + 1, st->txtscroll.ymin, st->txtscroll.xmax - 1, st->txtscroll.ymax, rad, col);
}
/*********************** draw documentation *******************************/
@@ -963,26 +966,32 @@ static void draw_documentation(const SpaceText *st, ARegion *ar)
boxh = (DOC_HEIGHT + 1) * (st->lheight_dpi + TXT_LINE_SPACING);
/* Draw panel */
- UI_ThemeColor(TH_BACK);
- glRecti(x, y, x + boxw, y - boxh);
- UI_ThemeColor(TH_SHADE1);
- glBegin(GL_LINE_LOOP);
- glVertex2i(x, y);
- glVertex2i(x + boxw, y);
- glVertex2i(x + boxw, y - boxh);
- glVertex2i(x, y - boxh);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex2i(x + boxw - 10, y - 7);
- glVertex2i(x + boxw - 4, y - 7);
- glVertex2i(x + boxw - 7, y - 2);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex2i(x + boxw - 10, y - boxh + 7);
- glVertex2i(x + boxw - 4, y - boxh + 7);
- glVertex2i(x + boxw - 7, y - boxh + 2);
- glEnd();
- UI_ThemeColor(TH_TEXT);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_BACK);
+ immRecti(pos, x, y, x + boxw, y - boxh);
+ immUniformThemeColor(TH_SHADE1);
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2i(pos, x, y);
+ immVertex2i(pos, x + boxw, y);
+ immVertex2i(pos, x + boxw, y - boxh);
+ immVertex2i(pos, x, y - boxh);
+ immEnd();
+ immBegin(PRIM_LINE_LOOP, 3);
+ immVertex2i(pos, x + boxw - 10, y - 7);
+ immVertex2i(pos, x + boxw - 4, y - 7);
+ immVertex2i(pos, x + boxw - 7, y - 2);
+ immEnd();
+ immBegin(PRIM_LINE_LOOP, 3);
+ immVertex2i(pos, x + boxw - 10, y - boxh + 7);
+ immVertex2i(pos, x + boxw - 4, y - boxh + 7);
+ immVertex2i(pos, x + boxw - 7, y - boxh + 2);
+ immEnd();
+
+ immUnbindProgram();
+
+ UI_FontThemeColor(tdc.font_id, TH_TEXT);
i = 0; br = DOC_WIDTH; lines = 0; // XXX -doc_scroll;
for (p = docs; *p; p++) {
@@ -1009,11 +1018,6 @@ static void draw_documentation(const SpaceText *st, ARegion *ar)
}
if (lines >= DOC_HEIGHT) break;
}
-
- if (0 /* XXX doc_scroll*/ /* > 0 && lines < DOC_HEIGHT */) {
- // XXX doc_scroll--;
- draw_documentation(st, ar);
- }
}
#endif
@@ -1061,10 +1065,15 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
/* not needed but stands out nicer */
UI_draw_box_shadow(220, x, y - boxh, x + boxw, y);
- UI_ThemeColor(TH_SHADE1);
- glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1);
- UI_ThemeColorShade(TH_BACK, 16);
- glRecti(x, y, x + boxw, y - boxh);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_SHADE1);
+ immRecti(pos, x - 1, y + 1, x + boxw + 1, y - boxh - 1);
+ immUniformThemeColorShade(TH_BACK, 16);
+ immRecti(pos, x, y, x + boxw, y - boxh);
+
+ immUnbindProgram();
/* Set the top 'item' of the visible list */
for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
@@ -1079,11 +1088,16 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
w = st->cwidth * text_get_char_pos(st, str, len);
if (item == sel) {
- UI_ThemeColor(TH_SHADE2);
- glRecti(x + margin_x, y - 3, x + margin_x + w, y + lheight - 3);
+ unsigned int posi = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_SHADE2);
+ immRecti(posi, x + margin_x, y - 3, x + margin_x + w, y + lheight - 3);
+
+ immUnbindProgram();
}
- format_draw_color(item->type);
+ format_draw_color(tdc, item->type);
text_draw(st, tdc, str, 0, 0, x + margin_x, y - 1, NULL);
if (item == last) break;
@@ -1092,42 +1106,57 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
/*********************** draw cursor ************************/
-static void draw_cursor(SpaceText *st, ARegion *ar)
+static void draw_text_decoration(SpaceText *st, ARegion *ar)
{
Text *text = st->text;
int vcurl, vcurc, vsell, vselc, hidden = 0;
int x, y, w, i;
+ int offl, offc;
const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
+ /* Convert to view space character coordinates to determine if cursor is hidden */
+ wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
+ vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
+ vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
+
+ if (vselc < 0) {
+ vselc = 0;
+ hidden = 1;
+ }
+
+ if (text->curl == text->sell && text->curc == text->selc && !st->line_hlight && hidden) {
+ /* Nothing to draw here */
+ return;
+ }
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* Draw the selection */
if (text->curl != text->sell || text->curc != text->selc) {
- int offl, offc;
/* Convert all to view space character coordinates */
wrap_offset(st, ar, text->curl, text->curc, &offl, &offc);
vcurl = txt_get_span(text->lines.first, text->curl) - st->top + offl;
vcurc = text_get_char_pos(st, text->curl->line, text->curc) - st->left + offc;
- wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
- vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
- vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
if (vcurc < 0) {
vcurc = 0;
}
- if (vselc < 0) {
- vselc = 0;
- hidden = 1;
- }
-
- UI_ThemeColor(TH_SHADE2);
+
+ immUniformThemeColor(TH_SHADE2);
+
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
y = ar->winy;
if (vcurl == vsell) {
y -= vcurl * lheight;
- if (vcurc < vselc)
- glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight);
- else
- glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight);
+
+ if (vcurc < vselc) {
+ immRecti(pos, x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight);
+ }
+ else {
+ immRecti(pos, x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight);
+ }
}
else {
int froml, fromc, tol, toc;
@@ -1143,35 +1172,24 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
y -= froml * lheight;
- glRecti(x + fromc * st->cwidth - 1, y, ar->winx, y - lheight);
+ immRecti(pos, x + fromc * st->cwidth - 1, y, ar->winx, y - lheight);
y -= lheight;
+
for (i = froml + 1; i < tol; i++) {
- glRecti(x - 4, y, ar->winx, y - lheight);
+ immRecti(pos, x - 4, y, ar->winx, y - lheight);
y -= lheight;
}
- glRecti(x - 4, y, x + toc * st->cwidth, y - lheight);
+ immRecti(pos, x - 4, y, x + toc * st->cwidth, y - lheight);
y -= lheight;
}
}
- else {
- int offl, offc;
- wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
- vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
- vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
-
- if (vselc < 0) {
- vselc = 0;
- hidden = 1;
- }
- }
if (st->line_hlight) {
int x1, x2, y1, y2;
if (st->wordwrap) {
int visible_lines = text_get_visible_lines(st, ar, text->sell->line);
- int offl, offc;
wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc);
@@ -1187,36 +1205,38 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
x1 = 0; // st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
x2 = x1 + ar->winx;
- glColor4ub(255, 255, 255, 32);
-
+ immUniformColor4ub(255, 255, 255, 32);
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- glRecti(x1 - 4, y1, x2, y2);
+ immRecti(pos, x1 - 4, y1, x2, y2);
glDisable(GL_BLEND);
}
}
-
+
if (!hidden) {
/* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
x += vselc * st->cwidth;
y = ar->winy - vsell * lheight;
-
+
+ immUniformThemeColor(TH_HILITE);
+
if (st->overwrite) {
char ch = text->sell->line[text->selc];
-
+
y += TXT_LINE_SPACING;
w = st->cwidth;
if (ch == '\t') w *= st->tabnumber - (vselc + st->left) % st->tabnumber;
-
- UI_ThemeColor(TH_HILITE);
- glRecti(x, y - lheight - 1, x + w, y - lheight + 1);
+
+ immRecti(pos, x, y - lheight - 1, x + w, y - lheight + 1);
}
else {
- UI_ThemeColor(TH_HILITE);
- glRecti(x - 1, y, x + 1, y - lheight);
+ immRecti(pos, x - 1, y, x + 1, y - lheight);
}
}
+
+ immUnbindProgram();
}
/******************* draw matching brackets *********************/
@@ -1317,7 +1337,7 @@ static void draw_brackets(const SpaceText *st, const TextDrawContext *tdc, ARegi
if (!endl || endc == -1)
return;
- UI_ThemeColor(TH_HILITE);
+ UI_FontThemeColor(tdc->font_id, TH_HILITE);
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
y = ar->winy - st->lheight_dpi;
@@ -1422,8 +1442,11 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->showlinenrs) {
x = TXT_OFFSET + TEXTXLOC;
- UI_ThemeColor(TH_GRID);
- glRecti((TXT_OFFSET - 12), 0, (TXT_OFFSET - 5) + TEXTXLOC, ar->winy - 2);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_GRID);
+ immRecti(pos, (TXT_OFFSET - 12), 0, (TXT_OFFSET - 5) + TEXTXLOC, ar->winy - 2);
+ immUnbindProgram();
}
else {
st->linenrs_tot = 0; /* not used */
@@ -1432,11 +1455,11 @@ void draw_text_main(SpaceText *st, ARegion *ar)
y = ar->winy - st->lheight_dpi;
winx = ar->winx - TXT_SCROLL_WIDTH;
- /* draw cursor */
- draw_cursor(st, ar);
+ /* draw cursor, margin, selection and highlight */
+ draw_text_decoration(st, ar);
/* draw the text */
- UI_ThemeColor(TH_TEXT);
+ UI_FontThemeColor(tdc.font_id, TH_TEXT);
for (i = 0; y > clip_min_y && i < st->viewlines && tmp; i++, tmp = tmp->next) {
if (st->showsyntax && !tmp->format)
@@ -1444,16 +1467,20 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->showlinenrs && !wrap_skip) {
/* draw line number */
- if (tmp == text->curl)
- UI_ThemeColor(TH_HILITE);
- else
- UI_ThemeColor(TH_TEXT);
+ if (tmp == text->curl) {
+ UI_FontThemeColor(tdc.font_id, TH_HILITE);
+ }
+ else {
+ UI_FontThemeColor(tdc.font_id, TH_TEXT);
+ }
BLI_snprintf(linenr, sizeof(linenr), "%*d", st->linenrs_tot, i + linecount + 1);
/* itoa(i + linecount + 1, linenr, 10); */ /* not ansi-c :/ */
text_font_draw(&tdc, TXT_OFFSET - 7, y, linenr);
- UI_ThemeColor(TH_TEXT);
+ if (tmp == text->curl) {
+ UI_FontThemeColor(tdc.font_id, TH_TEXT);
+ }
}
if (st->wordwrap) {
@@ -1474,15 +1501,24 @@ void draw_text_main(SpaceText *st, ARegion *ar)
margin_column_x = x + st->cwidth * (st->margin_column - st->left);
if (margin_column_x >= x) {
- /* same color as line number background */
- UI_ThemeColor(TH_GRID);
-
- setlinestyle(1);
- glBegin(GL_LINES);
- glVertex2i(margin_column_x, 0);
- glVertex2i(margin_column_x, ar->winy - 2);
- glEnd();
- setlinestyle(0);
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformThemeColor(TH_GRID); /* same color as line number background */
+ immUniform1f("dash_width", 2.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2i(shdr_pos, margin_column_x, 0);
+ immVertex2i(shdr_pos, margin_column_x, ar->winy - 2);
+ immEnd();
+ immUnbindProgram();
}
}
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 15eb154c757..9a3ae2dcd70 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -60,7 +60,6 @@
#include "WM_types.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -69,6 +68,9 @@
#include "ED_space_api.h"
#include "ED_markers.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "time_intern.h"
/* ************************ main time area region *********************** */
@@ -80,28 +82,42 @@ static void time_draw_sfra_efra(Scene *scene, View2D *v2d)
*/
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
-
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+
if (PSFRA < PEFRA) {
- glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
- glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
+ immRectf(pos, (float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
else {
- glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
+
glDisable(GL_BLEND);
- UI_ThemeColorShade(TH_BACK, -60);
/* thin lines where the actual frames are */
- fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
- fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax);
+ immUniformThemeColorShade(TH_BACK, -60);
+
+ immBegin(PRIM_LINES, 4);
+
+ immVertex2f(pos, (float)PSFRA, v2d->cur.ymin);
+ immVertex2f(pos, (float)PSFRA, v2d->cur.ymax);
+
+ immVertex2f(pos, (float)PEFRA, v2d->cur.ymin);
+ immVertex2f(pos, (float)PEFRA, v2d->cur.ymax);
+
+ immEnd();
+ immUnbindProgram();
}
static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
{
PTCacheID *pid;
ListBase pidlist;
- SpaceTimeCache *stc = stime->caches.first;
const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize);
float yoffs = 0.f;
@@ -110,12 +126,13 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* iterate over pointcaches on the active object,
* add spacetimecache and vertex array for each */
for (pid = pidlist.first; pid; pid = pid->next) {
- float col[4], *fp;
- int i, sta = pid->cache->startframe, end = pid->cache->endframe;
- int len = (end - sta + 1) * 4;
+ float col[4];
switch (pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@@ -142,43 +159,9 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
if (pid->cache->cached_frames == NULL)
continue;
- /* make sure we have stc with correct array length */
- if (stc == NULL || MEM_allocN_len(stc->array) != len * 2 * sizeof(float)) {
- if (stc) {
- MEM_freeN(stc->array);
- }
- else {
- stc = MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache");
- BLI_addtail(&stime->caches, stc);
- }
-
- stc->array = MEM_callocN(len * 2 * sizeof(float), "SpaceTimeCache array");
- }
-
- /* fill the vertex array with a quad for each cached frame */
- for (i = sta, fp = stc->array; i <= end; i++) {
- if (pid->cache->cached_frames[i - sta]) {
- fp[0] = (float)i - 0.5f;
- fp[1] = 0.0;
- fp += 2;
-
- fp[0] = (float)i - 0.5f;
- fp[1] = 1.0;
- fp += 2;
-
- fp[0] = (float)i + 0.5f;
- fp[1] = 1.0;
- fp += 2;
-
- fp[0] = (float)i + 0.5f;
- fp[1] = 0.0;
- fp += 2;
- }
- }
-
- glPushMatrix();
- glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT + yoffs, 0.0);
- glScalef(1.0, cache_draw_height, 0.0);
+ gpuPushMatrix();
+ gpuTranslate2f(0.0, (float)V2D_SCROLL_HEIGHT + yoffs);
+ gpuScale2f(1.0, cache_draw_height);
switch (pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@@ -212,12 +195,15 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
BLI_assert(0);
break;
}
- glColor4fv(col);
-
+
+ const int sta = pid->cache->startframe, end = pid->cache->endframe;
+ const int len = (end - sta + 1) * 6;
+
glEnable(GL_BLEND);
-
- glRectf((float)sta, 0.0, (float)end, 1.0);
-
+
+ immUniformColor4fv(col);
+ immRectf(pos, (float)sta, 0.0, (float)end, 1.0);
+
col[3] = 0.4f;
if (pid->cache->flag & PTCACHE_BAKED) {
col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f;
@@ -225,52 +211,38 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
else if (pid->cache->flag & PTCACHE_OUTDATED) {
col[0] += 0.4f; col[1] += 0.4f; col[2] += 0.4f;
}
- glColor4fv(col);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, stc->array);
- glDrawArrays(GL_QUADS, 0, (fp - stc->array) / 2);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glDisable(GL_BLEND);
-
- glPopMatrix();
-
- yoffs += cache_draw_height;
- stc = stc->next;
- }
+ immUniformColor4fv(col);
- BLI_freelistN(&pidlist);
+ if (len > 0) {
+ immBeginAtMost(PRIM_TRIANGLES, len);
- /* free excessive caches */
- while (stc) {
- SpaceTimeCache *tmp = stc->next;
- BLI_remlink(&stime->caches, stc);
- MEM_freeN(stc->array);
- MEM_freeN(stc);
- stc = tmp;
- }
-}
+ /* draw a quad for each cached frame */
+ for (int i = sta; i <= end; i++) {
+ if (pid->cache->cached_frames[i - sta]) {
+ immVertex2f(pos, (float)i - 0.5f, 0.0f);
+ immVertex2f(pos, (float)i - 0.5f, 1.0f);
+ immVertex2f(pos, (float)i + 0.5f, 1.0f);
-static void time_cache_free(SpaceTime *stime)
-{
- SpaceTimeCache *stc;
-
- for (stc = stime->caches.first; stc; stc = stc->next) {
- if (stc->array) {
- MEM_freeN(stc->array);
- stc->array = NULL;
+ immVertex2f(pos, (float)i - 0.5f, 0.0f);
+ immVertex2f(pos, (float)i + 0.5f, 1.0f);
+ immVertex2f(pos, (float)i + 0.5f, 0.0f);
+ }
+ }
+
+ immEnd();
}
+
+ glDisable(GL_BLEND);
+
+ gpuPopMatrix();
+
+ yoffs += cache_draw_height;
}
-
- BLI_freelistN(&stime->caches);
-}
-static void time_cache_refresh(SpaceTime *stime)
-{
- /* Free previous caches to indicate full refresh */
- time_cache_free(stime);
+ immUnbindProgram();
+
+ BLI_freelistN(&pidlist);
}
/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */
@@ -296,7 +268,7 @@ static ActKeyColumn *time_cfra_find_ak(ActKeyColumn *ak, float cframe)
}
/* helper for time_draw_keyframes() */
-static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
+static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel, const unsigned char color[3])
{
bDopeSheet ads = {NULL};
DLRBT_Tree keys;
@@ -339,21 +311,42 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
* the first visible keyframe (last one can then be easily checked)
* - draw within a single GL block to be faster
*/
- glBegin(GL_LINES);
- for (ak = time_cfra_find_ak(keys.root, v2d->cur.xmin);
- (ak) && (ak->cfra <= v2d->cur.xmax);
- ak = ak->next)
- {
- glVertex2f(ak->cfra, ymin);
- glVertex2f(ak->cfra, ymax);
+
+ ActKeyColumn *link;
+ int max_len = 0;
+
+ ak = time_cfra_find_ak(keys.root, v2d->cur.xmin);
+
+ for (link = ak; link; link = link->next) {
+ max_len++;
}
- glEnd(); // GL_LINES
-
+
+ if (max_len > 0) {
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ubv(color);
+
+ immBeginAtMost(PRIM_LINES, max_len * 2);
+
+ for (; (ak) && (ak->cfra <= v2d->cur.xmax);
+ ak = ak->next)
+ {
+ immVertex2f(pos, ak->cfra, ymin);
+ immVertex2f(pos, ak->cfra, ymax);
+ }
+
+ immEnd();
+ immUnbindProgram();
+ }
+
/* free temp stuff */
BLI_dlrbTree_free(&keys);
}
-static void time_draw_caches_keyframes(Main *bmain, Scene *scene, View2D *v2d, bool onlysel)
+static void time_draw_caches_keyframes(Main *bmain, SceneLayer *sl, View2D *v2d, bool onlysel, const unsigned char color[3])
{
CacheFile *cache_file;
@@ -364,7 +357,7 @@ static void time_draw_caches_keyframes(Main *bmain, Scene *scene, View2D *v2d, b
cache_file->draw_flag &= ~CACHEFILE_KEYFRAME_DRAWN;
}
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
@@ -380,7 +373,7 @@ static void time_draw_caches_keyframes(Main *bmain, Scene *scene, View2D *v2d, b
cache_file->draw_flag |= CACHEFILE_KEYFRAME_DRAWN;
- time_draw_idblock_keyframes(v2d, (ID *)cache_file, onlysel);
+ time_draw_idblock_keyframes(v2d, (ID *)cache_file, onlysel, color);
}
for (bConstraint *con = ob->constraints.first; con; con = con->next) {
@@ -398,7 +391,7 @@ static void time_draw_caches_keyframes(Main *bmain, Scene *scene, View2D *v2d, b
cache_file->draw_flag |= CACHEFILE_KEYFRAME_DRAWN;
- time_draw_idblock_keyframes(v2d, (ID *)cache_file, onlysel);
+ time_draw_idblock_keyframes(v2d, (ID *)cache_file, onlysel, color);
}
}
}
@@ -407,24 +400,27 @@ static void time_draw_caches_keyframes(Main *bmain, Scene *scene, View2D *v2d, b
static void time_draw_keyframes(const bContext *C, ARegion *ar)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = CTX_data_active_object(C);
View2D *v2d = &ar->v2d;
bool onlysel = ((scene->flag & SCE_KEYS_NO_SELONLY) == 0);
+ unsigned char color[3];
/* set this for all keyframe lines once and for all */
glLineWidth(1.0);
/* draw cache files keyframes (if available) */
- UI_ThemeColor(TH_TIME_KEYFRAME);
- time_draw_caches_keyframes(CTX_data_main(C), scene, v2d, onlysel);
+ UI_GetThemeColor3ubv(TH_TIME_KEYFRAME, color);
+ time_draw_caches_keyframes(CTX_data_main(C), sl, v2d, onlysel, color);
/* draw grease pencil keyframes (if available) */
- UI_ThemeColor(TH_TIME_GP_KEYFRAME);
+ UI_GetThemeColor3ubv(TH_TIME_GP_KEYFRAME, color);
+
if (scene->gpd) {
- time_draw_idblock_keyframes(v2d, (ID *)scene->gpd, onlysel);
+ time_draw_idblock_keyframes(v2d, (ID *)scene->gpd, onlysel, color);
}
if (ob && ob->gpd) {
- time_draw_idblock_keyframes(v2d, (ID *)ob->gpd, onlysel);
+ time_draw_idblock_keyframes(v2d, (ID *)ob->gpd, onlysel, color);
}
/* draw scene keyframes first
@@ -433,8 +429,8 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
*/
if (onlysel == 0) {
/* set draw color */
- UI_ThemeColorShade(TH_TIME_KEYFRAME, -50);
- time_draw_idblock_keyframes(v2d, (ID *)scene, onlysel);
+ UI_GetThemeColorShade3ubv(TH_TIME_KEYFRAME, -50, color);
+ time_draw_idblock_keyframes(v2d, (ID *)scene, onlysel, color);
}
/* draw keyframes from selected objects
@@ -442,11 +438,11 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
* OR the onlysel flag was set, which means that only active object's keyframes should
* be considered
*/
- UI_ThemeColor(TH_TIME_KEYFRAME);
-
+ UI_GetThemeColor3ubv(TH_TIME_KEYFRAME, color);
+
if (ob && ((ob->mode == OB_MODE_POSE) || onlysel)) {
/* draw keyframes for active object only */
- time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel);
+ time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel, color);
}
else {
bool active_done = false;
@@ -455,7 +451,7 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
CTX_DATA_BEGIN (C, Object *, obsel, selected_objects)
{
/* last arg is 0, since onlysel doesn't apply here... */
- time_draw_idblock_keyframes(v2d, (ID *)obsel, 0);
+ time_draw_idblock_keyframes(v2d, (ID *)obsel, 0, color);
/* if this object is the active one, set flag so that we don't draw again */
if (obsel == ob)
@@ -465,24 +461,14 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
/* if active object hasn't been done yet, draw it... */
if (ob && (active_done == 0))
- time_draw_idblock_keyframes(v2d, (ID *)ob, 0);
+ time_draw_idblock_keyframes(v2d, (ID *)ob, 0, color);
}
}
/* ---------------- */
-static void time_refresh(const bContext *UNUSED(C), ScrArea *sa)
-{
- /* find the main timeline region and refresh cache display*/
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar) {
- SpaceTime *stime = (SpaceTime *)sa->spacedata.first;
- time_cache_refresh(stime);
- }
-}
-
/* editor level listener */
-static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* mainly for updating cache display */
@@ -623,7 +609,9 @@ static void time_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_scrollers_free(scrollers);
}
-static void time_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void time_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -668,7 +656,9 @@ static void time_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void time_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void time_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -752,13 +742,6 @@ static SpaceLink *time_new(const bContext *C)
return (SpaceLink *)stime;
}
-/* not spacelink itself */
-static void time_free(SpaceLink *sl)
-{
- SpaceTime *stime = (SpaceTime *)sl;
-
- time_cache_free(stime);
-}
/* spacetype; init callback in ED_area_initialize() */
/* init is called to (re)initialize an existing editor (file read, screen changes) */
/* validate spacedata, add own area level handlers */
@@ -766,8 +749,6 @@ static void time_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceTime *stime = (SpaceTime *)sa->spacedata.first;
- time_cache_free(stime);
-
/* enable all cache display */
stime->cache_display |= TIME_CACHE_DISPLAY;
stime->cache_display |= (TIME_CACHE_SOFTBODY | TIME_CACHE_PARTICLES);
@@ -796,13 +777,11 @@ void ED_spacetype_time(void)
strncpy(st->name, "Timeline", BKE_ST_MAXNAME);
st->new = time_new;
- st->free = time_free;
st->init = time_init;
st->duplicate = time_duplicate;
st->operatortypes = time_operatortypes;
st->keymap = NULL;
st->listener = time_listener;
- st->refresh = time_refresh;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype time region");
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index aeba4a86f3e..f640fe63f93 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -136,12 +136,16 @@ static void userpref_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void userpref_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void userpref_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
+ wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
{
/* context changes */
}
-static void userpref_header_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void userpref_header_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
+ wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
{
/* context changes */
#if 0
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index a5c60248bf1..34b68a80a0f 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -25,6 +25,7 @@ set(INC
../../blenlib
../../blentranslation
../../bmesh
+ ../../draw
../../gpu
../../imbuf
../../makesdna
@@ -52,6 +53,7 @@ set(SRC
view3d_buttons.c
view3d_camera_control.c
view3d_draw.c
+ view3d_draw_legacy.c
view3d_edit.c
view3d_fly.c
view3d_walk.c
@@ -94,8 +96,4 @@ if(WITH_MOD_SMOKE)
add_definitions(-DWITH_SMOKE)
endif()
-if(WITH_LEGACY_DEPSGRAPH)
- add_definitions(-DWITH_LEGACY_DEPSGRAPH)
-endif()
-
blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index f0e65f84205..c2db34d8d1a 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -49,7 +49,8 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "ED_keyframes_draw.h"
@@ -71,8 +72,8 @@ void draw_motion_paths_init(View3D *v3d, ARegion *ar)
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
}
/* set color
@@ -86,10 +87,11 @@ void draw_motion_paths_init(View3D *v3d, ARegion *ar)
* - User selected color for next frames
*/
static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short sel, int sfra, int efra,
- float prev_color[3], float frame_color[3], float next_color[3])
+ float prev_color[3], float frame_color[3], float next_color[3], unsigned color)
{
int frame = sfra + i;
int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */
+ unsigned char ubcolor[3];
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min)
float intensity; /* how faint */
@@ -97,7 +99,7 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
if (frame < CFRA) {
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
/* Custom color: previous frames color is darker than current frame */
- glColor3fv(prev_color);
+ rgb_float_to_uchar(ubcolor, prev_color);
}
else {
/* black - before cfra */
@@ -109,13 +111,14 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
/* intensity = 0.8f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_WIRE, blend_base, intensity);
+
+ UI_GetThemeColorBlend3ubv(TH_WIRE, blend_base, intensity, ubcolor);
}
}
else if (frame > CFRA) {
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
/* Custom color: next frames color is equal to user selected color */
- glColor3fv(next_color);
+ rgb_float_to_uchar(ubcolor, next_color);
}
else {
/* blue - after cfra */
@@ -127,13 +130,14 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
/* intensity = 0.8f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity);
+
+ UI_GetThemeColorBlend3ubv(TH_BONE_POSE, blend_base, intensity, ubcolor);
}
}
else {
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
/* Custom color: current frame color is slightly darker than user selected color */
- glColor3fv(frame_color);
+ rgb_float_to_uchar(ubcolor, frame_color);
}
else {
/* green - on cfra */
@@ -143,9 +147,12 @@ static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short
else {
intensity = 0.99f;
}
- UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
+ UI_GetThemeColorBlendShade3ubv(TH_CFRAME, TH_BACK, intensity, 10, ubcolor);
}
}
+
+ immAttrib3ubv(color, ubcolor);
+
#undef SET_INTENSITY
}
@@ -231,42 +238,65 @@ void draw_motion_path_instance(Scene *scene,
/* set line thickness */
glLineWidth(mpath->line_thickness);
- glBegin(GL_LINE_STRIP);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+
+ immBegin(PRIM_LINE_STRIP, len);
+
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
+
/* Set color */
- set_motion_path_color(scene, mpath, i, sel, sfra, efra, prev_color, frame_color, next_color);
+ set_motion_path_color(scene, mpath, i, sel, sfra, efra, prev_color, frame_color, next_color, color);
+
/* draw a vertex with this color */
- glVertex3fv(mpv->co);
+ immVertex3fv(pos, mpv->co);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
+
/* back to old line thickness */
glLineWidth(old_width);
}
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
/* Point must be bigger than line thickness */
glPointSize(mpath->line_thickness + 1.0);
- /* draw little black point at each frame
- * NOTE: this is not really visible/noticeable
- */
- glBegin(GL_POINTS);
- for (i = 0, mpv = mpv_start; i < len; i++, mpv++)
- glVertex3fv(mpv->co);
- glEnd();
-
+ /* draw little black point at each frame */
+ immUniformColor3ub(0, 0, 0);
+
+ immBegin(PRIM_POINTS, len);
+
+ for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
+ immVertex3fv(pos, mpv->co);
+ }
+
+ immEnd();
+
/* Draw little white dots at each framestep value or replace with custom color */
if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
- glColor4fv(mpath->color);
+ immUniformColor3fv(mpath->color);
}
else {
- UI_ThemeColor(TH_TEXT_HI);
+ immUniformThemeColor(TH_TEXT_HI);
}
- glBegin(GL_POINTS);
- for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize)
- glVertex3fv(mpv->co);
- glEnd();
+
+ immBegin(PRIM_POINTS, (len + stepsize - 1) / stepsize);
+
+ for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
+ immVertex3fv(pos, mpv->co);
+ }
+
+ immEnd();
/* Draw big green dot where the current frame is
* NOTE: this is only done when keyframes are shown, since this adds similar types of clutter
@@ -274,16 +304,18 @@ void draw_motion_path_instance(Scene *scene,
if ((avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) &&
(sfra < CFRA) && (CFRA <= efra))
{
- UI_ThemeColor(TH_CFRAME);
-
glPointSize(mpath->line_thickness + 5.0);
- glBegin(GL_POINTS);
+ immUniformThemeColor(TH_CFRAME);
+
+ immBegin(PRIM_POINTS, 1);
+
mpv = mpv_start + (CFRA - sfra);
- glVertex3fv(mpv->co);
- glEnd();
-
- UI_ThemeColor(TH_TEXT_HI);
+ immVertex3fv(pos, mpv->co);
+
+ immEnd();
}
+
+ immUnbindProgram();
/* XXX, this isn't up to date but probably should be kept so. */
invert_m4_m4(ob->imat, ob->obmat);
@@ -353,24 +385,28 @@ void draw_motion_path_instance(Scene *scene,
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
col[3] = 255;
- /* if custom, point must be bigger than line */
- if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) {
- glPointSize(mpath->line_thickness + 3.0);
- }
- else {
- glPointSize(4.0f);
- }
- glColor3ubv(col);
+ /* point must be bigger than line */
+ glPointSize(mpath->line_thickness + 3.0);
+
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(col);
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, len);
+
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
int frame = sfra + i;
float mframe = (float)(frame);
- if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
- glVertex3fv(mpv->co);
+ if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
+ immVertex3fv(pos, mpv->co);
+ }
}
- glEnd();
+
+ immEnd();
+
+ immUnbindProgram();
/* Draw frame numbers of keyframes */
if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) {
@@ -398,5 +434,5 @@ void draw_motion_path_instance(Scene *scene,
void draw_motion_paths_cleanup(View3D *v3d)
{
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- glPopMatrix();
+ gpuPopMatrix();
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 314b7bf3335..621c217fd89 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -55,14 +55,16 @@
#include "BKE_nla.h"
#include "BKE_curve.h"
-
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "ED_armature.h"
#include "ED_keyframes_draw.h"
#include "GPU_basic_shader.h"
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
#include "UI_resources.h"
@@ -74,8 +76,10 @@
/* global here is reset before drawing each bone */
static ThemeWireColor *bcolor = NULL;
+static float fcolor[4] = {0.0f};
+static bool flat_color;
-/* values of colCode for set_pchan_glcolor */
+/* values of colCode for set_pchan_color */
enum {
PCHAN_COLOR_NORMAL = 0, /* normal drawing */
PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
@@ -128,7 +132,7 @@ static void set_pchan_colorset(Object *ob, bPoseChannel *pchan)
}
}
-/* This function is for brightening/darkening a given color (like UI_ThemeColorShade()) */
+/* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */
static void cp_shade_color3ub(unsigned char cp[3], const int offset)
{
int r, g, b;
@@ -146,13 +150,13 @@ static void cp_shade_color3ub(unsigned char cp[3], const int offset)
}
/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
-static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
+static bool set_pchan_color(short colCode, int boneflag, short constflag)
{
switch (colCode) {
case PCHAN_COLOR_NORMAL:
{
if (bcolor) {
- unsigned char cp[3];
+ unsigned char cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_char((char *)cp, bcolor->active);
@@ -169,20 +173,20 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
cp_shade_color3ub(cp, -50);
}
- glColor3ubv(cp);
+ rgb_uchar_to_float(fcolor, cp);
}
else {
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
- UI_ThemeColor(TH_BONE_POSE_ACTIVE);
+ UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor);
}
else if (boneflag & BONE_DRAW_ACTIVE) {
- UI_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.15f); /* unselected active */
+ UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor);
}
else if (boneflag & BONE_SELECTED) {
- UI_ThemeColor(TH_BONE_POSE);
+ UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
}
else {
- UI_ThemeColor(TH_WIRE);
+ UI_GetThemeColor4fv(TH_WIRE, fcolor);
}
}
@@ -191,21 +195,25 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
case PCHAN_COLOR_SOLID:
{
if (bcolor) {
- glColor3ubv((unsigned char *)bcolor->solid);
+ rgb_uchar_to_float(fcolor, (unsigned char *)bcolor->solid);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
- else
- UI_ThemeColor(TH_BONE_SOLID);
return true;
}
case PCHAN_COLOR_CONSTS:
{
if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
- if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
- else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
- else if (constflag & PCHAN_HAS_SPLINEIK) glColor4ub(200, 255, 0, 80);
- else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
-
+ unsigned char cp[4];
+ if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 80);
+ else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 80);
+
+ rgba_uchar_to_float(fcolor, cp);
+
return true;
}
return false;
@@ -213,7 +221,7 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
case PCHAN_COLOR_SPHEREBONE_BASE:
{
if (bcolor) {
- unsigned char cp[3];
+ unsigned char cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_char((char *)cp, bcolor->active);
@@ -225,12 +233,18 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
copy_v3_v3_char((char *)cp, bcolor->solid);
}
- glColor3ubv(cp);
+ rgb_uchar_to_float(fcolor, cp);
}
else {
- if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE);
- else UI_ThemeColor(TH_BONE_SOLID);
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
}
return true;
@@ -238,7 +252,7 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
case PCHAN_COLOR_SPHEREBONE_END:
{
if (bcolor) {
- unsigned char cp[3];
+ unsigned char cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_char((char *)cp, bcolor->active);
@@ -253,12 +267,18 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
cp_shade_color3ub(cp, -30);
}
- glColor3ubv(cp);
+ rgb_uchar_to_float(fcolor, cp);
}
else {
- if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 10);
- else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, -30);
- else UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ if (boneflag & BONE_DRAW_ACTIVE) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor);
+ }
+ else {
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
+ }
}
break;
}
@@ -266,19 +286,24 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
{
/* inner part in background color or constraint */
if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) {
- if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
- else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
- else if (constflag & PCHAN_HAS_SPLINEIK) glColor3ub(200, 255, 0);
- else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
- else if (constflag) UI_ThemeColor(TH_BONE_POSE); /* PCHAN_HAS_ACTION */
+ unsigned char cp[4];
+ if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 255);
+ else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 255);
+ else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 255);
+ else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 255);
+ else if (constflag) UI_GetThemeColor4ubv(TH_BONE_POSE, cp); /* PCHAN_HAS_ACTION */
+
+ rgb_uchar_to_float(fcolor, cp);
}
else {
if (bcolor) {
const char *cp = bcolor->solid;
- glColor4ub(cp[0], cp[1], cp[2], 204);
+ rgb_uchar_to_float(fcolor, (unsigned char *)cp);
+ fcolor[3] = 204.f / 255.f;
+ }
+ else {
+ UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor);
}
- else
- UI_ThemeColorShade(TH_BACK, -30);
}
return true;
@@ -288,26 +313,37 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
return false;
}
-static void set_ebone_glColor(const unsigned int boneflag)
+static void set_ebone_color(const unsigned int boneflag)
{
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
- UI_ThemeColor(TH_EDGE_SELECT);
+ UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor);
}
else if (boneflag & BONE_DRAW_ACTIVE) {
- UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f); /* unselected active */
+ UI_GetThemeColorBlendShade4fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, fcolor);
}
else if (boneflag & BONE_SELECTED) {
- UI_ThemeColorShade(TH_EDGE_SELECT, -20);
+ UI_GetThemeColorShade4fv(TH_EDGE_SELECT, -20, fcolor);
}
else {
- UI_ThemeColor(TH_WIRE_EDIT);
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor);
}
}
/* *************** Armature drawing, helper calls for parts ******************* */
+static void add_solid_flat_triangle(VertexBuffer *vbo, unsigned int *vertex, unsigned int pos, unsigned int nor,
+ const float p1[3], const float p2[3], const float p3[3], const float n[3])
+{
+ VertexBuffer_set_attrib(vbo, nor, *vertex, n);
+ VertexBuffer_set_attrib(vbo, pos, (*vertex)++, p1);
+ VertexBuffer_set_attrib(vbo, nor, *vertex, n);
+ VertexBuffer_set_attrib(vbo, pos, (*vertex)++, p2);
+ VertexBuffer_set_attrib(vbo, nor, *vertex, n);
+ VertexBuffer_set_attrib(vbo, pos, (*vertex)++, p3);
+}
+
/* half the cube, in Y */
-static const float cube[8][3] = {
+static const float cube_vert[8][3] = {
{-1.0, 0.0, -1.0},
{-1.0, 0.0, 1.0},
{-1.0, 1.0, 1.0},
@@ -318,128 +354,184 @@ static const float cube[8][3] = {
{ 1.0, 1.0, -1.0},
};
+static const float cube_wire[24] = {
+ 0, 1, 1, 2, 2, 3, 3, 0,
+ 4, 5, 5, 6, 6, 7, 7, 4,
+ 0, 4, 1, 5, 2, 6, 3, 7,
+};
+
static void drawsolidcube_size(float xsize, float ysize, float zsize)
{
- static GLuint displist = 0;
- float n[3] = {0.0f};
-
- glScalef(xsize, ysize, zsize);
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static Batch batch = {{0}};
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ if (format.attrib_ct == 0) {
+ unsigned int i = 0;
+ float n[3] = {0.0f};
+ /* Vertex format */
+ unsigned int pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int nor = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 36);
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glBegin(GL_QUADS);
n[0] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[1], cube_vert[2], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[3], cube_vert[0], n);
n[0] = 0;
n[1] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[4], cube_vert[5], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[5], cube_vert[1], cube_vert[0], n);
n[1] = 0;
n[0] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[4], cube_vert[7], cube_vert[6], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[5], cube_vert[4], n);
n[0] = 0;
n[1] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[3], cube_vert[2], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[6], cube_vert[7], n);
n[1] = 0;
n[2] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[1], cube_vert[5], cube_vert[6], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[2], cube_vert[1], n);
n[2] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
- glEnd();
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[4], cube_vert[0], n);
+ add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[3], cube_vert[7], n);
- glEndList();
+ Batch_init(&batch, PRIM_TRIANGLES, &vbo, NULL);
}
- glCallList(displist);
+ gpuPushMatrix();
+ gpuScale3f(xsize, ysize, zsize);
+
+ if (flat_color) {
+ Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ else {
+ /* TODO replace with good default lighting shader ? */
+ Batch_set_builtin_program(&batch, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform3fv(&batch, "light", light_vec);
+ }
+ Batch_Uniform4fv(&batch, "color", fcolor);
+ Batch_draw(&batch);
+
+ gpuPopMatrix();
}
static void drawcube_size(float xsize, float ysize, float zsize)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glBegin(GL_LINE_STRIP);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[6]);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]);
- glEnd();
-
- glBegin(GL_LINES);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]);
- glVertex3fv(cube[2]); glVertex3fv(cube[6]);
- glVertex3fv(cube[3]); glVertex3fv(cube[7]);
- glEnd();
-
- glEndList();
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static ElementListBuilder elb = {0};
+ static ElementList el = {0};
+ static Batch batch = {{0}};
+
+ if (format.attrib_ct == 0) {
+ /* Vertex format */
+ unsigned int pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ /* Elements */
+ ElementListBuilder_init(&elb, PRIM_LINES, 12, 8);
+ for (int i = 0; i < 12; ++i) {
+ add_line_vertices(&elb, cube_wire[i*2], cube_wire[i*2+1]);
+ }
+ ElementList_build_in_place(&elb, &el);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 8);
+ for (int i = 0; i < 8; ++i) {
+ VertexBuffer_set_attrib(&vbo, pos, i, cube_vert[i]);
+ }
+
+ Batch_init(&batch, PRIM_LINES, &vbo, &el);
+ Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
- glScalef(xsize, ysize, zsize);
- glCallList(displist);
-
+ gpuPushMatrix();
+ gpuScale3f(xsize, ysize, zsize);
+
+ Batch_use_program(&batch);
+ Batch_Uniform4fv(&batch, "color", fcolor);
+ Batch_draw(&batch);
+
+ gpuPopMatrix();
}
static void draw_bonevert(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glPushMatrix();
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0.0, 0.05, 16, 1);
-
- glRotatef(90, 0, 1, 0);
- gluDisk(qobj, 0.0, 0.05, 16, 1);
-
- glRotatef(90, 1, 0, 0);
- gluDisk(qobj, 0.0, 0.05, 16, 1);
-
- gluDeleteQuadric(qobj);
-
- glPopMatrix();
- glEndList();
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static Batch batch = {{0}};
+
+ if (format.attrib_ct == 0) {
+ /* Vertex format */
+ unsigned int pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 96);
+ for (int i = 0; i < 16; ++i) {
+ float vert[3] = {0.f, 0.f, 0.f};
+ const float r = 0.05f;
+
+ vert[0] = r * cosf(2 * M_PI * i / 16.f);
+ vert[1] = r * sinf(2 * M_PI * i / 16.f);
+ VertexBuffer_set_attrib(&vbo, pos, i * 6 + 0, vert);
+ vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f);
+ vert[1] = r * sinf(2 * M_PI * (i + 1) / 16.f);
+ VertexBuffer_set_attrib(&vbo, pos, i * 6 + 1, vert);
+
+ vert[0] = 0.f;
+ vert[1] = r * cosf(2 * M_PI * i / 16.f);
+ vert[2] = r * sinf(2 * M_PI * i / 16.f);
+ VertexBuffer_set_attrib(&vbo, pos, i * 6 + 2, vert);
+ vert[1] = r * cosf(2 * M_PI * (i + 1) / 16.f);
+ vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f);
+ VertexBuffer_set_attrib(&vbo, pos, i * 6 + 3, vert);
+
+ vert[1] = 0.f;
+ vert[0] = r * cosf(2 * M_PI * i / 16.f);
+ vert[2] = r * sinf(2 * M_PI * i / 16.f);
+ VertexBuffer_set_attrib(&vbo, pos, i * 6 + 4, vert);
+ vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f);
+ vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f);
+ VertexBuffer_set_attrib(&vbo, pos, i * 6 + 5, vert);
+ }
+
+ Batch_init(&batch, PRIM_LINES, &vbo, NULL);
+ Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
- glCallList(displist);
+ Batch_use_program(&batch);
+ Batch_Uniform4fv(&batch, "color", fcolor);
+ Batch_draw(&batch);
}
static void draw_bonevert_solid(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
- /* Draw tips of a bone */
- gluSphere(qobj, 0.05, 8, 5);
- gluDeleteQuadric(qobj);
-
- glEndList();
+ Batch *batch = Batch_get_sphere(0);
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ gpuPushMatrix();
+ gpuScaleUniform(0.05);
+
+ if (flat_color) {
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ else {
+ /* TODO replace with good default lighting shader ? */
+ Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform3fv(batch, "light", light_vec);
}
+ Batch_Uniform4fv(batch, "color", fcolor);
+ Batch_draw(batch);
- glCallList(displist);
+ gpuPopMatrix();
}
static const float bone_octahedral_verts[6][3] = {
@@ -451,8 +543,11 @@ static const float bone_octahedral_verts[6][3] = {
{ 0.0f, 1.0f, 0.0f}
};
-static const unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2};
-static const unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1};
+static const unsigned int bone_octahedral_wire[24] = {
+ 0, 1, 1, 5, 5, 3, 3, 0,
+ 0, 4, 4, 5, 5, 2, 2, 0,
+ 1, 2, 2, 3, 3, 4, 4, 1,
+};
static const unsigned int bone_octahedral_solid_tris[8][3] = {
{2, 1, 0}, /* bottom */
@@ -480,70 +575,78 @@ static const float bone_octahedral_solid_normals[8][3] = {
static void draw_bone_octahedral(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- /* Section 1, sides */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts);
- glDrawElements(GL_LINE_LOOP,
- sizeof(bone_octahedral_wire_sides) / sizeof(*bone_octahedral_wire_sides),
- GL_UNSIGNED_INT,
- bone_octahedral_wire_sides);
-
- /* Section 1, square */
- glDrawElements(GL_LINE_LOOP,
- sizeof(bone_octahedral_wire_square) / sizeof(*bone_octahedral_wire_square),
- GL_UNSIGNED_INT,
- bone_octahedral_wire_square);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glEndList();
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static ElementListBuilder elb = {0};
+ static ElementList el = {0};
+ static Batch batch = {{0}};
+
+ if (format.attrib_ct == 0) {
+ /* Vertex format */
+ unsigned int pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ /* Elements */
+ ElementListBuilder_init(&elb, PRIM_LINES, 12, 6);
+ for (int i = 0; i < 12; ++i) {
+ add_line_vertices(&elb, bone_octahedral_wire[i*2], bone_octahedral_wire[i*2+1]);
+ }
+ ElementList_build_in_place(&elb, &el);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 6);
+ for (int i = 0; i < 6; ++i) {
+ VertexBuffer_set_attrib(&vbo, pos, i, bone_octahedral_verts[i]);
+ }
+
+ Batch_init(&batch, PRIM_LINES, &vbo, &el);
+ Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
- glCallList(displist);
-}
+ Batch_use_program(&batch);
+ Batch_Uniform4fv(&batch, "color", fcolor);
+ Batch_draw(&batch);
+}
static void draw_bone_solid_octahedral(void)
{
- static GLuint displist = 0;
-
- if (displist == 0) {
- int i;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
-#if 1
- glBegin(GL_TRIANGLES);
- for (i = 0; i < 8; i++) {
- glNormal3fv(bone_octahedral_solid_normals[i]);
- glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][0]]);
- glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][1]]);
- glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]);
- }
-
- glEnd();
-
-#else /* not working because each vert needs a different normal */
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
- glNormalPointer(GL_FLOAT, 0, bone_octahedral_solid_normals);
- glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts);
- glDrawElements(GL_TRIANGLES, sizeof(bone_octahedral_solid_tris) / sizeof(unsigned int),
- GL_UNSIGNED_INT, bone_octahedral_solid_tris);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-#endif
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static Batch batch = {{0}};
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ if (format.attrib_ct == 0) {
+ unsigned int v_idx = 0;
+ /* Vertex format */
+ unsigned int pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int nor = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 24);
+
+ for (int i = 0; i < 8; i++) {
+ add_solid_flat_triangle(&vbo, &v_idx, pos, nor,
+ bone_octahedral_verts[bone_octahedral_solid_tris[i][0]],
+ bone_octahedral_verts[bone_octahedral_solid_tris[i][1]],
+ bone_octahedral_verts[bone_octahedral_solid_tris[i][2]],
+ bone_octahedral_solid_normals[i]);
+ }
- glEndList();
+ Batch_init(&batch, PRIM_TRIANGLES, &vbo, NULL);
}
- glCallList(displist);
-}
+ if (flat_color) {
+ Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+ else {
+ /* TODO replace with good default lighting shader ? */
+ Batch_set_builtin_program(&batch, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform3fv(&batch, "light", light_vec);
+ }
+ Batch_Uniform4fv(&batch, "color", fcolor);
+ Batch_draw(&batch);
+}
/* *************** Armature drawing, bones ******************* */
@@ -557,15 +660,20 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
if (dt <= OB_WIRE) {
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_ROOTSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
}
else {
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0);
- else
- UI_ThemeColor(TH_BONE_SOLID);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0);
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
}
if (dt > OB_WIRE)
@@ -580,24 +688,29 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
if (dt <= OB_WIRE) {
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_TIPSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
}
else {
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0);
- else
- UI_ThemeColor(TH_BONE_SOLID);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0);
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
}
- glTranslatef(0.0f, 1.0f, 0.0f);
+ gpuPushMatrix();
+ gpuTranslate2f(0.0f, 1.0f);
if (dt > OB_WIRE)
draw_bonevert_solid();
else
draw_bonevert();
- glTranslatef(0.0f, -1.0f, 0.0f);
-
+ gpuPopMatrix();
}
/* 16 values of sin function (still same result!) */
@@ -696,8 +809,13 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
//mul_v3_fl(dirvec, head);
cross_v3_v3v3(norvec, dirvec, imat[2]);
-
- glBegin(GL_QUAD_STRIP);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immBegin(PRIM_TRIANGLE_STRIP, 66);
+ immUniformColor4ub(255, 255, 255, 50);
for (a = 0; a < 16; a++) {
vec[0] = -si[a] * dirvec[0] + co[a] * norvec[0];
@@ -707,10 +825,8 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
madd_v3_v3v3fl(vec1, headvec, vec, head);
madd_v3_v3v3fl(vec2, headvec, vec, head + dist);
- glColor4ub(255, 255, 255, 50);
- glVertex3fv(vec1);
- //glColor4ub(255, 255, 255, 0);
- glVertex3fv(vec2);
+ immVertex3fv(pos, vec1);
+ immVertex3fv(pos, vec2);
}
for (a = 15; a >= 0; a--) {
@@ -721,10 +837,8 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
madd_v3_v3v3fl(vec1, tailvec, vec, tail);
madd_v3_v3v3fl(vec2, tailvec, vec, tail + dist);
- //glColor4ub(255, 255, 255, 50);
- glVertex3fv(vec1);
- //glColor4ub(255, 255, 255, 0);
- glVertex3fv(vec2);
+ immVertex3fv(pos, vec1);
+ immVertex3fv(pos, vec2);
}
/* make it cyclic... */
@@ -735,12 +849,11 @@ static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChann
madd_v3_v3v3fl(vec1, headvec, vec, head);
madd_v3_v3v3fl(vec2, headvec, vec, head + dist);
- //glColor4ub(255, 255, 255, 50);
- glVertex3fv(vec1);
- //glColor4ub(255, 255, 255, 0);
- glVertex3fv(vec2);
+ immVertex3fv(pos, vec1);
+ immVertex3fv(pos, vec2);
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
}
@@ -752,6 +865,11 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
{
float head, tail /*, length*/;
float *headvec, *tailvec, dirvec[3];
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
/* figure out the sizes of spheres */
if (ebone) {
@@ -780,35 +898,49 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
/* sphere root color */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_ROOTSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
else if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
-
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
+
+ immUniformColor4fv(fcolor);
+
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
GPU_select_load_id(id | BONESEL_ROOT);
- drawcircball(GL_LINE_LOOP, headvec, head, imat);
+ imm_drawcircball(headvec, head, imat, pos);
}
/* Draw tip point */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_TIPSEL) {
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_VERTEX, fcolor);
+ }
}
if (id != -1)
GPU_select_load_id(id | BONESEL_TIP);
- drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
+ imm_drawcircball(tailvec, tail, imat, pos);
/* base */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT);
- else UI_ThemeColor(TH_WIRE_EDIT);
+ if (boneflag & BONE_SELECTED){
+ UI_GetThemeColor4fv(TH_SELECT, fcolor);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor);
+ }
}
sub_v3_v3v3(dirvec, tailvec, headvec);
@@ -834,34 +966,40 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
if (id != -1)
GPU_select_load_id(id | BONESEL_BONE);
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, 4);
add_v3_v3v3(vec, headvec, norvech);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
add_v3_v3v3(vec, tailvec, norvect);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
sub_v3_v3v3(vec, headvec, norvech);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
sub_v3_v3v3(vec, tailvec, norvect);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
- glEnd();
+ immEnd();
}
+
+ immUnbindProgram();
}
/* does wire only for outline selecting */
static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
- GLUquadricObj *qobj;
+ Batch *sphere = Batch_get_sphere(1);
float head, tail, length;
- float fac1, fac2;
-
- glPushMatrix();
- qobj = gluNewQuadric();
+ float fac1, fac2, size1, size2;
+ const float light_vec[3] = {0.0f, 0.0f, 1.0f};
+
+ /* dt is always OB_SOlID */
+ Batch_set_builtin_program(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform3fv(sphere, "light", light_vec);
+
+ gpuPushMatrix();
/* figure out the sizes of spheres */
if (ebone) {
@@ -882,110 +1020,124 @@ static void draw_sphere_bone(const short dt, int armflag, int boneflag, short co
}
/* move to z-axis space */
- glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
+ gpuRotateAxis(-90.0f, 'X');
- if (dt == OB_SOLID) {
- /* set up solid drawing */
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-
- gluQuadricDrawStyle(qobj, GLU_FILL);
- }
- else {
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- }
-
/* sphere root color */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ if (boneflag & BONE_ROOTSEL)
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
}
else if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag);
else if (dt == OB_SOLID)
- UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
GPU_select_load_id(id | BONESEL_ROOT);
- gluSphere(qobj, head, 16, 10);
+ gpuPushMatrix();
+ gpuScaleUniform(head);
+ Batch_Uniform4fv(sphere, "color", fcolor);
+ Batch_draw(sphere);
+ gpuPopMatrix();
}
/* Draw tip point */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColorShade(TH_BONE_SOLID, -30);
+ if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
}
if (id != -1)
GPU_select_load_id(id | BONESEL_TIP);
- glTranslatef(0.0f, 0.0f, length);
- gluSphere(qobj, tail, 16, 10);
- glTranslatef(0.0f, 0.0f, -length);
+ gpuTranslate3f(0.0f, 0.0f, length);
+
+ gpuPushMatrix();
+ gpuScaleUniform(tail);
+ Batch_use_program(sphere); /* hack to make the following uniforms stick */
+ Batch_Uniform4fv(sphere, "color", fcolor);
+ Batch_draw(sphere);
+ gpuPopMatrix();
+
+ gpuTranslate3f(0.0f, 0.0f, -length);
/* base */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT);
- else UI_ThemeColor(TH_BONE_SOLID);
+ if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_SELECT, fcolor);
+ else UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
else if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag);
else if (dt == OB_SOLID)
- UI_ThemeColor(TH_BONE_SOLID);
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+
+ Batch_use_program(sphere); /* hack to make the following uniforms stick */
+ Batch_Uniform4fv(sphere, "color", fcolor);
fac1 = (length - head) / length;
fac2 = (length - tail) / length;
if (length > (head + tail)) {
+ size1 = fac2 * tail + (1.0f - fac2) * head;
+ size2 = fac1 * head + (1.0f - fac1) * tail;
+
if (id != -1)
GPU_select_load_id(id | BONESEL_BONE);
+ /* draw sphere on extrema */
+ gpuPushMatrix();
+ gpuTranslate3f(0.0f, 0.0f, length - tail);
+ gpuScaleUniform(size1);
+
+ Batch_draw(sphere);
+ gpuPopMatrix();
+
+ gpuPushMatrix();
+ gpuTranslate3f(0.0f, 0.0f, head);
+ gpuScaleUniform(size2);
+
+ Batch_draw(sphere);
+ gpuPopMatrix();
+
+ /* draw cynlinder between spheres */
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -1.0f);
-
- glTranslatef(0.0f, 0.0f, head);
- gluCylinder(qobj, fac1 * head + (1.0f - fac1) * tail, fac2 * tail + (1.0f - fac2) * head, length - head - tail, 16, 1);
- glTranslatef(0.0f, 0.0f, -head);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int nor = VertexFormat_add_attrib(format, "nor", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING);
+ immUniformColor4fv(fcolor);
+ immUniform3fv("light", light_vec);
+
+ gpuTranslate3f(0.0f, 0.0f, head);
+ imm_draw_cylinder_fill_normal_3d(pos, nor, size2, size1, length - head - tail, 16, 1);
+
+ immUnbindProgram();
glDisable(GL_POLYGON_OFFSET_FILL);
-
- /* draw sphere on extrema */
- glTranslatef(0.0f, 0.0f, length - tail);
- gluSphere(qobj, fac2 * tail + (1.0f - fac2) * head, 16, 10);
- glTranslatef(0.0f, 0.0f, -length + tail);
-
- glTranslatef(0.0f, 0.0f, head);
- gluSphere(qobj, fac1 * head + (1.0f - fac1) * tail, 16, 10);
}
else {
+ size1 = fac1 * head + (1.0f - fac1) * tail;
+
/* 1 sphere in center */
- glTranslatef(0.0f, 0.0f, (head + length - tail) / 2.0f);
- gluSphere(qobj, fac1 * head + (1.0f - fac1) * tail, 16, 10);
- }
-
- /* restore */
- if (dt == OB_SOLID) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ gpuTranslate3f(0.0f, 0.0f, (head + length - tail) / 2.0f);
+
+ gpuScaleUniform(size1);
+ Batch_draw(sphere);
}
- glPopMatrix();
- gluDeleteQuadric(qobj);
+ gpuPopMatrix();
}
-static GLubyte bm_dot6[] = {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0};
-static GLubyte bm_dot8[] = {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C};
-
-static GLubyte bm_dot5[] = {0x0, 0x0, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x0};
-static GLubyte bm_dot7[] = {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38};
-
-
static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
- /* call this once, avoid constant changing */
- BLI_assert(glaGetOneInt(GL_UNPACK_ALIGNMENT) == 1);
-
float length;
if (pchan)
@@ -993,103 +1145,119 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
else
length = ebone->length;
- glPushMatrix();
- glScalef(length, length, length);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ gpuPushMatrix();
+ gpuScaleUniform(length);
/* this chunk not in object mode */
if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) {
glLineWidth(4.0f);
- if (G.f & G_PICKSEL) {
- /* no bitmap in selection mode, crashes 3d cards...
- * instead draw a solid point the same size */
- glPointSize(8.0f);
- }
+ glPointSize(8.0f);
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
else if (armflag & ARM_EDITMODE) {
- UI_ThemeColor(TH_WIRE_EDIT);
+ UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor);
}
-
+
+ /* line */
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
+ if (id != -1)
+ GPU_select_load_id(id | BONESEL_BONE);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
- if (G.f & G_PICKSEL) {
+ if (G.f & G_PICKSEL)
GPU_select_load_id(id | BONESEL_ROOT);
- glBegin(GL_POINTS);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glEnd();
- }
- else {
- glRasterPos3f(0.0f, 0.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot8);
- }
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
}
-
- if (id != -1)
- GPU_select_load_id((GLuint) id | BONESEL_BONE);
-
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
-
+
/* tip */
- if (G.f & G_PICKSEL) {
- /* no bitmap in selection mode, crashes 3d cards... */
+ if (G.f & G_PICKSEL)
GPU_select_load_id(id | BONESEL_TIP);
- glBegin(GL_POINTS);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
- }
- else {
- glRasterPos3f(0.0f, 1.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot7);
- }
-
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+
/* further we send no names */
if (id != -1)
GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_LINEBONE, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_LINEBONE, boneflag, constflag);
}
-
- glLineWidth(2.0);
-
+
+ /* Now draw the inner color */
+ glLineWidth(2.0f);
+ glPointSize(5.0f);
+
+ /* line */
+ if (armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor);
+ else UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor);
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+
/*Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
- if ((G.f & G_PICKSEL) == 0) {
- /* no bitmap in selection mode, crashes 3d cards... */
- if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
- }
- glRasterPos3f(0.0f, 0.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot6);
+ if (armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_ROOTSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else UI_GetThemeColor4fv(TH_VERTEX, fcolor);
}
+ immUniformColor4fv(fcolor);
+ immBegin(PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immEnd();
}
-
- if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_EDGE_SELECT);
- else UI_ThemeColorShade(TH_BACK, -30);
- }
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
-
+
/* tip */
if ((G.f & G_PICKSEL) == 0) {
/* no bitmap in selection mode, crashes 3d cards... */
if (armflag & ARM_EDITMODE) {
- if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
+ if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor);
+ else UI_GetThemeColor4fv(TH_VERTEX, fcolor);
}
- glRasterPos3f(0.0f, 1.0f, 0.0f);
- glBitmap(8, 8, 4, 4, 0, 0, bm_dot5);
+ immUniformColor4fv(fcolor);
+ immBegin(PRIM_POINTS, 1);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+ immEnd();
}
-
- glPopMatrix();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
}
/* A partial copy of b_bone_spline_setup(), with just the parts for previewing editmode curve settings
@@ -1188,18 +1356,16 @@ static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, EditBone *ebo
}
for (a = 0; a < segments; a++) {
- glPushMatrix();
- glMultMatrixf(bbone[a].mat);
+ gpuPushMatrix();
+ gpuMultMatrix(bbone[a].mat);
if (dt == OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
else drawcube_size(xwidth, dlen, zwidth);
- glPopMatrix();
+ gpuPopMatrix();
}
}
else {
- glPushMatrix();
if (dt == OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
else drawcube_size(xwidth, length, zwidth);
- glPopMatrix();
}
}
@@ -1222,26 +1388,27 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
/* draw points only if... */
if (armflag & ARM_EDITMODE) {
/* move to unitspace */
- glPushMatrix();
- glScalef(length, length, length);
+ gpuPushMatrix();
+ gpuScaleUniform(length);
draw_bone_points(dt, armflag, boneflag, id);
- glPopMatrix();
+ gpuPopMatrix();
length *= 0.95f; /* make vertices visible */
}
/* colors for modes */
if (armflag & ARM_POSEMODE) {
if (dt <= OB_WIRE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
else
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
}
else if (armflag & ARM_EDITMODE) {
if (dt == OB_WIRE) {
- set_ebone_glColor(boneflag);
+ set_ebone_color(boneflag);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
- else
- UI_ThemeColor(TH_BONE_SOLID);
}
if (id != -1) {
@@ -1250,33 +1417,31 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
/* set up solid drawing */
if (dt > OB_WIRE) {
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
- else
- UI_ThemeColor(TH_BONE_SOLID);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
+ else {
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ }
+ flat_color = false;
draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth);
-
- /* disable solid drawing */
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
}
else {
/* wire */
if (armflag & ARM_POSEMODE) {
if (constflag && ((G.f & G_PICKSEL) == 0)) {
/* set constraint colors */
- if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
+ if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
glEnable(GL_BLEND);
+ flat_color = true;
draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth);
glDisable(GL_BLEND);
}
/* restore colors */
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
}
}
@@ -1286,33 +1451,41 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments)
{
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(fcolor);
+
if ((segments > 1) && (pchan)) {
float dlen = length / (float)segments;
Mat4 *bbone = bbones;
int a;
-
+
for (a = 0; a < segments; a++, bbone++) {
- glPushMatrix();
- glMultMatrixf(bbone->mat);
-
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, dlen, 0.0f);
- glEnd(); /* GL_LINES */
-
- glPopMatrix();
+ gpuPushMatrix();
+ gpuMultMatrix(bbone->mat);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immVertex3f(pos, 0.0f, dlen, 0.0f);
+ immEnd();
+
+ gpuPopMatrix();
}
}
else {
- glPushMatrix();
-
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, length, 0.0f);
- glEnd();
-
- glPopMatrix();
+ gpuPushMatrix();
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immVertex3f(pos, 0.0f, length, 0.0f);
+ immEnd();
+
+ gpuPopMatrix();
}
+
+ immUnbindProgram();
}
static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
@@ -1338,10 +1511,11 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
/* draw points only if... */
if (armflag & ARM_EDITMODE) {
/* move to unitspace */
- glPushMatrix();
- glScalef(length, length, length);
+ gpuPushMatrix();
+ gpuScaleUniform(length);
+ flat_color = true;
draw_bone_points(dt, armflag, boneflag, id);
- glPopMatrix();
+ gpuPopMatrix();
length *= 0.95f; /* make vertices visible */
}
@@ -1359,10 +1533,10 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
/* colors for modes */
if (armflag & ARM_POSEMODE) {
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
}
else if (armflag & ARM_EDITMODE) {
- set_ebone_glColor(boneflag);
+ set_ebone_color(boneflag);
}
/* draw normal */
@@ -1372,23 +1546,23 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length)
{
- /* Draw a 3d octahedral bone, we use normalized space based on length,
- * for display-lists */
-
- glScalef(length, length, length);
+ /* Draw a 3d octahedral bone, we use normalized space based on length */
+ gpuScaleUniform(length);
/* set up solid drawing */
if (dt > OB_WIRE) {
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
- UI_ThemeColor(TH_BONE_SOLID);
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
+ flat_color = false;
}
+ else
+ flat_color = true;
/* colors for posemode */
if (armflag & ARM_POSEMODE) {
if (dt <= OB_WIRE)
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
else
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
}
@@ -1403,12 +1577,12 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
if (dt <= OB_WIRE) {
/* colors */
if (armflag & ARM_EDITMODE) {
- set_ebone_glColor(boneflag);
+ set_ebone_color(boneflag);
}
else if (armflag & ARM_POSEMODE) {
if (constflag && ((G.f & G_PICKSEL) == 0)) {
/* draw constraint colors */
- if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
+ if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
glEnable(GL_BLEND);
draw_bone_solid_octahedral();
@@ -1417,7 +1591,7 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
}
/* restore colors */
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag);
}
}
draw_bone_octahedral();
@@ -1425,35 +1599,31 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
else {
/* solid */
if (armflag & ARM_POSEMODE)
- set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
+ set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag);
else
- UI_ThemeColor(TH_BONE_SOLID);
- draw_bone_solid_octahedral();
- }
+ UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
- /* disable solid drawing */
- if (dt > OB_WIRE) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ draw_bone_solid_octahedral();
}
}
-static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
+static void draw_custom_bone(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob,
const short dt, int armflag, int boneflag, unsigned int id, float length)
{
if (ob == NULL) return;
- glScalef(length, length, length);
+ gpuScaleUniform(length);
/* colors for posemode */
if (armflag & ARM_POSEMODE) {
- set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, 0);
+ set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, 0);
}
if (id != -1) {
GPU_select_load_id((GLuint) id | BONESEL_BONE);
}
-
- draw_object_instance(scene, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE);
+
+ draw_object_instance(scene, sl, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor);
}
@@ -1461,7 +1631,20 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
{
bConstraint *con;
bPoseChannel *parchan;
-
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4fv(fcolor);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
for (con = pchan->constraints.first; con; con = con->next) {
if (con->enforce == 0.0f)
continue;
@@ -1471,47 +1654,45 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
{
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
int segcount = 0;
+ float ik_tip[3];
/* if only_temp, only draw if it is a temporary ik-chain */
if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP))
continue;
-
- setlinestyle(3);
- glBegin(GL_LINES);
-
+
/* exclude tip from chain? */
if ((data->flag & CONSTRAINT_IK_TIP) == 0)
parchan = pchan->parent;
else
parchan = pchan;
- glVertex3fv(parchan->pose_tail);
+ copy_v3_v3(ik_tip, parchan->pose_tail);
/* Find the chain's root */
while (parchan->parent) {
segcount++;
- if (segcount == data->rootbone || segcount > 255) {
- break; /* 255 is weak */
- }
+ /* FIXME: revise the breaking conditions */
+ if (segcount == data->rootbone || segcount > 255) break; /* 255 is weak */
parchan = parchan->parent;
}
- if (parchan)
- glVertex3fv(parchan->pose_head);
+
+ if (parchan) {
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, ik_tip);
+ immVertex3fv(shdr_pos, parchan->pose_head);
+ immEnd();
+ }
- glEnd();
- setlinestyle(0);
break;
}
case CONSTRAINT_TYPE_SPLINEIK:
{
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
int segcount = 0;
-
- setlinestyle(3);
- glBegin(GL_LINES);
+ float ik_tip[3];
parchan = pchan;
- glVertex3fv(parchan->pose_tail);
+ copy_v3_v3(ik_tip, parchan->pose_tail);
/* Find the chain's root */
while (parchan->parent) {
@@ -1521,18 +1702,21 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
parchan = parchan->parent;
}
/* Only draw line in case our chain is more than one bone long! */
- if (parchan != pchan) /* XXX revise the breaking conditions to only stop at the tail? */
- glVertex3fv(parchan->pose_head);
-
- glEnd();
- setlinestyle(0);
+ if (parchan != pchan) { /* XXX revise the breaking conditions to only stop at the tail? */
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, ik_tip);
+ immVertex3fv(shdr_pos, parchan->pose_head);
+ immEnd();
+ }
break;
}
}
}
+
+ immUnbindProgram();
}
-static void bgl_sphere_project(float ax, float az)
+static void imm_sphere_project(unsigned int pos, float ax, float az)
{
float dir[3], sine, q3;
@@ -1543,11 +1727,13 @@ static void bgl_sphere_project(float ax, float az)
dir[1] = 1.0f - 2.0f * sine;
dir[2] = ax * q3;
- glVertex3fv(dir);
+ immVertex3fv(pos, dir);
}
-static void draw_dof_ellipse(float ax, float az)
+static void draw_dof_ellipse(unsigned int pos, float ax, float az)
{
+ const int n = 16;
+ const int tri = n*n - 2*n + 1; /* Yay fancy math ! */
const float staticSine[16] = {
0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f,
0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f,
@@ -1556,15 +1742,15 @@ static void draw_dof_ellipse(float ax, float az)
0.994521895368f, 1.0f
};
- int i, j, n = 16;
+ int i, j;
float x, z, px, pz;
glEnable(GL_BLEND);
glDepthMask(0);
- glColor4ub(70, 70, 70, 50);
+ immUniformColor4ub(70, 70, 70, 50);
- glBegin(GL_QUADS);
+ immBegin(PRIM_TRIANGLES, tri*3);
pz = 0.0f;
for (i = 1; i < n; i++) {
z = staticSine[i];
@@ -1574,36 +1760,35 @@ static void draw_dof_ellipse(float ax, float az)
x = staticSine[j];
if (j == n - i) {
- glEnd();
- glBegin(GL_TRIANGLES);
- bgl_sphere_project(ax * px, az * z);
- bgl_sphere_project(ax * px, az * pz);
- bgl_sphere_project(ax * x, az * pz);
- glEnd();
- glBegin(GL_QUADS);
+ imm_sphere_project(pos, ax * px, az * z);
+ imm_sphere_project(pos, ax * px, az * pz);
+ imm_sphere_project(pos, ax * x, az * pz);
}
else {
- bgl_sphere_project(ax * x, az * z);
- bgl_sphere_project(ax * x, az * pz);
- bgl_sphere_project(ax * px, az * pz);
- bgl_sphere_project(ax * px, az * z);
+ imm_sphere_project(pos, ax * x, az * z);
+ imm_sphere_project(pos, ax * x, az * pz);
+ imm_sphere_project(pos, ax * px, az * pz);
+
+ imm_sphere_project(pos, ax * px, az * pz);
+ imm_sphere_project(pos, ax * px, az * z);
+ imm_sphere_project(pos, ax * x, az * z);
}
px = x;
}
pz = z;
}
- glEnd();
+ immEnd();
glDisable(GL_BLEND);
glDepthMask(1);
- glColor3ub(0, 0, 0);
+ immUniformColor3ub(0, 0, 0);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, n);
for (i = 0; i < n; i++)
- bgl_sphere_project(staticSine[n - i - 1] * ax, staticSine[i] * az);
- glEnd();
+ imm_sphere_project(pos, staticSine[n - i - 1] * ax, staticSine[i] * az);
+ immEnd();
}
static void draw_pose_dofs(Object *ob)
@@ -1611,7 +1796,12 @@ static void draw_pose_dofs(Object *ob)
bArmature *arm = ob->data;
bPoseChannel *pchan;
Bone *bone;
-
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
@@ -1625,54 +1815,55 @@ static void draw_pose_dofs(Object *ob)
int a, i;
/* in parent-bone pose, but own restspace */
- glPushMatrix();
+ gpuPushMatrix();
copy_v3_v3(posetrans, pchan->pose_mat[3]);
- glTranslate3fv(posetrans);
+ gpuTranslate3fv(posetrans);
if (pchan->parent) {
copy_m4_m4(mat, pchan->parent->pose_mat);
mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
- glMultMatrixf(mat);
+ gpuMultMatrix(mat);
}
copy_m4_m3(mat, pchan->bone->bone_mat);
- glMultMatrixf(mat);
+ gpuMultMatrix(mat);
scale = bone->length * pchan->size[1];
- glScalef(scale, scale, scale);
+ gpuScaleUniform(scale);
- if (pchan->ikflag & BONE_IK_XLIMIT) {
- if (pchan->ikflag & BONE_IK_ZLIMIT) {
- float amin[3], amax[3];
-
- for (i = 0; i < 3; i++) {
- /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
- amin[i] = sinf(pchan->limitmin[i] * 0.5f);
- amax[i] = sinf(pchan->limitmax[i] * 0.5f);
- }
-
- glScalef(1.0f, -1.0f, 1.0f);
- if ((amin[0] != 0.0f) && (amin[2] != 0.0f))
- draw_dof_ellipse(amin[0], amin[2]);
- if ((amin[0] != 0.0f) && (amax[2] != 0.0f))
- draw_dof_ellipse(amin[0], amax[2]);
- if ((amax[0] != 0.0f) && (amin[2] != 0.0f))
- draw_dof_ellipse(amax[0], amin[2]);
- if ((amax[0] != 0.0f) && (amax[2] != 0.0f))
- draw_dof_ellipse(amax[0], amax[2]);
- glScalef(1.0f, -1.0f, 1.0f);
+ if (((pchan->ikflag & BONE_IK_XLIMIT) != 0) &&
+ ((pchan->ikflag & BONE_IK_ZLIMIT) != 0))
+ {
+ float amin[3], amax[3];
+
+ for (i = 0; i < 3; i++) {
+ /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
+ amin[i] = sinf(pchan->limitmin[i] * 0.5f);
+ amax[i] = sinf(pchan->limitmax[i] * 0.5f);
}
+
+ gpuScale3f(1.0f, -1.0f, 1.0f);
+ if ((amin[0] != 0.0f) && (amin[2] != 0.0f))
+ draw_dof_ellipse(pos, amin[0], amin[2]);
+ if ((amin[0] != 0.0f) && (amax[2] != 0.0f))
+ draw_dof_ellipse(pos, amin[0], amax[2]);
+ if ((amax[0] != 0.0f) && (amin[2] != 0.0f))
+ draw_dof_ellipse(pos, amax[0], amin[2]);
+ if ((amax[0] != 0.0f) && (amax[2] != 0.0f))
+ draw_dof_ellipse(pos, amax[0], amax[2]);
+ gpuScale3f(1.0f, -1.0f, 1.0f); /* XXX same as above, is this intentional? */
}
/* arcs */
if (pchan->ikflag & BONE_IK_ZLIMIT) {
/* OpenGL requires rotations in degrees; so we're taking the average angle here */
theta = RAD2DEGF(0.5f * (pchan->limitmin[2] + pchan->limitmax[2]));
- glRotatef(theta, 0.0f, 0.0f, 1.0f);
+ gpuPushMatrix();
+ gpuRotateAxis(theta, 'Z');
- glColor3ub(50, 50, 255); /* blue, Z axis limit */
- glBegin(GL_LINE_STRIP);
+ immUniformColor3ub(50, 50, 255); /* blue, Z axis limit */
+ immBegin(PRIM_LINE_STRIP, 33);
for (a = -16; a <= 16; a++) {
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
float fac = ((float)a) / 16.0f * 0.5f;
@@ -1683,20 +1874,21 @@ static void draw_pose_dofs(Object *ob)
corner[i][0] = sinf(phi);
corner[i][1] = cosf(phi);
corner[i][2] = 0.0f;
- glVertex3fv(corner[i]);
+ immVertex3fv(pos, corner[i]);
}
- glEnd();
+ immEnd();
- glRotatef(-theta, 0.0f, 0.0f, 1.0f);
+ gpuPopMatrix();
}
if (pchan->ikflag & BONE_IK_XLIMIT) {
/* OpenGL requires rotations in degrees; so we're taking the average angle here */
theta = RAD2DEGF(0.5f * (pchan->limitmin[0] + pchan->limitmax[0]));
- glRotatef(theta, 1.0f, 0.0f, 0.0f);
+ gpuPushMatrix();
+ gpuRotateAxis(theta, 'X');
- glColor3ub(255, 50, 50); /* Red, X axis limit */
- glBegin(GL_LINE_STRIP);
+ immUniformColor3ub(255, 50, 50); /* Red, X axis limit */
+ immBegin(PRIM_LINE_STRIP, 33);
for (a = -16; a <= 16; a++) {
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
float fac = ((float)a) / 16.0f * 0.5f;
@@ -1706,21 +1898,23 @@ static void draw_pose_dofs(Object *ob)
corner[i][0] = 0.0f;
corner[i][1] = sinf(phi);
corner[i][2] = cosf(phi);
- glVertex3fv(corner[i]);
+ immVertex3fv(pos, corner[i]);
}
- glEnd();
+ immEnd();
- glRotatef(-theta, 1.0f, 0.0f, 0.0f);
+ gpuPopMatrix();
}
/* out of cone, out of bone */
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
}
}
}
+
+ immUnbindProgram();
}
static void bone_matrix_translate_y(float mat[4][4], float y)
@@ -1733,7 +1927,7 @@ static void bone_matrix_translate_y(float mat[4][4], float y)
}
/* assumes object is Armature with pose */
-static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
+static void draw_pose_bones(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
const short dt, const unsigned char ob_wire_col[4],
const bool do_const_color, const bool is_outline)
{
@@ -1756,7 +1950,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* being set below */
arm->layer_used = 0;
-
+
+ rgba_uchar_to_float(fcolor, ob_wire_col);
+
/* precalc inverse matrix for drawing screen aligned */
if (arm->drawtype == ARM_ENVELOPE) {
/* precalc inverse matrix for drawing screen aligned */
@@ -1817,13 +2013,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
{
if (bone->layer & arm->layer) {
const bool use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM);
- glPushMatrix();
+ gpuPushMatrix();
if (use_custom && pchan->custom_tx) {
- glMultMatrixf(pchan->custom_tx->pose_mat);
+ gpuMultMatrix(pchan->custom_tx->pose_mat);
}
else {
- glMultMatrixf(pchan->pose_mat);
+ gpuMultMatrix(pchan->pose_mat);
}
/* catch exception for bone with hidden parent */
@@ -1858,7 +2054,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
glDisable(GL_CULL_FACE);
}
- draw_custom_bone(scene, v3d, rv3d, pchan->custom,
+ draw_custom_bone(scene, sl, v3d, rv3d, pchan->custom,
OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
}
}
@@ -1885,7 +2081,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -1921,13 +2117,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (bone->layer & arm->layer) {
if (pchan->custom) {
if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) {
- glPushMatrix();
+ gpuPushMatrix();
if (pchan->custom_tx) {
- glMultMatrixf(pchan->custom_tx->pose_mat);
+ gpuMultMatrix(pchan->custom_tx->pose_mat);
}
else {
- glMultMatrixf(pchan->pose_mat);
+ gpuMultMatrix(pchan->pose_mat);
}
/* prepare colors */
@@ -1937,7 +2133,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
else if (arm->flag & ARM_POSEMODE)
set_pchan_colorset(ob, pchan);
else {
- glColor3ubv(ob_wire_col);
+ rgba_uchar_to_float(fcolor, ob_wire_col);
}
/* catch exception for bone with hidden parent */
@@ -1949,10 +2145,10 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (bone == arm->act_bone)
flag |= BONE_DRAW_ACTIVE;
- draw_custom_bone(scene, v3d, rv3d, pchan->custom,
+ draw_custom_bone(scene, sl, v3d, rv3d, pchan->custom,
OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -2011,16 +2207,30 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
* - only if V3D_HIDE_HELPLINES is enabled...
*/
if ((do_dashed & DASH_HELP_LINES) && ((bone->flag & BONE_CONNECTED) == 0)) {
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4fv(fcolor);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
if (arm->flag & ARM_POSEMODE) {
GPU_select_load_id(index & 0xFFFF); /* object tag, for bordersel optim */
- UI_ThemeColor(TH_WIRE);
+ immUniformThemeColor(TH_WIRE);
}
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(pchan->pose_head);
- glVertex3fv(pchan->parent->pose_tail);
- glEnd();
- setlinestyle(0);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, pchan->parent->pose_tail);
+ immVertex3fv(shdr_pos, pchan->pose_head);
+ immEnd();
+
+ immUnbindProgram();
}
/* Draw a line to IK root bone
@@ -2029,8 +2239,8 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (arm->flag & ARM_POSEMODE) {
if (constflag & PCHAN_HAS_IK) {
if (bone->flag & BONE_SELECTED) {
- if (constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
- else glColor3ub(200, 200, 50); /* add theme! */
+ if (constflag & PCHAN_HAS_TARGET) rgba_float_args_set(fcolor, 200.f/255.f, 120.f/255.f, 0.f/255.f, 1.0f);
+ else rgba_float_args_set(fcolor, 200.f/255.f, 200.f/255.f, 50.f/255.f, 1.0f); /* add theme! */
GPU_select_load_id(index & 0xFFFF);
pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES));
@@ -2038,7 +2248,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
else if (constflag & PCHAN_HAS_SPLINEIK) {
if (bone->flag & BONE_SELECTED) {
- glColor3ub(150, 200, 50); /* add theme! */
+ rgba_float_args_set(fcolor, 150.f/255.f, 200.f/255.f, 50.f/255.f, 1.0f); /* add theme! */
GPU_select_load_id(index & 0xFFFF);
pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES));
@@ -2047,9 +2257,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
}
- glPushMatrix();
+ gpuPushMatrix();
if (arm->drawtype != ARM_ENVELOPE)
- glMultMatrixf(pchan->pose_mat);
+ gpuMultMatrix(pchan->pose_mat);
/* catch exception for bone with hidden parent */
flag = bone->flag;
@@ -2086,7 +2296,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
else
draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -2106,7 +2316,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* draw DoFs */
if (arm->flag & ARM_POSEMODE) {
- if (((base->flag & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) {
+ if (((base->flag_legacy & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) {
draw_pose_dofs(ob);
}
}
@@ -2114,26 +2324,17 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* finally names and axes */
if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) &&
(is_outline == 0) &&
- ((base->flag & OB_FROMDUPLI) == 0))
+ ((base->flag_legacy & OB_FROMDUPLI) == 0))
{
/* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
if ((G.f & G_PICKSEL) == 0) {
float vec[3];
unsigned char col[4];
- if (do_const_color) {
- /* so we can draw bone names in current const color */
- float tcol[4];
- glGetFloatv(GL_CURRENT_COLOR, tcol);
- rgb_float_to_uchar(col, tcol);
- col[3] = 255;
- }
- else {
- col[0] = ob_wire_col[0];
- col[1] = ob_wire_col[1];
- col[2] = ob_wire_col[2];
- col[3] = 255;
- }
+ col[0] = ob_wire_col[0];
+ col[1] = ob_wire_col[1];
+ col[2] = ob_wire_col[2];
+ col[3] = 255;
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
@@ -2156,18 +2357,16 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* Draw additional axes on the bone tail */
if ((arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE)) {
- glPushMatrix();
+ gpuPushMatrix();
copy_m4_m4(bmat, pchan->pose_mat);
bone_matrix_translate_y(bmat, pchan->bone->length);
- glMultMatrixf(bmat);
+ gpuMultMatrix(bmat);
- glColor3ubv(col);
-
float viewmat_pchan[4][4];
mul_m4_m4m4(viewmat_pchan, rv3d->viewmatob, bmat);
- drawaxes(viewmat_pchan, pchan->bone->length * 0.25f, OB_ARROWS);
+ drawaxes(viewmat_pchan, pchan->bone->length * 0.25f, OB_ARROWS, col);
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -2233,9 +2432,9 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
- glPushMatrix();
+ gpuPushMatrix();
get_matrix_editbone(eBone, bmat);
- glMultMatrixf(bmat);
+ gpuMultMatrix(bmat);
/* catch exception for bone with hidden parent */
flag = eBone->flag;
@@ -2257,7 +2456,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
}
@@ -2295,9 +2494,9 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
}
else {
- glPushMatrix();
+ gpuPushMatrix();
get_matrix_editbone(eBone, bmat);
- glMultMatrixf(bmat);
+ gpuMultMatrix(bmat);
if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
@@ -2308,21 +2507,32 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
else
draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
- glPopMatrix();
+ gpuPopMatrix();
}
/* offset to parent */
if (eBone->parent) {
- UI_ThemeColor(TH_WIRE_EDIT);
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
GPU_select_load_id(-1); /* -1 here is OK! */
- setlinestyle(3);
-
- glBegin(GL_LINES);
- glVertex3fv(eBone->parent->tail);
- glVertex3fv(eBone->head);
- glEnd();
-
- setlinestyle(0);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformThemeColor(TH_WIRE_EDIT);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, eBone->parent->tail);
+ immVertex3fv(shdr_pos, eBone->head);
+ immEnd();
+
+ immUnbindProgram();
}
}
}
@@ -2364,18 +2574,16 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
}
/* Draw additional axes */
if (arm->flag & ARM_DRAWAXES) {
- glPushMatrix();
+ gpuPushMatrix();
get_matrix_editbone(eBone, bmat);
bone_matrix_translate_y(bmat, eBone->length);
- glMultMatrixf(bmat);
-
- glColor3ubv(col);
+ gpuMultMatrix(bmat);
float viewmat_ebone[4][4];
mul_m4_m4m4(viewmat_ebone, rv3d->viewmatob, bmat);
- drawaxes(viewmat_ebone, eBone->length * 0.25f, OB_ARROWS);
+ drawaxes(viewmat_ebone, eBone->length * 0.25f, OB_ARROWS, col);
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -2448,7 +2656,7 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
/* draw ghosts that occur within a frame range
* note: object should be in posemode
*/
-static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses_range(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
@@ -2456,6 +2664,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
bPose *posen, *poseo;
float start, end, stepsize, range, colfac;
int cfrao, flago;
+ unsigned char col[4];
start = (float)arm->ghostsf;
end = (float)arm->ghostef;
@@ -2488,11 +2697,11 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
/* draw from first frame of range to last */
for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) {
colfac = (end - (float)CFRA) / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2514,7 +2723,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
/* draw ghosts on keyframes in action within range
* - object should be in posemode
*/
-static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses_keys(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, BaseLegacy *base)
{
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
@@ -2525,6 +2734,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
ActKeyColumn *ak, *akn;
float start, end, range, colfac, i;
int cfrao, flago;
+ unsigned char col[4];
start = (float)arm->ghostsf;
end = (float)arm->ghostef;
@@ -2566,13 +2776,13 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
/* draw from first frame of range to last */
for (ak = keys.first, i = 0; ak; ak = ak->next, i++) {
colfac = i / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
CFRA = (int)ak->cfra;
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2595,7 +2805,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
/* draw ghosts around current frame
* - object is supposed to be armature in posemode
*/
-static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
@@ -2603,6 +2813,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
bPose *posen, *poseo;
float cur, start, end, stepsize, range, colfac, actframe, ctime;
int cfrao, flago;
+ unsigned char col[4];
/* pre conditions, get an action with sufficient frames */
if (ELEM(NULL, adt, adt->action))
@@ -2640,7 +2851,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
for (cur = stepsize; cur < range; cur += stepsize) {
ctime = cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */
colfac = ctime / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
/* only within action range */
if (actframe + ctime >= start && actframe + ctime <= end) {
@@ -2649,13 +2860,13 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
}
ctime = cur + (float)fmod((float)cfrao, stepsize) - stepsize + 1.0f; /* ensures consistent stepping */
colfac = ctime / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
+ UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
/* only within action range */
if ((actframe - ctime >= start) && (actframe - ctime <= end)) {
@@ -2664,7 +2875,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
BKE_pose_where_is(scene, ob);
- draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
+ draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
}
}
@@ -2689,7 +2900,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
/* called from drawobject.c, return true if nothing was drawn
* (ob_wire_col == NULL) when drawing ghost */
-bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
+bool draw_armature(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
const short dt, const short dflag, const unsigned char ob_wire_col[4],
const bool is_outline)
{
@@ -2700,11 +2911,7 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (v3d->flag2 & V3D_RENDER_OVERRIDE)
return true;
- /* needed for 'draw_line_bone' which draws pixel. */
- if (arm->drawtype == ARM_LINE) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- }
-
+#if 0 /* Not used until lighting is properly reimplemented */
if (dt > OB_WIRE) {
/* we use color for solid lighting */
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
@@ -2719,7 +2926,8 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); /* only for lighting... */
}
}
-
+#endif
+
/* arm->flag is being used to detect mode... */
/* editmode? */
if (arm->edbo) {
@@ -2736,7 +2944,7 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* drawing posemode selection indices or colors only in these cases */
- if (!(base->flag & OB_FROMDUPLI)) {
+ if (!(base->flag_legacy & OB_FROMDUPLI)) {
if (G.f & G_PICKSEL) {
#if 0
/* nifty but actually confusing to allow bone selection out of posemode */
@@ -2752,31 +2960,28 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
else if (ob->mode & OB_MODE_POSE) {
if (arm->ghosttype == ARM_GHOST_RANGE) {
- draw_ghost_poses_range(scene, v3d, ar, base);
+ draw_ghost_poses_range(scene, sl, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_KEYS) {
- draw_ghost_poses_keys(scene, v3d, ar, base);
+ draw_ghost_poses_keys(scene, sl, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_CUR) {
if (arm->ghostep)
- draw_ghost_poses(scene, v3d, ar, base);
+ draw_ghost_poses(scene, sl, v3d, ar, base);
}
if ((dflag & DRAW_SCENESET) == 0) {
- if (ob == OBACT)
+ if (ob == OBACT_NEW)
arm->flag |= ARM_POSEMODE;
- else if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
- if (ob == modifiers_isDeformedByArmature(OBACT))
+ else if (OBACT_NEW && (OBACT_NEW->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (ob == modifiers_isDeformedByArmature(OBACT_NEW))
arm->flag |= ARM_POSEMODE;
}
draw_pose_paths(scene, v3d, ar, ob);
}
}
}
- draw_pose_bones(scene, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
+ draw_pose_bones(scene, sl, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
arm->flag &= ~ARM_POSEMODE;
-
- if (ob->mode & OB_MODE_POSE)
- UI_ThemeColor(TH_WIRE); /* restore, for extra draw stuff */
}
else {
retval = true;
@@ -2785,9 +2990,5 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* restore */
glFrontFace(GL_CCW);
- if (arm->drawtype == ARM_LINE) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- }
-
return retval;
}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index ecbfd5c7c85..719fb6f764f 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -55,7 +55,6 @@
#include "BKE_editmesh.h"
#include "BKE_scene.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "UI_resources.h"
@@ -64,6 +63,7 @@
#include "GPU_material.h"
#include "GPU_basic_shader.h"
#include "GPU_shader.h"
+#include "GPU_matrix.h"
#include "RE_engine.h"
@@ -77,20 +77,6 @@ typedef struct drawMeshFaceSelect_userData {
BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */
} drawMeshFaceSelect_userData;
-typedef struct drawEMTFMapped_userData {
- BMEditMesh *em;
- bool has_mcol;
- int cd_poly_tex_offset;
- const MPoly *mpoly;
- const MTexPoly *mtexpoly;
-} drawEMTFMapped_userData;
-
-typedef struct drawTFace_userData {
- const Mesh *me;
- const MPoly *mpoly;
- const MTexPoly *mtexpoly;
-} drawTFace_userData;
-
/**************************** Face Select Mode *******************************/
/* mainly to be less confusing */
@@ -213,560 +199,6 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool d
/***************************** Texture Drawing ******************************/
-static Material *give_current_material_or_def(Object *ob, int matnr)
-{
- extern Material defmaterial; /* render module abuse... */
- Material *ma = give_current_material(ob, matnr);
-
- return ma ? ma : &defmaterial;
-}
-
-/* Icky globals, fix with userdata parameter */
-
-static struct TextureDrawState {
- Object *ob;
- Image *stencil; /* texture painting stencil */
- Image *canvas; /* texture painting canvas, for image mode */
- bool use_game_mat;
- int is_lit, is_tex;
- int color_profile;
- bool use_backface_culling;
- bool two_sided_lighting;
- unsigned char obcol[4];
- bool is_texpaint;
- bool texpaint_material; /* use material slots for texture painting */
-} Gtexdraw = {NULL, NULL, NULL, false, 0, 0, 0, false, false, {0, 0, 0, 0}, false, false};
-
-static bool set_draw_settings_cached(
- int clearcache, MTexPoly *texface, Material *ma,
- const struct TextureDrawState *gtexdraw)
-{
- static Material *c_ma;
- static int c_textured;
- static MTexPoly c_texface;
- static int c_backculled;
- static bool c_badtex;
- static int c_lit;
- static int c_has_texface;
-
- int backculled = 1;
- int alphablend = GPU_BLEND_SOLID;
- int textured = 0;
- int lit = 0;
- int has_texface = texface != NULL;
- bool need_set_tpage = false;
- bool texpaint = ((gtexdraw->ob->mode & OB_MODE_TEXTURE_PAINT) != 0);
-
- Image *ima = NULL;
-
- if (ma != NULL) {
- if (ma->mode & MA_TRANSP) {
- alphablend = GPU_BLEND_ALPHA;
- }
- }
-
- if (clearcache) {
- c_textured = c_lit = c_backculled = -1;
- memset(&c_texface, 0, sizeof(c_texface));
- c_badtex = false;
- c_has_texface = -1;
- c_ma = NULL;
- }
- else {
- textured = gtexdraw->is_tex;
- }
-
- /* convert number of lights into boolean */
- if (gtexdraw->is_lit) {
- lit = 1;
- }
-
- backculled = gtexdraw->use_backface_culling;
- if (ma) {
- if (ma->mode & MA_SHLESS) lit = 0;
- if (gtexdraw->use_game_mat) {
- backculled = backculled || (ma->game.flag & GEMAT_BACKCULL);
- alphablend = ma->game.alpha_blend;
- }
- }
-
- if (texface && !texpaint) {
- textured = textured && (texface->tpage);
-
- /* no material, render alpha if texture has depth=32 */
- if (!ma && BKE_image_has_alpha(texface->tpage))
- alphablend = GPU_BLEND_ALPHA;
- }
- else if (texpaint) {
- if (gtexdraw->texpaint_material)
- ima = ma && ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
- else
- ima = gtexdraw->canvas;
- }
- else
- textured = 0;
-
- if (backculled != c_backculled) {
- if (backculled) glEnable(GL_CULL_FACE);
- else glDisable(GL_CULL_FACE);
-
- c_backculled = backculled;
- }
-
- /* need to re-set tpage if textured flag changed or existsment of texface changed.. */
- need_set_tpage = textured != c_textured || has_texface != c_has_texface;
- /* ..or if settings inside texface were changed (if texface was used) */
- need_set_tpage |= (texpaint && c_ma != ma) || (texface && memcmp(&c_texface, texface, sizeof(c_texface)));
-
- if (need_set_tpage) {
- if (textured) {
- if (texpaint) {
- c_badtex = false;
- if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, 0, 1, 0, false)) {
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
-
- glActiveTexture(GL_TEXTURE1);
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
- glActiveTexture(GL_TEXTURE0);
- }
- else {
- glActiveTexture(GL_TEXTURE1);
- glDisable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, 0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glActiveTexture(GL_TEXTURE0);
-
- c_badtex = true;
- GPU_clear_tpage(true);
- glDisable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, 0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- }
- else {
- c_badtex = !GPU_set_tpage(texface, !texpaint, alphablend);
- }
- }
- else {
- GPU_set_tpage(NULL, 0, 0);
- c_badtex = false;
- }
- c_textured = textured;
- c_has_texface = has_texface;
- if (texface)
- memcpy(&c_texface, texface, sizeof(c_texface));
- }
-
- if (c_badtex) lit = 0;
- if (lit != c_lit || ma != c_ma || textured != c_textured) {
- int options = GPU_SHADER_USE_COLOR;
-
- if (c_textured && !c_badtex) {
- options |= GPU_SHADER_TEXTURE_2D;
- }
- if (gtexdraw->two_sided_lighting) {
- options |= GPU_SHADER_TWO_SIDED;
- }
-
- if (lit) {
- options |= GPU_SHADER_LIGHTING;
- if (!ma)
- ma = give_current_material_or_def(NULL, 0); /* default material */
-
- float specular[3];
- mul_v3_v3fl(specular, &ma->specr, ma->spec);
-
- GPU_basic_shader_colors(NULL, specular, ma->har, 1.0f);
- }
-
- GPU_basic_shader_bind(options);
-
- c_lit = lit;
- c_ma = ma;
- }
-
- return c_badtex;
-}
-
-static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
-{
- unsigned char obcol[4];
- bool is_tex, solidtex;
- Mesh *me = ob->data;
- ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
-
- /* XXX scene->obedit warning */
-
- /* texture draw is abused for mask selection mode, do this so wire draw
- * with face selection in weight paint is not lit. */
- if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
- solidtex = false;
- Gtexdraw.is_lit = 0;
- }
- else if ((ob->mode & OB_MODE_TEXTURE_PAINT) && BKE_scene_use_new_shading_nodes(scene)) {
- solidtex = true;
- if (v3d->flag2 & V3D_SHADELESS_TEX)
- Gtexdraw.is_lit = 0;
- else
- Gtexdraw.is_lit = -1;
- }
- else if ((v3d->drawtype == OB_SOLID) ||
- ((ob->mode & OB_MODE_EDIT) && (v3d->drawtype != OB_TEXTURE)))
- {
- /* draw with default lights in solid draw mode and edit mode */
- solidtex = true;
- Gtexdraw.is_lit = -1;
- }
- else {
- /* draw with lights in the scene otherwise */
- solidtex = false;
- if (v3d->flag2 & V3D_SHADELESS_TEX) {
- Gtexdraw.is_lit = 0;
- }
- else {
- Gtexdraw.is_lit = GPU_scene_object_lights(
- scene, ob, v3d->localvd ? v3d->localvd->lay : v3d->lay,
- rv3d->viewmat, !rv3d->is_persp);
- }
- }
-
- rgba_float_to_uchar(obcol, ob->col);
-
- if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = true;
- else is_tex = false;
-
- Gtexdraw.ob = ob;
- Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
- Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
- Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
- Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
- Gtexdraw.is_tex = is_tex;
-
- /* naughty multitexturing hacks to quickly support stencil + shading + alpha blending
- * in new texpaint code. The better solution here would be to support GLSL */
- if (Gtexdraw.is_texpaint) {
- glActiveTexture(GL_TEXTURE1);
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
-
- /* load the stencil texture here */
- if (Gtexdraw.stencil != NULL) {
- glActiveTexture(GL_TEXTURE2);
- if (GPU_verify_image(Gtexdraw.stencil, NULL, GL_TEXTURE_2D, false, false, false, false)) {
- float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col);
- if ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) == 0) {
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
- }
- else {
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
- }
- }
- }
- glActiveTexture(GL_TEXTURE0);
- }
-
- Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
- Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
- Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
- Gtexdraw.two_sided_lighting = (me->flag & ME_TWOSIDED);
-
- memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
- set_draw_settings_cached(1, NULL, NULL, &Gtexdraw);
- glCullFace(GL_BACK);
-}
-
-static void draw_textured_end(void)
-{
- if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) {
- glActiveTexture(GL_TEXTURE1);
- glDisable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- if (Gtexdraw.stencil != NULL) {
- glActiveTexture(GL_TEXTURE2);
- glDisable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
- glActiveTexture(GL_TEXTURE0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- /* manual reset, since we don't use tpage */
- glBindTexture(GL_TEXTURE_2D, 0);
- /* force switch off textures */
- GPU_clear_tpage(true);
- }
- else {
- /* switch off textures */
- GPU_set_tpage(NULL, 0, 0);
- }
-
- glDisable(GL_CULL_FACE);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
- /* XXX, bad patch - GPU_default_lights() calls
- * glLightfv(GL_POSITION, ...) which
- * is transformed by the current matrix... we
- * need to make sure that matrix is identity.
- *
- * It would be better if drawmesh.c kept track
- * of and restored the light settings it changed.
- * - zr
- */
- glPushMatrix();
- glLoadIdentity();
- GPU_default_lights();
- glPopMatrix();
-}
-
-static DMDrawOption draw_tface__set_draw_legacy(MTexPoly *mtexpoly, const bool has_mcol, int matnr)
-{
- Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
- bool invalidtexture = false;
-
- if (ma && (ma->game.flag & GEMAT_INVISIBLE))
- return DM_DRAW_OPTION_SKIP;
-
- invalidtexture = set_draw_settings_cached(0, mtexpoly, ma, &Gtexdraw);
-
- if (mtexpoly && invalidtexture) {
- glColor3ub(0xFF, 0x00, 0xFF);
- return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
- }
- else if (!has_mcol) {
- if (mtexpoly) {
- glColor3f(1.0, 1.0, 1.0);
- }
- else {
- if (ma) {
- if (ma->shade_flag & MA_OBCOLOR) {
- glColor3ubv(Gtexdraw.obcol);
- }
- else {
- float col[3];
- if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
- else copy_v3_v3(col, &ma->r);
-
- glColor3fv(col);
- }
- }
- else {
- glColor3f(1.0, 1.0, 1.0);
- }
- }
- return DM_DRAW_OPTION_NORMAL; /* normal drawing (no mcols anyway, no need to turn off) */
- }
- else {
- return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
- }
-}
-
-static DMDrawOption draw_tface__set_draw(MTexPoly *mtexpoly, const bool UNUSED(has_mcol), int matnr)
-{
- Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
-
- if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return DM_DRAW_OPTION_SKIP;
-
- if (mtexpoly || Gtexdraw.is_texpaint)
- set_draw_settings_cached(0, mtexpoly, ma, &Gtexdraw);
-
- /* always use color from mcol, as set in update_tface_color_layer */
- return DM_DRAW_OPTION_NORMAL;
-}
-
-static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
-{
- const MPoly *mp = dm->getPolyArray(dm);
- const int mpoly_num = dm->getNumPolys(dm);
- MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
- MLoopCol *finalCol;
- int i, j;
- MLoopCol *mloopcol = NULL;
-
- /* cache material values to avoid a lot of lookups */
- Material *ma = NULL;
- short mat_nr_prev = -1;
- enum {
- COPY_CALC,
- COPY_ORIG,
- COPY_PREV,
- } copy_mode = COPY_CALC;
-
- if (use_mcol) {
- mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL);
- if (!mloopcol)
- mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL);
- }
-
- if (CustomData_has_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL)) {
- finalCol = CustomData_get_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL);
- }
- else {
- finalCol = MEM_mallocN(sizeof(MLoopCol) * dm->numLoopData, "add_tface_color_layer");
- CustomData_add_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL, CD_ASSIGN, finalCol, dm->numLoopData);
- }
-
- for (i = mpoly_num; i--; mp++) {
- const short mat_nr = mp->mat_nr;
-
- if (UNLIKELY(mat_nr_prev != mat_nr)) {
- ma = give_current_material(Gtexdraw.ob, mat_nr + 1);
- copy_mode = COPY_CALC;
- mat_nr_prev = mat_nr;
- }
-
- /* avoid lookups */
- if (copy_mode == COPY_ORIG) {
- memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
- }
- else if (copy_mode == COPY_PREV) {
- int loop_index = mp->loopstart;
- const MLoopCol *lcol_prev = &finalCol[(mp - 1)->loopstart];
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- finalCol[loop_index] = *lcol_prev;
- }
- }
-
- /* (copy_mode == COPY_CALC) */
- else if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
- if (mloopcol) {
- memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_ORIG;
- }
- else {
- memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_PREV;
- }
- }
- else if (mtexpoly && set_draw_settings_cached(0, mtexpoly, ma, &Gtexdraw)) {
- int loop_index = mp->loopstart;
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- finalCol[loop_index].r = 255;
- finalCol[loop_index].g = 0;
- finalCol[loop_index].b = 255;
- }
- copy_mode = COPY_PREV;
- }
- else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
- int loop_index = mp->loopstart;
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- copy_v3_v3_uchar(&finalCol[loop_index].r, Gtexdraw.obcol);
- }
- copy_mode = COPY_PREV;
- }
- else {
- if (mloopcol) {
- memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_ORIG;
- }
- else if (mtexpoly) {
- memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
- copy_mode = COPY_PREV;
- }
- else {
- float col[3];
-
- if (ma) {
- int loop_index = mp->loopstart;
- MLoopCol lcol;
-
- if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
- else copy_v3_v3(col, &ma->r);
- rgb_float_to_uchar((unsigned char *)&lcol.r, col);
- lcol.a = 255;
-
- for (j = 0; j < mp->totloop; j++, loop_index++) {
- finalCol[loop_index] = lcol;
- }
- }
- else {
- memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
- }
- copy_mode = COPY_PREV;
- }
- }
- }
-
- dm->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW;
-}
-
-static DMDrawOption draw_tface_mapped__set_draw(void *userData, int origindex, int UNUSED(mat_nr))
-{
- const Mesh *me = ((drawTFace_userData *)userData)->me;
-
- /* array checked for NULL before calling */
- MPoly *mpoly = &me->mpoly[origindex];
-
- BLI_assert(origindex >= 0 && origindex < me->totpoly);
-
- if (mpoly->flag & ME_HIDE) {
- return DM_DRAW_OPTION_SKIP;
- }
- else {
- MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[origindex] : NULL;
- int matnr = mpoly->mat_nr;
-
- return draw_tface__set_draw(tpoly, (me->mloopcol != NULL), matnr);
- }
-}
-
-static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int origindex, int mat_nr)
-{
- drawEMTFMapped_userData *data = userData;
- BMEditMesh *em = data->em;
- BMFace *efa;
-
- if (UNLIKELY(origindex >= em->bm->totface))
- return DM_DRAW_OPTION_NORMAL;
-
- efa = BM_face_at_index(em->bm, origindex);
-
- if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- return DM_DRAW_OPTION_SKIP;
- }
- else {
- MTexPoly *mtexpoly = (data->cd_poly_tex_offset != -1) ?
- BM_ELEM_CD_GET_VOID_P(efa, data->cd_poly_tex_offset) : NULL;
- int matnr = (mat_nr != -1) ? mat_nr : efa->mat_nr;
-
- return draw_tface__set_draw_legacy(mtexpoly, data->has_mcol, matnr);
- }
-}
-
/* when face select is on, use face hidden flag */
static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index)
{
@@ -777,288 +209,6 @@ static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int ind
return DM_DRAW_OPTION_NORMAL;
}
-static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
-{
- Mesh *me = ob->data;
- DerivedMesh *ddm;
- MPoly *mp, *mface = me->mpoly;
- MTexPoly *mtpoly = me->mtpoly;
- MLoopUV *mloopuv = me->mloopuv;
- MLoopUV *luv;
- MLoopCol *mloopcol = me->mloopcol; /* why does mcol exist? */
- MLoopCol *lcol;
-
- bProperty *prop = BKE_bproperty_object_get(ob, "Text");
- GPUVertexAttribs gattribs;
- int a, totpoly = me->totpoly;
-
- /* fake values to pass to GPU_render_text() */
- MCol tmp_mcol[4] = {{0}};
- MCol *tmp_mcol_pt = mloopcol ? tmp_mcol : NULL;
-
- /* don't draw without tfaces */
- if (!mtpoly || !mloopuv)
- return;
-
- /* don't draw when editing */
- if (ob->mode & OB_MODE_EDIT)
- return;
- else if (ob == OBACT)
- if (BKE_paint_select_elem_test(ob))
- return;
-
- ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
-
- for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
- short matnr = mp->mat_nr;
- const bool mf_smooth = (mp->flag & ME_SMOOTH) != 0;
- Material *mat = (me->mat) ? me->mat[matnr] : NULL;
- int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;
-
-
- if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) {
- /* get the polygon as a tri/quad */
- int mp_vi[4];
- float v_quad_data[4][3];
- const float *v_quad[4];
- const float *uv_quad[4];
- char string[MAX_PROPSTRING];
- int characters, i, glattrib = -1, badtex = 0;
-
-
- /* TEXFACE */
- if (glsl) {
- GPU_object_material_bind(matnr + 1, &gattribs);
-
- for (i = 0; i < gattribs.totlayer; i++) {
- if (gattribs.layer[i].type == CD_MTFACE) {
- glattrib = gattribs.layer[i].glindex;
- break;
- }
- }
- }
- else {
- badtex = set_draw_settings_cached(0, mtpoly, mat, &Gtexdraw);
- if (badtex) {
- continue;
- }
- }
-
- mp_vi[0] = me->mloop[mp->loopstart + 0].v;
- mp_vi[1] = me->mloop[mp->loopstart + 1].v;
- mp_vi[2] = me->mloop[mp->loopstart + 2].v;
- mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0;
-
- /* UV */
- luv = &mloopuv[mp->loopstart];
- uv_quad[0] = luv->uv; luv++;
- uv_quad[1] = luv->uv; luv++;
- uv_quad[2] = luv->uv; luv++;
- if (mp->totloop >= 4) {
- uv_quad[3] = luv->uv;
- }
- else {
- uv_quad[3] = NULL;
- }
-
-
- /* COLOR */
- if (mloopcol) {
- unsigned int totloop_clamp = min_ii(4, mp->totloop);
- unsigned int j;
- lcol = &mloopcol[mp->loopstart];
-
- for (j = 0; j < totloop_clamp; j++, lcol++) {
- MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]);
- }
- }
-
- /* LOCATION */
- ddm->getVertCo(ddm, mp_vi[0], v_quad_data[0]);
- ddm->getVertCo(ddm, mp_vi[1], v_quad_data[1]);
- ddm->getVertCo(ddm, mp_vi[2], v_quad_data[2]);
- if (mp->totloop >= 4) {
- ddm->getVertCo(ddm, mp_vi[3], v_quad_data[3]);
- }
-
- v_quad[0] = v_quad_data[0];
- v_quad[1] = v_quad_data[1];
- v_quad[2] = v_quad_data[2];
- if (mp->totloop >= 4) {
- v_quad[3] = v_quad_data[2];
- }
- else {
- v_quad[3] = NULL;
- }
-
-
- /* The BM_FONT handling is in the gpu module, shared with the
- * game engine, was duplicated previously */
-
- BKE_bproperty_set_valstr(prop, string);
- characters = strlen(string);
-
- if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
- characters = 0;
-
- if (!mf_smooth) {
- float nor[3];
-
- normal_tri_v3(nor, v_quad[0], v_quad[1], v_quad[2]);
-
- glNormal3fv(nor);
- }
-
- GPU_render_text(
- mtpoly, mode, string, characters,
- (unsigned int *)tmp_mcol_pt,
- v_quad, uv_quad,
- glattrib);
- }
- }
-
- ddm->release(ddm);
-}
-
-static int compareDrawOptions(void *userData, int cur_index, int next_index)
-{
- drawTFace_userData *data = userData;
-
- if (data->mpoly && data->mpoly[cur_index].mat_nr != data->mpoly[next_index].mat_nr)
- return 0;
-
- if (data->mtexpoly && data->mtexpoly[cur_index].tpage != data->mtexpoly[next_index].tpage)
- return 0;
-
- return 1;
-}
-
-
-static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
-{
- drawEMTFMapped_userData *data = userData;
-
- if (data->mpoly && data->mpoly[cur_index].mat_nr != data->mpoly[next_index].mat_nr)
- return 0;
-
- if (data->mtexpoly && data->mtexpoly[cur_index].tpage != data->mtexpoly[next_index].tpage)
- return 0;
-
- return 1;
-}
-
-static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Object *ob, DerivedMesh *dm, const int draw_flags)
-{
- Mesh *me = ob->data;
-
- /* correct for negative scale */
- if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
- else glFrontFace(GL_CCW);
-
- /* draw the textured mesh */
- draw_textured_begin(scene, v3d, rv3d, ob);
-
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- if (ob->mode & OB_MODE_EDIT) {
- drawEMTFMapped_userData data;
-
- data.em = me->edit_btmesh;
- data.has_mcol = CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
- data.cd_poly_tex_offset = CustomData_get_offset(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
-
- data.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
- data.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
-
- dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0);
- }
- else {
- DMDrawFlag dm_draw_flag;
- drawTFace_userData userData;
-
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- dm_draw_flag = DM_DRAW_USE_TEXPAINT_UV;
- }
- else {
- dm_draw_flag = DM_DRAW_USE_ACTIVE_UV;
- }
-
- if (ob == OBACT) {
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
- dm_draw_flag |= DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH | DM_DRAW_SKIP_HIDDEN;
- }
- else if (ob->mode & OB_MODE_SCULPT) {
- dm_draw_flag |= DM_DRAW_SKIP_HIDDEN | DM_DRAW_USE_COLORS;
- }
- else if ((ob->mode & OB_MODE_TEXTURE_PAINT) == 0) {
- dm_draw_flag |= DM_DRAW_USE_COLORS;
- }
- }
- else {
- if ((ob->mode & OB_MODE_TEXTURE_PAINT) == 0) {
- dm_draw_flag |= DM_DRAW_USE_COLORS;
- }
- }
-
-
- userData.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
- userData.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
-
- if (draw_flags & DRAW_FACE_SELECT) {
- userData.me = me;
-
- dm->drawMappedFacesTex(
- dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions,
- &userData, dm_draw_flag);
- }
- else {
- userData.me = NULL;
-
- /* if ((ob->mode & OB_MODE_ALL_PAINT) == 0) */ {
-
- /* Note: this isn't efficient and runs on every redraw,
- * its needed so material colors are used for vertex colors.
- * In the future we will likely remove 'texface' so, just avoid running this where possible,
- * (when vertex paint or weight paint are used).
- *
- * Note 2: We disable optimization for now since it causes T48788
- * and it is now too close to release to do something smarter.
- *
- * TODO(sergey): Find some real solution here.
- */
-
- update_tface_color_layer(dm, !(ob->mode & OB_MODE_TEXTURE_PAINT));
- }
-
- dm->drawFacesTex(
- dm, draw_tface__set_draw, compareDrawOptions,
- &userData, dm_draw_flag);
- }
- }
-
- /* draw game engine text hack */
- if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- if (BKE_bproperty_object_get(ob, "Text")) {
- draw_mesh_text(scene, ob, 0);
- }
- }
-
- draw_textured_end();
-
- /* draw edges and selected faces over textured mesh */
- if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
- bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
- draw_mesh_face_select(rv3d, me, dm, draw_select_edges);
- }
-
- /* reset from negative scale correction */
- glFrontFace(GL_CCW);
-
- /* in editmode, the blend mode needs to be set in case it was ADD */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
/************************** NEW SHADING NODES ********************************/
typedef struct TexMatCallback {
@@ -1070,187 +220,11 @@ typedef struct TexMatCallback {
bool two_sided_lighting;
} TexMatCallback;
-static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
-{
- /* all we have to do here is simply enable the GLSL material, but note
- * that the GLSL code will give different result depending on the drawtype,
- * in texture draw mode it will output the active texture node, in material
- * draw mode it will show the full material. */
- GPU_object_material_bind(mat_nr, attribs);
-}
-
-static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
-{
- /* texture draw mode without GLSL */
- TexMatCallback *data = (TexMatCallback *)userData;
- GPUVertexAttribs *gattribs = attribs;
- Image *ima;
- ImageUser *iuser;
- bNode *node;
-
- /* draw image texture if we find one */
- if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) {
- /* get openl texture */
- int mipmap = 1;
- int bindcode = (ima) ? GPU_verify_image(ima, iuser, GL_TEXTURE_2D, 0, 0, mipmap, false) : 0;
-
- if (bindcode) {
- NodeTexBase *texbase = node->storage;
-
- /* disable existing material */
- GPU_object_material_unbind();
-
- /* bind texture */
- glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
-
- glMatrixMode(GL_TEXTURE);
- glLoadMatrixf(texbase->tex_mapping.mat);
- glMatrixMode(GL_MODELVIEW);
-
- /* use active UV texture layer */
- memset(gattribs, 0, sizeof(*gattribs));
-
- gattribs->layer[0].type = CD_MTFACE;
- gattribs->layer[0].name[0] = '\0';
- gattribs->layer[0].gltexco = 1;
- gattribs->totlayer = 1;
-
- /* bind material */
- float diffuse[3] = {1.0f, 1.0f, 1.0f};
-
- int options = GPU_SHADER_TEXTURE_2D;
- if (!data->shadeless)
- options |= GPU_SHADER_LIGHTING;
- if (data->two_sided_lighting)
- options |= GPU_SHADER_TWO_SIDED;
-
- GPU_basic_shader_colors(diffuse, NULL, 0, 1.0f);
- GPU_basic_shader_bind(options);
-
- return;
- }
- }
-
- /* disable texture material */
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
- if (data->shadeless) {
- glColor3f(1.0f, 1.0f, 1.0f);
- memset(gattribs, 0, sizeof(*gattribs));
- }
- else {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- /* enable solid material */
- GPU_object_material_bind(mat_nr, attribs);
- }
-}
-
-static bool tex_mat_set_face_mesh_cb(void *userData, int index)
-{
- /* faceselect mode face hiding */
- TexMatCallback *data = (TexMatCallback *)userData;
- Mesh *me = (Mesh *)data->me;
- MPoly *mp = &me->mpoly[index];
-
- return !(mp->flag & ME_HIDE);
-}
-
-static bool tex_mat_set_face_editmesh_cb(void *userData, int index)
-{
- /* editmode face hiding */
- TexMatCallback *data = (TexMatCallback *)userData;
- Mesh *me = (Mesh *)data->me;
- BMEditMesh *em = me->edit_btmesh;
- BMFace *efa;
-
- if (UNLIKELY(index >= em->bm->totface))
- return DM_DRAW_OPTION_NORMAL;
-
- efa = BM_face_at_index(em->bm, index);
-
- return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
-}
-
-void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
+void draw_mesh_textured(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
Object *ob, DerivedMesh *dm, const int draw_flags)
{
- /* if not cycles, or preview-modifiers, or drawing matcaps */
- if ((draw_flags & DRAW_MODIFIERS_PREVIEW) ||
- (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) ||
- (BKE_scene_use_new_shading_nodes(scene) == false) ||
- ((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID)))
- {
- draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
- return;
- }
- else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
- draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
- return;
- }
-
- /* set opengl state for negative scale & color */
- if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
- else glFrontFace(GL_CCW);
-
- Mesh *me = ob->data;
-
- bool shadeless = ((v3d->flag2 & V3D_SHADELESS_TEX) &&
- ((v3d->drawtype == OB_TEXTURE) || (ob->mode & OB_MODE_TEXTURE_PAINT)));
- bool two_sided_lighting = (me->flag & ME_TWOSIDED) != 0;
-
- TexMatCallback data = {scene, ob, me, dm, shadeless, two_sided_lighting};
- bool (*set_face_cb)(void *, int);
- bool picking = (G.f & G_PICKSEL) != 0;
-
- /* face hiding callback depending on mode */
- if (ob == scene->obedit)
- set_face_cb = tex_mat_set_face_editmesh_cb;
- else if (draw_flags & DRAW_FACE_SELECT)
- set_face_cb = tex_mat_set_face_mesh_cb;
- else
- set_face_cb = NULL;
-
- /* test if we can use glsl */
- const int drawtype = view3d_effective_drawtype(v3d);
- bool glsl = (drawtype == OB_MATERIAL) && !picking;
-
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
-
- if (glsl || picking) {
- /* draw glsl or solid */
- dm->drawMappedFacesMat(dm,
- tex_mat_set_material_cb,
- set_face_cb, &data);
- }
- else {
- /* draw textured */
- dm->drawMappedFacesMat(dm,
- tex_mat_set_texture_cb,
- set_face_cb, &data);
- }
-
- GPU_end_object_materials();
-
- /* reset opengl state */
- GPU_end_object_materials();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- glFrontFace(GL_CCW);
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- /* faceselect mode drawing over textured mesh */
- if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
- bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
- draw_mesh_face_select(rv3d, ob->data, dm, draw_select_edges);
- }
+ UNUSED_VARS(scene, sl, v3d, rv3d, ob, dm, draw_flags);
+ return;
}
/* Vertex Paint and Weight Paint */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 884bc6b83ba..7bb95ba6d15 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -62,6 +62,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -90,6 +91,10 @@
#include "GPU_select.h"
#include "GPU_basic_shader.h"
#include "GPU_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_batch.h"
+#include "GPU_matrix.h"
#include "ED_mesh.h"
#include "ED_particle.h"
@@ -105,6 +110,11 @@
#include "view3d_intern.h" /* bad level include */
+#include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */
+
+/* prototypes */
+static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos);
+
/* Workaround for sequencer scene render mode.
*
* Strips doesn't use DAG to update objects or so, which
@@ -129,6 +139,7 @@ typedef struct drawDMVerts_userData {
BMVert *eve_act;
char sel;
+ unsigned int pos, color;
/* cached theme values */
unsigned char th_editmesh_active[4];
@@ -181,6 +192,7 @@ typedef struct drawDMFacesSel_userData {
} drawDMFacesSel_userData;
typedef struct drawDMNormal_userData {
+ unsigned int pos;
BMesh *bm;
int uniform_scale;
float normalsize;
@@ -189,6 +201,7 @@ typedef struct drawDMNormal_userData {
} drawDMNormal_userData;
typedef struct drawMVertOffset_userData {
+ unsigned int pos, col;
MVert *mvert;
int offset;
} drawMVertOffset_userData;
@@ -196,9 +209,11 @@ typedef struct drawMVertOffset_userData {
typedef struct drawDMLayer_userData {
BMesh *bm;
int cd_layer_offset;
+ unsigned int pos, col;
} drawDMLayer_userData;
typedef struct drawBMOffset_userData {
+ unsigned int pos, col;
BMesh *bm;
int offset;
} drawBMOffset_userData;
@@ -206,25 +221,23 @@ typedef struct drawBMOffset_userData {
typedef struct drawBMSelect_userData {
BMesh *bm;
bool select;
+ unsigned int pos;
} drawBMSelect_userData;
-static void draw_bounding_volume(Object *ob, char type);
-static void drawcube_size(float size);
-static void drawcircle_size(float size);
-static void draw_empty_sphere(float size);
-static void draw_empty_cone(float size);
-static void draw_box(const float vec[8][3], bool solid);
+static void drawcube_size(float size, unsigned pos);
+static void drawcircle_size(float size, unsigned pos);
+static void draw_empty_sphere(float size, unsigned pos);
+static void draw_empty_cone(float size, unsigned pos);
-static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac)
+static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac, float r_col[3])
{
- float col_wire[3], col_bg[3], col[3];
+ float col_wire[3], col_bg[3];
rgb_uchar_to_float(col_wire, ob_wire_col);
UI_GetThemeColor3fv(theme_id, col_bg);
- interp_v3_v3v3(col, col_bg, col_wire, fac);
- glColor3fv(col);
+ interp_v3_v3v3(r_col, col_bg, col_wire, fac);
}
int view3d_effective_drawtype(const struct View3D *v3d)
@@ -296,13 +309,13 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
/* check for glsl drawing */
-bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
+bool draw_glsl_material(Scene *scene, SceneLayer *sl, Object *ob, View3D *v3d, const char dt)
{
if (G.f & G_PICKSEL)
return false;
if (!check_object_draw_texture(scene, v3d, dt))
return false;
- if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
+ if (ob == OBACT_NEW && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
return false;
if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
@@ -318,7 +331,7 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
static bool check_alpha_pass(Base *base)
{
- if (base->flag & OB_FROMDUPLI)
+ if (base->flag_legacy & OB_FROMDUPLI)
return false;
if (G.f & G_PICKSEL)
@@ -414,9 +427,9 @@ static const float cosval[CIRCLE_RESOL] = {
* \param viewmat_local_unit is typically the 'rv3d->viewmatob'
* copied into a 3x3 matrix and normalized.
*/
-static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
+static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis, unsigned pos)
{
- int line_type;
+ PrimitiveType line_type = PRIM_LINES;
float buffer[4][3];
int n = 0;
@@ -429,8 +442,6 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
switch (axis) {
case 0: /* x axis */
- line_type = GL_LINES;
-
/* bottom left to top right */
negate_v3_v3(v1, dx);
sub_v3_v3(v1, dy);
@@ -450,8 +461,6 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
break;
case 1: /* y axis */
- line_type = GL_LINES;
-
/* bottom left to top right */
mul_v3_fl(dx, 0.75f);
negate_v3_v3(v1, dx);
@@ -472,7 +481,7 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
break;
case 2: /* z axis */
- line_type = GL_LINE_STRIP;
+ line_type = PRIM_LINE_STRIP;
/* start at top left */
negate_v3_v3(v1, dx);
@@ -501,54 +510,60 @@ static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3]
return;
}
+ immBegin(line_type, n);
for (int i = 0; i < n; i++) {
mul_transposed_m3_v3((float (*)[3])viewmat_local_unit, buffer[i]);
add_v3_v3(buffer[i], c);
+ immVertex3fv(pos, buffer[i]);
}
+ immEnd();
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, buffer);
- glDrawArrays(line_type, 0, n);
- glDisableClientState(GL_VERTEX_ARRAY);
+ /* TODO: recode this function for clarity once we're not in a hurry to modernize GL usage */
}
-void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
+void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4])
{
int axis;
float v1[3] = {0.0, 0.0, 0.0};
float v2[3] = {0.0, 0.0, 0.0};
float v3[3] = {0.0, 0.0, 0.0};
- glLineWidth(1);
+ glLineWidth(1.0f);
- switch (drawtype) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ if (color) {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4ubv(color);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+ }
+ switch (drawtype) {
case OB_PLAINAXES:
+ immBegin(PRIM_LINES, 6);
for (axis = 0; axis < 3; axis++) {
- glBegin(GL_LINES);
-
v1[axis] = size;
v2[axis] = -size;
- glVertex3fv(v1);
- glVertex3fv(v2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
/* reset v1 & v2 to zero */
v1[axis] = v2[axis] = 0.0f;
-
- glEnd();
}
+ immEnd();
break;
- case OB_SINGLE_ARROW:
- glBegin(GL_LINES);
+ case OB_SINGLE_ARROW:
+ immBegin(PRIM_LINES, 2);
/* in positive z direction only */
v1[2] = size;
- glVertex3fv(v1);
- glVertex3fv(v2);
- glEnd();
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immEnd();
/* square pyramid */
- glBegin(GL_TRIANGLES);
+ immBegin(PRIM_TRIANGLES, 12);
v2[0] = size * 0.035f; v2[1] = size * 0.035f;
v3[0] = size * -0.035f; v3[1] = size * 0.035f;
@@ -564,28 +579,27 @@ void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
v3[0] = -v3[0];
}
- glVertex3fv(v1);
- glVertex3fv(v2);
- glVertex3fv(v3);
-
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immVertex3fv(pos, v3);
}
- glEnd();
-
+ immEnd();
break;
+
case OB_CUBE:
- drawcube_size(size);
+ drawcube_size(size, pos);
break;
case OB_CIRCLE:
- drawcircle_size(size);
+ drawcircle_size(size, pos);
break;
case OB_EMPTY_SPHERE:
- draw_empty_sphere(size);
+ draw_empty_sphere(size, pos);
break;
case OB_EMPTY_CONE:
- draw_empty_cone(size);
+ draw_empty_cone(size, pos);
break;
case OB_ARROWS:
@@ -599,34 +613,34 @@ void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
for (axis = 0; axis < 3; axis++) {
const int arrow_axis = (axis == 0) ? 1 : 0;
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, 6);
v2[axis] = size;
- glVertex3fv(v1);
- glVertex3fv(v2);
-
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+
v1[axis] = size * 0.85f;
v1[arrow_axis] = -size * 0.08f;
- glVertex3fv(v1);
- glVertex3fv(v2);
-
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+
v1[arrow_axis] = size * 0.08f;
- glVertex3fv(v1);
- glVertex3fv(v2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
- glEnd();
-
- v2[axis] += size * 0.125f;
+ immEnd();
- draw_xyz_wire(viewmat_local_unit, v2, size, axis);
+ v2[axis] += size * 0.125f;
+ draw_xyz_wire(viewmat_local_unit, v2, size, axis, pos);
/* reset v1 & v2 to zero */
v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
}
- break;
}
}
+
+ immUnbindProgram();
}
@@ -634,38 +648,39 @@ void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4], StereoViews sview)
{
Image *ima = ob->data;
- ImBuf *ibuf;
- ImageUser iuser = *ob->iuser;
- /* Support multi-view */
- if (ima && (sview == STEREO_RIGHT_ID)) {
- iuser.multiview_eye = sview;
- iuser.flag |= IMA_SHOW_STEREO;
- BKE_image_multiview_index(ima, &iuser);
- }
+ const float ob_alpha = ob->col[3];
+ float ima_x, ima_y;
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ int bindcode = 0;
- if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
- IMB_rect_from_float(ibuf);
- }
+ if (ima) {
+ ImageUser iuser = *ob->iuser;
- int ima_x, ima_y;
+ /* Support multi-view */
+ if (ima && (sview == STEREO_RIGHT_ID)) {
+ iuser.multiview_eye = sview;
+ iuser.flag |= IMA_SHOW_STEREO;
+ BKE_image_multiview_index(ima, &iuser);
+ }
- /* Get the buffer dimensions so we can fallback to fake ones */
- if (ibuf && ibuf->rect) {
- ima_x = ibuf->x;
- ima_y = ibuf->y;
+ if (ob_alpha > 0.0f) {
+ bindcode = GPU_verify_image(ima, &iuser, GL_TEXTURE_2D, 0, false, false, false);
+ /* don't bother drawing the image if alpha = 0 */
+ }
+
+ int w, h;
+ BKE_image_get_size(ima, &iuser, &w, &h);
+ ima_x = w;
+ ima_y = h;
}
else {
- ima_x = 1;
- ima_y = 1;
+ /* if no image, make it a 1x1 empty square, honor scale & offset */
+ ima_x = ima_y = 1.0f;
}
- float sca_x = 1.0f;
- float sca_y = 1.0f;
-
/* Get the image aspect even if the buffer is invalid */
+ float sca_x = 1.0f, sca_y = 1.0f;
if (ima) {
if (ima->aspx > ima->aspy) {
sca_y = ima->aspy / ima->aspx;
@@ -675,61 +690,98 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
}
}
- /* Calculate the scale center based on object's origin */
- float ofs_x = ob->ima_ofs[0] * ima_x;
- float ofs_y = ob->ima_ofs[1] * ima_y;
+ float scale_x;
+ float scale_y;
+ {
+ const float scale_x_inv = ima_x * sca_x;
+ const float scale_y_inv = ima_y * sca_y;
+ if (scale_x_inv > scale_y_inv) {
+ scale_x = ob->empty_drawsize;
+ scale_y = ob->empty_drawsize * (scale_y_inv / scale_x_inv);
+ }
+ else {
+ scale_x = ob->empty_drawsize * (scale_x_inv / scale_y_inv);
+ scale_y = ob->empty_drawsize;
+ }
+ }
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ const float ofs_x = ob->ima_ofs[0] * scale_x;
+ const float ofs_y = ob->ima_ofs[1] * scale_y;
- /* Calculate Image scale */
- float scale = ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y * sca_y);
+ const rctf rect = {
+ .xmin = ofs_x,
+ .xmax = ofs_x + scale_x,
+ .ymin = ofs_y,
+ .ymax = ofs_y + scale_y,
+ };
- /* Set the object scale */
- glScalef(scale * sca_x, scale * sca_y, 1.0f);
+ bool use_blend = false;
- if (ibuf && ibuf->rect) {
- const bool use_clip = (U.glalphaclip != 1.0f);
- int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP) ? GL_NEAREST : GL_LINEAR;
- /* Setup GL params */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if (bindcode) {
+ use_blend = ob_alpha < 1.0f || BKE_image_has_alpha(ima);
- if (use_clip) {
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, U.glalphaclip);
+ if (use_blend) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- /* Use the object color and alpha */
- glColor4fv(ob->col);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int texCoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+ immUniform1f("alpha", ob_alpha);
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
- /* Draw the Image on the screen */
- glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immAttrib2f(texCoord, 0.0f, 0.0f);
+ immVertex2f(pos, rect.xmin, rect.ymin);
- glDisable(GL_BLEND);
+ immAttrib2f(texCoord, 1.0f, 0.0f);
+ immVertex2f(pos, rect.xmax, rect.ymin);
- if (use_clip) {
- glDisable(GL_ALPHA_TEST);
- glAlphaFunc(GL_ALWAYS, 0.0f);
- }
+ immAttrib2f(texCoord, 1.0f, 1.0f);
+ immVertex2f(pos, rect.xmax, rect.ymax);
+
+ immAttrib2f(texCoord, 0.0f, 1.0f);
+ immVertex2f(pos, rect.xmin, rect.ymax);
+ immEnd();
+
+ immUnbindProgram();
+
+ glBindTexture(GL_TEXTURE_2D, 0); /* necessary? */
}
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
+ /* Draw the image outline */
+ glLineWidth(1.5f);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ const bool picking = dflag & DRAW_CONSTCOLOR;
+ if (picking) {
+ /* TODO: deal with picking separately, use this function just to draw */
+ immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+ if (use_blend) {
+ glDisable(GL_BLEND);
+ }
+
+ imm_draw_line_box(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(ob_wire_col);
+ glEnable(GL_LINE_SMOOTH);
+
+ if (!use_blend) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
- /* Calculate the outline vertex positions */
- glBegin(GL_LINE_LOOP);
- glVertex2f(ofs_x, ofs_y);
- glVertex2f(ofs_x + ima_x, ofs_y);
- glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
- glVertex2f(ofs_x, ofs_y + ima_y);
- glEnd();
+ imm_draw_line_box(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- /* Reset GL settings */
- glPopMatrix();
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
+ }
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ immUnbindProgram();
}
static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
@@ -747,62 +799,65 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3
}
}
-void drawcircball(int mode, const float cent[3], float rad, const float tmat[4][4])
+void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos)
{
float verts[CIRCLE_RESOL][3];
circball_array_fill(verts, cent, rad, tmat);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, verts);
- glDrawArrays(mode, 0, CIRCLE_RESOL);
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(PRIM_LINE_LOOP, CIRCLE_RESOL);
+ for (int i = 0; i < CIRCLE_RESOL; ++i) {
+ immVertex3fv(pos, verts[i]);
+ }
+ immEnd();
}
/* circle for object centers, special_color is for library or ob users */
-static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, bool special_color)
+static void drawcentercircle(View3D *v3d, RegionView3D *UNUSED(rv3d), const float co[3], int selstate, bool special_color)
{
- const float size = ED_view3d_pixel_size(rv3d, co) * (float)U.obcenter_dia * 0.5f;
- float verts[CIRCLE_RESOL][3];
+ const float outlineWidth = 1.0f * U.pixelsize;
+ const float size = U.obcenter_dia * U.pixelsize + outlineWidth;
+
+ if (v3d->zbuf) {
+ glDisable(GL_DEPTH_TEST);
+ /* TODO(merwin): fit things like this into plates/buffers design */
+ }
- /* using glDepthFunc guarantees that it does write z values,
- * but not checks for it, so centers remain visible independent of draw order */
- if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
- /* write to near buffer always */
- glDepthRange(0.0, 0.0);
glEnable(GL_BLEND);
-
+ GPU_enable_program_point_size();
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniform1f("size", size);
+
if (special_color) {
- if (selstate == ACTIVE || selstate == SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
- else glColor4ub(0x55, 0xCC, 0xCC, 155);
+ if (selstate == ACTIVE || selstate == SELECT) immUniformColor4ub(0x88, 0xFF, 0xFF, 155);
+ else immUniformColor4ub(0x55, 0xCC, 0xCC, 155);
}
else {
- if (selstate == ACTIVE) UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
- else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT, 0, -80);
- else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
+ if (selstate == ACTIVE) immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
+ else if (selstate == SELECT) immUniformThemeColorShadeAlpha(TH_SELECT, 0, -80);
+ else if (selstate == DESELECT) immUniformThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
}
- circball_array_fill(verts, co, size, rv3d->viewinv);
+ /* set up outline */
+ float outlineColor[4];
+ UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, outlineColor);
+ immUniform4fv("outlineColor", outlineColor);
+ immUniform1f("outlineWidth", outlineWidth);
- /* enable vertex array */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, verts);
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, co);
+ immEnd();
- /* 1. draw filled, blended polygon */
- glDrawArrays(GL_POLYGON, 0, CIRCLE_RESOL);
+ immUnbindProgram();
- /* 2. draw outline */
- glLineWidth(1);
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30);
- glDrawArrays(GL_LINE_LOOP, 0, CIRCLE_RESOL);
-
- /* finish up */
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glDepthRange(0.0, 1.0);
+ GPU_disable_program_point_size();
glDisable(GL_BLEND);
- if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ }
}
/* *********** text drawing for object/particles/armature ************* */
@@ -893,36 +948,30 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
if (tot) {
int col_pack_prev = 0;
-#if 0
- bglMats mats; /* ZBuffer depth vars */
- double ux, uy, uz;
- float depth;
-
- if (v3d->zbuf)
- bgl_get_mats(&mats);
-#endif
if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_disable();
}
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ float original_proj[4][4];
+ gpuGetProjectionMatrix(original_proj);
wmOrtho2_region_pixelspace(ar);
- glLoadIdentity();
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
if (depth_write) {
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
}
else {
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
}
+ const int font_id = BLF_default();
+
for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
if (vos->sco[0] != IS_CLIPPED) {
if (col_pack_prev != vos->col.pack) {
- glColor3ubv(vos->col.ub);
+ BLF_color3ubv(font_id, vos->col.ub);
col_pack_prev = vos->col.pack;
}
@@ -941,13 +990,11 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
else {
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
}
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ gpuPopMatrix();
+ gpuLoadProjectionMatrix(original_proj);
if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_enable();
@@ -971,9 +1018,9 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
/* draws a cube given the scaling of the cube, assuming that
* all required matrices have been set (used for drawing empties)
*/
-static void drawcube_size(float size)
+static void drawcube_size(float size, unsigned pos)
{
- const GLfloat pos[8][3] = {
+ const float verts[8][3] = {
{-size, -size, -size},
{-size, -size, size},
{-size, size, -size},
@@ -986,13 +1033,21 @@ static void drawcube_size(float size)
const GLubyte indices[24] = {0,1,1,3,3,2,2,0,0,4,4,5,5,7,7,6,6,4,1,5,3,7,2,6};
+#if 0
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pos);
+ glVertexPointer(3, GL_FLOAT, 0, verts);
glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
glDisableClientState(GL_VERTEX_ARRAY);
+#else
+ immBegin(PRIM_LINES, 24);
+ for (int i = 0; i < 24; ++i) {
+ immVertex3fv(pos, verts[indices[i]]);
+ }
+ immEnd();
+#endif
}
-static void drawshadbuflimits(Lamp *la, float mat[4][4])
+static void drawshadbuflimits(const Lamp *la, const float mat[4][4], unsigned pos)
{
float sta[3], end[3], lavec[3];
@@ -1002,16 +1057,16 @@ static void drawshadbuflimits(Lamp *la, float mat[4][4])
madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta);
madd_v3_v3v3fl(end, mat[3], lavec, la->clipend);
- glBegin(GL_LINES);
- glVertex3fv(sta);
- glVertex3fv(end);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, sta);
+ immVertex3fv(pos, end);
+ immEnd();
- glPointSize(3.0);
- glBegin(GL_POINTS);
- glVertex3fv(sta);
- glVertex3fv(end);
- glEnd();
+ glPointSize(3.0f);
+ immBegin(PRIM_POINTS, 2);
+ immVertex3fv(pos, sta);
+ immVertex3fv(pos, end);
+ immEnd();
}
static void spotvolume(float lvec[3], float vvec[3], const float inp)
@@ -1077,62 +1132,63 @@ static void spotvolume(float lvec[3], float vvec[3], const float inp)
mul_m3_v3(mat2, vvec);
}
-static void draw_spot_cone(Lamp *la, float x, float z)
+static void draw_spot_cone(Lamp *la, float x, float z, unsigned pos)
{
z = fabsf(z);
- glBegin(GL_TRIANGLE_FAN);
- glVertex3f(0.0f, 0.0f, -x);
+ const bool square = (la->mode & LA_SQUARE);
- if (la->mode & LA_SQUARE) {
- glVertex3f(z, z, 0);
- glVertex3f(-z, z, 0);
- glVertex3f(-z, -z, 0);
- glVertex3f(z, -z, 0);
- glVertex3f(z, z, 0);
+ immBegin(PRIM_TRIANGLE_FAN, square ? 6 : 34);
+ immVertex3f(pos, 0.0f, 0.0f, -x);
+
+ if (square) {
+ immVertex3f(pos, z, z, 0);
+ immVertex3f(pos, -z, z, 0);
+ immVertex3f(pos, -z, -z, 0);
+ immVertex3f(pos, z, -z, 0);
+ immVertex3f(pos, z, z, 0);
}
else {
for (int a = 0; a < 33; a++) {
float angle = a * M_PI * 2 / (33 - 1);
- glVertex3f(z * cosf(angle), z * sinf(angle), 0);
+ immVertex3f(pos, z * cosf(angle), z * sinf(angle), 0.0f);
}
}
- glEnd();
+ immEnd();
}
-static void draw_transp_spot_volume(Lamp *la, float x, float z)
+static void draw_transp_spot_volume(Lamp *la, float x, float z, unsigned pos)
{
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
/* draw backside darkening */
glCullFace(GL_FRONT);
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- draw_spot_cone(la, x, z);
+ draw_spot_cone(la, x, z, pos);
/* draw front side lighting */
glCullFace(GL_BACK);
glBlendFunc(GL_ONE, GL_ONE);
- glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
+ immUniformColor3f(0.2f, 0.2f, 0.2f);
- draw_spot_cone(la, x, z);
+ draw_spot_cone(la, x, z, pos);
/* restore state */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
- glCullFace(GL_BACK);
}
#ifdef WITH_GAMEENGINE
-static void draw_transp_sun_volume(Lamp *la)
+static void draw_transp_sun_volume(Lamp *la, unsigned pos)
{
float box[8][3];
@@ -1145,50 +1201,46 @@ static void draw_transp_sun_volume(Lamp *la)
box[1][2] = box[2][2] = box[5][2] = box[6][2] = -la->clipsta;
/* draw edges */
- draw_box(box, false);
+ imm_draw_box(box, false, pos);
/* draw faces */
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
/* draw backside darkening */
glCullFace(GL_FRONT);
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- draw_box(box, true);
+ imm_draw_box(box, true, pos);
/* draw front side lighting */
glCullFace(GL_BACK);
glBlendFunc(GL_ONE, GL_ONE);
- glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
+ immUniformColor3f(0.2f, 0.2f, 0.2f);
- draw_box(box, true);
+ imm_draw_box(box, true, pos);
/* restore state */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
- glCullFace(GL_BACK);
}
#endif
-static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
+void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
{
Object *ob = base->object;
const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
Lamp *la = ob->data;
float vec[3], lvec[3], vvec[3], circrad;
- float lampsize;
float imat[4][4];
- unsigned char curcol[4];
- unsigned char col[4];
/* cone can't be drawn for duplicated lamps, because duplilist would be freed */
/* the moment of view3d_draw_transp() call */
const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object);
@@ -1196,7 +1248,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
!(G.f & G_PICKSEL) &&
(la->type == LA_SPOT) &&
(la->mode & LA_SHOW_CONE) &&
- !(base->flag & OB_FROMDUPLI) &&
+ !(base->flag_legacy & OB_FROMDUPLI) &&
!is_view);
#ifdef WITH_GAMEENGINE
@@ -1208,7 +1260,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
((la->mode & LA_SHAD_BUF) ||
(la->mode & LA_SHAD_RAY)) &&
(la->mode & LA_SHOW_SHADOW_BOX) &&
- !(base->flag & OB_FROMDUPLI) &&
+ !(base->flag_legacy & OB_FROMDUPLI) &&
!is_view);
#else
const bool drawshadowbox = false;
@@ -1216,118 +1268,159 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
if ((drawcone || drawshadowbox) && !v3d->transp) {
/* in this case we need to draw delayed */
- ED_view3d_after_add(v3d->xray ? &v3d->afterdraw_xraytransp : &v3d->afterdraw_transp, base, dflag);
+ ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
return;
}
-
+
/* we first draw only the screen aligned & fixed scale stuff */
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
/* lets calculate the scale: */
- lampsize = pixsize * ((float)U.obcenter_dia * 0.5f);
+ const float lampsize_px = U.obcenter_dia;
+ const float lampsize = pixsize * lampsize_px * 0.5f;
/* and view aligned matrix: */
copy_m4_m4(imat, rv3d->viewinv);
normalize_v3(imat[0]);
normalize_v3(imat[1]);
+ const unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
/* lamp center */
copy_v3_v3(vec, ob->obmat[3]);
+ float curcol[4];
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* for AA effects */
- curcol[0] = ob_wire_col[0];
- curcol[1] = ob_wire_col[1];
- curcol[2] = ob_wire_col[2];
- curcol[3] = 154;
- glColor4ubv(curcol);
+ rgb_uchar_to_float(curcol, ob_wire_col);
+ curcol[3] = 0.6f;
+ /* TODO: pay attention to GL_BLEND */
}
- glLineWidth(1);
+ glLineWidth(1.0f);
+ setlinestyle(3);
if (lampsize > 0.0f) {
+ const float outlineWidth = 1.5f * U.pixelsize;
+ const float lampdot_size = lampsize_px * U.pixelsize + outlineWidth;
+ /* Inner Circle */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ const float *color = curcol;
if (ob->id.us > 1) {
- if (is_obact || (ob->flag & SELECT)) {
- glColor4ub(0x88, 0xFF, 0xFF, 155);
+ if (is_obact || ((base->flag & BASE_SELECTED) != 0)) {
+ static const float active_color[4] = {0.533f, 1.0f, 1.0f, 1.0f};
+ color = active_color;
}
else {
- glColor4ub(0x77, 0xCC, 0xCC, 155);
+ static const float inactive_color[4] = {0.467f, 0.8f, 0.8f, 1.0f};
+ color = inactive_color;
}
}
+
+ GPU_enable_program_point_size();
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ immUniform1f("size", lampdot_size);
+ immUniform1f("outlineWidth", outlineWidth);
+ immUniformColor3fvAlpha(color, 0.3f);
+ immUniform4fv("outlineColor", color);
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
+
+ immUnbindProgram();
+
+ glDisable(GL_BLEND);
+ GPU_disable_program_point_size();
}
-
- /* Inner Circle */
- glEnable(GL_BLEND);
- drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
- glDisable(GL_BLEND);
- drawcircball(GL_POLYGON, vec, lampsize, imat);
-
+ else {
+ /* CONSTCOLOR in effect */
+ /* TODO: separate picking from drawing */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ /* color doesn't matter, so don't set */
+ glPointSize(lampdot_size);
+
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
+
+ immUnbindProgram();
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ /* TODO(merwin): short term, use DEPTH_ONLY for picking
+ * long term, separate picking from drawing
+ */
+
/* restore */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (ob->id.us > 1)
- glColor4ubv(curcol);
+ immUniformColor4fv(curcol);
}
/* Outer circle */
circrad = 3.0f * lampsize;
- setlinestyle(3);
- drawcircball(GL_LINE_LOOP, vec, circrad, imat);
+ imm_drawcircball(vec, circrad, imat, pos);
/* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
if (la->type != LA_HEMI) {
if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
- drawcircball(GL_LINE_LOOP, vec, circrad + 3.0f * pixsize, imat);
+ imm_drawcircball(vec, circrad + 3.0f * pixsize, imat, pos);
}
}
}
else {
- setlinestyle(3);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ immUniformColor4fv(curcol);
+ }
circrad = 0.0f;
}
-
+
/* draw the pretty sun rays */
if (la->type == LA_SUN) {
float v1[3], v2[3], mat[3][3];
short axis;
-
+
/* setup a 45 degree rotation matrix */
axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2);
/* vectors */
mul_v3_v3fl(v1, imat[0], circrad * 1.2f);
mul_v3_v3fl(v2, imat[0], circrad * 2.5f);
-
+
/* center */
- glTranslate3fv(vec);
-
+ gpuPushMatrix();
+ gpuTranslate3fv(vec);
+
setlinestyle(3);
-
- glBegin(GL_LINES);
+
+ immBegin(PRIM_LINES, 16);
for (axis = 0; axis < 8; axis++) {
- glVertex3fv(v1);
- glVertex3fv(v2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
mul_m3_v3(mat, v1);
mul_m3_v3(mat, v2);
}
- glEnd();
-
- glTranslatef(-vec[0], -vec[1], -vec[2]);
+ immEnd();
+ gpuPopMatrix();
}
-
+
if (la->type == LA_LOCAL) {
if (la->mode & LA_SPHERE) {
- drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
+ imm_drawcircball(vec, la->dist, imat, pos);
}
}
-
- glPopMatrix(); /* back in object space */
+
+ gpuPopMatrix(); /* back in object space */
zero_v3(vec);
-
+
if (is_view) {
/* skip drawing extra info */
}
@@ -1359,24 +1452,18 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
{z_abs, -z_abs, x},
{-z_abs, z_abs, x},
};
- const unsigned char indices[] = {
- 0, 1, 3,
- 0, 3, 2,
- 0, 2, 4,
- 0, 1, 4,
- };
- /* Draw call:
- * activate and specify pointer to vertex array */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vertices);
- /* draw the pyramid */
- glDrawElements(GL_LINE_STRIP, 12, GL_UNSIGNED_BYTE, indices);
-
- /* deactivate vertex arrays after drawing */
- glDisableClientState(GL_VERTEX_ARRAY);
+ immBegin(PRIM_LINES, 16);
+ for (int i = 1; i <= 4; ++i) {
+ immVertex3fv(pos, vertices[0]); /* apex to corner */
+ immVertex3fv(pos, vertices[i]);
+ int next_i = (i == 4) ? 1 : (i + 1);
+ immVertex3fv(pos, vertices[i]); /* corner to next corner */
+ immVertex3fv(pos, vertices[next_i]);
+ }
+ immEnd();
- glTranslatef(0.0f, 0.0f, x);
+ gpuTranslate3f(0.0f, 0.0f, x);
/* draw the square representing spotbl */
if (la->type == LA_SPOT) {
@@ -1386,22 +1473,21 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
if (blend != 0.0f && blend != z_abs) {
- fdrawbox(blend, -blend, -blend, blend);
+ imm_draw_line_box_3d(pos, blend, -blend, -blend, blend);
}
}
}
else {
-
/* draw the angled sides of the cone */
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vvec);
- glVertex3fv(vec);
- glVertex3fv(lvec);
- glEnd();
+ immBegin(PRIM_LINE_STRIP, 3);
+ immVertex3fv(pos, vvec);
+ immVertex3fv(pos, vec);
+ immVertex3fv(pos, lvec);
+ immEnd();
/* draw the circle at the end of the cone */
- glTranslatef(0.0f, 0.0f, x);
- circ(0.0f, 0.0f, z_abs);
+ gpuTranslate3f(0.0f, 0.0f, x);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, z_abs, 32);
/* draw the circle representing spotbl */
if (la->type == LA_SPOT) {
@@ -1411,17 +1497,17 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
if (blend != 0.0f && blend != z_abs) {
- circ(0.0f, 0.0f, blend);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, blend, 32);
}
}
}
if (drawcone)
- draw_transp_spot_volume(la, x, z);
+ draw_transp_spot_volume(la, x, z, pos);
/* draw clip start, useful for wide cones where its not obvious where the start is */
- glTranslatef(0.0, 0.0, -x); /* reverse translation above */
- glBegin(GL_LINES);
+ gpuTranslate3f(0.0f, 0.0f, -x); /* reverse translation above */
+ immBegin(PRIM_LINES, 2);
if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) {
float lvec_clip[3];
float vvec_clip[3];
@@ -1430,41 +1516,40 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac);
interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac);
- glVertex3fv(lvec_clip);
- glVertex3fv(vvec_clip);
+ immVertex3fv(pos, lvec_clip);
+ immVertex3fv(pos, vvec_clip);
}
/* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
else {
- glVertex3f(0.0, 0.0, -circrad);
- glVertex3f(0.0, 0.0, -la->dist);
+ immVertex3f(pos, 0.0f, 0.0f, -circrad);
+ immVertex3f(pos, 0.0f, 0.0f, -la->dist);
}
- glEnd();
+ immEnd();
}
else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
-
/* draw the line from the circle along the dist */
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, 2);
vec[2] = -circrad;
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
vec[2] = -la->dist;
- glVertex3fv(vec);
- glEnd();
-
+ immVertex3fv(pos, vec);
+ immEnd();
+
if (la->type == LA_HEMI) {
/* draw the hemisphere curves */
short axis, steps, dir;
float outdist, zdist, mul;
zero_v3(vec);
- outdist = 0.14; mul = 1.4; dir = 1;
-
+ outdist = 0.14f; mul = 1.4f; dir = 1;
+
setlinestyle(4);
/* loop over the 4 compass points, and draw each arc as a LINE_STRIP */
for (axis = 0; axis < 4; axis++) {
- float v[3] = {0.0, 0.0, 0.0};
- zdist = 0.02;
-
- glBegin(GL_LINE_STRIP);
-
+ float v[3] = {0.0f, 0.0f, 0.0f};
+ zdist = 0.02f;
+
+ immBegin(PRIM_LINE_STRIP, 6);
+
for (steps = 0; steps < 6; steps++) {
if (axis == 0 || axis == 1) { /* x axis up, x axis down */
/* make the arcs start at the edge of the energy circle */
@@ -1477,13 +1562,13 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
}
v[2] = v[2] - steps * zdist;
-
- glVertex3fv(v);
-
+
+ immVertex3fv(pos, v);
+
zdist = zdist * mul;
}
-
- glEnd();
+
+ immEnd();
/* flip the direction */
dir = -dir;
}
@@ -1491,96 +1576,92 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
#ifdef WITH_GAMEENGINE
if (drawshadowbox) {
- draw_transp_sun_volume(la);
+ draw_transp_sun_volume(la, pos);
}
#endif
-
}
else if (la->type == LA_AREA) {
setlinestyle(3);
if (la->area_shape == LA_AREA_SQUARE)
- fdrawbox(-la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
+ imm_draw_line_box_3d(pos, -la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
else if (la->area_shape == LA_AREA_RECT)
- fdrawbox(-la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
+ imm_draw_line_box_3d(pos, -la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, -circrad);
- glVertex3f(0.0, 0.0, -la->dist);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, -circrad);
+ immVertex3f(pos, 0.0f, 0.0f, -la->dist);
+ immEnd();
}
-
+
/* and back to viewspace */
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
copy_v3_v3(vec, ob->obmat[3]);
setlinestyle(0);
-
+
if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) {
- drawshadbuflimits(la, ob->obmat);
+ drawshadbuflimits(la, ob->obmat, pos);
}
-
+
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- UI_GetThemeColor4ubv(TH_LAMP, col);
- glColor4ubv(col);
+ immUniformThemeColor(TH_LAMP);
}
glEnable(GL_BLEND);
-
+
if (vec[2] > 0) vec[2] -= circrad;
else vec[2] += circrad;
-
- glBegin(GL_LINES);
- glVertex3fv(vec);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, vec);
vec[2] = 0;
- glVertex3fv(vec);
- glEnd();
-
- glPointSize(2.0);
- glBegin(GL_POINTS);
- glVertex3fv(vec);
- glEnd();
-
+ immVertex3fv(pos, vec);
+ immEnd();
+
+ glPointSize(2.0f);
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
+
glDisable(GL_BLEND);
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- /* restore for drawing extra stuff */
- glColor3ubv(ob_wire_col);
- }
- /* and finally back to org object space! */
- glPopMatrix();
+
+ immUnbindProgram();
+ gpuPopMatrix();
}
-static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3])
+static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3], unsigned pos)
{
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, -sta);
- glVertex3f(0.0, 0.0, -end);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, 0.0f, 0.0f, -sta);
+ immVertex3f(pos, 0.0f, 0.0f, -end);
+ immEnd();
if (!(dflag & DRAW_PICKING)) {
- glPointSize(3.0);
- glBegin(GL_POINTS);
+ glPointSize(3.0f);
+ /* would like smooth round points here, but that means binding another shader...
+ * if it's really desired, pull these points into their own function to be called after */
+ immBegin(PRIM_POINTS, 2);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(col);
+ immUniformColor3ubv(col);
}
- glVertex3f(0.0, 0.0, -sta);
- glVertex3f(0.0, 0.0, -end);
- glEnd();
+ immVertex3f(pos, 0.0f, 0.0f, -sta);
+ immVertex3f(pos, 0.0f, 0.0f, -end);
+ immEnd();
}
}
/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
/* qdn: now also enabled for Blender to set focus point for defocus composite node */
-static void draw_focus_cross(float dist, float size)
+static void draw_focus_cross(float dist, float size, unsigned pos)
{
- glBegin(GL_LINES);
- glVertex3f(-size, 0.0f, -dist);
- glVertex3f(size, 0.0f, -dist);
- glVertex3f(0.0f, -size, -dist);
- glVertex3f(0.0f, size, -dist);
- glEnd();
+ immBegin(PRIM_LINES, 4);
+ immVertex3f(pos, -size, 0.0f, -dist);
+ immVertex3f(pos, size, 0.0f, -dist);
+ immVertex3f(pos, 0.0f, -size, -dist);
+ immVertex3f(pos, 0.0f, size, -dist);
+ immEnd();
}
#ifdef VIEW3D_CAMERA_BORDER_HACK
@@ -1590,28 +1671,8 @@ bool view3d_camera_border_hack_test = false;
/* ****************** draw clip data *************** */
-static void draw_bundle_sphere(void)
-{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
- gluSphere(qobj, 0.05, 8, 8);
- gluDeleteQuadric(qobj);
-
- glEndList();
- }
-
- glCallList(displist);
-}
-
static void draw_viewport_object_reconstruction(
- Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d,
+ Scene *scene, BaseLegacy *base, const View3D *v3d, const RegionView3D *rv3d,
MovieClip *clip, MovieTrackingObject *tracking_object,
const short dflag, const unsigned char ob_wire_col[4],
int *global_track_index, bool draw_selected)
@@ -1635,7 +1696,7 @@ static void draw_viewport_object_reconstruction(
if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0)
mul_v3_fl(camera_size, tracking_object->scale);
- glPushMatrix();
+ gpuPushMatrix();
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
/* current ogl matrix is translated in camera space, bundles should
@@ -1643,8 +1704,8 @@ static void draw_viewport_object_reconstruction(
* from current ogl matrix */
invert_m4_m4(imat, base->object->obmat);
- glMultMatrixf(imat);
- glMultMatrixf(mat);
+ gpuMultMatrix(imat);
+ gpuMultMatrix(mat);
}
else {
float obmat[4][4];
@@ -1653,7 +1714,7 @@ static void draw_viewport_object_reconstruction(
BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat);
invert_m4_m4(imat, obmat);
- glMultMatrixf(imat);
+ gpuMultMatrix(imat);
}
for (track = tracksbase->first; track; track = track->next) {
@@ -1668,64 +1729,91 @@ static void draw_viewport_object_reconstruction(
if (dflag & DRAW_PICKING)
GPU_select_load_id(base->selcol + (tracknr << 16));
- glPushMatrix();
- glTranslate3fv(track->bundle_pos);
- glScalef(v3d->bundle_size / 0.05f / camera_size[0],
- v3d->bundle_size / 0.05f / camera_size[1],
- v3d->bundle_size / 0.05f / camera_size[2]);
+ gpuPushMatrix();
+ gpuTranslate3fv(track->bundle_pos);
+ gpuScale3f(v3d->bundle_size / 0.05f / camera_size[0],
+ v3d->bundle_size / 0.05f / camera_size[1],
+ v3d->bundle_size / 0.05f / camera_size[2]);
const int v3d_drawtype = view3d_effective_drawtype(v3d);
if (v3d_drawtype == OB_WIRE) {
+ unsigned char color[4];
+ const unsigned char *color_ptr = NULL;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
+ color_ptr = ob_wire_col;
}
else {
- glColor3fv(track->color);
+ rgba_float_to_uchar(color, track->color);
+ color_ptr = color;
}
}
- drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype);
+ drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr);
}
else if (v3d_drawtype > OB_WIRE) {
if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) {
+ Batch *batch;
+
+ gpuScaleUniform(0.05f);
+
/* selection outline */
if (selected) {
+ batch = Batch_get_sphere_wire(1);
+
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform4f(batch, "color",
+ ob_wire_col[0]/255.f,
+ ob_wire_col[1]/255.f,
+ ob_wire_col[2]/255.f, 1.0f);
+ }
+ else {
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_DEPTH_ONLY);
}
-
glLineWidth(2.0f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- draw_bundle_sphere();
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ Batch_draw(batch);
}
+ batch = Batch_get_sphere(0);
+
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
- else UI_ThemeColor(TH_BUNDLE_SOLID);
+ const float light[3] = {0.0f, 0.0f, 1.0f};
+ float col[3];
+ Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform3fv(batch, "light", light);
+
+ if (track->flag & TRACK_CUSTOMCOLOR) copy_v3_v3(col, track->color);
+ else UI_GetThemeColor3fv(TH_BUNDLE_SOLID, col);
+ Batch_Uniform4f(batch, "color", col[0], col[1], col[2], 1.0f);
+ }
+ else {
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_DEPTH_ONLY);
}
- draw_bundle_sphere();
+ Batch_draw(batch);
}
else {
+ unsigned char color[4];
+ const unsigned char *color_ptr = NULL;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (selected) {
- glColor3ubv(ob_wire_col);
+ color_ptr = ob_wire_col;
}
else {
- if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
- else UI_ThemeColor(TH_WIRE);
+ if (track->flag & TRACK_CUSTOMCOLOR) rgba_float_to_uchar(color, track->color);
+ else UI_GetThemeColor4ubv(TH_WIRE, color);
+
+ color_ptr = color;
}
}
- drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype);
+ drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr);
}
}
- glPopMatrix();
+ gpuPopMatrix();
if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
float pos[3];
@@ -1745,28 +1833,33 @@ static void draw_viewport_object_reconstruction(
MovieTrackingReconstruction *reconstruction;
reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
- if (reconstruction->camnr) {
+ if (reconstruction->camnr >= 2) {
MovieReconstructedCamera *camera = reconstruction->cameras;
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CAMERA_PATH);
- UI_ThemeColor(TH_CAMERA_PATH);
glLineWidth(2.0f);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, reconstruction->camnr);
for (int a = 0; a < reconstruction->camnr; a++, camera++) {
- glVertex3fv(camera->mat[3]);
+ immVertex3fv(pos, camera->mat[3]);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
}
}
- glPopMatrix();
+ gpuPopMatrix();
*global_track_index = tracknr;
}
static void draw_viewport_reconstruction(
- Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d, MovieClip *clip,
+ Scene *scene, BaseLegacy *base, const View3D *v3d, const RegionView3D *rv3d, MovieClip *clip,
const short dflag, const unsigned char ob_wire_col[4],
const bool draw_selected)
{
@@ -1795,67 +1888,65 @@ static void draw_viewport_reconstruction(
/* restore */
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(ob_wire_col);
- }
-
if (dflag & DRAW_PICKING)
GPU_select_load_id(base->selcol);
}
-static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], const GLenum mode)
+/* camera frame */
+static void drawcamera_frame(float vec[4][3], bool filled, unsigned pos)
{
- glBegin(mode);
- glVertex3fv(near_plane[0]);
- glVertex3fv(far_plane[0]);
- glVertex3fv(far_plane[1]);
- glVertex3fv(near_plane[1]);
- glEnd();
-
- glBegin(mode);
- glVertex3fv(near_plane[1]);
- glVertex3fv(far_plane[1]);
- glVertex3fv(far_plane[2]);
- glVertex3fv(near_plane[2]);
- glEnd();
-
- glBegin(mode);
- glVertex3fv(near_plane[2]);
- glVertex3fv(far_plane[2]);
- glVertex3fv(far_plane[3]);
- glVertex3fv(near_plane[3]);
- glEnd();
-
- glBegin(mode);
- glVertex3fv(far_plane[3]);
- glVertex3fv(near_plane[3]);
- glVertex3fv(near_plane[0]);
- glVertex3fv(far_plane[0]);
- glEnd();
+ immBegin(filled ? PRIM_TRIANGLE_FAN : PRIM_LINE_LOOP, 4);
+ immVertex3fv(pos, vec[0]);
+ immVertex3fv(pos, vec[1]);
+ immVertex3fv(pos, vec[2]);
+ immVertex3fv(pos, vec[3]);
+ immEnd();
}
-/* camera frame */
-static void drawcamera_frame(float vec[4][3], const GLenum mode)
+/* center point to camera frame */
+static void drawcamera_framelines(float vec[4][3], float origin[3], unsigned pos)
{
- glBegin(mode);
- glVertex3fv(vec[0]);
- glVertex3fv(vec[1]);
- glVertex3fv(vec[2]);
- glVertex3fv(vec[3]);
- glEnd();
+ immBegin(PRIM_LINES, 8);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[0]);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[1]);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[2]);
+ immVertex3fv(pos, origin);
+ immVertex3fv(pos, vec[3]);
+ immEnd();
}
-/* center point to camera frame */
-static void drawcamera_framelines(float vec[4][3], float origin[3])
+static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], bool filled, unsigned pos)
{
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec[1]);
- glVertex3fv(origin);
- glVertex3fv(vec[0]);
- glVertex3fv(vec[3]);
- glVertex3fv(origin);
- glVertex3fv(vec[2]);
- glEnd();
+ drawcamera_frame(near_plane, filled, pos);
+ drawcamera_frame(far_plane, filled, pos);
+
+ if (filled) {
+ immBegin(PRIM_TRIANGLE_STRIP, 10);
+
+ immVertex3fv(pos, near_plane[0]);
+ immVertex3fv(pos, far_plane[0]);
+ immVertex3fv(pos, near_plane[1]);
+ immVertex3fv(pos, far_plane[1]);
+ immVertex3fv(pos, near_plane[2]);
+ immVertex3fv(pos, far_plane[2]);
+ immVertex3fv(pos, near_plane[3]);
+ immVertex3fv(pos, far_plane[3]);
+ immVertex3fv(pos, near_plane[0]);
+ immVertex3fv(pos, far_plane[0]);
+
+ immEnd();
+ }
+ else {
+ immBegin(PRIM_LINES, 8);
+ for (int i = 0; i < 4; ++i) {
+ immVertex3fv(pos, near_plane[i]);
+ immVertex3fv(pos, far_plane[i]);
+ }
+ immEnd();
+ }
}
static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
@@ -1867,7 +1958,7 @@ static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
static void drawcamera_stereo3d(
Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam,
- float vec[4][3], float drawsize, const float scale[3])
+ float vec[4][3], float drawsize, const float scale[3], unsigned pos)
{
float obmat[4][4];
float vec_lr[2][4][3];
@@ -1883,15 +1974,15 @@ static void drawcamera_stereo3d(
zero_v3(tvec);
- glPushMatrix();
+ /* caller bound GPU_SHADER_3D_UNIFORM_COLOR, passed in pos attribute ID */
for (int i = 0; i < 2; i++) {
ob = BKE_camera_multiview_render(scene, ob, names[i]);
cam_lr[i] = ob->data;
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat);
- glMultMatrixf(obmat);
+ gpuMultMatrix(obmat);
copy_m3_m3(vec_lr[i], vec);
copy_v3_v3(vec_lr[i][3], vec[3]);
@@ -1908,10 +1999,10 @@ static void drawcamera_stereo3d(
if (is_stereo3d_cameras) {
/* camera frame */
- drawcamera_frame(vec_lr[i], GL_LINE_LOOP);
+ drawcamera_frame(vec_lr[i], false, pos);
/* center point to camera frame */
- drawcamera_framelines(vec_lr[i], tvec);
+ drawcamera_framelines(vec_lr[i], tvec, pos);
}
/* connecting line */
@@ -1925,21 +2016,20 @@ static void drawcamera_stereo3d(
}
}
-
/* the remaining drawing takes place in the view space */
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
if (is_stereo3d_cameras) {
/* draw connecting lines */
- GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- GPU_basic_shader_line_stipple(2, 0xAAAA);
+ glLineStipple(2, 0xAAAA);
+ glEnable(GL_LINE_STIPPLE);
- glBegin(GL_LINES);
- glVertex3fv(origin[0]);
- glVertex3fv(origin[1]);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, origin[0]);
+ immVertex3fv(pos, origin[1]);
+ immEnd();
- GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
+ glDisable(GL_LINE_STIPPLE);
}
/* draw convergence plane */
@@ -1964,21 +2054,21 @@ static void drawcamera_stereo3d(
add_v3_v3(local_plane[i], axis_center);
}
- glColor3f(0.0f, 0.0f, 0.0f);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
/* camera frame */
- drawcamera_frame(local_plane, GL_LINE_LOOP);
+ drawcamera_frame(local_plane, false, pos);
if (v3d->stereo3d_convergence_alpha > 0.0f) {
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
- glColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
- drawcamera_frame(local_plane, GL_QUADS);
+ drawcamera_frame(local_plane, true, pos);
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
}
@@ -2003,37 +2093,31 @@ static void drawcamera_stereo3d(
}
/* camera frame */
- glColor3f(0.0f, 0.0f, 0.0f);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
- drawcamera_frame(near_plane, GL_LINE_LOOP);
- drawcamera_frame(far_plane, GL_LINE_LOOP);
- drawcamera_volume(near_plane, far_plane, GL_LINE_LOOP);
+ drawcamera_volume(near_plane, far_plane, false, pos);
if (v3d->stereo3d_volume_alpha > 0.0f) {
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
if (i == 0)
- glColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
+ immUniformColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
else
- glColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
+ immUniformColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
- drawcamera_frame(near_plane, GL_QUADS);
- drawcamera_frame(far_plane, GL_QUADS);
- drawcamera_volume(near_plane, far_plane, GL_QUADS);
+ drawcamera_volume(near_plane, far_plane, true, pos);
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
}
}
-
- glPopMatrix();
}
/* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dflag, const unsigned char ob_wire_col[4])
+void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const short dflag, const unsigned char ob_wire_col[4])
{
/* a standing up pyramid with (0,0,0) as top */
Camera *cam;
@@ -2096,8 +2180,12 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
asp, shift, &drawsize, vec);
- glDisable(GL_CULL_FACE);
- glLineWidth(1);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) {
+ immUniformColor3ubv(ob_wire_col);
+ }
+ glLineWidth(1.0f);
/* camera frame */
if (!is_stereo3d_cameras) {
@@ -2106,27 +2194,29 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
float obmat[4][4];
bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat);
- glMultMatrixf(obmat);
+ gpuMultMatrix(obmat);
- drawcamera_frame(vec, GL_LINE_LOOP);
- glPopMatrix();
+ drawcamera_frame(vec, false, pos);
+ gpuPopMatrix();
}
else {
- drawcamera_frame(vec, GL_LINE_LOOP);
+ drawcamera_frame(vec, false, pos);
}
}
- if (is_view)
+ if (is_view) {
+ immUnbindProgram();
return;
+ }
zero_v3(tvec);
/* center point to camera frame */
if (!is_stereo3d_cameras)
- drawcamera_framelines(vec, tvec);
+ drawcamera_framelines(vec, tvec, pos);
/* arrow on top */
tvec[2] = vec[1][2]; /* copy the depth */
@@ -2135,22 +2225,25 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
* for active cameras. We actually draw both outline+filled
* for active cameras so the wire can be seen side-on */
for (int i = 0; i < 2; i++) {
- if (i == 0) glBegin(GL_LINE_LOOP);
- else if (i == 1 && is_active) glBegin(GL_TRIANGLES);
+ if (i == 0) immBegin(PRIM_LINE_LOOP, 3);
+ else if (i == 1 && is_active) {
+ glDisable(GL_CULL_FACE); /* TODO: declarative state tracking */
+ immBegin(PRIM_TRIANGLES, 3);
+ }
else break;
tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]);
tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
- glVertex3fv(tvec); /* left */
+ immVertex3fv(pos, tvec); /* left */
tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]);
- glVertex3fv(tvec); /* right */
+ immVertex3fv(pos, tvec); /* right */
tvec[0] = shift[0];
tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
- glVertex3fv(tvec); /* top */
+ immVertex3fv(pos, tvec); /* top */
- glEnd();
+ immEnd();
}
if ((dflag & DRAW_SCENESET) == 0) {
@@ -2161,16 +2254,15 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
copy_m4_m4(nobmat, ob->obmat);
normalize_m4(nobmat);
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
- glMultMatrixf(nobmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ gpuMultMatrix(nobmat);
if (cam->flag & CAM_SHOWLIMITS) {
const unsigned char col[3] = {128, 128, 60}, col_hi[3] = {255, 255, 120};
- draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col));
+ draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col), pos);
/* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */
- draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize);
+ draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize, pos);
}
if (cam->flag & CAM_SHOWMIST) {
@@ -2179,69 +2271,79 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
if (world) {
draw_limit_line(world->miststa, world->miststa + world->mistdist,
- dflag, (is_active ? col_hi : col));
+ dflag, (is_active ? col_hi : col), pos);
}
}
- glPopMatrix();
}
}
/* stereo cameras drawing */
if (is_stereo3d) {
- drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale);
+ drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale, pos);
}
+
+ immUnbindProgram();
}
/* flag similar to draw_object() */
-static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D *UNUSED(rv3d),
- Object *UNUSED(ob), int UNUSED(flag))
+void drawspeaker(const unsigned char ob_wire_col[3])
{
- float vec[3];
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
- glEnable(GL_BLEND);
- glLineWidth(1);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (ob_wire_col) {
+ immUniformColor3ubv(ob_wire_col);
+ }
+
+ glLineWidth(1.0f);
+
+ const int segments = 16;
for (int j = 0; j < 3; j++) {
- vec[2] = 0.25f * j - 0.125f;
+ float z = 0.25f * j - 0.125f;
- glBegin(GL_LINE_LOOP);
- for (int i = 0; i < 16; i++) {
- vec[0] = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
- vec[1] = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
- glVertex3fv(vec);
+ immBegin(PRIM_LINE_LOOP, segments);
+ for (int i = 0; i < segments; i++) {
+ float x = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
+ float y = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
+ immVertex3f(pos, x, y, z);
}
- glEnd();
+ immEnd();
}
for (int j = 0; j < 4; j++) {
- vec[0] = (((j + 1) % 2) * (j - 1)) * 0.5f;
- vec[1] = ((j % 2) * (j - 2)) * 0.5f;
- glBegin(GL_LINE_STRIP);
+ float x = (((j + 1) % 2) * (j - 1)) * 0.5f;
+ float y = ((j % 2) * (j - 2)) * 0.5f;
+ immBegin(PRIM_LINE_STRIP, 3);
for (int i = 0; i < 3; i++) {
if (i == 1) {
- vec[0] *= 0.5f;
- vec[1] *= 0.5f;
+ x *= 0.5f;
+ y *= 0.5f;
}
- vec[2] = 0.25f * i - 0.125f;
- glVertex3fv(vec);
+ float z = 0.25f * i - 0.125f;
+ immVertex3f(pos, x, y, z);
}
- glEnd();
+ immEnd();
}
- glDisable(GL_BLEND);
+ immUnbindProgram();
}
-static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel)
+static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel,
+ unsigned int pos, unsigned int color)
{
BPoint *bp = lt->def;
const float *co = dl ? dl->verts : NULL;
+ float active_color[4], draw_color[4];
- const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
- UI_ThemeColor(color);
+ UI_GetThemeColor4fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, draw_color);
+ UI_GetThemeColor4fv(TH_ACTIVE_VERT, active_color);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, lt->pntsw * lt->pntsv * lt->pntsu);
for (int w = 0; w < lt->pntsw; w++) {
int wxt = (w == 0 || w == lt->pntsw - 1);
@@ -2253,12 +2355,12 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
if (bp->hide == 0) {
/* check for active BPoint and ensure selected */
if ((bp == actbp) && (bp->f1 & SELECT)) {
- UI_ThemeColor(TH_ACTIVE_VERT);
- glVertex3fv(dl ? co : bp->vec);
- UI_ThemeColor(color);
+ immAttrib4fv(color, active_color);
+ immVertex3fv(pos, dl ? co : bp->vec);
}
else if ((bp->f1 & SELECT) == sel) {
- glVertex3fv(dl ? co : bp->vec);
+ immAttrib4fv(color, draw_color);
+ immVertex3fv(pos, dl ? co : bp->vec);
}
}
}
@@ -2266,27 +2368,26 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
}
}
- glEnd();
+ immEnd();
}
-static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol)
+static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol,
+ unsigned int pos, unsigned int color)
{
int index = ((w * lt->pntsv + v) * lt->pntsu) + u;
if (actdef_wcol) {
float col[3];
MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1);
-
weight_to_rgb(col, mdw ? mdw->weight : 0.0f);
- glColor3fv(col);
-
+ immAttrib3fv(color, col);
}
if (dl) {
- glVertex3fv(&dl->verts[index * 3]);
+ immVertex3fv(pos, &dl->verts[index * 3]);
}
else {
- glVertex3fv(lt->def[index].vec);
+ immVertex3fv(pos, lt->def[index].vec);
}
}
@@ -2334,7 +2435,7 @@ static void ensure_curve_cache(Scene *scene, Object *object)
#endif
/* lattice color is hardcoded, now also shows weightgroup values in edit mode */
-static void drawlattice(View3D *v3d, Object *ob)
+static void drawlattice(View3D *v3d, Object *ob, const short dflag, const unsigned char ob_wire_col[4])
{
Lattice *lt = ob->data;
DispList *dl;
@@ -2347,15 +2448,37 @@ static void drawlattice(View3D *v3d, Object *ob)
if (is_edit) {
lt = lt->editlatt->latt;
- UI_ThemeColor(TH_WIRE_EDIT);
-
if (ob->defbase.first && lt->dvert) {
actdef_wcol = ob->actdef;
}
}
- glLineWidth(1);
- glBegin(GL_LINES);
+ VertexFormat *format = immVertexFormat();
+ unsigned int color, pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ if (actdef_wcol) {
+ color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (is_edit) {
+ immUniformThemeColor(TH_WIRE_EDIT);
+ }
+ else {
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ immUniformColor3ubv(ob_wire_col);
+ }
+ else {
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ glLineWidth(1.0f);
+ immBeginAtMost(PRIM_LINES, lt->pntsw * lt->pntsv * lt->pntsu * 6);
+
for (w = 0; w < lt->pntsw; w++) {
int wxt = (w == 0 || w == lt->pntsw - 1);
for (v = 0; v < lt->pntsv; v++) {
@@ -2364,30 +2487,40 @@ static void drawlattice(View3D *v3d, Object *ob)
int uxt = (u == 0 || u == lt->pntsu - 1);
if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
- drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol);
- drawlattice__point(lt, dl, u, v, w, actdef_wcol);
+ drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol, pos, color);
+ drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color);
}
if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
- drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol);
- drawlattice__point(lt, dl, u, v, w, actdef_wcol);
+ drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol, pos, color);
+ drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color);
}
if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
- drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol);
- drawlattice__point(lt, dl, u, v, w, actdef_wcol);
+ drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol, pos, color);
+ drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color);
}
}
}
}
- glEnd();
+
+ immEnd();
+ immUnbindProgram();
if (is_edit) {
BPoint *actbp = BKE_lattice_active_point_get(lt);
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
-
- lattice_draw_verts(lt, dl, actbp, 0);
- lattice_draw_verts(lt, dl, actbp, 1);
-
+
+ VertexFormat *v_format = immVertexFormat();
+ unsigned int v_pos = VertexFormat_add_attrib(v_format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int v_color = VertexFormat_add_attrib(v_format, "color", COMP_F32, 4, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+
+ lattice_draw_verts(lt, dl, actbp, 0, v_pos, v_color);
+ lattice_draw_verts(lt, dl, actbp, 1, v_pos, v_color);
+
+ immUnbindProgram();
+
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
}
@@ -2401,6 +2534,7 @@ typedef struct drawDMVertSel_userData {
int active;
unsigned char *col[3]; /* (base, sel, act) */
char sel_prev;
+ unsigned int pos, color;
} drawDMVertSel_userData;
static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3],
@@ -2412,17 +2546,18 @@ static void drawSelectedVertices__mapFunc(void *userData, int index, const float
if (!(mv->flag & ME_HIDE)) {
const char sel = (index == data->active) ? 2 : (mv->flag & SELECT);
if (sel != data->sel_prev) {
- glColor3ubv(data->col[sel]);
+ immAttrib3ubv(data->color, data->col[sel]);
data->sel_prev = sel;
}
- glVertex3fv(co);
+ immVertex3fv(data->pos, co);
}
}
static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
{
drawDMVertSel_userData data;
+ VertexFormat *format = immVertexFormat();
/* TODO define selected color */
unsigned char base_col[3] = {0x0, 0x0, 0x0};
@@ -2437,9 +2572,18 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
data.col[1] = sel_col;
data.col[2] = act_col;
- glBegin(GL_POINTS);
+ data.color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ if (dm->getNumVerts(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ immBeginAtMost(PRIM_POINTS, dm->getNumVerts(dm));
dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* ************** DRAW MESH ****************** */
@@ -2486,25 +2630,34 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, const float
copy_v3_v3(n, no);
}
- glVertex3fv(cent);
- glVertex3f(cent[0] + n[0] * data->normalsize,
- cent[1] + n[1] * data->normalsize,
- cent[2] + n[2] * data->normalsize);
+ immVertex3fv(data->pos, cent);
+ immVertex3f(data->pos, cent[0] + n[0] * data->normalsize,
+ cent[1] + n[1] * data->normalsize,
+ cent[2] + n[2] * data->normalsize);
}
}
-static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id)
{
+ VertexFormat *format = immVertexFormat();
drawDMNormal_userData data;
data.bm = em->bm;
data.normalsize = scene->toolsettings->normalsize;
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
calcDrawDMNormalScale(ob, &data);
- glBegin(GL_LINES);
+ if (dm->getNumPolys(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(theme_id);
+
+ immBeginAtMost(PRIM_LINES, dm->getNumPolys(dm) * 2);
dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
@@ -2515,16 +2668,28 @@ static void draw_dm_face_centers__mapFunc(void *userData, int index, const float
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) &&
(BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select))
{
- glVertex3fv(cent);
+ immVertex3fv(data->pos, cent);
}
}
-static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select)
+static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select, const unsigned char fcol[3])
{
- drawBMSelect_userData data = {em->bm, select};
+ VertexFormat *format = immVertexFormat();
+
+ drawBMSelect_userData data;
+ data.bm = em->bm;
+ data.select = select;
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ if (dm->getNumPolys(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(fcol);
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, dm->getNumPolys(dm));
dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
@@ -2551,71 +2716,83 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float
copy_v3_v3(n, no);
}
- glVertex3fv(co);
- glVertex3f(co[0] + n[0] * data->normalsize,
- co[1] + n[1] * data->normalsize,
- co[2] + n[2] * data->normalsize);
+ immVertex3fv(data->pos, co);
+ immVertex3f(data->pos, co[0] + n[0] * data->normalsize,
+ co[1] + n[1] * data->normalsize,
+ co[2] + n[2] * data->normalsize);
}
}
-static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id)
{
drawDMNormal_userData data;
+ VertexFormat *format = immVertexFormat();
data.bm = em->bm;
data.normalsize = scene->toolsettings->normalsize;
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
calcDrawDMNormalScale(ob, &data);
- glBegin(GL_LINES);
+ if (dm->getNumVerts(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(theme_id);
+
+ immBeginAtMost(PRIM_LINES, dm->getNumVerts(dm) * 2);
dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
-/* Draw verts with color set based on selection */
-static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
- const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+static void draw_dm_verts_skin_root__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
drawDMVerts_userData *data = userData;
BMVert *eve = BM_vert_at_index(data->bm, index);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
/* skin nodes: draw a red circle around the root node(s) */
- if (data->cd_vskin_offset != -1) {
- const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
- if (vs->flag & MVERT_SKIN_ROOT) {
- float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
- glEnd();
-
- glColor4ubv(data->th_skin_root);
- drawcircball(GL_LINES, co, radius, data->imat);
-
- glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
- glBegin(GL_POINTS);
- }
+ const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
+ if (vs->flag & MVERT_SKIN_ROOT) {
+ float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
+ imm_drawcircball(co, radius, data->imat, data->pos);
}
+ }
+}
+/* Draw verts with color set based on selection */
+static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ drawDMVerts_userData *data = userData;
+ BMVert *eve = BM_vert_at_index(data->bm, index);
+
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
/* draw active in a different color - no need to stop/start point drawing for this :D */
if (eve == data->eve_act) {
- glColor4ubv(data->th_editmesh_active);
- glVertex3fv(co);
-
- /* back to regular vertex color */
- glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
+ immAttrib4ubv(data->color, data->th_editmesh_active);
+ immVertex3fv(data->pos, co);
}
else {
- glVertex3fv(co);
+ immAttrib4ubv(data->color, data->sel ? data->th_vertex_select : data->th_vertex);
+ immVertex3fv(data->pos, co);
}
}
}
static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act,
- RegionView3D *rv3d)
+ RegionView3D *rv3d, const unsigned char col[4])
{
+ VertexFormat *format = immVertexFormat();
+
drawDMVerts_userData data;
data.sel = sel;
data.eve_act = eve_act;
data.bm = em->bm;
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
/* Cache theme values */
UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active);
@@ -2623,16 +2800,37 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer
UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex);
UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root);
- /* For skin root drawing */
- data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
+ /* Set correct alpha */
+ data.th_editmesh_active[3] = data.th_vertex_select[3] = data.th_vertex[3] = data.th_skin_root[3] = col[3];
+
/* view-aligned matrix */
mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
invert_m4(data.imat);
+ if (dm->getNumVerts(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+
+ immBeginAtMost(PRIM_POINTS, dm->getNumVerts(dm));
dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
+
+ /* For skin root drawing */
+ data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
+
+ if (data.cd_vskin_offset != -1) {
+ data.pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4ubv(data.th_skin_root);
+
+ dm->foreachMappedVert(dm, draw_dm_verts_skin_root__mapFunc, &data, DM_FOREACH_NOP);
+
+ immUnbindProgram();
+ }
}
/* Draw edges with color set based on selection */
@@ -2938,24 +3136,32 @@ static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int
}
mul_v3_fl(vec, data->normalsize);
add_v3_v3(vec, co);
- glVertex3fv(co);
- glVertex3fv(vec);
+ immVertex3fv(data->pos, co);
+ immVertex3fv(data->pos, vec);
}
}
}
-static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id)
{
drawDMNormal_userData data;
data.bm = em->bm;
data.normalsize = scene->toolsettings->normalsize;
+ data.pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ if (dm->getNumLoops(dm) == 0) return;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(theme_id);
calcDrawDMNormalScale(ob, &data);
- glBegin(GL_LINES);
+ immBeginAtMost(PRIM_LINES, dm->getNumLoops(dm) * 2);
dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* Draw faces with color set based on selection
@@ -3072,7 +3278,7 @@ static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
if (data.cd_layer_offset != -1) {
- glLineWidth(3.0);
+ glLineWidth(3.0f);
dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data);
}
}
@@ -3102,8 +3308,10 @@ static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset);
if (bweight != 0.0f) {
- UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_BEVEL, bweight);
- glVertex3fv(co);
+ unsigned char col[3];
+ UI_GetThemeColorBlend3ubv(TH_VERTEX, TH_VERTEX_BEVEL, bweight, col);
+ immAttrib3ubv(data->col, col);
+ immVertex3fv(data->pos, co);
}
}
}
@@ -3117,11 +3325,21 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
data.bm = em->bm;
data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT);
+ /* is that ever true? */
if (data.cd_layer_offset != -1) {
- glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
- glBegin(GL_POINTS);
+ VertexFormat *format = immVertexFormat();
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2.0f);
+
+ immBeginAtMost(PRIM_POINTS, dm->getNumVerts(dm));
dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
}
else {
@@ -3131,7 +3349,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
if (data.cd_layer_offset != -1) {
- glLineWidth(3.0);
+ glLineWidth(3.0f);
dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data);
}
}
@@ -3152,7 +3370,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
{
ToolSettings *ts = scene->toolsettings;
- if (v3d->zbuf) glDepthMask(0); /* disable write in zbuffer, zbuf select */
+ if (v3d->zbuf) glDepthMask(GL_FALSE); /* disable write in zbuffer, zbuf select */
for (int sel = 0; sel < 2; sel++) {
unsigned char col[4], fcol[4];
@@ -3182,15 +3400,12 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
}
if (ts->selectmode & SCE_SELECT_VERTEX) {
- glPointSize(size);
- glColor4ubv(col);
- draw_dm_verts(em, cageDM, sel, eve_act, rv3d);
+ draw_dm_verts(em, cageDM, sel, eve_act, rv3d, col);
}
if (check_ob_drawface_dot(scene, v3d, obedit->dt)) {
glPointSize(fsize);
- glColor4ubv(fcol);
- draw_dm_face_centers(em, cageDM, sel);
+ draw_dm_face_centers(em, cageDM, sel, fcol);
}
if (pass == 0) {
@@ -3200,7 +3415,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
}
}
- if (v3d->zbuf) glDepthMask(1);
+ if (v3d->zbuf) glDepthMask(GL_TRUE);
}
static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
@@ -3307,11 +3522,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) {
BoundBox bb;
- bglMats mats = {{0}};
const rcti rect = {0, ar->winx, 0, ar->winy};
- view3d_get_transformation(ar, ar->regiondata, em->ob, &mats);
- ED_view3d_clipping_calc(&bb, clip_planes, &mats, &rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, ar, em->ob, &rect);
}
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
@@ -3675,7 +3888,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
}
}
-static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
+static void draw_em_fancy(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d,
Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
{
@@ -3684,7 +3897,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
const bool use_occlude_wire = (dt > OB_WIRE) && (v3d->flag2 & V3D_OCCLUDE_WIRE);
bool use_depth_offset = false;
- glLineWidth(1);
+ glLineWidth(1.0f);
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
@@ -3693,7 +3906,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_mesh_paint_weight_faces(finalDM, true, draw_em_fancy__setFaceOpts, me->edit_btmesh);
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
use_depth_offset = true;
}
else {
@@ -3713,7 +3926,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
else if (check_object_draw_texture(scene, v3d, dt)) {
- if (draw_glsl_material(scene, ob, v3d, dt)) {
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind,
@@ -3723,7 +3936,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
glFrontFace(GL_CCW);
}
else {
- draw_mesh_textured(scene, v3d, rv3d, ob, finalDM, 0);
+ draw_mesh_textured(scene, sl, v3d, rv3d, ob, finalDM, 0);
}
}
else {
@@ -3740,7 +3953,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
UI_ThemeColor(TH_WIRE_EDIT);
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
use_depth_offset = true;
}
else {
@@ -3790,7 +4003,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
/* don't draw unselected faces, only selected, this is MUCH nicer when texturing */
if (check_object_draw_texture(scene, v3d, dt))
@@ -3806,7 +4019,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
else if (efa_act) {
/* even if draw faces is off it would be nice to draw the stipple face
@@ -3821,7 +4034,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
glEnable(GL_BLEND);
- glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */
#ifdef WITH_FREESTYLE
draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act);
@@ -3830,7 +4043,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
glDisable(GL_BLEND);
- glDepthMask(1); /* restore write in zbuffer */
+ glDepthMask(GL_TRUE); /* restore write in zbuffer */
}
/* here starts all fancy draw-extra over */
@@ -3844,7 +4057,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
else {
if (me->drawflag & ME_DRAWSEAMS) {
UI_ThemeColor(TH_EDGE_SEAM);
- glLineWidth(2);
+ glLineWidth(2.0f);
draw_dm_edges_seams(em, cageDM);
@@ -3853,7 +4066,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
if (me->drawflag & ME_DRAWSHARP) {
UI_ThemeColor(TH_EDGE_SHARP);
- glLineWidth(2);
+ glLineWidth(2.0f);
draw_dm_edges_sharp(em, cageDM);
@@ -3863,7 +4076,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#ifdef WITH_FREESTYLE
if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) {
UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
- glLineWidth(2);
+ glLineWidth(2.0f);
draw_dm_edges_freestyle(em, cageDM);
@@ -3878,7 +4091,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_dm_bweights(em, scene, cageDM);
}
- glLineWidth(1);
+ glLineWidth(1.0f);
draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act);
}
@@ -3886,16 +4099,13 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d);
if (me->drawflag & ME_DRAWNORMALS) {
- UI_ThemeColor(TH_NORMAL);
- draw_dm_face_normals(em, scene, ob, cageDM);
+ draw_dm_face_normals(em, scene, ob, cageDM, TH_NORMAL);
}
if (me->drawflag & ME_DRAW_VNORMALS) {
- UI_ThemeColor(TH_VNORMAL);
- draw_dm_vert_normals(em, scene, ob, cageDM);
+ draw_dm_vert_normals(em, scene, ob, cageDM, TH_VNORMAL);
}
if (me->drawflag & ME_DRAW_LNORMALS) {
- UI_ThemeColor(TH_LNORMAL);
- draw_dm_loop_normals(em, scene, ob, cageDM);
+ draw_dm_loop_normals(em, scene, ob, cageDM, TH_LNORMAL);
}
if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN |
@@ -3916,7 +4126,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
if (use_depth_offset) {
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
ED_view3d_polygon_offset(rv3d, 0.0);
GPU_object_material_unbind();
}
@@ -3927,15 +4137,97 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
#endif
}
+static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D *UNUSED(v3d),
+ Object *UNUSED(ob), Mesh *me, BMEditMesh *UNUSED(em), DerivedMesh *UNUSED(cageDM), DerivedMesh *UNUSED(finalDM), const char UNUSED(dt))
+{
+ /* for now... something simple! */
+ Batch *surface = DRW_mesh_batch_cache_get_all_triangles(me);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+
+ glEnable(GL_BLEND);
+
+ /* disable depth writes for transparent surface, so it doesn't interfere with itself */
+ glDepthMask(GL_FALSE);
+
+ Batch_set_builtin_program(surface, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform4f(surface, "color", 1.0f, 0.5f, 0.0f, 0.5f);
+ Batch_draw(surface);
+
+#if 0 /* until I understand finalDM better */
+ if (finalDM != cageDM) {
+ puts("finalDM != cageDM");
+ Batch *finalSurface = MBC_get_all_triangles(finalDM);
+ Batch_set_builtin_program(finalSurface, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform4f(finalSurface, "color", 0.0f, 0.0f, 0.0f, 0.05f);
+ Batch_draw(finalSurface);
+ }
+#endif
+
+ glDepthMask(GL_TRUE);
+
+ /* now write surface depth so other objects won't poke through
+ * NOTE: does not help as much as desired
+ * TODO: draw edit object last to avoid this mess
+ */
+ Batch_set_builtin_program(surface, GPU_SHADER_3D_DEPTH_ONLY);
+ Batch_draw(surface);
+
+ if (GLEW_VERSION_3_2) {
+#if 0
+ Batch *overlay = DRW_mesh_batch_cache_get_overlay_edges(me);
+ Batch_set_builtin_program(overlay, GPU_SHADER_EDGES_OVERLAY);
+ Batch_Uniform2f(overlay, "viewportSize", ar->winx, ar->winy);
+ Batch_draw(overlay);
+#endif
+
+#if 0 /* TODO: use this SIMPLE variant for pure triangle meshes */
+ Batch_set_builtin_program(surface, GPU_SHADER_EDGES_OVERLAY_SIMPLE);
+ /* use these defaults:
+ * const float edgeColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ * Batch_Uniform4f(surface, "fillColor", edgeColor[0], edgeColor[1], edgeColor[2], 0.0f);
+ * Batch_Uniform4fv(surface, "outlineColor", edgeColor);
+ * Batch_Uniform1f(surface, "outlineWidth", 1.0f);
+ */
+ Batch_Uniform2f(surface, "viewportSize", ar->winx, ar->winy);
+ Batch_draw(surface);
+#endif
+ }
+ else {
+ Batch *edges = DRW_mesh_batch_cache_get_all_edges(me);
+ Batch_set_builtin_program(edges, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform4f(edges, "color", 0.0f, 0.0f, 0.0f, 1.0f);
+ glEnable(GL_LINE_SMOOTH);
+ glLineWidth(1.5f);
+ Batch_draw(edges);
+ glDisable(GL_LINE_SMOOTH);
+ }
+
+#if 0 /* looks good even without points */
+ Batch *verts = MBC_get_all_verts(me);
+ glEnable(GL_BLEND);
+
+ Batch_set_builtin_program(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ Batch_Uniform4f(verts, "color", 0.0f, 0.0f, 0.0f, 1.0f);
+ Batch_Uniform1f(verts, "size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f);
+ Batch_draw(verts);
+
+ glDisable(GL_BLEND);
+#endif
+}
+
/* Mesh drawing routines */
-static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
+void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */
{
if ((v3d->transp == false) && /* not when we draw the transparent pass */
(ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
{
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
+
+ if (ob_wire_col) glColor4ubv(ob_wire_col);
/* if transparent, we cannot draw the edges for solid select... edges
* have no material info. GPU_object_material_visible will skip the
@@ -3949,7 +4241,49 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
dm->drawEdges(dm, 0, 1);
}
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
+ }
+}
+
+static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active)
+{
+ if ((v3d->transp == false) && /* not when we draw the transparent pass */
+ (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
+ {
+ glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
+ glDepthMask(GL_FALSE);
+
+ float outline_color[4];
+ UI_GetThemeColor4fv((is_active ? TH_ACTIVE : TH_SELECT), outline_color);
+
+#if 1 /* new version that draws only silhouette edges */
+ Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me);
+
+ if (rv3d->persp == RV3D_ORTHO) {
+ Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+ /* set eye vector, transformed to object coords */
+ float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
+ mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye);
+ Batch_Uniform3fv(fancy_edges, "eye", eye);
+ }
+ else {
+ Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+ }
+
+ Batch_Uniform1b(fancy_edges, "drawFront", false);
+ Batch_Uniform1b(fancy_edges, "drawBack", false);
+ Batch_Uniform1b(fancy_edges, "drawSilhouette", true);
+ Batch_Uniform4fv(fancy_edges, "silhouetteColor", outline_color);
+
+ Batch_draw(fancy_edges);
+#else /* alternate version that matches look of old viewport (but more efficient) */
+ Batch *batch = MBC_get_all_edges(dm);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ Batch_Uniform4fv(batch, "color", outline_color);
+ Batch_draw(batch);
+#endif
+
+ glDepthMask(GL_TRUE);
}
}
@@ -3959,11 +4293,11 @@ static bool object_is_halo(Scene *scene, Object *ob)
return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
}
-static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+static void draw_mesh_fancy(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
#ifdef WITH_GAMEENGINE
- Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, scene) : base->object;
+ Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, sl) : base->object;
#else
Object *ob = base->object;
#endif
@@ -3971,7 +4305,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
bool /* no_verts,*/ no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- const bool is_obact = (ob == OBACT);
+ const bool is_obact = (ob == OBACT_NEW);
int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
if (!dm)
@@ -4007,12 +4341,12 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (dt == OB_BOUNDBOX) {
if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else if ((no_faces && no_edges) ||
((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
{
- glPointSize(1.5);
+ glPointSize(1.5f);
dm->drawVerts(dm);
}
else if ((dt == OB_WIRE) || no_faces) {
@@ -4025,19 +4359,19 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
- (base->flag & SELECT) &&
+ (base->flag & BASE_SELECTED) &&
!(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
(draw_wire == OBDRAW_WIRE_OFF))
{
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
- if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ if (draw_glsl_material(scene, sl, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
Paint *p;
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
GPUVertexAttribs gattribs;
float planes[4][4];
float (*fpl)[4] = NULL;
@@ -4045,7 +4379,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (ob->sculpt->partial_redraw) {
if (ar->do_draw & RGN_DRAW_PARTIAL) {
- ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
fpl = planes;
ob->sculpt->partial_redraw = 0;
}
@@ -4070,7 +4404,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
draw_mesh_face_select(rv3d, me, dm, false);
}
else {
- draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
+ draw_mesh_textured(scene, sl, v3d, rv3d, ob, dm, draw_flags);
}
if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
@@ -4096,11 +4430,11 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
/* draw outline */
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
- (base->flag & SELECT) &&
+ (base->flag & BASE_SELECTED) &&
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
/* materials arent compatible with vertex colors */
@@ -4120,23 +4454,23 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
- (base->flag & SELECT) &&
+ (base->flag & BASE_SELECTED) &&
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if (ob->sculpt && (p = BKE_paint_get_active(scene))) {
+ if (ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
float planes[4][4];
float (*fpl)[4] = NULL;
const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
if (ob->sculpt->partial_redraw) {
if (ar->do_draw & RGN_DRAW_PARTIAL) {
- ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
fpl = planes;
ob->sculpt->partial_redraw = 0;
}
@@ -4177,7 +4511,9 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f);
+ float color[3];
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f, color);
+ glColor3fv(color);
}
else {
glColor3ubv(ob_wire_col);
@@ -4195,14 +4531,14 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
*/
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */
}
glLineWidth(1.0f);
dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
ED_view3d_polygon_offset(rv3d, 0.0);
}
}
@@ -4221,7 +4557,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
/* returns true if nothing was drawn, for detecting to draw an object center */
-static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+static bool draw_mesh_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base,
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
Object *ob = base->object;
@@ -4233,7 +4569,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
/* If we are drawing shadows and any of the materials don't cast a shadow,
* then don't draw the object */
if (v3d->flag2 & V3D_RENDER_SHADOW) {
- for (int i = 1; i <= ob->totcol; ++i) {
+ for (int i = 0; i < ob->totcol; ++i) {
Material *ma = give_current_material(ob, i);
if (ma && !(ma->mode2 & MA_CASTSHADOW)) {
return true;
@@ -4275,13 +4611,13 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
if (use_material) {
if (dt > OB_WIRE) {
- const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
}
}
- draw_em_fancy(scene, ar, v3d, ob, em, cageDM, finalDM, dt);
+ draw_em_fancy(scene, sl, ar, v3d, ob, em, cageDM, finalDM, dt);
if (use_material) {
GPU_end_object_materials();
@@ -4294,16 +4630,16 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
/* ob->bb was set by derived mesh system, do NULL check just to be sure */
if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
if (dt > OB_WIRE) {
- const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
if (dt == OB_SOLID || glsl) {
const bool check_alpha = check_alpha_pass(base);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl,
(check_alpha) ? &do_alpha_after : NULL);
}
}
- draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ draw_mesh_fancy(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
GPU_end_object_materials();
@@ -4311,7 +4647,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
}
}
- if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* GPU_begin_object_materials checked if this is needed */
if (do_alpha_after) {
if (ob->dtx & OB_DRAWXRAY) {
@@ -4335,18 +4671,547 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
return retval;
}
+static void make_color_variations(const unsigned char base_ubyte[4], float low[4], float med[4], float high[4], const bool other_obedit)
+{
+ /* original idea: nice variations (lighter & darker shades) of base color
+ * current implementation uses input color as high; med & low get closer to background color
+ */
+
+ float bg[3];
+ UI_GetThemeColor3fv(TH_BACK, bg);
+
+ float base[4];
+ rgba_uchar_to_float(base, base_ubyte);
+
+ if (other_obedit) {
+ /* this object should fade away so user can focus on the object being edited */
+ interp_v3_v3v3(low, bg, base, 0.1f);
+ interp_v3_v3v3(med, bg, base, 0.2f);
+ interp_v3_v3v3(high, bg, base, 0.25f);
+ }
+ else {
+ interp_v3_v3v3(low, bg, base, 0.333f);
+ interp_v3_v3v3(med, bg, base, 0.667f);
+ copy_v3_v3(high, base);
+ }
+
+ /* use original alpha */
+ low[3] = base[3];
+ med[3] = base[3];
+ high[3] = base[3];
+}
+
+static void draw_mesh_fancy_new(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit)
+{
+ if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
+ /* too complicated! use existing methods */
+ /* TODO: move this into a separate depth pre-pass */
+ draw_mesh_fancy(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ return;
+ }
+
+#ifdef WITH_GAMEENGINE
+ Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, sl) : base->object;
+#else
+ Object *ob = base->object;
+#endif
+ Mesh *me = ob->data;
+ eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; /* could be bool draw_wire_overlay */
+ bool no_edges, no_faces;
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+ const bool is_obact = (ob == OBACT_NEW);
+ int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
+
+ if (!dm)
+ return;
+
+ const bool solid = dt >= OB_SOLID;
+ if (solid) {
+ DM_update_materials(dm, ob);
+ }
+
+ /* Check to draw dynamic paint colors (or weights from WeightVG modifiers).
+ * Note: Last "preview-active" modifier in stack will win! */
+ if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob))
+ draw_flags |= DRAW_MODIFIERS_PREVIEW;
+
+ /* Unwanted combination */
+ if (draw_flags & DRAW_FACE_SELECT) {
+ draw_wire = OBDRAW_WIRE_OFF;
+ }
+ else if (ob->dtx & OB_DRAWWIRE) {
+ draw_wire = OBDRAW_WIRE_ON;
+ }
+
+ /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */
+ if (dm->type == DM_TYPE_CCGDM) {
+ no_edges = !subsurf_has_edges(dm);
+ no_faces = !subsurf_has_faces(dm);
+ }
+ else {
+ no_edges = (dm->getNumEdges(dm) == 0);
+ no_faces = (dm->getNumPolys(dm) == 0);
+ }
+
+ if (solid) {
+ /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ }
+
+ if (dt == OB_BOUNDBOX) {
+ if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
+ }
+ else if ((no_faces && no_edges) ||
+ ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
+ {
+ glPointSize(1.5f);
+ // dm->drawVerts(dm);
+ // TODO: draw smooth round points as a batch
+ }
+ else if ((dt == OB_WIRE) || no_faces) {
+ draw_wire = OBDRAW_WIRE_ON;
+
+ /* enable depth for wireframes */
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ glLineWidth(1.0f);
+
+#if 1 /* fancy wireframes */
+
+ Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me);
+
+ if (rv3d->persp == RV3D_ORTHO) {
+ Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+ /* set eye vector, transformed to object coords */
+ float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
+ mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye);
+ Batch_Uniform3fv(fancy_edges, "eye", eye);
+ }
+ else {
+ Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+ }
+
+ float frontColor[4];
+ float backColor[4];
+ float outlineColor[4];
+ make_color_variations(ob_wire_col, backColor, frontColor, outlineColor, other_obedit);
+
+ Batch_Uniform4fv(fancy_edges, "frontColor", frontColor);
+ Batch_Uniform4fv(fancy_edges, "backColor", backColor);
+ Batch_Uniform1b(fancy_edges, "drawFront", true);
+ Batch_Uniform1b(fancy_edges, "drawBack", true); /* false here = backface cull */
+ Batch_Uniform1b(fancy_edges, "drawSilhouette", false);
+
+ Batch_draw(fancy_edges);
+
+ /* extra oomph for the silhouette contours */
+ glLineWidth(2.0f);
+ Batch_use_program(fancy_edges); /* hack to make the following uniforms stick */
+ Batch_Uniform1b(fancy_edges, "drawFront", false);
+ Batch_Uniform1b(fancy_edges, "drawBack", false);
+ Batch_Uniform1b(fancy_edges, "drawSilhouette", true);
+ Batch_Uniform4fv(fancy_edges, "silhouetteColor", outlineColor);
+
+ Batch_draw(fancy_edges);
+
+#else /* simple wireframes */
+
+ Batch *batch = MBC_get_all_edges(dm);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+ float color[4];
+ rgba_uchar_to_float(color, ob_wire_col);
+
+ Batch_Uniform4fv(batch, "color", color);
+
+ Batch_draw(batch);
+#endif
+ }
+ else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
+ check_object_draw_texture(scene, v3d, dt))
+ {
+ bool draw_loose = true;
+
+ if ((v3d->flag & V3D_SELECT_OUTLINE) &&
+ ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
+ (base->flag & BASE_SELECTED) &&
+ !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
+ (draw_wire == OBDRAW_WIRE_OFF))
+ {
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW));
+ }
+
+ if (draw_glsl_material(scene, sl, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ Paint *p;
+
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
+ GPUVertexAttribs gattribs;
+ float planes[4][4];
+ float (*fpl)[4] = NULL;
+ const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+
+ if (ob->sculpt->partial_redraw) {
+ if (ar->do_draw & RGN_DRAW_PARTIAL) {
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
+ fpl = planes;
+ ob->sculpt->partial_redraw = 0;
+ }
+ }
+
+ GPU_object_material_bind(1, &gattribs);
+ dm->drawFacesSolid(dm, fpl, fast, NULL);
+ draw_loose = false;
+ }
+ else
+ dm->drawFacesGLSL(dm, GPU_object_material_bind);
+
+ GPU_object_material_unbind();
+
+ glFrontFace(GL_CCW);
+
+ if (draw_flags & DRAW_FACE_SELECT)
+ draw_mesh_face_select(rv3d, me, dm, false);
+ }
+ else {
+ draw_mesh_textured(scene, sl, v3d, rv3d, ob, dm, draw_flags);
+ }
+
+ if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ glColor3ubv(ob_wire_col);
+ }
+ glLineWidth(1.0f);
+ dm->drawLooseEdges(dm);
+ }
+ }
+ }
+ else if (dt == OB_SOLID) {
+ if (draw_flags & DRAW_MODIFIERS_PREVIEW) {
+ /* for object selection draws no shade */
+ if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
+ /* TODO: draw basic faces with GPU_SHADER_3D_DEPTH_ONLY */
+ }
+ else {
+ const float specular[3] = {0.47f, 0.47f, 0.47f};
+
+ /* draw outline */
+ /* TODO: move this into a separate pass */
+ if ((v3d->flag & V3D_SELECT_OUTLINE) &&
+ ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
+ (base->flag & BASE_SELECTED) &&
+ (draw_wire == OBDRAW_WIRE_OFF) &&
+ (ob->sculpt == NULL))
+ {
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW));
+ }
+
+ /* materials arent compatible with vertex colors */
+ GPU_end_object_materials();
+
+ /* set default specular */
+ GPU_basic_shader_colors(NULL, specular, 35, 1.0f);
+ GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
+
+ dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS);
+
+ GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ }
+ }
+ else {
+ Paint *p;
+
+ if ((v3d->flag & V3D_SELECT_OUTLINE) &&
+ ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
+ (base->flag & BASE_SELECTED) &&
+ (draw_wire == OBDRAW_WIRE_OFF) &&
+ (ob->sculpt == NULL))
+ {
+ /* TODO: move this into a separate pass */
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW));
+ }
+
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+
+ if (ob->sculpt && (p = BKE_paint_get_active(scene, sl))) {
+ float planes[4][4];
+ float (*fpl)[4] = NULL;
+ const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+
+ if (ob->sculpt->partial_redraw) {
+ if (ar->do_draw & RGN_DRAW_PARTIAL) {
+ ED_sculpt_redraw_planes_get(planes, ar, ob);
+ fpl = planes;
+ ob->sculpt->partial_redraw = 0;
+ }
+ }
+
+ dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind);
+ }
+ else
+ dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
+
+ glFrontFace(GL_CCW);
+
+ GPU_object_material_unbind();
+
+ if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ glColor3ubv(ob_wire_col);
+ }
+ glLineWidth(1.0f);
+ dm->drawLooseEdges(dm);
+ }
+ }
+ }
+ else if (dt == OB_PAINT) {
+ draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
+
+ /* since we already draw wire as wp guide, don't draw over the top */
+ draw_wire = OBDRAW_WIRE_OFF;
+ }
+
+ if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */
+ /* when overriding with render only, don't bother */
+ (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)) // <-- is this "== 0" in the right spot???
+ {
+ /* When using wireframe object draw in particle edit mode
+ * the mesh gets in the way of seeing the particles, fade the wire color
+ * with the background. */
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ /* TODO:
+ * Batch_UniformColor4ubv(ob_wire_col);
+ */
+ }
+
+ /* If drawing wire and drawtype is not OB_WIRE then we are
+ * overlaying the wires.
+ *
+ * No need for polygon offset because new technique is AWESOME.
+ */
+#if 0
+ glLineWidth(1.0f);
+ dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
+#else
+ /* something */
+#endif
+ }
+
+#if 0 // (merwin) what is this for?
+ if (is_obact && BKE_paint_select_vert_test(ob)) {
+ const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0;
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if (!use_depth) glDisable(GL_DEPTH_TEST);
+ else ED_view3d_polygon_offset(rv3d, 1.0);
+ drawSelectedVertices(dm, ob->data);
+ if (!use_depth) glEnable(GL_DEPTH_TEST);
+ else ED_view3d_polygon_offset(rv3d, 0.0);
+ }
+#endif
+
+ dm->release(dm);
+}
+
+static bool UNUSED_FUNCTION(draw_mesh_object_new)(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
+{
+ Object *ob = base->object;
+ Object *obedit = scene->obedit;
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ bool do_alpha_after = false, drawlinked = false, retval = false;
+
+ if (v3d->flag2 & V3D_RENDER_SHADOW) {
+ /* TODO: handle shadow pass separately */
+ return true;
+ }
+
+ if (obedit && ob != obedit && ob->data == obedit->data) {
+ if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {}
+ else if (ob->modifiers.first || obedit->modifiers.first) {}
+ else drawlinked = true;
+ }
+
+ /* backface culling */
+ const bool solid = dt > OB_WIRE;
+ const bool cullBackface = solid && (v3d->flag2 & V3D_BACKFACE_CULLING);
+ if (cullBackface) {
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ if (ob == obedit || drawlinked) {
+ DerivedMesh *finalDM, *cageDM;
+
+ if (obedit != ob) {
+ /* linked to the edit object */
+ finalDM = cageDM = editbmesh_get_derived_base(
+ ob, em, scene->customdata_mask);
+ }
+ else {
+ cageDM = editbmesh_get_derived_cage_and_final(
+ scene, ob, em, scene->customdata_mask,
+ &finalDM);
+ }
+
+ const bool use_material = solid && ((me->drawflag & ME_DRAWEIGHT) == 0);
+
+#if 0 // why update if not being used?
+ DM_update_materials(finalDM, ob);
+ if (cageDM != finalDM) {
+ DM_update_materials(cageDM, ob);
+ }
+#endif // moved to below
+
+ if (use_material) {
+ DM_update_materials(finalDM, ob);
+ if (cageDM != finalDM) {
+ DM_update_materials(cageDM, ob);
+ }
+
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
+ }
+
+ draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt);
+
+ if (use_material) {
+ GPU_end_object_materials();
+ }
+
+ if (obedit != ob)
+ finalDM->release(finalDM);
+ }
+ else {
+ /* ob->bb was set by derived mesh system, do NULL check just to be sure */
+ if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
+ if (solid) {
+ const bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+
+ if (dt == OB_SOLID || glsl) {
+ const bool check_alpha = check_alpha_pass(base);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl,
+ (check_alpha) ? &do_alpha_after : NULL);
+ }
+ }
+
+ const bool other_obedit = obedit && (obedit != ob);
+
+ draw_mesh_fancy_new(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit);
+
+ GPU_end_object_materials();
+
+ if (me->totvert == 0) retval = true;
+ }
+ }
+
+ if (cullBackface)
+ glDisable(GL_CULL_FACE);
+
+ return retval;
+}
+
/* ************** DRAW DISPLIST ****************** */
+static void drawDispListVerts(PrimitiveType prim_type, const void *data, unsigned int vert_ct, const unsigned char wire_col[3])
+{
+ VertexFormat format = {0};
+ unsigned int pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, vert_ct);
+
+ VertexBuffer_fill_attrib(vbo, pos_id, data);
+
+ Batch *batch = Batch_create(prim_type, vbo, NULL);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ if (wire_col) {
+ Batch_Uniform4f(batch, "color", wire_col[0]/255.0f, wire_col[1]/255.0f, wire_col[2]/255.0f, 1.0f);
+ }
+ Batch_draw(batch);
+ Batch_discard_all(batch);
+}
+
+/* convert dispList with elem indices to batch, only support triangles and quads
+ * XXX : This is a huge perf issue. We should cache the resulting batches inside the object instead.
+ * But new viewport will do it anyway
+ * TODO implement flat drawing */
+static void drawDispListElem(
+ bool quads, bool UNUSED(smooth), bool ndata_is_single,
+ const float *data, const float *ndata, unsigned int data_len,
+ const int *elem, unsigned int elem_len, const unsigned char wire_col[3])
+{
+ VertexFormat format = {0};
+ int i;
+ const int *idx = elem;
+ unsigned int pos_id, nor_id;
+
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ if (ndata) {
+ if (ndata_is_single) {
+ /* pass */
+ }
+ else {
+ nor_id = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+ }
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, (quads) ? elem_len * 2 : elem_len, 0xffffffff);
+
+ if (quads) {
+ for (i = elem_len; i; --i, idx += 4) {
+ add_triangle_vertices(&elb, idx[0], idx[1], idx[2]);
+ add_triangle_vertices(&elb, idx[0], idx[2], idx[3]);
+ }
+ }
+ else {
+ for (i = elem_len; i; --i, idx += 3) {
+ add_triangle_vertices(&elb, idx[0], idx[1], idx[2]);
+ }
+ }
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, data_len);
+
+ VertexBuffer_fill_attrib(vbo, pos_id, data);
+
+ if (ndata) {
+ if (ndata_is_single) {
+ /* TODO: something like glNormal for a single value */
+ }
+ else {
+ VertexBuffer_fill_attrib(vbo, nor_id, ndata);
+ }
+ }
+
+ Batch *batch = Batch_create(PRIM_TRIANGLES, vbo, ElementList_build(&elb));
+ Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ if (wire_col) {
+ Batch_Uniform4f(batch, "color", wire_col[0]/255.0f, wire_col[1]/255.0f, wire_col[2]/255.0f, 1.0f);
+ }
+ Batch_Uniform4f(batch, "color", 0.8f, 0.8f, 0.8f, 1.0f);
+ Batch_Uniform3f(batch, "light", 0.0f, 0.0f, 1.0f);
+ Batch_draw(batch);
+ Batch_discard_all(batch);
+}
/**
* \param dl_type_mask Only draw types matching this mask.
* \return true when nothing was drawn
*/
-static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask)
+static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask, const unsigned char wire_col[3])
{
if (dlbase == NULL) return true;
- glEnableClientState(GL_VERTEX_ARRAY);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for (DispList *dl = dlbase->first; dl; dl = dl->next) {
@@ -4357,83 +5222,76 @@ static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask)
if ((dl_type_mask & (1 << dl->type)) == 0) {
continue;
}
-
+
const float *data = dl->verts;
int parts;
switch (dl->type) {
case DL_SEGM:
-
- glVertexPointer(3, GL_FLOAT, 0, data);
-
for (parts = 0; parts < dl->parts; parts++)
- glDrawArrays(GL_LINE_STRIP, parts * dl->nr, dl->nr);
-
+ drawDispListVerts(PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col);
break;
- case DL_POLY:
-
- glVertexPointer(3, GL_FLOAT, 0, data);
+ case DL_POLY:
for (parts = 0; parts < dl->parts; parts++)
- glDrawArrays(GL_LINE_LOOP, parts * dl->nr, dl->nr);
-
+ drawDispListVerts(PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col);
break;
- case DL_SURF:
-
- glVertexPointer(3, GL_FLOAT, 0, data);
+ case DL_SURF:
for (parts = 0; parts < dl->parts; parts++) {
if (dl->flag & DL_CYCL_U)
- glDrawArrays(GL_LINE_LOOP, parts * dl->nr, dl->nr);
+ drawDispListVerts(PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col);
else
- glDrawArrays(GL_LINE_STRIP, parts * dl->nr, dl->nr);
+ drawDispListVerts(PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col);
}
+ float *data_aligned = MEM_mallocN(sizeof(float) * 3 * dl->parts, "aligned data");
for (int nr = 0; nr < dl->nr; nr++) {
int ofs = 3 * dl->nr;
+ int idx = 0;
data = (dl->verts) + 3 * nr;
parts = dl->parts;
- if (dl->flag & DL_CYCL_V) glBegin(GL_LINE_LOOP);
- else glBegin(GL_LINE_STRIP);
-
while (parts--) {
- glVertex3fv(data);
+ copy_v3_v3(data_aligned + idx, data);
data += ofs;
+ idx += 3;
}
- glEnd();
-#if 0
- /* (ton) this code crashes for me when resolv is 86 or higher... no clue */
- glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr);
- if (dl->flag & DL_CYCL_V)
- glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
- else
- glDrawArrays(GL_LINE_STRIP, 0, dl->parts);
-#endif
+ if (dl->flag & DL_CYCL_V)
+ drawDispListVerts(PRIM_LINE_LOOP, data_aligned, dl->parts, wire_col);
+ else
+ drawDispListVerts(PRIM_LINE_STRIP, data_aligned, dl->parts, wire_col);
}
+
+ if (data_aligned)
+ MEM_freeN(data_aligned);
+
break;
case DL_INDEX3:
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
+ drawDispListElem(
+ false, true, false,
+ dl->verts, NULL, dl->nr,
+ dl->index, dl->parts, wire_col);
break;
case DL_INDEX4:
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIGNED_INT, dl->index);
+ drawDispListElem(
+ true, true, false,
+ dl->verts, NULL, dl->nr,
+ dl->index, dl->parts, wire_col);
break;
}
}
- glDisableClientState(GL_VERTEX_ARRAY);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
return false;
}
-static bool drawDispListwire(ListBase *dlbase, const short ob_type)
+static bool drawDispListwire(ListBase *dlbase, const short ob_type, const unsigned char wire_col[3])
{
unsigned int dl_mask = 0xffffffff;
@@ -4442,27 +5300,25 @@ static bool drawDispListwire(ListBase *dlbase, const short ob_type)
dl_mask &= ~((1 << DL_INDEX3) | (1 << DL_INDEX4));
}
- return drawDispListwire_ex(dlbase, dl_mask);
+ return drawDispListwire_ex(dlbase, dl_mask, wire_col);
}
static bool index3_nors_incr = true;
-static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
+static void drawDispListsolid(ListBase *lb, Object *ob, const short UNUSED(dflag),
const unsigned char ob_wire_col[4], const bool use_glsl)
{
GPUVertexAttribs gattribs;
if (lb == NULL) return;
- glEnableClientState(GL_VERTEX_ARRAY);
-
/* track current material, -1 for none (needed for lines) */
short col = -1;
DispList *dl = lb->first;
while (dl) {
const float *data = dl->verts;
- const float *ndata = dl->nors;
+ //const float *ndata = dl->nors;
switch (dl->type) {
case DL_SEGM:
@@ -4472,15 +5328,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = -1;
}
- if ((dflag & DRAW_CONSTCOLOR) == 0)
- glColor3ubv(ob_wire_col);
-
- // glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- // glDrawArrays(GL_LINE_STRIP, 0, dl->nr);
- glBegin(GL_LINE_STRIP);
- for (int nr = dl->nr; nr; nr--, data += 3)
- glVertex3fv(data);
- glEnd();
+ drawDispListVerts(PRIM_LINE_STRIP, data, dl->nr, ob_wire_col);
}
break;
case DL_POLY:
@@ -4490,14 +5338,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = -1;
}
- /* for some reason glDrawArrays crashes here in half of the platforms (not osx) */
- //glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- //glDrawArrays(GL_LINE_LOOP, 0, dl->nr);
-
- glBegin(GL_LINE_LOOP);
- for (int nr = dl->nr; nr; nr--, data += 3)
- glVertex3fv(data);
- glEnd();
+ drawDispListVerts(PRIM_LINE_LOOP, data, dl->nr, ob_wire_col);
}
break;
case DL_SURF:
@@ -4507,15 +5348,12 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL);
col = dl->col;
}
- /* FLAT/SMOOTH shading for surfaces */
- glShadeModel((dl->rt & CU_SMOOTH) ? GL_SMOOTH : GL_FLAT);
+ const unsigned int verts_len = dl->nr * dl->parts;
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glNormalPointer(GL_FLOAT, 0, dl->nors);
- glDrawElements(GL_QUADS, 4 * dl->totindex, GL_UNSIGNED_INT, dl->index);
- glDisableClientState(GL_NORMAL_ARRAY);
- glShadeModel(GL_SMOOTH);
+ drawDispListElem(
+ true, (dl->rt & CU_SMOOTH) != 0, false,
+ dl->verts, dl->nors, verts_len,
+ dl->index, dl->totindex, ob_wire_col);
}
break;
@@ -4525,8 +5363,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = dl->col;
}
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-
+#if 0
/* for polys only one normal needed */
if (index3_nors_incr) {
glEnableClientState(GL_NORMAL_ARRAY);
@@ -4534,11 +5371,17 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
}
else
glNormal3fv(ndata);
+#endif
+ /* special case, 'nors' is a single value */
+ drawDispListElem(
+ false, (dl->rt & CU_SMOOTH) != 0, true,
+ dl->verts, dl->nors, dl->nr,
+ dl->index, dl->parts, ob_wire_col);
- glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
-
+#if 0
if (index3_nors_incr)
glDisableClientState(GL_NORMAL_ARRAY);
+#endif
break;
@@ -4548,18 +5391,16 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
col = dl->col;
}
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, dl->verts);
- glNormalPointer(GL_FLOAT, 0, dl->nors);
- glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIGNED_INT, dl->index);
- glDisableClientState(GL_NORMAL_ARRAY);
+ drawDispListElem(
+ true, true, false,
+ dl->verts, dl->nors, dl->nr,
+ dl->index, dl->parts, ob_wire_col);
break;
}
dl = dl->next;
}
- glDisableClientState(GL_VERTEX_ARRAY);
glFrontFace(GL_CCW);
if (col != -1) {
@@ -4574,7 +5415,7 @@ static void drawCurveDMWired(Object *ob)
}
/* return true when nothing was drawn */
-static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
+static bool drawCurveDerivedMesh(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base, const char dt)
{
Object *ob = base->object;
DerivedMesh *dm = ob->derivedFinal;
@@ -4588,8 +5429,8 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
if (dt > OB_WIRE && dm->getNumPolys(dm)) {
- bool glsl = draw_glsl_material(scene, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
if (!glsl)
dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
@@ -4610,7 +5451,7 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
* Only called by #drawDispList
* \return true when nothing was drawn
*/
-static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+static bool drawDispList_nobackface(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
@@ -4640,10 +5481,10 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
if (!render_only) {
/* when we have faces, only draw loose-wire */
if (has_faces) {
- drawDispListwire_ex(lb, (1 << DL_SEGM));
+ drawDispListwire_ex(lb, (1 << DL_SEGM), ob_wire_col);
}
else {
- drawDispListwire(lb, ob->type);
+ drawDispListwire(lb, ob->type, ob_wire_col);
}
}
@@ -4651,26 +5492,26 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
/* pass */
}
else {
- if (draw_glsl_material(scene, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 1, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 0, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
- cpack(0);
- drawDispListwire(lb, ob->type);
+ unsigned char col[4] = {0, 0, 0, 0};
+ drawDispListwire(lb, ob->type, col);
}
}
index3_nors_incr = true;
}
else {
if (!render_only || BKE_displist_has_faces(lb)) {
- return drawDispListwire(lb, ob->type);
+ return drawDispListwire(lb, ob->type, ob_wire_col);
}
}
break;
@@ -4686,19 +5527,19 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
if (dl->nors == NULL) BKE_displist_normals_add(lb);
- if (draw_glsl_material(scene, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 1, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 0, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
}
else {
- return drawDispListwire(lb, ob->type);
+ return drawDispListwire(lb, ob->type, ob_wire_col);
}
break;
case OB_MBALL:
@@ -4711,19 +5552,19 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
if (solid) {
- if (draw_glsl_material(scene, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+ if (draw_glsl_material(scene, sl, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 1, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, 0, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
}
else {
- return drawDispListwire(lb, ob->type);
+ return drawDispListwire(lb, ob->type, ob_wire_col);
}
}
break;
@@ -4731,7 +5572,7 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
return false;
}
-static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+static bool drawDispList(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
bool retval;
@@ -4747,7 +5588,7 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
ensure_curve_cache(scene, base->object);
#endif
- if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == false) {
+ if (drawCurveDerivedMesh(scene, sl, v3d, rv3d, base, dt) == false) {
retval = false;
}
else {
@@ -4763,7 +5604,7 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
glFrontFace(mode);
- retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ retval = drawDispList_nobackface(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
if (mode != GL_CCW) {
glFrontFace(GL_CCW);
@@ -4778,16 +5619,63 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
}
/* *********** drawing for particles ************* */
-static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select)
+/* stride : offset size in bytes
+ * col[4] : the color to use when *color is NULL, can be also NULL */
+static void draw_vertex_array(PrimitiveType prim_type, const float *vert, const float *nor, const float *color, int stride, int vert_ct, float col[4])
+{
+ VertexFormat format = {0};
+ unsigned int pos_id, nor_id, col_id;
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ if (nor) nor_id = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ if (color) col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 3, KEEP_FLOAT);
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, vert_ct);
+
+ if (stride == 0) {
+ VertexBuffer_fill_attrib(vbo, pos_id, vert);
+ if (nor) VertexBuffer_fill_attrib(vbo, nor_id, nor);
+ if (color) VertexBuffer_fill_attrib(vbo, col_id, color);
+ }
+ else {
+ VertexBuffer_fill_attrib_stride(vbo, pos_id, stride, vert);
+ if (nor) VertexBuffer_fill_attrib_stride(vbo, nor_id, stride, nor);
+ if (color) VertexBuffer_fill_attrib_stride(vbo, col_id, stride, color);
+ }
+
+ Batch *batch = Batch_create(prim_type, vbo, NULL);
+ if (nor && color) {
+ Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR);
+ Batch_Uniform3f(batch, "light", 0.0f, 0.0f, 1.0f);
+ }
+ else if (nor) {
+ Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ Batch_Uniform3f(batch, "light", 0.0f, 0.0f, 1.0f);
+ if (col) Batch_Uniform4fv(batch, "color", col);
+ }
+ else if (color) {
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+ else {
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ if (col) Batch_Uniform4fv(batch, "color", col);
+ }
+ Batch_draw(batch);
+ Batch_discard_all(batch);
+}
+
+static void draw_particle_arrays_new(int draw_as, int ob_dt, int select,
+ const float *vert, const float *nor, const float *color,
+ int totpoint, float col[4])
{
/* draw created data arrays */
switch (draw_as) {
case PART_DRAW_AXIS:
case PART_DRAW_CROSS:
- glDrawArrays(GL_LINES, 0, 6 * totpoint);
+ draw_vertex_array(PRIM_LINES, vert, nor, color, 0, 6 * totpoint, col);
break;
case PART_DRAW_LINE:
- glDrawArrays(GL_LINES, 0, 2 * totpoint);
+ draw_vertex_array(PRIM_LINES, vert, nor, color, 0, 2 * totpoint, col);
break;
case PART_DRAW_BB:
if (ob_dt <= OB_WIRE || select)
@@ -4795,15 +5683,16 @@ static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int selec
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glDrawArrays(GL_QUADS, 0, 4 * totpoint);
+ draw_vertex_array(PRIM_TRIANGLES, vert, nor, color, 0, 6 * totpoint, col);
break;
default:
- glDrawArrays(GL_POINTS, 0, totpoint);
+ draw_vertex_array(PRIM_POINTS, vert, nor, color, 0, totpoint, col);
break;
}
}
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize,
- float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd)
+ float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd,
+ unsigned int pos)
{
float vec[3], vec2[3];
float *vd = NULL;
@@ -4913,24 +5802,19 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
}
case PART_DRAW_CIRC:
{
- drawcircball(GL_LINE_LOOP, state->co, pixsize, imat);
+ imm_drawcircball(state->co, pixsize, imat, pos);
break;
}
case PART_DRAW_BB:
{
float xvec[3], yvec[3], zvec[3], bb_center[3];
- if (cd) {
- cd[0] = cd[3] = cd[6] = cd[9] = ma_col[0];
- cd[1] = cd[4] = cd[7] = cd[10] = ma_col[1];
- cd[2] = cd[5] = cd[8] = cd[11] = ma_col[2];
- pdd->cd += 12;
- }
copy_v3_v3(bb->vec, state->co);
copy_v3_v3(bb->vel, state->vel);
psys_make_billboard(bb, xvec, yvec, zvec, bb_center);
-
+
+ /* First tri */
add_v3_v3v3(pdd->vd, bb_center, xvec);
add_v3_v3(pdd->vd, yvec); pdd->vd += 3;
@@ -4940,13 +5824,24 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
sub_v3_v3v3(pdd->vd, bb_center, xvec);
sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
+ /* Second tri */
+ add_v3_v3v3(pdd->vd, bb_center, xvec);
+ add_v3_v3(pdd->vd, yvec); pdd->vd += 3;
+
+ sub_v3_v3v3(pdd->vd, bb_center, xvec);
+ sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
+
add_v3_v3v3(pdd->vd, bb_center, xvec);
sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
- copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
+ if (cd) {
+ for (int i = 0; i < 6; i++, cd += 3, pdd->cd += 3) {
+ copy_v3_v3(cd, ma_col);
+ }
+ }
+ for (int i = 0; i < 6; i++, pdd->nd += 3) {
+ copy_v3_v3(pdd->nd, zvec);
+ }
break;
}
}
@@ -4954,7 +5849,8 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
ParticleKey *state, int draw_as,
float imat[4][4], ParticleBillboardData *bb, ParticleDrawData *pdd,
- const float ct, const float pa_size, const float r_tilt, const float pixsize_scale)
+ const float ct, const float pa_size, const float r_tilt, const float pixsize_scale,
+ unsigned int pos)
{
ParticleSettings *part = psys->part;
float pixsize;
@@ -4985,7 +5881,7 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
pixsize = ED_view3d_pixel_size(rv3d, state->co) * pixsize_scale;
- draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd);
+ draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd, pos);
}
/* unified drawing of all new particle systems draw types except dupli ob & group
* mostly tries to use vertex arrays for speed
@@ -5018,10 +5914,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
float cfra;
float ma_col[3] = {0.0f, 0.0f, 0.0f};
int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0;
- bool select = (ob->flag & SELECT) != 0, create_cdata = false, need_v = false;
+ bool select = (base->flag & BASE_SELECTED) != 0, create_cdata = false, need_v = false;
GLint polygonmode[2];
char numstr[32];
unsigned char tcol[4] = {0, 0, 0, 255};
+ unsigned int pos;
/* 1. */
if (part == NULL || !psys_check_enabled(ob, psys, G.is_rendering))
@@ -5083,16 +5980,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
copy_v3_v3(ma_col, &ma->r);
}
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(tcol);
- }
-
timestep = psys_get_timestep(&sim);
- if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) {
+ if ((ob->flag & OB_FROMGROUP) != 0) {
float mat[4][4];
mul_m4_m4m4(mat, ob->obmat, psys->imat);
- glMultMatrixf(mat);
+ gpuMultMatrix(mat);
}
/* needed for text display */
@@ -5212,7 +6105,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
tot_vec_size *= 2;
break;
case PART_DRAW_BB:
- tot_vec_size *= 4;
+ tot_vec_size *= 6; /* New OGL only understands tris, no choice here. */
create_ndata = 1;
break;
}
@@ -5266,6 +6159,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
totpoint = pdd->totpoint; /* draw data is up to date */
}
else {
+ if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) {
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ imm_cpack(0xFFFFFF);
+ }
for (a = 0, pa = pars; a < totpart + totchild; a++, pa++) {
/* setup per particle individual stuff */
if (a < totpart) {
@@ -5336,7 +6234,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
draw_particle_data(psys, rv3d,
&state, draw_as, imat, &bb, psys->pdd,
- ct, pa_size, r_tilt, pixsize_scale);
+ ct, pa_size, r_tilt, pixsize_scale, pos);
totpoint++;
drawn = 1;
@@ -5348,7 +6246,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
draw_particle_data(psys, rv3d,
&state, draw_as, imat, &bb, psys->pdd,
- pa_time, pa_size, r_tilt, pixsize_scale);
+ pa_time, pa_size, r_tilt, pixsize_scale, pos);
totpoint++;
drawn = 1;
@@ -5370,7 +6268,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (part->draw & PART_DRAW_SIZE) {
setlinestyle(3);
- drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
+ imm_drawcircball(state.co, pa_size, imat, pos);
setlinestyle(0);
}
@@ -5407,31 +6305,19 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
}
}
+ if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) {
+ immUnbindProgram();
+ }
}
}
/* 6. */
glGetIntegerv(GL_POLYGON_MODE, polygonmode);
- glEnableClientState(GL_VERTEX_ARRAY);
if (draw_as == PART_DRAW_PATH) {
ParticleCacheKey **cache, *path;
float *cdata2 = NULL;
- /* setup gl flags */
- if (1) { //ob_dt > OB_WIRE) {
- glEnableClientState(GL_NORMAL_ARRAY);
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (part->draw_col == PART_DRAW_COL_MAT)
- glEnableClientState(GL_COLOR_ARRAY);
- }
-
- // XXX test
- GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
- }
-
if (totchild && (part->draw & PART_DRAW_PARENT) == 0)
totpart = 0;
else if (psys->pathcache == NULL)
@@ -5442,41 +6328,28 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
path = cache[a];
if (path->segments > 0) {
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-
- if (1) { //ob_dt > OB_WIRE) {
- glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (part->draw_col == PART_DRAW_COL_MAT) {
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- }
- }
+ if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) {
+ draw_vertex_array(PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL);
+ }
+ else {
+ float color[4];
+ rgba_uchar_to_float(color, tcol);
+ draw_vertex_array(PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color);
}
-
- glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
}
if (part->type == PART_HAIR) {
if (part->draw & PART_DRAW_GUIDE_HAIRS) {
DerivedMesh *hair_dm = psys->hair_out_dm;
-
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
+
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
if (pa->totkey > 1) {
HairKey *hkey = pa->hair;
- glVertexPointer(3, GL_FLOAT, sizeof(HairKey), hkey->world_co);
-
-#if 0 /* XXX use proper theme color here */
- UI_ThemeColor(TH_NORMAL);
-#else
- glColor3f(0.58f, 0.67f, 1.0f);
-#endif
-
- glDrawArrays(GL_LINE_STRIP, 0, pa->totkey);
+ /* XXX use proper theme color here */
+ float color[4] = {0.58f, 0.67f, 1.0f, 1.0f};
+ draw_vertex_array(PRIM_LINE_STRIP, hkey->world_co, NULL, NULL, sizeof(HairKey), pa->totkey, color);
}
}
@@ -5484,30 +6357,36 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
MVert *mvert = hair_dm->getVertArray(hair_dm);
int i;
- glColor3f(0.9f, 0.4f, 0.4f);
-
- glBegin(GL_LINES);
+ unsigned int pos_id = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3f(0.9f, 0.4f, 0.4f);
+
+ unsigned int count = 0;
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
- for (i = 1; i < pa->totkey; ++i) {
- float v1[3], v2[3];
-
- copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co);
- copy_v3_v3(v2, mvert[pa->hair_index + i].co);
-
- mul_m4_v3(ob->obmat, v1);
- mul_m4_v3(ob->obmat, v2);
-
- glVertex3fv(v1);
- glVertex3fv(v2);
+ count += MAX2(pa->totkey - 1, 0);
+ }
+
+ if (count > 0) {
+ immBegin(PRIM_LINES, count * 2);
+ for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
+ for (i = 1; i < pa->totkey; ++i) {
+ float v1[3], v2[3];
+
+ copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co);
+ copy_v3_v3(v2, mvert[pa->hair_index + i].co);
+
+ mul_m4_v3(ob->obmat, v1);
+ mul_m4_v3(ob->obmat, v2);
+
+ immVertex3fv(pos_id, v1);
+ immVertex3fv(pos_id, v2);
+ }
}
+ immEnd();
}
- glEnd();
+
+ immUnbindProgram();
}
-
- glEnableClientState(GL_NORMAL_ARRAY);
- if ((dflag & DRAW_CONSTCOLOR) == 0)
- if (part->draw_col == PART_DRAW_COL_MAT)
- glEnableClientState(GL_COLOR_ARRAY);
}
if (part->draw & PART_DRAW_HAIR_GRID) {
@@ -5518,64 +6397,69 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
int *res = clmd->hair_grid_res;
int i;
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
+ unsigned int pos_id = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (select)
- UI_ThemeColor(TH_ACTIVE);
+ immUniformThemeColor(TH_ACTIVE);
else
- UI_ThemeColor(TH_WIRE);
- glBegin(GL_LINES);
- glVertex3f(gmin[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmin[1], gmin[2]);
- glVertex3f(gmax[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmax[1], gmin[2]);
- glVertex3f(gmax[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmax[1], gmin[2]);
- glVertex3f(gmin[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmin[1], gmin[2]);
+ immUniformThemeColor(TH_WIRE);
+
+ immBegin(PRIM_LINES, 24);
+ immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]);
+ immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]);
+ immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]);
+ immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]);
- glVertex3f(gmin[0], gmin[1], gmax[2]); glVertex3f(gmax[0], gmin[1], gmax[2]);
- glVertex3f(gmax[0], gmin[1], gmax[2]); glVertex3f(gmax[0], gmax[1], gmax[2]);
- glVertex3f(gmax[0], gmax[1], gmax[2]); glVertex3f(gmin[0], gmax[1], gmax[2]);
- glVertex3f(gmin[0], gmax[1], gmax[2]); glVertex3f(gmin[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]);
+ immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]);
- glVertex3f(gmin[0], gmin[1], gmin[2]); glVertex3f(gmin[0], gmin[1], gmax[2]);
- glVertex3f(gmax[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmin[1], gmax[2]);
- glVertex3f(gmin[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmax[1], gmax[2]);
- glVertex3f(gmax[0], gmax[1], gmin[2]); glVertex3f(gmax[0], gmax[1], gmax[2]);
- glEnd();
+ immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]);
+ immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]);
+ immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]);
+ immEnd();
if (select)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
+ immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
else
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -100);
- glEnable(GL_BLEND);
- glBegin(GL_LINES);
- for (i = 1; i < res[0] - 1; ++i) {
- float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1));
- glVertex3f(f, gmin[1], gmin[2]); glVertex3f(f, gmax[1], gmin[2]);
- glVertex3f(f, gmax[1], gmin[2]); glVertex3f(f, gmax[1], gmax[2]);
- glVertex3f(f, gmax[1], gmax[2]); glVertex3f(f, gmin[1], gmax[2]);
- glVertex3f(f, gmin[1], gmax[2]); glVertex3f(f, gmin[1], gmin[2]);
- }
- for (i = 1; i < res[1] - 1; ++i) {
- float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1));
- glVertex3f(gmin[0], f, gmin[2]); glVertex3f(gmax[0], f, gmin[2]);
- glVertex3f(gmax[0], f, gmin[2]); glVertex3f(gmax[0], f, gmax[2]);
- glVertex3f(gmax[0], f, gmax[2]); glVertex3f(gmin[0], f, gmax[2]);
- glVertex3f(gmin[0], f, gmax[2]); glVertex3f(gmin[0], f, gmin[2]);
- }
- for (i = 1; i < res[2] - 1; ++i) {
- float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1));
- glVertex3f(gmin[0], gmin[1], f); glVertex3f(gmax[0], gmin[1], f);
- glVertex3f(gmax[0], gmin[1], f); glVertex3f(gmax[0], gmax[1], f);
- glVertex3f(gmax[0], gmax[1], f); glVertex3f(gmin[0], gmax[1], f);
- glVertex3f(gmin[0], gmax[1], f); glVertex3f(gmin[0], gmin[1], f);
+ immUniformThemeColorShadeAlpha(TH_WIRE, 0, -100);
+
+ int count = 0;
+ count += MAX2(0, res[0] - 2) * 8;
+ count += MAX2(0, res[1] - 2) * 8;
+ count += MAX2(0, res[2] - 2) * 8;
+
+ if (count >= 2) {
+ glEnable(GL_BLEND);
+ immBegin(PRIM_LINES, count);
+ for (i = 1; i < res[0] - 1; ++i) {
+ float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1));
+ immVertex3f(pos_id, f, gmin[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmin[2]);
+ immVertex3f(pos_id, f, gmax[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmax[2]);
+ immVertex3f(pos_id, f, gmax[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmax[2]);
+ immVertex3f(pos_id, f, gmin[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmin[2]);
+ }
+ for (i = 1; i < res[1] - 1; ++i) {
+ float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1));
+ immVertex3f(pos_id, gmin[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmin[2]);
+ immVertex3f(pos_id, gmax[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmax[2]);
+ immVertex3f(pos_id, gmax[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmax[2]);
+ immVertex3f(pos_id, gmin[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmin[2]);
+ }
+ for (i = 1; i < res[2] - 1; ++i) {
+ float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1));
+ immVertex3f(pos_id, gmin[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmin[1], f);
+ immVertex3f(pos_id, gmax[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmax[1], f);
+ immVertex3f(pos_id, gmax[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmax[1], f);
+ immVertex3f(pos_id, gmin[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmin[1], f);
+ }
+ immEnd();
+ glDisable(GL_BLEND);
}
- glEnd();
- glDisable(GL_BLEND);
-
- glEnableClientState(GL_NORMAL_ARRAY);
- if ((dflag & DRAW_CONSTCOLOR) == 0)
- if (part->draw_col == PART_DRAW_COL_MAT)
- glEnableClientState(GL_COLOR_ARRAY);
+
+ immUnbindProgram();
}
}
}
@@ -5584,27 +6468,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
cache = psys->childcache;
for (a = 0; a < totchild; a++) {
path = cache[a];
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
- if (1) { //ob_dt > OB_WIRE) {
- glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (part->draw_col == PART_DRAW_COL_MAT) {
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- }
- }
+ if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) {
+ draw_vertex_array(PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL);
+ }
+ else {
+ float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ draw_vertex_array(PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color);
}
-
- glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
/* restore & clean up */
- if (1) { //ob_dt > OB_WIRE) {
- if (part->draw_col == PART_DRAW_COL_MAT)
- glDisableClientState(GL_COLOR_ARRAY);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- }
-
if (cdata2) {
MEM_freeN(cdata2);
cdata2 = NULL;
@@ -5624,19 +6498,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
}
else if (pdd && ELEM(draw_as, 0, PART_DRAW_CIRC) == 0) {
- glDisableClientState(GL_COLOR_ARRAY);
- /* enable point data array */
if (pdd->vdata) {
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
- }
- else
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
if (select) {
- UI_ThemeColor(TH_ACTIVE);
+ float color[4];
+ UI_GetThemeColor4fv(TH_ACTIVE, color);
if (part->draw_size)
glPointSize(part->draw_size + 2);
@@ -5645,48 +6511,39 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glLineWidth(3.0);
- draw_particle_arrays(draw_as, totpoint, ob_dt, 1);
+ draw_particle_arrays_new(draw_as, ob_dt, 1, pdd->vdata, NULL, NULL, totpoint, color);
}
- /* restore from select */
- glColor3fv(ma_col);
- }
+ glPointSize(part->draw_size ? part->draw_size : 2.0);
+ glLineWidth(1.0);
- glPointSize(part->draw_size ? part->draw_size : 2.0);
- glLineWidth(1.0);
- /* enable other data arrays */
-
- /* billboards are drawn this way */
- if (pdd->ndata && ob_dt > OB_WIRE) {
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 0, pdd->ndata);
- GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
- GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
- }
-
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (pdd->cdata) {
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
+#if 0
+ /* enable other data arrays */
+ /* billboards are drawn this way */
+ if (pdd->ndata && ob_dt > OB_WIRE) {
+ GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
+ GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
}
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ if (pdd->cdata) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
+ }
+ }
+#endif
+
+ draw_particle_arrays_new(draw_as, ob_dt, 0, pdd->vdata, pdd->ndata, pdd->cdata, totpoint, NULL);
}
- draw_particle_arrays(draw_as, totpoint, ob_dt, 0);
pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
pdd->totpoint = totpoint;
}
if (pdd && pdd->vedata) {
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glDisableClientState(GL_COLOR_ARRAY);
- cpack(0xC0C0C0);
- }
-
- glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
-
- glDrawArrays(GL_LINES, 0, 2 * totve);
+ float color[4] = {0.75f, 0.75f, 0.75f, 1.0f};
+ draw_vertex_array(PRIM_LINES, pdd->vedata, NULL, NULL, 0, 2 * totve, color);
}
glPolygonMode(GL_FRONT, polygonmode[0]);
@@ -5695,9 +6552,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
/* 7. */
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
if (states)
MEM_freeN(states);
@@ -5720,15 +6574,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pdd->ma_col = NULL;
}
- if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) {
- glLoadMatrixf(rv3d->viewmat);
+ if ((ob->flag & OB_FROMGROUP) != 0) {
+ gpuLoadMatrix(rv3d->viewmat);
}
}
-static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit)
+static void draw_update_ptcache_edit(Scene *scene, SceneLayer *sl, Object *ob, PTCacheEdit *edit)
{
if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
- PE_update_object(scene, ob, 0);
+ PE_update_object(scene, sl, ob, 0);
/* create path and child path cache if it doesn't exist already */
if (edit->pathcache == NULL)
@@ -5737,15 +6591,9 @@ static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit
static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
{
- ParticleCacheKey **cache, *path, *pkey;
- PTCacheEditPoint *point;
- PTCacheEditKey *key;
ParticleEditSettings *pset = PE_settings(scene);
- int i, k, totpoint = edit->totpoint, timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : 0;
- int totkeys = 1;
- float sel_col[3];
- float nosel_col[3];
- float *pathcol = NULL, *pcol;
+ const int totpoint = edit->totpoint;
+ const bool timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : false;
if (edit->pathcache == NULL)
return;
@@ -5757,50 +6605,71 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
glDisable(GL_DEPTH_TEST);
/* get selection theme colors */
+ float sel_col[3], nosel_col[3];
UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col);
UI_GetThemeColor3fv(TH_VERTEX, nosel_col);
/* draw paths */
- totkeys = (*edit->pathcache)->segments + 1;
+ const int totkeys = (*edit->pathcache)->segments + 1;
glEnable(GL_BLEND);
- pathcol = MEM_callocN(totkeys * 4 * sizeof(float), "particle path color data");
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
+ float *pathcol = MEM_callocN(totkeys * 4 * sizeof(float), "particle path color data");
if (pset->brushtype == PE_BRUSH_WEIGHT)
glLineWidth(2.0f);
- cache = edit->pathcache;
+ ParticleCacheKey **cache = edit->pathcache;
+ PTCacheEditPoint *point;
+ int i;
+
for (i = 0, point = edit->points; i < totpoint; i++, point++) {
- path = cache[i];
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+ ParticleCacheKey *path = cache[i];
+
+ VertexFormat format = {0};
+ unsigned int pos_id, col_id, col_comp;
+
+ col_comp = ((point->flag & PEP_HIDE) || timed) ? 4 : 3;
+
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, col_comp, KEEP_FLOAT);
+
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, path->segments + 1);
+
+ VertexBuffer_fill_attrib_stride(vbo, pos_id, sizeof(ParticleCacheKey), path->co);
+
+ float *pcol = pathcol;
if (point->flag & PEP_HIDE) {
- for (k = 0, pcol = pathcol; k < totkeys; k++, pcol += 4) {
+ for (int k = 0; k < totkeys; k++, pcol += 4) {
copy_v3_v3(pcol, path->col);
pcol[3] = 0.25f;
}
- glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
+ VertexBuffer_fill_attrib(vbo, col_id, pathcol);
}
else if (timed) {
- for (k = 0, pcol = pathcol, pkey = path; k < totkeys; k++, pkey++, pcol += 4) {
+ ParticleCacheKey *pkey = path;
+ for (int k = 0; k < totkeys; k++, pkey++, pcol += 4) {
copy_v3_v3(pcol, pkey->col);
pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames;
}
- glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
+ VertexBuffer_fill_attrib(vbo, col_id, pathcol);
+ }
+ else {
+ /* FIXME: shader wants 4 color components but the cache only contains ParticleCacheKey
+ * So alpha is random */
+ VertexBuffer_fill_attrib_stride(vbo, col_id, sizeof(ParticleCacheKey), path->col);
}
- else
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
+ Batch *batch = Batch_create(PRIM_LINE_STRIP, vbo, NULL);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ Batch_draw(batch);
+ Batch_discard_all(batch);
}
- if (pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; }
-
+ if (pathcol) { MEM_freeN(pathcol); pathcol = NULL; }
/* draw edit vertices */
if (pset->selectmode != SCE_SELECT_PATH) {
@@ -5811,6 +6680,10 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
float *cd = NULL, *cdata = NULL;
int totkeys_visible = 0;
+ VertexFormat format = {0};
+ unsigned int pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, (timed ? 4 : 3), KEEP_FLOAT);
+
for (i = 0, point = edit->points; i < totpoint; i++, point++)
if (!(point->flag & PEP_HIDE))
totkeys_visible += point->totkey;
@@ -5825,7 +6698,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (point->flag & PEP_HIDE)
continue;
- for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
+ PTCacheEditKey *key = point->keys;
+ for (int k = 0; k < point->totkey; k++, key++) {
if (pd) {
copy_v3_v3(pd, key->co);
pd += 3;
@@ -5850,14 +6724,20 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (point->flag & PEP_HIDE || point->totkey == 0)
continue;
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, point->totkey);
+
if (point->keys->flag & PEK_USE_WCO)
- glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co);
+ VertexBuffer_fill_attrib_stride(vbo, pos_id, sizeof(PTCacheEditKey), point->keys->world_co);
else
- glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), pd);
+ VertexBuffer_fill_attrib(vbo, pos_id, pd);
- glColorPointer((timed ? 4 : 3), GL_FLOAT, (timed ? 4 : 3) * sizeof(float), cd);
+ VertexBuffer_fill_attrib(vbo, col_id, cd);
- glDrawArrays(GL_POINTS, 0, point->totkey);
+ Batch *batch = Batch_create(PRIM_POINTS, vbo, NULL);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ Batch_draw(batch);
+ Batch_discard_all(batch);
pd += pd ? 3 * point->totkey : 0;
cd += (timed ? 4 : 3) * point->totkey;
@@ -5866,23 +6746,30 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (cdata) { MEM_freeN(cdata); cd = cdata = NULL; }
}
else if (pset->selectmode == SCE_SELECT_END) {
- glBegin(GL_POINTS);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos_id = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int col_id = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+ immBeginAtMost(PRIM_POINTS, totpoint);
for (i = 0, point = edit->points; i < totpoint; i++, point++) {
if ((point->flag & PEP_HIDE) == 0 && point->totkey) {
- key = point->keys + point->totkey - 1;
- glColor3fv((key->flag & PEK_SELECT) ? sel_col : nosel_col);
+ PTCacheEditKey *key = point->keys + point->totkey - 1;
+ if ((key->flag & PEK_SELECT) != 0) {
+ immAttrib3fv(col_id, sel_col);
+ }
+ else {
+ immAttrib3fv(col_id, nosel_col);
+ }
/* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/
- glVertex3fv((key->flag & PEK_USE_WCO) ? key->world_co : key->co);
+ immVertex3fv(pos_id, (key->flag & PEK_USE_WCO) ? key->world_co : key->co);
}
}
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
}
glDisable(GL_BLEND);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -5895,130 +6782,137 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo
float tw = itw * drw_size;
float th = ith * drw_size;
- glBegin(GL_LINES);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ immBegin(PRIM_LINES, 30);
- glColor4ub(0x7F, 0x00, 0x00, 155);
+ immAttrib4ub(col, 0x7F, 0x00, 0x00, 155);
root[1] = root[2] = 0.0f;
root[0] = -drw_size;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
+ immVertex3fv(pos, root);
tip[1] = tip[2] = 0.0f;
tip[0] = drw_size;
mul_m3_v3(tr, tip);
add_v3_v3(tip, com);
- glVertex3fv(tip);
+ immVertex3fv(pos, tip);
root[1] = 0.0f; root[2] = tw;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[1] = 0.0f; root[2] = -tw;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[1] = tw; root[2] = 0.0f;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[1] = -tw; root[2] = 0.0f;
root[0] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
- glColor4ub(0x00, 0x7F, 0x00, 155);
+ immAttrib4ub(col, 0x00, 0x7F, 0x00, 155);
root[0] = root[2] = 0.0f;
root[1] = -drw_size;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
+ immVertex3fv(pos, root);
tip[0] = tip[2] = 0.0f;
tip[1] = drw_size;
mul_m3_v3(tr, tip);
add_v3_v3(tip, com);
- glVertex3fv(tip);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[2] = tw;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[2] = -tw;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = tw; root[2] = 0.0f;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = -tw; root[2] = 0.0f;
root[1] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
- glColor4ub(0x00, 0x00, 0x7F, 155);
+ immAttrib4ub(col, 0x00, 0x00, 0x7F, 155);
root[0] = root[1] = 0.0f;
root[2] = -drw_size;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
+ immVertex3fv(pos, root);
tip[0] = tip[1] = 0.0f;
tip[2] = drw_size;
mul_m3_v3(tr, tip);
add_v3_v3(tip, com);
- glVertex3fv(tip);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[1] = tw;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = 0.0f; root[1] = -tw;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = tw; root[1] = 0.0f;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
root[0] = -tw; root[1] = 0.0f;
root[2] = th;
mul_m3_v3(tr, root);
add_v3_v3(root, com);
- glVertex3fv(root);
- glVertex3fv(tip);
+ immVertex3fv(pos, root);
+ immVertex3fv(pos, tip);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* place to add drawers */
@@ -6027,7 +6921,7 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
{
if (nu->hide || hide_handles) return;
- if (nu->type == CU_BEZIER) {
+ if (nu->type == CU_BEZIER && nu->pntsu > 0) {
const float *fp;
@@ -6040,9 +6934,14 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
UI_GetThemeColor3ubv(basecol + a, handle_cols[a]);
}
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
glLineWidth(1.0f);
- glBegin(GL_LINES);
+ immBeginAtMost(PRIM_LINES, nu->pntsu * 4);
BezTriple *bezt = nu->bezt;
int a = nu->pntsu;
@@ -6051,33 +6950,35 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
if ((bezt->f2 & SELECT) == sel) {
fp = bezt->vec[0];
- glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
- glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp + 3);
- glVertex3fv(fp + 6);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp + 3);
+ immVertex3fv(pos, fp + 6);
}
else if ((bezt->f1 & SELECT) == sel) {
fp = bezt->vec[0];
- glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
}
else if ((bezt->f3 & SELECT) == sel) {
fp = bezt->vec[1];
- glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
}
}
bezt++;
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
#undef TH_HANDLE_COL_TOT
@@ -6088,153 +6989,196 @@ static void drawhandlesN_active(Nurb *nu)
{
if (nu->hide) return;
- UI_ThemeColor(TH_ACTIVE_SPLINE);
- glLineWidth(2);
-
- glBegin(GL_LINES);
+ if (nu->type == CU_BEZIER && nu->pntsu > 0) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE_SPLINE);
+ glLineWidth(2.0f);
- if (nu->type == CU_BEZIER) {
+ immBeginAtMost(PRIM_LINES, nu->pntsu * 4);
BezTriple *bezt = nu->bezt;
int a = nu->pntsu;
while (a--) {
if (bezt->hide == 0) {
const float *fp = bezt->vec[0];
- glVertex3fv(fp);
- glVertex3fv(fp + 3);
+ immVertex3fv(pos, fp);
+ immVertex3fv(pos, fp + 3);
- glVertex3fv(fp + 3);
- glVertex3fv(fp + 6);
+ immVertex3fv(pos, fp + 3);
+ immVertex3fv(pos, fp + 6);
}
bezt++;
}
+ immEnd();
+ immUnbindProgram();
}
- glEnd();
-
- glColor3ub(0, 0, 0);
}
-static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, const void *vert)
+static void drawvertsN(const Nurb *nurb, const bool hide_handles, const void *vert)
{
- if (nu->hide) return;
+ const Nurb *nu;
+
+ // just quick guesstimate of how many verts to draw
+ int count = 0;
+ for (nu = nurb; nu; nu = nu->next) {
+ if (!nu->hide) {
+ if (nu->type == CU_BEZIER) {
+ count += nu->pntsu * 3;
+ }
+ else {
+ count += nu->pntsu * nu->pntsv;
+ }
+ }
+ }
+ if (count == 0) return;
- const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
- UI_ThemeColor(color);
+ unsigned char vert_color[3];
+ unsigned char vert_color_select[3];
+ unsigned char vert_color_active[3];
+ UI_GetThemeColor3ubv(TH_VERTEX, vert_color);
+ UI_GetThemeColor3ubv(TH_VERTEX_SELECT, vert_color_select);
+ UI_GetThemeColor3ubv(TH_ACTIVE_VERT, vert_color_active);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ immBeginAtMost(PRIM_POINTS, count);
- glBegin(GL_POINTS);
-
- if (nu->type == CU_BEZIER) {
+ for (nu = nurb; nu; nu = nu->next) {
- BezTriple *bezt = nu->bezt;
- int a = nu->pntsu;
- while (a--) {
- if (bezt->hide == 0) {
- if (sel == 1 && bezt == vert) {
- UI_ThemeColor(TH_ACTIVE_VERT);
+ if (nu->hide) continue;
- if (bezt->f2 & SELECT) glVertex3fv(bezt->vec[1]);
- if (!hide_handles) {
- if (bezt->f1 & SELECT) glVertex3fv(bezt->vec[0]);
- if (bezt->f3 & SELECT) glVertex3fv(bezt->vec[2]);
- }
+ if (nu->type == CU_BEZIER) {
- UI_ThemeColor(color);
- }
- else if (hide_handles) {
- if ((bezt->f2 & SELECT) == sel) glVertex3fv(bezt->vec[1]);
- }
- else {
- if ((bezt->f1 & SELECT) == sel) glVertex3fv(bezt->vec[0]);
- if ((bezt->f2 & SELECT) == sel) glVertex3fv(bezt->vec[1]);
- if ((bezt->f3 & SELECT) == sel) glVertex3fv(bezt->vec[2]);
+ const BezTriple *bezt = nu->bezt;
+ int a = nu->pntsu;
+ while (a--) {
+ if (bezt->hide == 0) {
+ if (bezt == vert) {
+ immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_active : vert_color);
+ immVertex3fv(pos, bezt->vec[1]);
+ if (!hide_handles) {
+ immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_active : vert_color);
+ immVertex3fv(pos, bezt->vec[0]);
+ immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_active : vert_color);
+ immVertex3fv(pos, bezt->vec[2]);
+ }
+ }
+ else {
+ immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_select : vert_color);
+ immVertex3fv(pos, bezt->vec[1]);
+ if (!hide_handles) {
+ immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_select : vert_color);
+ immVertex3fv(pos, bezt->vec[0]);
+ immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_select : vert_color);
+ immVertex3fv(pos, bezt->vec[2]);
+ }
+ }
}
+ bezt++;
}
- bezt++;
}
- }
- else {
- BPoint *bp = nu->bp;
- int a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->hide == 0) {
- if (bp == vert) {
- UI_ThemeColor(TH_ACTIVE_VERT);
- glVertex3fv(bp->vec);
- UI_ThemeColor(color);
- }
- else {
- if ((bp->f1 & SELECT) == sel) glVertex3fv(bp->vec);
+ else {
+ const BPoint *bp = nu->bp;
+ int a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->hide == 0) {
+ if (bp == vert) {
+ immAttrib3ubv(color, vert_color_active);
+ }
+ else {
+ immAttrib3ubv(color, bp->f1 & SELECT ? vert_color_select : vert_color);
+ }
+ immVertex3fv(pos, bp->vec);
}
+ bp++;
}
- bp++;
}
}
-
- glEnd();
+
+ immEnd();
+ immUnbindProgram();
}
static void editnurb_draw_active_poly(Nurb *nu)
{
- UI_ThemeColor(TH_ACTIVE_SPLINE);
- glLineWidth(2);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE_SPLINE);
+
+ glLineWidth(2.0f);
BPoint *bp = nu->bp;
for (int b = 0; b < nu->pntsv; b++) {
- if (nu->flagu & 1) glBegin(GL_LINE_LOOP);
- else glBegin(GL_LINE_STRIP);
+ if (nu->pntsu >= 2) {
+ if (nu->flagu & 1) immBegin(PRIM_LINE_LOOP, nu->pntsu);
+ else immBegin(PRIM_LINE_STRIP, nu->pntsu);
- for (int a = 0; a < nu->pntsu; a++, bp++) {
- glVertex3fv(bp->vec);
- }
+ for (int a = 0; a < nu->pntsu; a++, bp++) {
+ immVertex3fv(pos, bp->vec);
+ }
- glEnd();
+ immEnd();
+ }
}
- glColor3ub(0, 0, 0);
+ immUnbindProgram();
}
static void editnurb_draw_active_nurbs(Nurb *nu)
{
- UI_ThemeColor(TH_ACTIVE_SPLINE);
- glLineWidth(2);
+ if (nu->pntsv > 0) {
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE_SPLINE);
- glBegin(GL_LINES);
- BPoint *bp = nu->bp;
- for (int b = 0; b < nu->pntsv; b++) {
- BPoint *bp1 = bp;
- bp++;
-
- for (int a = nu->pntsu - 1; a > 0; a--, bp++) {
- if (bp->hide == 0 && bp1->hide == 0) {
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
- }
- bp1 = bp;
- }
- }
+ glLineWidth(2.0f);
+ // just quick guesstimate of how many verts to draw
+ int count = (nu->pntsu - 1) * nu->pntsv * 2;
+ if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2;
+ if (count < 2) return;
- if (nu->pntsv > 1) { /* surface */
+ immBeginAtMost(PRIM_LINES, count);
+ BPoint *bp = nu->bp;
+ for (int b = 0; b < nu->pntsv; b++) {
+ BPoint *bp1 = bp;
+ bp++;
- int ofs = nu->pntsu;
- for (int b = 0; b < nu->pntsu; b++) {
- BPoint *bp1 = nu->bp + b;
- bp = bp1 + ofs;
- for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) {
+ for (int a = nu->pntsu - 1; a > 0; a--, bp++) {
if (bp->hide == 0 && bp1->hide == 0) {
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
bp1 = bp;
}
}
- }
- glEnd();
+ if (nu->pntsv > 1) { /* surface */
+ int ofs = nu->pntsu;
+ for (int b = 0; b < nu->pntsu; b++) {
+ BPoint *bp1 = nu->bp + b;
+ bp = bp1 + ofs;
+ for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) {
+ if (bp->hide == 0 && bp1->hide == 0) {
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
+ }
+ bp1 = bp;
+ }
+ }
+ }
+
+ immEnd();
- glColor3ub(0, 0, 0);
+ immUnbindProgram();
+ }
}
static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
@@ -6242,6 +7186,9 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
BPoint *bp, *bp1;
int a, b;
Curve *cu = ob->data;
+ VertexFormat *format;
+ unsigned int pos, col;
+ unsigned char color[3];
int index = 0;
Nurb *nu = nurb;
@@ -6249,35 +7196,55 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
if (nu->hide == 0) {
switch (nu->type) {
case CU_POLY:
+ {
if (!sel && index == cu->actnu) {
/* we should draw active spline highlight below everything */
editnurb_draw_active_poly(nu);
}
- glLineWidth(1);
+ format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- UI_ThemeColor(TH_NURB_ULINE);
+ glLineWidth(1.0f);
+
+ immUniformThemeColor(TH_NURB_ULINE);
bp = nu->bp;
for (b = 0; b < nu->pntsv; b++) {
- if (nu->flagu & 1) glBegin(GL_LINE_LOOP);
- else glBegin(GL_LINE_STRIP);
+ if (nu->pntsu >= 2) {
+ if (nu->flagu & 1) immBegin(PRIM_LINE_LOOP, nu->pntsu);
+ else immBegin(PRIM_LINE_STRIP, nu->pntsu);
- for (a = 0; a < nu->pntsu; a++, bp++) {
- glVertex3fv(bp->vec);
- }
+ for (a = 0; a < nu->pntsu; a++, bp++) {
+ immVertex3fv(pos, bp->vec);
+ }
- glEnd();
+ immEnd();
+ }
}
+ immUnbindProgram();
break;
+ }
case CU_NURBS:
+ {
if (!sel && index == cu->actnu) {
/* we should draw active spline highlight below everything */
editnurb_draw_active_nurbs(nu);
}
- glLineWidth(1);
+ format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ col = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ // just quick guesstimate of how many verts to draw
+ int count = (nu->pntsu - 1) * nu->pntsv * 2;
+ if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2;
+ if (count < 2) return;
- glBegin(GL_LINES);
+ glLineWidth(1.0f);
+
+ immBeginAtMost(PRIM_LINES, count);
bp = nu->bp;
for (b = 0; b < nu->pntsv; b++) {
@@ -6287,10 +7254,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
if (bp->hide == 0 && bp1->hide == 0) {
if (sel) {
if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
- UI_ThemeColor(TH_NURB_SEL_ULINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_SEL_ULINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
else {
@@ -6298,10 +7265,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
/* pass */
}
else {
- UI_ThemeColor(TH_NURB_ULINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_ULINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
}
@@ -6318,10 +7285,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
if (bp->hide == 0 && bp1->hide == 0) {
if (sel) {
if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
- UI_ThemeColor(TH_NURB_SEL_VLINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_SEL_VLINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
else {
@@ -6329,10 +7296,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
/* pass */
}
else {
- UI_ThemeColor(TH_NURB_VLINE);
-
- glVertex3fv(bp->vec);
- glVertex3fv(bp1->vec);
+ UI_GetThemeColor3ubv(TH_NURB_VLINE, color);
+ immAttrib3ubv(col, color);
+ immVertex3fv(pos, bp->vec);
+ immVertex3fv(pos, bp1->vec);
}
}
}
@@ -6340,9 +7307,10 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
}
}
}
-
- glEnd();
+ immEnd();
+ immUnbindProgram();
break;
+ }
}
}
@@ -6352,8 +7320,8 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
}
static void draw_editnurb(
- Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+ Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
+ const char dt, const short dflag, const unsigned char UNUSED(ob_wire_col[4]))
{
ToolSettings *ts = scene->toolsettings;
Object *ob = base->object;
@@ -6365,9 +7333,8 @@ static void draw_editnurb(
/* DispList */
UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col);
- glColor3ubv(wire_col);
- drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
/* for shadows only show solid faces */
if (v3d->flag2 & V3D_RENDER_SHADOW)
@@ -6391,78 +7358,108 @@ static void draw_editnurb(
for (nu = nurb; nu; nu = nu->next) {
if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0)
drawhandlesN(nu, 1, hide_handles);
- drawvertsN(nu, 0, hide_handles, NULL);
}
if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
- glColor3ubv(wire_col);
-
/* direction vectors for 3d curve paths
* when at its lowest, don't render normals */
if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) {
BevList *bl;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_WIRE_EDIT);
+
glLineWidth(1.0f);
+
+ int count = 0;
+ int count_used = 0;
for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) {
- BevPoint *bevp = bl->bevpoints;
int nr = bl->nr;
int skip = nu->resolu / 16;
-
+
+#if 0
while (nr-- > 0) { /* accounts for empty bevel lists */
- const float fac = bevp->radius * ts->normalsize;
- float vec_a[3]; /* Offset perpendicular to the curve */
- float vec_b[3]; /* Delta along the curve */
+ count += 4;
+ nr -= skip;
+ }
+#else
+ /* Same as loop above */
+ count += 4 * max_ii((nr + max_ii(skip - 1, 0)) / (skip + 1), 0);
+#endif
+ }
- vec_a[0] = fac;
- vec_a[1] = 0.0f;
- vec_a[2] = 0.0f;
-
- mul_qt_v3(bevp->quat, vec_a);
- madd_v3_v3fl(vec_a, bevp->dir, -fac);
+ if (count > 2) {
+ immBegin(PRIM_LINES, count);
+ for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) {
+ BevPoint *bevp = bl->bevpoints;
+ int nr = bl->nr;
+ int skip = nu->resolu / 16;
- reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
- negate_v3(vec_b);
+ while (nr-- > 0) { /* accounts for empty bevel lists */
+ const float fac = bevp->radius * ts->normalsize;
+ float vec_a[3]; /* Offset perpendicular to the curve */
+ float vec_b[3]; /* Delta along the curve */
- add_v3_v3(vec_a, bevp->vec);
- add_v3_v3(vec_b, bevp->vec);
+ vec_a[0] = fac;
+ vec_a[1] = 0.0f;
+ vec_a[2] = 0.0f;
+
+ mul_qt_v3(bevp->quat, vec_a);
+ madd_v3_v3fl(vec_a, bevp->dir, -fac);
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec_a);
- glVertex3fv(bevp->vec);
- glVertex3fv(vec_b);
- glEnd();
-
- bevp += skip + 1;
- nr -= skip;
+ reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
+ negate_v3(vec_b);
+
+ add_v3_v3(vec_a, bevp->vec);
+ add_v3_v3(vec_b, bevp->vec);
+
+ immVertex3fv(pos, vec_a);
+ immVertex3fv(pos, bevp->vec);
+ immVertex3fv(pos, bevp->vec);
+ immVertex3fv(pos, vec_b);
+
+ bevp += skip + 1;
+ nr -= skip;
+ count_used += 4;
+ }
}
+ BLI_assert(count == count_used);
+ UNUSED_VARS_NDEBUG(count_used);
+
+ immEnd();
}
+ immUnbindProgram();
}
- if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
-
- for (nu = nurb; nu; nu = nu->next) {
- drawvertsN(nu, 1, hide_handles, vert);
- }
-
- if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ drawvertsN(nurb, hide_handles, vert);
+
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2])
{
- cpack(0);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
ED_view3d_polygon_offset(rv3d, -1.0);
set_inverted_drawing(1);
- glBegin(GL_QUADS);
- glVertex2fv(textcurs[0]);
- glVertex2fv(textcurs[1]);
- glVertex2fv(textcurs[2]);
- glVertex2fv(textcurs[3]);
- glEnd();
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ imm_cpack(0);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immVertex2fv(pos, textcurs[0]);
+ immVertex2fv(pos, textcurs[1]);
+ immVertex2fv(pos, textcurs[2]);
+ immVertex2fv(pos, textcurs[3]);
+ immEnd();
set_inverted_drawing(0);
ED_view3d_polygon_offset(rv3d, 0.0);
+ immUnbindProgram();
}
-static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+static void draw_editfont(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
@@ -6473,17 +7470,19 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
draw_editfont_textcurs(rv3d, ef->textcurs);
if (cu->flag & CU_FAST) {
- cpack(0xFFFFFF);
+ imm_cpack(0xFFFFFF);
set_inverted_drawing(1);
- drawDispList(scene, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
+ drawDispList(scene, sl, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
set_inverted_drawing(0);
}
else {
- drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
if (cu->linewidth != 0.0f) {
- UI_ThemeColor(TH_WIRE_EDIT);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_WIRE_EDIT);
copy_v3_v3(vec1, ob->orig);
copy_v3_v3(vec2, ob->orig);
vec1[0] += cu->linewidth;
@@ -6491,31 +7490,35 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
vec1[1] += cu->linedist * cu->fsize;
vec2[1] -= cu->lines * cu->linedist * cu->fsize;
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex2fv(vec1);
- glVertex2fv(vec2);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(pos, vec1);
+ immVertex2fv(pos, vec2);
+ immEnd();
setlinestyle(0);
+ immUnbindProgram();
}
setlinestyle(3);
for (int i = 0; i < cu->totbox; i++) {
if (cu->tb[i].w != 0.0f) {
- UI_ThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE);
vec1[0] = cu->xof + cu->tb[i].x;
vec1[1] = cu->yof + cu->tb[i].y + cu->fsize;
vec1[2] = 0.001;
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec1);
+ immBegin(PRIM_LINE_STRIP, 5);
+ immVertex3fv(pos, vec1);
vec1[0] += cu->tb[i].w;
- glVertex3fv(vec1);
+ immVertex3fv(pos, vec1);
vec1[1] -= cu->tb[i].h;
- glVertex3fv(vec1);
+ immVertex3fv(pos, vec1);
vec1[0] -= cu->tb[i].w;
- glVertex3fv(vec1);
+ immVertex3fv(pos, vec1);
vec1[1] += cu->tb[i].h;
- glVertex3fv(vec1);
- glEnd();
+ immVertex3fv(pos, vec1);
+ immEnd();
+ immUnbindProgram();
}
}
setlinestyle(0);
@@ -6524,7 +7527,9 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
if (ef->selboxes && ef->selboxes_len) {
float selboxw;
- cpack(0xffffff);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ imm_cpack(0xffffff);
set_inverted_drawing(1);
for (int i = 0; i < ef->selboxes_len; i++) {
EditFontSelBox *sb = &ef->selboxes[i];
@@ -6543,20 +7548,20 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
/* fill in xy below */
tvec[2] = 0.001;
- glBegin(GL_QUADS);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
if (sb->rot == 0.0f) {
copy_v2_fl2(tvec, sb->x, sb->y);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, sb->x + selboxw, sb->y);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, sb->x + selboxw, sb->y + sb->h);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, sb->x, sb->y + sb->h);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
}
else {
float mat[2][2];
@@ -6564,84 +7569,87 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
angle_to_mat2(mat, sb->rot);
copy_v2_fl2(tvec, sb->x, sb->y);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, selboxw, 0.0f);
mul_m2v2(mat, tvec);
add_v2_v2(tvec, &sb->x);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, selboxw, sb->h);
mul_m2v2(mat, tvec);
add_v2_v2(tvec, &sb->x);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
copy_v2_fl2(tvec, 0.0f, sb->h);
mul_m2v2(mat, tvec);
add_v2_v2(tvec, &sb->x);
- glVertex3fv(tvec);
+ immVertex3fv(pos, tvec);
}
- glEnd();
+ immEnd();
}
set_inverted_drawing(0);
+ immUnbindProgram();
}
}
/* draw a sphere for use as an empty drawtype */
-static void draw_empty_sphere(float size)
-{
- static GLuint displist = 0;
-
- if (displist == 0) {
- GLUquadricObj *qobj;
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glPushMatrix();
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0.0, 1, 16, 1);
-
- glRotatef(90, 0, 1, 0);
- gluDisk(qobj, 0.0, 1, 16, 1);
-
- glRotatef(90, 1, 0, 0);
- gluDisk(qobj, 0.0, 1, 16, 1);
-
- gluDeleteQuadric(qobj);
-
- glPopMatrix();
- glEndList();
- }
-
- glScalef(size, size, size);
- glCallList(displist);
- glScalef(1.0f / size, 1.0f / size, 1.0f / size);
+static void draw_empty_sphere(float size, unsigned pos)
+{
+#define NSEGMENTS 16
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = size * cosf(angle);
+ p[i][1] = size * sinf(angle);
+ }
+
+ immBegin(PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, p[i][0], p[i][1], 0.0f);
+ immEnd();
+ immBegin(PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, p[i][0], 0.0f, p[i][1]);
+ immEnd();
+ immBegin(PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, 0.0f, p[i][0], p[i][1]);
+ immEnd();
+#undef NSEGMENTS
}
/* draw a cone for use as an empty drawtype */
-static void draw_empty_cone(float size)
+static void draw_empty_cone(float size, unsigned pos)
{
- const float radius = size;
+#define NSEGMENTS 8
+ /* a single ring of vertices */
+ float p[NSEGMENTS][2];
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
+ p[i][0] = size * cosf(angle);
+ p[i][1] = size * sinf(angle);
+ }
- GLUquadricObj *qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-
- glPushMatrix();
-
- glScalef(radius, size * 2.0f, radius);
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
+ /* cone sides */
+ immBegin(PRIM_LINES, NSEGMENTS * 2);
+ for (int i = 0; i < NSEGMENTS; ++i) {
+ immVertex3f(pos, 0.0f, 2.0f * size, 0.0f);
+ immVertex3f(pos, p[i][0], 0.0f, p[i][1]);
+ }
+ immEnd();
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
+ /* end ring */
+ immBegin(PRIM_LINE_LOOP, NSEGMENTS);
+ for (int i = 0; i < NSEGMENTS; ++i)
+ immVertex3f(pos, p[i][0], 0.0f, p[i][1]);
+ immEnd();
+#undef NSEGMENTS
}
-static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start)
+static void drawspiral(unsigned int pos, const float cent[3], float rad, float tmat[4][4], int start)
{
float vec[3], vx[3], vy[3];
const float tot_inv = 1.0f / (float)CIRCLE_RESOL;
@@ -6657,11 +7665,11 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
mul_v3_v3fl(vx, tmat[0], rad);
mul_v3_v3fl(vy, tmat[1], rad);
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, CIRCLE_RESOL + 1);
if (inverse == 0) {
copy_v3_v3(vec, cent);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
for (a = 0; a < CIRCLE_RESOL; a++) {
if (a + start >= CIRCLE_RESOL)
@@ -6675,7 +7683,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
}
}
else {
@@ -6687,7 +7695,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
for (a = 0; a < CIRCLE_RESOL; a++) {
if (a + start >= CIRCLE_RESOL)
@@ -6700,78 +7708,77 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
vec[0] = cent[0] + (x * vx[0] + y * vy[0]);
vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
- glVertex3fv(vec);
+ immVertex3fv(pos, vec);
}
}
- glEnd();
+ immEnd();
}
/* draws a circle on x-z plane given the scaling of the circle, assuming that
* all required matrices have been set (used for drawing empties) */
-static void drawcircle_size(float size)
+static void drawcircle_size(float size, unsigned pos)
{
- glBegin(GL_LINE_LOOP);
+ immBegin(PRIM_LINE_LOOP, CIRCLE_RESOL);
/* coordinates are: cos(degrees * 11.25) = x, sin(degrees * 11.25) = y, 0.0f = z */
for (short degrees = 0; degrees < CIRCLE_RESOL; degrees++) {
float x = cosval[degrees];
float y = sinval[degrees];
-
- glVertex3f(x * size, 0.0f, y * size);
+
+ immVertex3f(pos, x * size, 0.0f, y * size);
}
-
- glEnd();
+ immEnd();
}
/* needs fixing if non-identity matrix used */
-static void drawtube(const float vec[3], float radius, float height, float tmat[4][4])
+static void imm_drawtube(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos)
{
float cur[3];
- drawcircball(GL_LINE_LOOP, vec, radius, tmat);
+ imm_drawcircball(vec, radius, tmat, pos);
copy_v3_v3(cur, vec);
cur[2] += height;
- drawcircball(GL_LINE_LOOP, cur, radius, tmat);
+ imm_drawcircball(cur, radius, tmat, pos);
- glBegin(GL_LINES);
- glVertex3f(vec[0] + radius, vec[1], vec[2]);
- glVertex3f(cur[0] + radius, cur[1], cur[2]);
- glVertex3f(vec[0] - radius, vec[1], vec[2]);
- glVertex3f(cur[0] - radius, cur[1], cur[2]);
- glVertex3f(vec[0], vec[1] + radius, vec[2]);
- glVertex3f(cur[0], cur[1] + radius, cur[2]);
- glVertex3f(vec[0], vec[1] - radius, vec[2]);
- glVertex3f(cur[0], cur[1] - radius, cur[2]);
- glEnd();
+ immBegin(PRIM_LINES, 8);
+ immVertex3f(pos, vec[0] + radius, vec[1], vec[2]);
+ immVertex3f(pos, cur[0] + radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0] - radius, vec[1], vec[2]);
+ immVertex3f(pos, cur[0] - radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0], vec[1] + radius, vec[2]);
+ immVertex3f(pos, cur[0], cur[1] + radius, cur[2]);
+ immVertex3f(pos, vec[0], vec[1] - radius, vec[2]);
+ immVertex3f(pos, cur[0], cur[1] - radius, cur[2]);
+ immEnd();
}
/* needs fixing if non-identity matrix used */
-static void drawcone(const float vec[3], float radius, float height, float tmat[4][4])
+static void imm_drawcone(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos)
{
float cur[3];
copy_v3_v3(cur, vec);
cur[2] += height;
- drawcircball(GL_LINE_LOOP, cur, radius, tmat);
+ imm_drawcircball(cur, radius, tmat, pos);
- glBegin(GL_LINES);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0] + radius, cur[1], cur[2]);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0] - radius, cur[1], cur[2]);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0], cur[1] + radius, cur[2]);
- glVertex3f(vec[0], vec[1], vec[2]);
- glVertex3f(cur[0], cur[1] - radius, cur[2]);
- glEnd();
+ immBegin(PRIM_LINES, 8);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0] + radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0] - radius, cur[1], cur[2]);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0], cur[1] + radius, cur[2]);
+ immVertex3f(pos, vec[0], vec[1], vec[2]);
+ immVertex3f(pos, cur[0], cur[1] - radius, cur[2]);
+ immEnd();
}
/* return true if nothing was drawn */
-static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+static bool drawmball(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
@@ -6785,15 +7792,13 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if ((G.f & G_PICKSEL) == 0) {
unsigned char wire_col[4];
UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col);
- glColor3ubv(wire_col);
-
- drawDispList(scene, v3d, rv3d, base, dt, dflag, wire_col);
+ drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
}
ml = mb->editelems->first;
}
else {
- if ((base->flag & OB_FROMDUPLI) == 0) {
- drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ if ((base->flag_legacy & OB_FROMDUPLI) == 0) {
+ drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
ml = mb->elems.first;
}
@@ -6810,20 +7815,25 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
normalize_v3(imat[0]);
normalize_v3(imat[1]);
+#if 0 /* no purpose? */
if (mb->editelems == NULL) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
glColor3ubv(ob_wire_col);
}
}
-
+#endif
+
glLineWidth(1.0f);
+ const unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
while (ml) {
/* draw radius */
if (mb->editelems) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) cpack(0xA0A0F0);
- else cpack(0x3030A0);
+ if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0A0F0);
+ else imm_cpack(0x3030A0);
}
if (G.f & G_PICKSEL) {
@@ -6831,24 +7841,26 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
GPU_select_load_id(code++);
}
}
- drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad, imat);
+ imm_drawcircball(&(ml->x), ml->rad, imat, pos);
/* draw stiffness */
if (mb->editelems) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) cpack(0xA0F0A0);
- else cpack(0x30A030);
+ if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0F0A0);
+ else imm_cpack(0x30A030);
}
if (G.f & G_PICKSEL) {
ml->selcol2 = code;
GPU_select_load_id(code++);
}
- drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat);
+ imm_drawcircball(&(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat, pos);
}
ml = ml->next;
}
+
+ immUnbindProgram();
return false;
}
@@ -6858,6 +7870,7 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
PartDeflect *pd = ob->pd;
float imat[4][4], tmat[4][4];
float vec[3] = {0.0, 0.0, 0.0};
+ float draw_color[3] = {0.0f, 0.0f, 0.0f};
/* scale size of circle etc with the empty drawsize */
const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f;
@@ -6867,35 +7880,53 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
normalize_v3(imat[0]); /* we don't do this because field doesnt scale either... apart from wind! */
normalize_v3(imat[1]);
#endif
+
+ const unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3fv(draw_color);
if (pd->forcefield == PFIELD_WIND) {
float force_val = pd->f_strength;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
}
unit_m4(tmat);
force_val *= 0.1f;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 0.5f * force_val;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 1.0f * force_val;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 1.5f * force_val;
- drawcircball(GL_LINE_LOOP, vec, size, tmat);
+ imm_drawcircball(vec, size, tmat, pos);
vec[2] = 0.0f; /* reset vec for max dist circle */
-
}
else if (pd->forcefield == PFIELD_FORCE) {
float ffall_val = pd->f_power;
- if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
- drawcircball(GL_LINE_LOOP, vec, size, imat);
- if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val));
- drawcircball(GL_LINE_LOOP, vec, size * 1.5f, imat);
- if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val));
- drawcircball(GL_LINE_LOOP, vec, size * 2.0f, imat);
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
+ }
+
+ imm_drawcircball(vec, size, imat, pos);
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val), draw_color);
+ immUniformColor3fv(draw_color);
+ }
+
+ imm_drawcircball(vec, size * 1.5f, imat, pos);
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val), draw_color);
+ immUniformColor3fv(draw_color);
+ }
+
+ imm_drawcircball(vec, size * 2.0f, imat, pos);
}
else if (pd->forcefield == PFIELD_VORTEX) {
float force_val = pd->f_strength;
@@ -6903,16 +7934,17 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
unit_m4(tmat);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f, draw_color);
+ immUniformColor3fv(draw_color);
}
if (force_val < 0) {
- drawspiral(vec, size, tmat, 1);
- drawspiral(vec, size, tmat, 16);
+ drawspiral(pos, vec, size, tmat, 1);
+ drawspiral(pos, vec, size, tmat, 16);
}
else {
- drawspiral(vec, size, tmat, -1);
- drawspiral(vec, size, tmat, -16);
+ drawspiral(pos, vec, size, tmat, -1);
+ drawspiral(pos, vec, size, tmat, -16);
}
}
else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) {
@@ -6922,18 +7954,19 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
float mindist = pd->f_strength;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
}
/* path end */
setlinestyle(3);
where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL, NULL);
- drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
+ imm_drawcircball(guidevec1, mindist, imat, pos);
/* path beginning */
setlinestyle(0);
where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL, NULL);
- drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
+ imm_drawcircball(guidevec1, mindist, imat, pos);
copy_v3_v3(vec, guidevec1); /* max center */
}
@@ -6942,16 +7975,19 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
setlinestyle(3);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
+ ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color);
+ immUniformColor3fv(draw_color);
}
if (pd->falloff == PFIELD_FALL_SPHERE) {
/* as last, guide curve alters it */
- if (pd->flag & PFIELD_USEMAX)
- drawcircball(GL_LINE_LOOP, vec, pd->maxdist, imat);
+ if ((pd->flag & PFIELD_USEMAX) != 0) {
+ imm_drawcircball(vec, pd->maxdist, imat, pos);
+ }
- if (pd->flag & PFIELD_USEMIN)
- drawcircball(GL_LINE_LOOP, vec, pd->mindist, imat);
+ if ((pd->flag & PFIELD_USEMIN) != 0) {
+ imm_drawcircball(vec, pd->mindist, imat, pos);
+ }
}
else if (pd->falloff == PFIELD_FALL_TUBE) {
float radius, distance;
@@ -6964,16 +8000,18 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
vec[2] = distance;
distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance;
- if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR))
- drawtube(vec, radius, distance, tmat);
+ if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
+ imm_drawtube(vec, radius, distance, tmat, pos);
+ }
radius = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
vec[2] = distance;
distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance;
- if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR))
- drawtube(vec, radius, distance, tmat);
+ if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
+ imm_drawtube(vec, radius, distance, tmat, pos);
+ }
}
else if (pd->falloff == PFIELD_FALL_CONE) {
float radius, distance;
@@ -6984,46 +8022,54 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
- drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos);
if ((pd->flag & PFIELD_POSZ) == 0)
- drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos);
}
radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
- drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos);
if ((pd->flag & PFIELD_POSZ) == 0)
- drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat);
+ imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos);
}
}
setlinestyle(0);
+
+ immUnbindProgram();
}
-static void draw_box(const float vec[8][3], bool solid)
+static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos)
{
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vec);
-
if (solid) {
- const GLubyte indices[24] = {0,1,2,3,7,6,5,4,4,5,1,0,3,2,6,7,3,7,4,0,1,5,6,2};
- glDrawRangeElements(GL_QUADS, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
+ /* Adpated from "Optimizing Triangle Strips for Fast Rendering" by F. Evans, S. Skiena and A. Varshney
+ * (http://www.cs.umd.edu/gvil/papers/av_ts.pdf). */
+ static const GLubyte tris_strip_indices[14] = {0,1,3,2,6,1,5,0,4,3,7,6,4,5};
+ immBegin(PRIM_TRIANGLE_STRIP, 14);
+ for (int i = 0; i < 14; ++i) {
+ immVertex3fv(pos, vec[tris_strip_indices[i]]);
+ }
+ immEnd();
}
else {
- const GLubyte indices[24] = {0,1,1,2,2,3,3,0,0,4,4,5,5,6,6,7,7,4,1,5,2,6,3,7};
- glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
+ static const GLubyte line_indices[24] = {0,1,1,2,2,3,3,0,0,4,4,5,5,6,6,7,7,4,1,5,2,6,3,7};
+ immBegin(PRIM_LINES, 24);
+ for (int i = 0; i < 24; ++i) {
+ immVertex3fv(pos, vec[line_indices[i]]);
+ }
+ immEnd();
}
- glDisableClientState(GL_VERTEX_ARRAY);
}
-static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
+static void imm_draw_bb(BoundBox *bb, char type, bool around_origin, const unsigned char ob_wire_col[4])
{
float size[3], cent[3];
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+ Batch *sphere = Batch_get_sphere_wire(0);
+ Batch_set_builtin_program(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) Batch_Uniform4f(sphere, "color", ob_wire_col[0]/255.0f, ob_wire_col[1]/255.0f, ob_wire_col[2]/255.0f, 1.0f);
BKE_boundbox_calc_size_aabb(bb, size);
@@ -7034,40 +8080,51 @@ static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
BKE_boundbox_calc_center_aabb(bb, cent);
}
- glPushMatrix();
+ gpuPushMatrix();
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
if (type == OB_BOUND_SPHERE) {
float scale = MAX3(size[0], size[1], size[2]);
- glTranslate3fv(cent);
- glScalef(scale, scale, scale);
- gluSphere(qobj, 1.0, 8, 5);
+ gpuTranslate3fv(cent);
+ gpuRotateAxis(90, 'X');
+ gpuScaleUniform(scale);
+ Batch_draw(sphere);
}
else if (type == OB_BOUND_CYLINDER) {
float radius = size[0] > size[1] ? size[0] : size[1];
- glTranslatef(cent[0], cent[1], cent[2] - size[2]);
- glScalef(radius, radius, 2.0f * size[2]);
- gluCylinder(qobj, 1.0, 1.0, 1.0, 8, 1);
+ gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]);
+ gpuScale3f(radius, radius, 2.0f * size[2]);
+ imm_draw_cylinder_wire_3d(pos, 1.0f, 1.0f, 1.0f, 8, 1);
}
else if (type == OB_BOUND_CONE) {
float radius = size[0] > size[1] ? size[0] : size[1];
- glTranslatef(cent[0], cent[1], cent[2] - size[2]);
- glScalef(radius, radius, 2.0f * size[2]);
- gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
+ gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]);
+ gpuScale3f(radius, radius, 2.0f * size[2]);
+ imm_draw_cylinder_wire_3d(pos, 1.0f, 0.0f, 1.0f, 8, 1);
+
}
else if (type == OB_BOUND_CAPSULE) {
float radius = size[0] > size[1] ? size[0] : size[1];
float length = size[2] > radius ? 2.0f * (size[2] - radius) : 0.0f;
- glTranslatef(cent[0], cent[1], cent[2] - length * 0.5f);
- gluCylinder(qobj, radius, radius, length, 8, 1);
- gluSphere(qobj, radius, 8, 4);
- glTranslatef(0.0, 0.0, length);
- gluSphere(qobj, radius, 8, 4);
+ gpuTranslate3f(cent[0], cent[1], cent[2] - length * 0.5f);
+ imm_draw_cylinder_wire_3d(pos, radius, radius, length, 8, 1);
+
+ gpuRotateAxis(90, 'X');
+ gpuScaleUniform(radius);
+ Batch_draw(sphere);
+
+ gpuTranslate3f(0.0f, length / radius, 0.0f);
+ Batch_draw(sphere);
}
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
+
+ gpuPopMatrix();
+ immUnbindProgram();
}
-static void draw_bounding_volume(Object *ob, char type)
+void draw_bounding_volume(Object *ob, char type, const unsigned char ob_wire_col[4])
{
BoundBox bb_local;
BoundBox *bb = NULL;
@@ -7097,12 +8154,16 @@ static void draw_bounding_volume(Object *ob, char type)
if (bb == NULL)
return;
-
+
if (ob->gameflag & OB_BOUNDS) { /* bounds need to be drawn around origin for game engine */
if (type == OB_BOUND_BOX) {
float vec[8][3], size[3];
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
BKE_boundbox_calc_size_aabb(bb, size);
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0];
@@ -7112,21 +8173,31 @@ static void draw_bounding_volume(Object *ob, char type)
vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2];
vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2];
- draw_box(vec, false);
+ imm_draw_box(vec, false, pos);
+
+ immUnbindProgram();
}
else {
- draw_bb_quadric(bb, type, true);
+ imm_draw_bb(bb, type, true, ob_wire_col);
}
}
else {
- if (type == OB_BOUND_BOX)
- draw_box(bb->vec, false);
+ if (type == OB_BOUND_BOX) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
+ imm_draw_box(bb->vec, false, pos);
+
+ immUnbindProgram();
+ }
else
- draw_bb_quadric(bb, type, false);
+ imm_draw_bb(bb, type, false, ob_wire_col);
}
+
}
-static void drawtexspace(Object *ob)
+static void drawtexspace(Object *ob, const unsigned char ob_wire_col[3])
{
float vec[8][3], loc[3], size[3];
@@ -7156,20 +8227,32 @@ static void drawtexspace(Object *ob)
setlinestyle(2);
- draw_box(vec, false);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ if (ob_wire_col) {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(ob_wire_col);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+ }
+
+ imm_draw_box(vec, false, pos);
+
+ immUnbindProgram();
setlinestyle(0);
}
/* draws wire outline */
static void draw_object_selected_outline(
- Scene *scene, View3D *v3d, ARegion *ar, Base *base,
+ Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
const unsigned char ob_wire_col[4])
{
RegionView3D *rv3d = ar->regiondata;
Object *ob = base->object;
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
bool has_faces = false;
@@ -7193,46 +8276,41 @@ static void draw_object_selected_outline(
if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
if (dm) {
- draw_mesh_object_outline(v3d, ob, dm);
+ draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
}
else {
/* only draw 'solid' parts of the display list as wire. */
- drawDispListwire_ex(&ob->curve_cache->disp, (DL_INDEX3 | DL_INDEX4 | DL_SURF));
+ drawDispListwire_ex(&ob->curve_cache->disp, (DL_INDEX3 | DL_INDEX4 | DL_SURF), ob_wire_col);
}
}
}
else if (ob->type == OB_MBALL) {
if (BKE_mball_is_basis(ob)) {
- if ((base->flag & OB_FROMDUPLI) == 0) {
+ if ((base->flag_legacy & OB_FROMDUPLI) == 0) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- drawDispListwire(&ob->curve_cache->disp, ob->type);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, ob_wire_col);
}
}
}
else if (ob->type == OB_ARMATURE) {
- if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) {
+ if (!(ob->mode & OB_MODE_POSE && base == sl->basact)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- draw_armature(scene, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
+ draw_armature(scene, sl, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
}
}
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
}
static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4])
{
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
-
- if (scene->obedit == ob) {
- UI_ThemeColor(TH_WIRE_EDIT);
- }
- else {
- glColor3ubv(ob_wire_col);
- }
+ unsigned char wire_edit_col[4];
+ UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_edit_col);
ED_view3d_polygon_offset(rv3d, 1.0);
- glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
- glLineWidth(1);
+ glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */
+ glLineWidth(1.0f);
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
@@ -7241,23 +8319,23 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const
drawCurveDMWired(ob);
}
else {
- drawDispListwire(&ob->curve_cache->disp, ob->type);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
}
}
}
else if (ob->type == OB_MBALL) {
if (BKE_mball_is_basis(ob)) {
- drawDispListwire(&ob->curve_cache->disp, ob->type);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
}
}
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
ED_view3d_polygon_offset(rv3d, 0.0);
}
}
/* should be called in view space */
-static void draw_hooks(Object *ob)
+static void draw_hooks(Object *ob, unsigned int pos)
{
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Hook) {
@@ -7268,17 +8346,17 @@ static void draw_hooks(Object *ob)
if (hmd->object) {
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(hmd->object->obmat[3]);
- glVertex3fv(vec);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, hmd->object->obmat[3]);
+ immVertex3fv(pos, vec);
+ immEnd();
setlinestyle(0);
}
- glPointSize(3.0);
- glBegin(GL_POINTS);
- glVertex3fv(vec);
- glEnd();
+ glPointSize(3.0f);
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, vec);
+ immEnd();
}
}
}
@@ -7289,9 +8367,16 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
const char *axis_str[3] = {"px", "py", "pz"};
float mat[4][4];
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
eul_to_mat4(mat, &data->axX);
glLineWidth(4.0f);
setlinestyle(2);
+
+ immBegin(PRIM_LINES, 6);
for (int axis = 0; axis < 3; axis++) {
float dir[3] = {0, 0, 0};
float v[3];
@@ -7299,12 +8384,10 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
copy_v3_v3(v, &data->pivX);
dir[axis] = 1.0f;
- glBegin(GL_LINES);
mul_m4_v3(mat, dir);
add_v3_v3(v, dir);
- glVertex3fv(&data->pivX);
- glVertex3fv(v);
- glEnd();
+ immVertex3fv(pos, &data->pivX);
+ immVertex3fv(pos, v);
/* when const color is set wirecolor is NULL - we could get the current color but
* with selection and group instancing its not needed to draw the text */
@@ -7312,11 +8395,15 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
view3d_cached_text_draw_add(v, axis_str[axis], 2, 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
}
}
+ immEnd();
setlinestyle(0);
+ glLineWidth(1.0f);
+
+ immUnbindProgram();
}
-static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_wire_col[4])
+void draw_object_wire_color(Scene *scene, SceneLayer *sl, Base *base, unsigned char r_ob_wire_col[4])
{
Object *ob = base->object;
int colindex = 0;
@@ -7330,23 +8417,23 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
if ((scene->obedit == NULL) &&
(G.moving & G_TRANSFORM_OBJ) &&
- (base->flag & (SELECT + BA_WAS_SEL)))
+ ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)))
{
theme_id = TH_TRANSFORM;
}
else {
/* Sets the 'colindex' */
if (ID_IS_LINKED_DATABLOCK(ob)) {
- colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 2 : 1;
+ colindex = ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) ? 2 : 1;
}
/* Sets the 'theme_id' or fallback to wire */
else {
- if (ob->flag & OB_FROMGROUP) {
- if (base->flag & (SELECT + BA_WAS_SEL)) {
+ if ((ob->flag & OB_FROMGROUP) != 0) {
+ if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) {
/* uses darker active color for non-active + selected */
theme_id = TH_GROUP_ACTIVE;
- if (scene->basact != base) {
+ if (sl->basact != base) {
theme_shade = -16;
}
}
@@ -7355,8 +8442,8 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
}
}
else {
- if (base->flag & (SELECT + BA_WAS_SEL)) {
- theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT;
+ if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) {
+ theme_id = sl->basact == base ? TH_ACTIVE : TH_SELECT;
}
else {
if (ob->type == OB_LAMP) theme_id = TH_LAMP;
@@ -7410,10 +8497,11 @@ static void draw_object_matcap_check(View3D *v3d, Object *ob)
v3d->flag2 |= V3D_SHOW_SOLID_MATCAP;
}
-static void draw_rigidbody_shape(Object *ob)
+void draw_rigidbody_shape(Object *ob, const unsigned char ob_wire_col[4])
{
BoundBox *bb = NULL;
float size[3], vec[8][3];
+ unsigned int pos;
if (ob->type == OB_MESH) {
bb = BKE_mesh_boundbox_get(ob);
@@ -7426,6 +8514,10 @@ static void draw_rigidbody_shape(Object *ob)
case RB_SHAPE_BOX:
BKE_boundbox_calc_size_aabb(bb, size);
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
+
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0];
vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0];
vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = -size[1];
@@ -7433,19 +8525,20 @@ static void draw_rigidbody_shape(Object *ob)
vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2];
vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2];
- draw_box(vec, false);
+ imm_draw_box(vec, false, pos);
+ immUnbindProgram();
break;
case RB_SHAPE_SPHERE:
- draw_bb_quadric(bb, OB_BOUND_SPHERE, true);
+ imm_draw_bb(bb, OB_BOUND_SPHERE, true, ob_wire_col);
break;
case RB_SHAPE_CONE:
- draw_bb_quadric(bb, OB_BOUND_CONE, true);
+ imm_draw_bb(bb, OB_BOUND_CONE, true, ob_wire_col);
break;
case RB_SHAPE_CYLINDER:
- draw_bb_quadric(bb, OB_BOUND_CYLINDER, true);
+ imm_draw_bb(bb, OB_BOUND_CYLINDER, true, ob_wire_col);
break;
case RB_SHAPE_CAPSULE:
- draw_bb_quadric(bb, OB_BOUND_CAPSULE, true);
+ imm_draw_bb(bb, OB_BOUND_CAPSULE, true, ob_wire_col);
break;
}
}
@@ -7454,17 +8547,16 @@ static void draw_rigidbody_shape(Object *ob)
* main object drawing function, draws in selection
* \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET
*/
-void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag)
{
ModifierData *md = NULL;
Object *ob = base->object;
Curve *cu;
RegionView3D *rv3d = ar->regiondata;
- unsigned int col = 0;
unsigned char _ob_wire_col[4]; /* dont initialize this */
const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
bool zbufoff = false, is_paint = false, empty_object = false;
- const bool is_obact = (ob == OBACT);
+ const bool is_obact = (ob == OBACT_NEW);
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
const bool is_picking = (G.f & G_PICKSEL) != 0;
const bool has_particles = (ob->particlesystem.first != NULL);
@@ -7504,7 +8596,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
- if (((base->flag & OB_FROMDUPLI) == 0) &&
+ if (((base->flag_legacy & OB_FROMDUPLI) == 0) &&
(md = modifiers_findByType(ob, eModifierType_Smoke)) &&
(modifier_isEnabled(scene, md, eModifierMode_Realtime)))
{
@@ -7528,7 +8620,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* xray delay? */
- if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* don't do xray in particle mode, need the z-buffer */
if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
/* xray and transp are set when it is drawing the 2nd/3rd pass */
@@ -7581,10 +8673,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
ED_view3d_project_base(ar, base);
- draw_object_wire_color(scene, base, _ob_wire_col);
+ draw_object_wire_color(scene, sl, base, _ob_wire_col);
ob_wire_col = _ob_wire_col;
- glColor3ubv(ob_wire_col);
+ //glColor3ubv(ob_wire_col);
}
/* maximum drawtype */
@@ -7636,15 +8728,22 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* draw outline for selected objects, mesh does itself */
if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) {
if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) {
- if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) {
- draw_object_selected_outline(scene, v3d, ar, base, ob_wire_col);
+ if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) {
+ draw_object_selected_outline(scene, sl, v3d, ar, base, ob_wire_col);
}
}
}
+ /* TODO Viewport: draw only for selection */
+ if ((dflag & DRAW_PICKING) == 0) {
+ if ((dt == OB_BOUNDBOX) || ELEM(ob->type, OB_EMPTY, OB_LAMP, OB_CAMERA, OB_SPEAKER)) {
+ goto afterdraw;
+ }
+ }
+
switch (ob->type) {
case OB_MESH:
- empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ empty_object = draw_mesh_object(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* mesh draws wire itself */
dtx &= ~OB_DRAWWIRE;
@@ -7654,18 +8753,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
case OB_FONT:
cu = ob->data;
if (cu->editfont) {
- draw_editfont(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ draw_editfont(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && v3d->drawtype >= OB_WIRE) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
ensure_curve_cache(scene, base->object);
#endif
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
- empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
break;
@@ -7675,18 +8774,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (cu->editnurb) {
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- draw_editnurb(scene, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
+ draw_editnurb(scene, sl, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
ensure_curve_cache(scene, base->object);
#endif
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
- empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
break;
case OB_MBALL:
@@ -7694,17 +8793,17 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
MetaBall *mb = ob->data;
if (mb->editelems)
- drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawmball(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
ensure_curve_cache(scene, base->object);
#endif
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else
- empty_object = drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawmball(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
break;
}
case OB_EMPTY:
@@ -7713,7 +8812,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
draw_empty_image(ob, dflag, ob_wire_col, v3d->multiview_eye);
}
else {
- drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype);
+ drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, ob_wire_col);
}
}
break;
@@ -7731,7 +8830,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
break;
case OB_SPEAKER:
if (!render_override)
- drawspeaker(scene, v3d, rv3d, ob, dflag);
+ drawspeaker(ob_wire_col);
break;
case OB_LATTICE:
if (!render_override) {
@@ -7739,13 +8838,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT))
dt = OB_WIRE;
if (dt == OB_BOUNDBOX) {
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else {
#ifdef SEQUENCER_DAG_WORKAROUND
ensure_curve_cache(scene, ob);
#endif
- drawlattice(v3d, ob);
+ drawlattice(v3d, ob, dflag, ob_wire_col);
}
}
break;
@@ -7755,21 +8854,33 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE)))
dt = OB_WIRE;
if (dt == OB_BOUNDBOX) {
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else {
+ unsigned char arm_col[4];
glLineWidth(1.0f);
- empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, false);
+
+ if (ob_wire_col == NULL) {
+ float fcol[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ rgba_float_to_uchar(arm_col, fcol);
+ }
+ else
+ copy_v4_v4_uchar(arm_col, ob_wire_col);
+
+ empty_object = draw_armature(scene, sl, v3d, ar, base, dt, dflag, arm_col, false);
}
}
break;
default:
if (!render_override) {
- drawaxes(rv3d->viewmatob, 1.0, OB_ARROWS);
+ drawaxes(rv3d->viewmatob, 1.0, OB_ARROWS, ob_wire_col);
}
break;
}
+ /* TODO Viewport: some elements are being drawn for object selection only */
+afterdraw:
+
if (!render_override) {
if (ob->soft /*&& dflag & OB_SBMOTION*/) {
float mrt[3][3], msc[3][3], mtr[3][3];
@@ -7778,12 +8889,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((sb = ob->soft)) {
if (sb->solverflags & SBSO_ESTIMATEIPO) {
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
copy_m3_m3(msc, sb->lscale);
copy_m3_m3(mrt, sb->lrot);
mul_m3_m3m3(mtr, mrt, msc);
ob_draw_RE_motion(sb->lcom, mtr, tipw, tiph, drawsize);
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
}
}
}
@@ -7800,15 +8911,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
{
ParticleSystem *psys;
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- /* for visibility, also while wpaint */
- if (col || (ob->flag & SELECT)) {
- cpack(0xFFFFFF);
- }
- }
//glDepthMask(GL_FALSE);
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
view3d_cached_text_draw_begin();
@@ -7817,7 +8922,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
PTCacheEdit *edit = PE_create_current(scene, ob);
if (edit && edit->psys == psys)
- draw_update_ptcache_edit(scene, ob, edit);
+ draw_update_ptcache_edit(scene, sl, ob, edit);
}
draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag);
@@ -7825,10 +8930,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
invert_m4_m4(ob->imat, ob->obmat);
view3d_cached_text_draw_end(v3d, ar, 0);
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
//glDepthMask(GL_TRUE);
- if (col) cpack(col);
}
/* draw edit particles last so that they can draw over child particles */
@@ -7839,10 +8943,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
PTCacheEdit *edit = PE_create_current(scene, ob);
if (edit) {
- glLoadMatrixf(rv3d->viewmat);
- draw_update_ptcache_edit(scene, ob, edit);
+ gpuLoadMatrix(rv3d->viewmat);
+ draw_update_ptcache_edit(scene, sl, ob, edit);
draw_ptcache_edit(scene, v3d, edit);
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
}
}
}
@@ -7850,21 +8954,25 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* draw code for smoke, only draw domains */
if (smd && smd->domain) {
SmokeDomainSettings *sds = smd->domain;
+ const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe);
float viewnormal[3];
- glLoadMatrixf(rv3d->viewmat);
- glMultMatrixf(ob->obmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ gpuMultMatrix(ob->obmat);
if (!render_override) {
BoundBox bb;
float p0[3], p1[3];
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (ob_wire_col) immUniformColor3ubv(ob_wire_col);
/* draw max domain bounds */
if ((sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN)) {
VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res);
VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res);
BKE_boundbox_init_from_minmax(&bb, p0, p1);
- draw_box(bb.vec, false);
+ imm_draw_box(bb.vec, false, pos);
}
/* draw a single voxel to hint the user about the resolution of the fluid */
@@ -7878,11 +8986,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
BKE_boundbox_init_from_minmax(&bb, p0, p1);
- draw_box(bb.vec, false);
+ imm_draw_box(bb.vec, false, pos);
+
+ immUnbindProgram();
}
/* don't show smoke before simulation starts, this could be made an option in the future */
- if (sds->fluid && CFRA >= sds->point_cache[0]->startframe) {
+ if (sds->fluid && show_smoke) {
float p0[3], p1[3];
/* get view vector */
@@ -7934,29 +9044,37 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((ob->gameflag & OB_BOUNDS) && (ob->mode == OB_MODE_OBJECT)) {
if (ob->boundtype != ob->collision_boundtype || (dtx & OB_DRAWBOUNDOX) == 0) {
setlinestyle(2);
- draw_bounding_volume(ob, ob->collision_boundtype);
+ draw_bounding_volume(ob, ob->collision_boundtype, ob_wire_col);
setlinestyle(0);
}
}
if (ob->rigidbody_object) {
- draw_rigidbody_shape(ob);
+ draw_rigidbody_shape(ob, ob_wire_col);
}
/* draw extra: after normal draw because of makeDispList */
if (dtx && (G.f & G_RENDER_OGL) == 0) {
if (dtx & OB_AXIS) {
- drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS);
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ /* prevent random colors being used */
+ drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, ob_wire_col);
+ }
+ else {
+ drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, NULL);
+ }
}
if (dtx & OB_DRAWBOUNDOX) {
- draw_bounding_volume(ob, ob->boundtype);
+ draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
if (dtx & OB_TEXSPACE) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* prevent random colors being used */
- glColor3ubv(ob_wire_col);
+ drawtexspace(ob, ob_wire_col);
+ }
+ else {
+ drawtexspace(ob, NULL);
}
- drawtexspace(ob);
}
if (dtx & OB_DRAWNAME) {
/* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
@@ -7983,16 +9101,21 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
{
float imat[4][4], vec[3] = {0.0f, 0.0f, 0.0f};
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
invert_m4_m4(imat, rv3d->viewmatob);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* prevent random colors being used */
- glColor3ubv(ob_wire_col);
+ immUniformColor3ubv(ob_wire_col);
}
setlinestyle(2);
- drawcircball(GL_LINE_LOOP, vec, ob->inertia, imat);
+ imm_drawcircball(vec, ob->inertia, imat, pos);
setlinestyle(0);
+
+ immUnbindProgram();
}
}
@@ -8002,13 +9125,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* return warning, clear temp flag */
v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP;
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
if (zbufoff) {
glDisable(GL_DEPTH_TEST);
}
- if ((base->flag & OB_FROMDUPLI) || render_override) {
+ if ((base->flag_legacy & OB_FROMDUPLI) || render_override) {
ED_view3d_clear_mats_rv3d(rv3d);
return;
}
@@ -8022,7 +9145,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
else if (is_obact)
do_draw_center = ACTIVE;
- else if (base->flag & SELECT)
+ else if (base->flag & BASE_SELECTED)
do_draw_center = SELECT;
else if (empty_object || (v3d->flag & V3D_DRAW_CENTERS))
do_draw_center = DESELECT;
@@ -8033,10 +9156,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((base->sx != IS_CLIPPED) &&
(U.obcenter_dia != 0.0))
{
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ /* TODO: short term, use DEPTH_ONLY shader or set appropriate color */
+ /* TODO: long term, solve picking & selection problem better */
glPointSize(U.obcenter_dia);
- glBegin(GL_POINTS);
- glVertex3fv(ob->obmat[3]);
- glEnd();
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(pos, ob->obmat[3]);
+ immEnd();
+ immUnbindProgram();
}
}
else if ((dflag & DRAW_CONSTCOLOR) == 0) {
@@ -8057,18 +9185,25 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
ListBase *list;
RigidBodyCon *rbc = ob->rigidbody_constraint;
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(ob_wire_col);
+
/* draw hook center and offset line */
if (ob != scene->obedit)
- draw_hooks(ob);
+ draw_hooks(ob, pos);
/* help lines and so */
- if (ob != scene->obedit && ob->parent && (ob->parent->lay & v3d->lay)) {
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(ob->obmat[3]);
- glVertex3fv(ob->orig);
- glEnd();
- setlinestyle(0);
+ if (ob != scene->obedit && ob->parent) {
+ Base *base_parent = BKE_scene_layer_base_find(sl, ob->parent);
+ if ((base_parent->flag & BASE_VISIBLED) != 0) {
+ setlinestyle(3);
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, ob->obmat[3]);
+ immVertex3fv(pos, ob->orig);
+ immEnd();
+ setlinestyle(0);
+ }
}
/* Drawing the constraint lines */
@@ -8081,7 +9216,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
UI_GetThemeColor3ubv(TH_GRID, col1);
UI_make_axis_color(col1, col2, 'Z');
- glColor3ubv(col2);
+ immUniformColor3ubv(col2);
cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
@@ -8106,10 +9241,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (camob) {
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(camob->obmat[3]);
- glVertex3fv(ob->obmat[3]);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, camob->obmat[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immEnd();
setlinestyle(0);
}
}
@@ -8130,10 +9265,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
unit_m4(ct->matrix);
setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(ct->matrix[3]);
- glVertex3fv(ob->obmat[3]);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, ct->matrix[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immEnd();
setlinestyle(0);
}
@@ -8146,21 +9281,24 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
BKE_constraints_clear_evalob(cob);
}
/* draw rigid body constraint lines */
- if (rbc) {
- UI_ThemeColor(TH_WIRE);
+ if (rbc && (rbc->ob1 || rbc->ob2)) {
+ immUniformThemeColor(TH_WIRE);
+
setlinestyle(3);
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, ((int)((bool)rbc->ob1) + (int)((bool)rbc->ob2)) * 2);
if (rbc->ob1) {
- glVertex3fv(ob->obmat[3]);
- glVertex3fv(rbc->ob1->obmat[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immVertex3fv(pos, rbc->ob1->obmat[3]);
}
if (rbc->ob2) {
- glVertex3fv(ob->obmat[3]);
- glVertex3fv(rbc->ob2->obmat[3]);
+ immVertex3fv(pos, ob->obmat[3]);
+ immVertex3fv(pos, rbc->ob2->obmat[3]);
}
- glEnd();
+ immEnd();
setlinestyle(0);
}
+
+ immUnbindProgram();
}
ED_view3d_clear_mats_rv3d(rv3d);
@@ -8171,10 +9309,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
* Drawing for selection picking,
* caller must have called 'GPU_select_load_id(base->selcode)' first.
*/
-void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+void draw_object_select(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag)
{
BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR);
- draw_object(scene, ar, v3d, base, dflag);
+ draw_object(scene, sl, ar, v3d, base, dflag);
/* we draw duplicators for selection too */
if ((base->object->transflag & OB_DUPLI)) {
@@ -8182,13 +9320,11 @@ void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, cons
DupliObject *dob;
Base tbase;
- tbase.flag = OB_FROMDUPLI;
+ tbase.flag_legacy = OB_FROMDUPLI;
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
for (dob = lb->first; dob; dob = dob->next) {
float omat[4][4];
- char dt;
- short dtx;
tbase.object = dob->ob;
copy_m4_m4(omat, dob->ob->obmat);
@@ -8196,10 +9332,10 @@ void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, cons
/* extra service: draw the duplicator in drawtype of parent */
/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
- dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
- dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
+ char dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
+ short dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
- draw_object(scene, ar, v3d, &tbase, dflag);
+ draw_object(scene, sl, ar, v3d, &tbase, dflag);
tbase.object->dt = dt;
tbase.object->dtx = dtx;
@@ -8219,8 +9355,10 @@ static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const floa
MVert *mv = &data->mvert[index];
if (!(mv->flag & ME_HIDE)) {
- GPU_select_index_set(data->offset + index);
- glVertex3fv(co);
+ int selcol;
+ GPU_select_index_get(data->offset + index, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, co);
}
}
@@ -8231,10 +9369,24 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
MVert *mvert = me->mvert;
data.mvert = mvert;
data.offset = offset;
+
+ const int imm_len = dm->getNumVerts(dm);
+
+ if (imm_len == 0) return;
+
+ VertexFormat *format = immVertexFormat();
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.col = VertexFormat_add_attrib(format, "color", COMP_U32, 1, KEEP_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+
+ immBeginAtMost(PRIM_POINTS, imm_len);
dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3],
@@ -8244,97 +9396,170 @@ static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3]
BMVert *eve = BM_vert_at_index(data->bm, index);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(data->offset + index);
- glVertex3fv(co);
+ int selcol;
+ GPU_select_index_get(data->offset + index, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, co);
}
}
static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
{
- drawBMOffset_userData data = {em->bm, offset};
+ drawBMOffset_userData data;
+ data.bm = em->bm;
+ data.offset = offset;
+ VertexFormat *format = immVertexFormat();
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.col = VertexFormat_add_attrib(format, "color", COMP_U32, 1, KEEP_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- glBegin(GL_POINTS);
+
+ immBeginAtMost(PRIM_POINTS, em->bm->totvert);
dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
-static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index)
+static void bbs_mesh_wire__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
{
drawBMOffset_userData *data = userData;
BMEdge *eed = BM_edge_at_index(data->bm, index);
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(data->offset + index);
- return DM_DRAW_OPTION_NORMAL;
- }
- else {
- return DM_DRAW_OPTION_SKIP;
+ int selcol;
+ GPU_select_index_get(data->offset + index, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, v0co);
+ immVertex3fv(data->pos, v1co);
}
}
+
static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
{
- drawBMOffset_userData data = {em->bm, offset};
- dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, &data);
+ drawBMOffset_userData data;
+ data.bm = em->bm;
+ data.offset = offset;
+
+ VertexFormat *format = immVertexFormat();
+
+ const int imm_len = dm->getNumEdges(dm) * 2;
+
+ if (imm_len == 0) return;
+
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.col = VertexFormat_add_attrib(format, "color", COMP_U32, 1, KEEP_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ immBeginAtMost(PRIM_LINES, imm_len);
+ dm->foreachMappedEdge(dm, bbs_mesh_wire__mapFunc, &data);
+ immEnd();
+
+ immUnbindProgram();
}
-/**
- * dont set #GPU_framebuffer_index_set. just use to mask other
- */
-static DMDrawOption bbs_mesh_mask__setSolidDrawOptions(void *userData, int index)
+static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select)
{
- BMFace *efa = BM_face_at_index(userData, index);
-
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- return DM_DRAW_OPTION_NORMAL;
+ UNUSED_VARS(dm);
+
+ drawBMOffset_userData data;
+ data.bm = em->bm;
+
+ const int tri_len = em->tottri;
+ const int imm_len = tri_len * 3;
+ const char hflag_skip = use_select ? BM_ELEM_HIDDEN : (BM_ELEM_HIDDEN | BM_ELEM_SELECT);
+
+ if (imm_len == 0) return;
+
+ VertexFormat *format = immVertexFormat();
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.col = VertexFormat_add_attrib(format, "color", COMP_U32, 1, KEEP_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
+
+ immBeginAtMost(PRIM_TRIANGLES, imm_len);
+
+ if (use_select == false) {
+ int selcol;
+ GPU_select_index_get(0, &selcol);
+ immAttrib1u(data.col, selcol);
}
- else {
- return DM_DRAW_OPTION_SKIP;
+
+ int index = 0;
+ while (index < tri_len) {
+ const BMFace *f = em->looptris[index][0]->f;
+ const int ntris = f->len - 2;
+ if (!BM_elem_flag_test(f, hflag_skip)) {
+ if (use_select) {
+ int selcol;
+ GPU_select_index_get(BM_elem_index_get(f) + 1, &selcol);
+ immAttrib1u(data.col, selcol);
+ }
+ for (int t = 0; t < ntris; t++) {
+ immVertex3fv(data.pos, em->looptris[index][0]->v->co);
+ immVertex3fv(data.pos, em->looptris[index][1]->v->co);
+ immVertex3fv(data.pos, em->looptris[index][2]->v->co);
+ index++;
+ }
+ }
+ else {
+ index += ntris;
+ }
}
+ immEnd();
+
+ immUnbindProgram();
}
-static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index)
+static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
{
+ drawBMOffset_userData *data = (drawBMOffset_userData *)userData;
BMFace *efa = BM_face_at_index(userData, index);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(index + 1);
- return DM_DRAW_OPTION_NORMAL;
- }
- else {
- return DM_DRAW_OPTION_SKIP;
+ int selcol;
+ GPU_select_index_get(index + 1, &selcol);
+ immAttrib1u(data->col, selcol);
+ immVertex3fv(data->pos, cent);
}
}
-static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
+static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
{
- BMFace *efa = BM_face_at_index(userData, index);
+ drawBMOffset_userData data; /* don't use offset */
+ data.bm = em->bm;
+ VertexFormat *format = immVertexFormat();
+ data.pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ data.col = VertexFormat_add_attrib(format, "color", COMP_U32, 1, KEEP_INT);
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- GPU_select_index_set(index + 1);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
- glVertex3fv(cent);
- }
+ glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
+
+ immBeginAtMost(PRIM_POINTS, em->bm->totface);
+ dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, &data, DM_FOREACH_NOP);
+ immEnd();
+
+ immUnbindProgram();
}
/* two options, facecolors or black */
static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
Object *ob, DerivedMesh *dm, bool use_faceselect)
{
- cpack(0);
-
if (use_faceselect) {
- dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_HIDDEN | DM_DRAW_SELECT_USE_EDITMODE);
+ bbs_mesh_face(em, dm, true);
if (check_ob_drawface_dot(scene, v3d, ob->dt)) {
- glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
-
- glBegin(GL_POINTS);
- dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, em->bm, DM_FOREACH_NOP);
- glEnd();
+ bbs_mesh_face_dot(em, dm);
}
-
}
else {
- dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_SELECT | DM_DRAW_SKIP_HIDDEN | DM_DRAW_SELECT_USE_EDITMODE);
+ bbs_mesh_face(em, dm, false);
}
}
@@ -8349,7 +9574,6 @@ static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index)
Mesh *me = userData;
if (!(me->mpoly[index].flag & ME_HIDE)) {
- GPU_select_index_set(index + 1);
return DM_DRAW_OPTION_NORMAL;
}
else {
@@ -8374,7 +9598,6 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
{
Mesh *me = ob->data;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- glColor3ub(0, 0, 0);
DM_update_materials(dm, ob);
@@ -8389,26 +9612,24 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
{
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
Mesh *me = ob->data;
-
- glColor3ub(0, 0, 0);
-
- DM_update_materials(dm, ob);
-
- if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
- dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, NULL, NULL, me, DM_DRAW_SKIP_HIDDEN);
- else
- dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, NULL, NULL, me, 0);
-
- dm->release(dm);
+ UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts);
+ Batch *batch;
+ if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true);
+ }
+ else {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false);
+ }
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ Batch_draw(batch);
}
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
ToolSettings *ts = scene->toolsettings;
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
@@ -8468,7 +9689,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
break;
}
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadMatrix(rv3d->viewmat);
}
@@ -8476,8 +9697,8 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
/* assumes all matrices/etc set OK */
/* helper function for drawing object instances - meshes */
-static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Object *ob, const short dt, int outline)
+static void draw_object_mesh_instance(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
+ Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4])
{
Mesh *me = ob->data;
DerivedMesh *dm = NULL, *edm = NULL;
@@ -8492,6 +9713,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
}
if (dt <= OB_WIRE) {
+ glColor4ubv(ob_wire_col);
if (dm)
dm->drawEdges(dm, 1, 0);
else if (edm)
@@ -8499,11 +9721,11 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
}
else {
if (outline)
- draw_mesh_object_outline(v3d, ob, dm ? dm : edm);
+ draw_mesh_object_outline(v3d, ob, dm ? dm : edm, ob_wire_col);
if (dm) {
- bool glsl = draw_glsl_material(scene, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ bool glsl = draw_glsl_material(scene, sl, ob, v3d, dt);
+ GPU_begin_object_materials(v3d, rv3d, scene, sl, ob, glsl, NULL);
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@@ -8522,22 +9744,24 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
if (dm) dm->release(dm);
}
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline)
+void draw_object_instance(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4])
{
if (ob == NULL)
return;
+ unsigned char bcol[4];
+ rgba_float_to_uchar(bcol, wire_col);
+
switch (ob->type) {
case OB_MESH:
- draw_object_mesh_instance(scene, v3d, rv3d, ob, dt, outline);
+ draw_object_mesh_instance(scene, sl, v3d, rv3d, ob, dt, outline, bcol);
break;
case OB_EMPTY:
if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
- /* CONSTCOLOR == no wire outline */
- draw_empty_image(ob, DRAW_CONSTCOLOR, NULL, v3d->multiview_eye);
+ draw_empty_image(ob, 0, bcol, v3d->multiview_eye);
}
else {
- drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype);
+ drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, bcol);
}
break;
}
diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c
index 3f23d4aa09a..24ac1c5b4db 100644
--- a/source/blender/editors/space_view3d/drawsimdebug.c
+++ b/source/blender/editors/space_view3d/drawsimdebug.c
@@ -40,102 +40,137 @@
#include "BKE_effect.h"
-#include "view3d_intern.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
-#include "BIF_gl.h"
+#include "view3d_intern.h"
static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4])
{
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ /* count element types */
GHashIterator iter;
+ int num_dots = 0;
+ int num_circles = 0;
+ int num_lines = 0;
+ int num_vectors = 0;
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ switch (elem->type) {
+ case SIM_DEBUG_ELEM_DOT: ++num_dots; break;
+ case SIM_DEBUG_ELEM_CIRCLE: ++num_circles; break;
+ case SIM_DEBUG_ELEM_LINE: ++num_lines; break;
+ case SIM_DEBUG_ELEM_VECTOR: ++num_vectors; break;
+ }
+ }
/**** dots ****/
glPointSize(3.0f);
- glBegin(GL_POINTS);
+ immBegin(PRIM_POINTS, num_dots);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
if (elem->type != SIM_DEBUG_ELEM_DOT)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
}
- glEnd();
+ immEnd();
/**** circles ****/
{
- float circle[16][2] = {
+#define CIRCLERES 16
+ float circle[CIRCLERES][2] = {
{0.000000, 1.000000}, {0.382683, 0.923880}, {0.707107, 0.707107}, {0.923880, 0.382683},
{1.000000, -0.000000}, {0.923880, -0.382683}, {0.707107, -0.707107}, {0.382683, -0.923880},
{-0.000000, -1.000000}, {-0.382683, -0.923880}, {-0.707107, -0.707107}, {-0.923879, -0.382684},
{-1.000000, 0.000000}, {-0.923879, 0.382684}, {-0.707107, 0.707107}, {-0.382683, 0.923880} };
+
+ immBegin(PRIM_LINES, num_circles * CIRCLERES * 2);
+
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
float radius = elem->v2[0];
- float co[3];
+ float co[3], nco[3];
int i;
if (elem->type != SIM_DEBUG_ELEM_CIRCLE)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glBegin(GL_LINE_LOOP);
- for (i = 0; i < 16; ++i) {
- co[0] = radius * circle[i][0];
- co[1] = radius * circle[i][1];
- co[2] = 0.0f;
- mul_mat3_m4_v3(imat, co);
- add_v3_v3(co, elem->v1);
+ immAttrib3fv(color, elem->color);
+ zero_v3(co);
+ for (i = 0; i <= CIRCLERES; ++i) {
+ int ni = i % CIRCLERES;
+ nco[0] = radius * circle[ni][0];
+ nco[1] = radius * circle[ni][1];
+ nco[2] = 0.0f;
+ mul_mat3_m4_v3(imat, nco);
+ add_v3_v3(nco, elem->v1);
- glVertex3f(co[0], co[1], co[2]);
+ if (i > 0) {
+ immVertex3fv(pos, co);
+ immVertex3fv(pos, nco);
+ }
+
+ copy_v3_v3(co, nco);
}
- glEnd();
}
+
+ immEnd();
+#undef CIRCLERES
}
/**** lines ****/
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, num_lines * 2);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
if (elem->type != SIM_DEBUG_ELEM_LINE)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
- glVertex3f(elem->v2[0], elem->v2[1], elem->v2[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
+ immVertex3fv(pos, elem->v2);
}
- glEnd();
+ immEnd();
/**** vectors ****/
glPointSize(2.0f);
- glBegin(GL_POINTS);
+ immBegin(PRIM_POINTS, num_vectors);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
if (elem->type != SIM_DEBUG_ELEM_VECTOR)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
}
- glEnd();
+ immEnd();
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, num_vectors * 2);
for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
float t[3];
if (elem->type != SIM_DEBUG_ELEM_VECTOR)
continue;
- glColor3f(elem->color[0], elem->color[1], elem->color[2]);
- glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ immAttrib3fv(color, elem->color);
+ immVertex3fv(pos, elem->v1);
add_v3_v3v3(t, elem->v1, elem->v2);
- glVertex3f(t[0], t[1], t[2]);
+ immVertex3fv(pos, t);
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
/**** strings ****/
@@ -163,18 +198,12 @@ void draw_sim_debug_data(Scene *UNUSED(scene), View3D *v3d, ARegion *ar)
invert_m4_m4(imat, rv3d->viewmatob);
-// glDepthMask(GL_FALSE);
-// glEnable(GL_BLEND);
-
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix(rv3d->viewmat);
view3d_cached_text_draw_begin();
draw_sim_debug_elements(_sim_debug_data, imat);
view3d_cached_text_draw_end(v3d, ar, false);
- glPopMatrix();
-
-// glDepthMask(GL_TRUE);
-// glDisable(GL_BLEND);
+ gpuPopMatrix();
}
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index c076bfb4aa4..3a80624acd9 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -48,7 +48,6 @@
#include "BIF_gl.h"
-#include "GPU_debug.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -160,7 +159,7 @@ static GPUTexture *create_field_texture(SmokeDomainSettings *sds)
default: return NULL;
}
- return GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, field);
+ return GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1, GPU_R8, field, NULL);
}
typedef struct VolumeSlicer {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index b8228c63209..9c55e99b151 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -43,22 +43,26 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_icons.h"
+#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "ED_space_api.h"
#include "ED_screen.h"
+#include "ED_transform.h"
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
#include "GPU_material.h"
-
-#include "BIF_gl.h"
+#include "GPU_viewport.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -250,7 +254,7 @@ void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
/* we have to multiply instead of loading viewmatob to make
* it work with duplis using displists, otherwise it will
* override the dupli-matrix */
- glMultMatrixf(ob->obmat);
+ gpuMultMatrix(ob->obmat);
}
#ifdef DEBUG
@@ -340,7 +344,7 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->near = 0.01f;
v3d->far = 1000.0f;
- v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
+ v3d->twflag |= U.manipulator_flag & V3D_USE_MANIPULATOR;
v3d->twtype = V3D_MANIP_TRANSLATE;
v3d->around = V3D_AROUND_CENTER_MEAN;
@@ -487,6 +491,13 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
ListBase *lb;
wmKeyMap *keymap;
+ if (!ar->manipulator_map) {
+ ar->manipulator_map = WM_manipulatormap_new_from_type(&(const struct wmManipulatorMapType_Params) {
+ "View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW});
+ }
+
+ WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
+
/* object ops. */
/* important to be before Pose keymap since they can both be enabled at once */
@@ -582,6 +593,12 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar)
GPU_fx_compositor_destroy(rv3d->compositor);
rv3d->compositor = NULL;
}
+
+ if (rv3d->viewport) {
+ GPU_viewport_free(rv3d->viewport);
+ MEM_freeN(rv3d->viewport);
+ rv3d->viewport = NULL;
+ }
}
static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
@@ -641,7 +658,7 @@ static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *eve
static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
- Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+ BaseLegacy *base = ED_view3d_give_base_under_cursor(C, event->mval);
/* either holding and ctrl and no object, or dropping to empty */
if (((base == NULL) && event->ctrl) ||
@@ -655,7 +672,7 @@ static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *
static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
- Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+ BaseLegacy *base = ED_view3d_give_base_under_cursor(C, event->mval);
if (base && base->object->type == OB_MESH)
return view3d_ima_drop_poll(C, drag, event);
@@ -712,6 +729,16 @@ static void view3d_dropboxes(void)
WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
}
+static void view3d_widgets(void)
+{
+ const struct wmManipulatorMapType_Params wmap_params = {
+ .idname = "View3D",
+ .spaceid = SPACE_VIEW3D, .regionid = RGN_TYPE_WINDOW,
+ };
+ wmManipulatorMapType *wmaptype = WM_manipulatormaptype_ensure(&wmap_params);
+
+ WM_manipulatorgrouptype_append(wmaptype, TRANSFORM_WGT_manipulator);
+}
/* type callback, not region itself */
@@ -739,6 +766,10 @@ static void view3d_main_region_free(ARegion *ar)
if (rv3d->compositor) {
GPU_fx_compositor_destroy(rv3d->compositor);
}
+ if (rv3d->viewport) {
+ GPU_viewport_free(rv3d->viewport);
+ MEM_freeN(rv3d->viewport);
+ }
MEM_freeN(rv3d);
ar->regiondata = NULL;
@@ -763,18 +794,19 @@ static void *view3d_main_region_duplicate(void *poin)
new->sms = NULL;
new->smooth_timer = NULL;
new->compositor = NULL;
+ new->viewport = NULL;
return new;
}
return NULL;
}
-static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene)
+static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, const Scene *scene)
{
wmWindow *win = wmn->wm->winactive;
ScrArea *sa;
unsigned int lay_used = 0;
- Base *base;
+ BaseLegacy *base;
if (!win) return;
@@ -799,13 +831,21 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
}
}
-static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *wmn)
+static void view3d_main_region_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar,
+ wmNotifier *wmn, const Scene *scene)
{
- Scene *scene = sc->scene;
View3D *v3d = sa->spacedata.first;
-
+ RegionView3D *rv3d = ar->regiondata;
+ wmManipulatorMap *mmap = ar->manipulator_map;
+
/* context changes */
switch (wmn->category) {
+ case NC_WM:
+ if (ELEM(wmn->data, ND_UNDO)) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
+ break;
case NC_ANIMATION:
switch (wmn->data) {
case ND_KEYFRAME_PROP:
@@ -829,6 +869,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
if (wmn->reference)
view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
case ND_FRAME:
case ND_TRANSFORM:
@@ -840,6 +881,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_MARKERS:
case ND_MODE:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
case ND_WORLD:
/* handled by space_view3d_listener() for v3d access */
@@ -847,7 +889,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_DRAW_RENDER_VIEWPORT:
{
if (v3d->camera && (scene == wmn->reference)) {
- RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
@@ -872,6 +913,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_POINTCACHE:
case ND_LOD:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
}
switch (wmn->action) {
@@ -882,9 +924,30 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
break;
case NC_GEOM:
switch (wmn->data) {
+ case ND_SELECT:
+ {
+ WM_manipulatormap_tag_refresh(mmap);
+
+ if (scene->obedit) {
+ Object *ob = scene->obedit;
+ switch (ob->type) {
+ case OB_MESH:
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ // case OB_FONT: /* handled by text_update_edited */
+ case OB_CURVE:
+ case OB_SURF:
+ BKE_curve_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ case OB_LATTICE:
+ BKE_lattice_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ }
+ }
+ ATTR_FALLTHROUGH;
+ }
case ND_DATA:
case ND_VERTEX_GROUP:
- case ND_SELECT:
ED_region_tag_redraw(ar);
break;
}
@@ -899,7 +962,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_DRAW_RENDER_VIEWPORT:
{
if (v3d->camera && (v3d->camera->data == wmn->reference)) {
- RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
@@ -928,21 +990,13 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
switch (wmn->data) {
case ND_SHADING:
case ND_NODES:
- {
-#ifdef WITH_LEGACY_DEPSGRAPH
- Object *ob = OBACT;
- if ((v3d->drawtype == OB_MATERIAL) ||
- (ob && (ob->mode == OB_MODE_TEXTURE_PAINT)) ||
- (v3d->drawtype == OB_TEXTURE &&
- (scene->gm.matmode == GAME_MAT_GLSL ||
- BKE_scene_use_new_shading_nodes(scene))) ||
- !DEG_depsgraph_use_legacy())
-#endif
- {
- ED_region_tag_redraw(ar);
- }
+ /* TODO(sergey) This is a bit too much updates, but needed to
+ * have proper material drivers update in the viewport.
+ *
+ * How to solve?
+ */
+ ED_region_tag_redraw(ar);
break;
- }
case ND_SHADING_DRAW:
case ND_SHADING_LINKS:
ED_region_tag_redraw(ar);
@@ -959,15 +1013,14 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case NC_LAMP:
switch (wmn->data) {
case ND_LIGHTING:
- if ((v3d->drawtype == OB_MATERIAL) ||
- (v3d->drawtype == OB_TEXTURE && (scene->gm.matmode == GAME_MAT_GLSL)) ||
- !DEG_depsgraph_use_legacy())
- {
- ED_region_tag_redraw(ar);
- }
+ /* TODO(sergey): This is a bit too much, but needed to
+ * handle updates from new depsgraph.
+ */
+ ED_region_tag_redraw(ar);
break;
case ND_LIGHTING_DRAW:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
}
break;
@@ -987,10 +1040,10 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case NC_SPACE:
if (wmn->data == ND_SPACE_VIEW3D) {
if (wmn->subtype == NS_VIEW3D_GPU) {
- RegionView3D *rv3d = ar->regiondata;
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
}
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
}
break;
case NC_ID:
@@ -1012,6 +1065,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
bScreen *sc_ref = wmn->reference;
view3d_recalc_used_layers(ar, wmn, sc_ref->scene);
}
+ WM_manipulatormap_tag_refresh(mmap);
ED_region_tag_redraw(ar);
break;
}
@@ -1053,7 +1107,9 @@ static void view3d_header_region_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
-static void view3d_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void view3d_header_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1099,7 +1155,9 @@ static void view3d_buttons_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, NULL, -1, true);
}
-static void view3d_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void view3d_buttons_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1205,7 +1263,9 @@ static void view3d_tools_region_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, CTX_data_mode_string(C), -1, true);
}
-static void view3d_props_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void view3d_props_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -1225,7 +1285,8 @@ static void view3d_props_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
}
/* area (not region) level listener */
-static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn)
+static void space_view3d_listener(
+ bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn, const Scene *UNUSED(scene))
{
View3D *v3d = sa->spacedata.first;
@@ -1260,8 +1321,6 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot
}
const char *view3d_context_dir[] = {
- "selected_objects", "selected_bases", "selected_editable_objects",
- "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"active_base", "active_object", NULL
};
@@ -1272,109 +1331,27 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, view3d_context_dir);
}
- else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool selected_objects = CTX_data_equals(member, "selected_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if ((base->flag & SELECT) && (base->lay & lay)) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (selected_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if ((base->flag & SELECT) && (base->lay & lay)) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (0 == BKE_object_is_libdata(base->object)) {
- if (selected_editable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool visible_objects = CTX_data_equals(member, "visible_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & lay) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
- if (visible_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- Base *base;
- const bool selectable_objects = CTX_data_equals(member, "selectable_objects");
-
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & lay) {
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
- if (selectable_objects)
- CTX_data_id_list_add(result, &base->object->id);
- else
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
else if (CTX_data_equals(member, "active_base")) {
- View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- if (scene->basact && (scene->basact->lay & lay)) {
- Object *ob = scene->basact->object;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ if (sl->basact) {
+ Object *ob = sl->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
- CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact);
+ if ((sl->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT)) {
+ CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, sl->basact);
+ }
}
return 1;
}
else if (CTX_data_equals(member, "active_object")) {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const unsigned int lay = v3d ? v3d->lay : scene->lay;
- if (scene->basact && (scene->basact->lay & lay)) {
- Object *ob = scene->basact->object;
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
- CTX_data_id_pointer_set(result, &scene->basact->object->id);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ if (sl->basact) {
+ Object *ob = sl->basact->object;
+ /* if hidden but in edit mode, we still display, can happen with animation */
+ if ((sl->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
+ CTX_data_id_pointer_set(result, &ob->id);
+ }
}
return 1;
@@ -1466,6 +1443,7 @@ void ED_spacetype_view3d(void)
st->operatortypes = view3d_operatortypes;
st->keymap = view3d_keymap;
st->dropboxes = view3d_dropboxes;
+ st->manipulators = view3d_widgets;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 34e01405e7e..c19fdb0d4b1 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -776,8 +776,8 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
return;
}
else {
- Scene *scene = CTX_data_scene(C);
- Object *ob = scene->basact->object;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = sl->basact->object;
ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
@@ -786,8 +786,8 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if (ob && (BKE_object_is_in_editmode_vgroup(ob) ||
BKE_object_is_in_wpaint_select_vert(ob)))
{
@@ -805,7 +805,8 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
{
uiBlock *block = uiLayoutAbsoluteBlock(pa->layout);
Scene *scene = CTX_data_scene(C);
- Object *ob = scene->basact->object;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = sl->basact->object;
MDeformVert *dv;
@@ -1095,9 +1096,9 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
{
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
switch (event) {
@@ -1119,16 +1120,17 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event
static int view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Scene *scene = CTX_data_scene(C);
- return (scene->basact != NULL);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ return (sl->basact != NULL);
}
static void view3d_panel_transform(const bContext *C, Panel *pa)
{
uiBlock *block;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
- Object *ob = scene->basact->object;
+ Object *ob = sl->basact->object;
uiLayout *col;
block = uiLayoutGetBlock(pa->layout);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 250e6559b8f..c664f66858e 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -28,948 +28,280 @@
* \ingroup spview3d
*/
-#include <string.h>
-#include <stdio.h>
#include <math.h>
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_customdata_types.h"
-#include "DNA_object_types.h"
-#include "DNA_group_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_world_types.h"
-#include "DNA_brush_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_jitter.h"
-#include "BLI_utildefines.h"
-#include "BLI_endian_switch.h"
-#include "BLI_threads.h"
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
-#include "BKE_anim.h"
#include "BKE_camera.h"
#include "BKE_context.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_image.h"
+#include "BKE_global.h"
#include "BKE_key.h"
-#include "BKE_main.h"
+#include "BKE_scene.h"
#include "BKE_object.h"
-#include "BKE_global.h"
#include "BKE_paint.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "BKE_unit.h"
-#include "BKE_movieclip.h"
-#include "RE_engine.h"
+#include "BLF_api.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-#include "IMB_colormanagement.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
+#include "BLI_string.h"
+#include "BLI_threads.h"
+#include "BLI_jitter.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "BLT_translation.h"
-#include "WM_api.h"
+#include "DNA_armature_types.h"
+#include "DNA_brush_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
-#include "BLF_api.h"
-#include "BLT_translation.h"
+#include "DRW_engine.h"
+#include "ED_keyframing.h"
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
-#include "ED_space_api.h"
-#include "ED_screen_types.h"
#include "ED_transform.h"
+#include "ED_gpencil.h"
-#include "UI_interface.h"
-#include "UI_interface_icons.h"
-#include "UI_resources.h"
+#include "DEG_depsgraph_query.h"
#include "GPU_draw.h"
-#include "GPU_framebuffer.h"
+#include "GPU_matrix.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "GPU_material.h"
+#include "GPU_viewport.h"
#include "GPU_compositing.h"
-#include "GPU_extensions.h"
-#include "GPU_select.h"
-#include "view3d_intern.h" /* own include */
-
-/* prototypes */
-static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
-static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect);
-static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- float winmat[4][4], const char *viewname);
-
-/* handy utility for drawing shapes in the viewport for arbitrary code.
- * could add lines and points too */
-// #define DEBUG_DRAW
-#ifdef DEBUG_DRAW
-static void bl_debug_draw(void);
-/* add these locally when using these functions for testing */
-extern void bl_debug_draw_quad_clear(void);
-extern void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3]);
-extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]);
-extern void bl_debug_color_set(const unsigned int col);
-#endif
-
-void circf(float x, float y, float rad)
-{
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_FILL);
-
- glPushMatrix();
-
- glTranslatef(x, y, 0.0);
-
- gluDisk(qobj, 0.0, rad, 32, 1);
-
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
-}
-
-void circ(float x, float y, float rad)
-{
- GLUquadricObj *qobj = gluNewQuadric();
-
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-
- glPushMatrix();
-
- glTranslatef(x, y, 0.0);
-
- gluDisk(qobj, 0.0, rad, 32, 1);
-
- glPopMatrix();
-
- gluDeleteQuadric(qobj);
-}
-
-
-/* ********* custom clipping *********** */
-
-static void view3d_draw_clipping(RegionView3D *rv3d)
-{
- BoundBox *bb = rv3d->clipbb;
-
- if (bb) {
- const unsigned int clipping_index[6][4] = {
- {0, 1, 2, 3},
- {0, 4, 5, 1},
- {4, 7, 6, 5},
- {7, 3, 2, 6},
- {1, 5, 6, 2},
- {7, 4, 0, 3}
- };
-
- /* fill in zero alpha for rendering & re-projection [#31530] */
- unsigned char col[4];
- UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
- glColor4ubv(col);
-
- glEnable(GL_BLEND);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, bb->vec);
- glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisable(GL_BLEND);
- }
-}
+#include "MEM_guardedalloc.h"
-void ED_view3d_clipping_set(RegionView3D *rv3d)
-{
- double plane[4];
- const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
- unsigned int a;
-
- for (a = 0; a < tot; a++) {
- copy_v4db_v4fl(plane, rv3d->clip[a]);
- glClipPlane(GL_CLIP_PLANE0 + a, plane);
- glEnable(GL_CLIP_PLANE0 + a);
- }
-}
+#include "UI_interface.h"
+#include "UI_resources.h"
-/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
-void ED_view3d_clipping_disable(void)
-{
- unsigned int a;
+#include "RE_engine.h"
- for (a = 0; a < 6; a++) {
- glDisable(GL_CLIP_PLANE0 + a);
- }
-}
-void ED_view3d_clipping_enable(void)
-{
- unsigned int a;
+#include "WM_api.h"
+#include "WM_types.h"
- for (a = 0; a < 6; a++) {
- glEnable(GL_CLIP_PLANE0 + a);
- }
-}
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
-static bool view3d_clipping_test(const float co[3], const float clip[6][4])
-{
- if (plane_point_side_v3(clip[0], co) > 0.0f)
- if (plane_point_side_v3(clip[1], co) > 0.0f)
- if (plane_point_side_v3(clip[2], co) > 0.0f)
- if (plane_point_side_v3(clip[3], co) > 0.0f)
- return false;
+#include "view3d_intern.h" /* own include */
- return true;
-}
+/* ******************** general functions ***************** */
-/* for 'local' ED_view3d_clipping_local must run first
- * then all comparisons can be done in localspace */
-bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
+static bool use_depth_doit(Scene *scene, View3D *v3d)
{
- return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
-}
-
-/* ********* end custom clipping *********** */
-
-
-static void drawgrid_draw(ARegion *ar, double wx, double wy, double x, double y, double dx)
-{
- double verts[2][2];
+ if (v3d->drawtype > OB_WIRE)
+ return true;
- x += (wx);
- y += (wy);
-
- /* set fixed 'Y' */
- verts[0][1] = 0.0f;
- verts[1][1] = (double)ar->winy;
-
- /* iter over 'X' */
- verts[0][0] = verts[1][0] = x - dx * floor(x / dx);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_DOUBLE, 0, verts);
-
- while (verts[0][0] < ar->winx) {
- glDrawArrays(GL_LINES, 0, 2);
- verts[0][0] = verts[1][0] = verts[0][0] + dx;
- }
-
- /* set fixed 'X' */
- verts[0][0] = 0.0f;
- verts[1][0] = (double)ar->winx;
-
- /* iter over 'Y' */
- verts[0][1] = verts[1][1] = y - dx * floor(y / dx);
- while (verts[0][1] < ar->winy) {
- glDrawArrays(GL_LINES, 0, 2);
- verts[0][1] = verts[1][1] = verts[0][1] + dx;
+ /* special case (depth for wire color) */
+ if (v3d->drawtype <= OB_WIRE) {
+ if (scene->obedit && scene->obedit->type == OB_MESH) {
+ Mesh *me = scene->obedit->data;
+ if (me->drawflag & ME_DRAWEIGHT) {
+ return true;
+ }
+ }
}
-
- glDisableClientState(GL_VERTEX_ARRAY);
+ return false;
}
-#define GRID_MIN_PX_D 6.0
-#define GRID_MIN_PX_F 6.0f
-
-static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
+/**
+ * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
+ */
+void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
- /* extern short bgpicmode; */
RegionView3D *rv3d = ar->regiondata;
- double wx, wy, x, y, fw, fx, fy, dx;
- double vec4[4];
- unsigned char col[3], col2[3];
-
- fx = rv3d->persmat[3][0];
- fy = rv3d->persmat[3][1];
- fw = rv3d->persmat[3][3];
-
- wx = (ar->winx / 2.0); /* because of rounding errors, grid at wrong location */
- wy = (ar->winy / 2.0);
-
- x = (wx) * fx / fw;
- y = (wy) * fy / fw;
-
- vec4[0] = vec4[1] = v3d->grid;
-
- vec4[2] = 0.0;
- vec4[3] = 1.0;
- mul_m4_v4d(rv3d->persmat, vec4);
- fx = vec4[0];
- fy = vec4[1];
- fw = vec4[3];
-
- dx = fabs(x - (wx) * fx / fw);
- if (dx == 0) dx = fabs(y - (wy) * fy / fw);
-
- glLineWidth(1.0f);
-
- glDepthMask(GL_FALSE); /* disable write in zbuffer */
-
- /* check zoom out */
- UI_ThemeColor(TH_GRID);
-
- if (unit->system) {
- /* Use GRID_MIN_PX * 2 for units because very very small grid
- * items are less useful when dealing with units */
- const void *usys;
- int len, i;
- double dx_scalar;
- float blend_fac;
-
- bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
- if (usys) {
- i = len;
- while (i--) {
- double scalar = bUnit_GetScaler(usys, i);
- dx_scalar = dx * scalar / (double)unit->scale_length;
- if (dx_scalar < (GRID_MIN_PX_D * 2.0))
- continue;
+ /* setup window matrices */
+ if (winmat)
+ copy_m4_m4(rv3d->winmat, winmat);
+ else
+ view3d_winmatrix_set(ar, v3d, rect);
- /* Store the smallest drawn grid size units name so users know how big each grid cell is */
- if (*grid_unit == NULL) {
- *grid_unit = bUnit_GetNameDisplay(usys, i);
- rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
- }
- blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
+ /* setup view matrix */
+ if (viewmat)
+ copy_m4_m4(rv3d->viewmat, viewmat);
+ else
+ view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
- /* tweak to have the fade a bit nicer */
- blend_fac = (blend_fac * blend_fac) * 2.0f;
- CLAMP(blend_fac, 0.3f, 1.0f);
+ /* update utility matrices */
+ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ invert_m4_m4(rv3d->persinv, rv3d->persmat);
+ invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+ /* calculate GLSL view dependent values */
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, blend_fac);
+ /* store window coordinates scaling/offset */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ rctf cameraborder;
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
+ rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
+ rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
- drawgrid_draw(ar, wx, wy, x, y, dx_scalar);
- }
- }
+ rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
+ rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
}
else {
- const double sublines = v3d->gridsubdiv;
- const float sublines_fl = v3d->gridsubdiv;
-
- if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines_fl;
- dx *= sublines;
-
- if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines_fl;
- dx *= sublines;
-
- if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines_fl;
- dx *= sublines;
- if (dx < GRID_MIN_PX_D) {
- /* pass */
- }
- else {
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx);
- }
- }
- else { /* start blending out */
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
-
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
- }
- }
- else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
-
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
- }
- }
- else {
- if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
- rv3d->gridview /= sublines_fl;
- dx /= sublines;
- if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
- rv3d->gridview /= sublines_fl;
- dx /= sublines;
- if (dx > (GRID_MIN_PX_D * 10.0)) {
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx);
- }
- else {
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
- }
- }
- else {
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
- }
- }
- else {
- UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
- drawgrid_draw(ar, wx, wy, x, y, dx);
- UI_ThemeColor(TH_GRID);
- drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
- }
- }
+ rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
+ rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
+ /* calculate pixelsize factor once, is used for lamps and obcenters */
+ {
+ /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
+ * because of float point precision problems at large values [#23908] */
+ float v1[3], v2[3];
+ float len_px, len_sc;
- x += (wx);
- y += (wy);
- UI_GetThemeColor3ubv(TH_GRID, col);
-
- setlinestyle(0);
-
- /* center cross */
- /* horizontal line */
- if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
- UI_make_axis_color(col, col2, 'Y');
- else UI_make_axis_color(col, col2, 'X');
- glColor3ubv(col2);
-
- fdrawline(0.0, y, (float)ar->winx, y);
-
- /* vertical line */
- if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
- UI_make_axis_color(col, col2, 'Y');
- else UI_make_axis_color(col, col2, 'Z');
- glColor3ubv(col2);
-
- fdrawline(x, 0.0, x, (float)ar->winy);
-
- glDepthMask(GL_TRUE); /* enable write in zbuffer */
-}
-#undef GRID_MIN_PX
+ v1[0] = rv3d->persmat[0][0];
+ v1[1] = rv3d->persmat[1][0];
+ v1[2] = rv3d->persmat[2][0];
-/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
-float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
-{
- /* apply units */
- if (scene->unit.system) {
- const void *usys;
- int len;
+ v2[0] = rv3d->persmat[0][1];
+ v2[1] = rv3d->persmat[1][1];
+ v2[2] = rv3d->persmat[2][1];
- bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
+ len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
+ len_sc = (float)MAX2(ar->winx, ar->winy);
- if (usys) {
- int i = bUnit_GetBaseUnit(usys);
- if (grid_unit)
- *grid_unit = bUnit_GetNameDisplay(usys, i);
- return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
- }
+ rv3d->pixsize = len_px / len_sc;
}
-
- return 1.0f;
-}
-
-float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
-{
- return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
}
-static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
+static void view3d_main_region_setup_view(
+ Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
- float grid, grid_scale;
- unsigned char col_grid[3];
- const int gridlines = v3d->gridlines / 2;
-
- if (v3d->gridlines < 3) return;
-
- /* use 'grid_scale' instead of 'v3d->grid' from now on */
- grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
- grid = gridlines * grid_scale;
-
- if (!write_depth)
- glDepthMask(GL_FALSE);
-
- UI_GetThemeColor3ubv(TH_GRID, col_grid);
-
- glLineWidth(1);
-
- /* draw the Y axis and/or grid lines */
- if (v3d->gridflag & V3D_SHOW_FLOOR) {
- const int sublines = v3d->gridsubdiv;
- float vert[4][3] = {{0.0f}};
- unsigned char col_bg[3];
- unsigned char col_grid_emphasise[3], col_grid_light[3];
- int a;
- int prev_emphasise = -1;
-
- UI_GetThemeColor3ubv(TH_BACK, col_bg);
-
- /* emphasise division lines lighter instead of darker, if background is darker than grid */
- UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
- UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
- (((col_grid[0] + col_grid[1] + col_grid[2]) + 30) >
- (col_bg[0] + col_bg[1] + col_bg[2])) ? 20 : -10);
-
- /* set fixed axis */
- vert[0][0] = vert[2][1] = grid;
- vert[1][0] = vert[3][1] = -grid;
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vert);
-
- for (a = -gridlines; a <= gridlines; a++) {
- const float line = a * grid_scale;
- const int is_emphasise = (a % sublines) == 0;
-
- if (is_emphasise != prev_emphasise) {
- glColor3ubv(is_emphasise ? col_grid_emphasise : col_grid_light);
- prev_emphasise = is_emphasise;
- }
-
- /* set variable axis */
- vert[0][1] = vert[1][1] = vert[2][0] = vert[3][0] = line;
+ RegionView3D *rv3d = ar->regiondata;
- glDrawArrays(GL_LINES, 0, 4);
- }
+ ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat, rect);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
-
- /* draw the Z axis line */
- /* check for the 'show Z axis' preference */
- if (v3d->gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
- glBegin(GL_LINES);
- int axis;
- for (axis = 0; axis < 3; axis++) {
- if (v3d->gridflag & (V3D_SHOW_X << axis)) {
- float vert[3];
- unsigned char tcol[3];
-
- UI_make_axis_color(col_grid, tcol, 'X' + axis);
- glColor3ubv(tcol);
-
- zero_v3(vert);
- vert[axis] = grid;
- glVertex3fv(vert);
- vert[axis] = -grid;
- glVertex3fv(vert);
- }
- }
- glEnd();
- }
-
- glDepthMask(GL_TRUE);
+ /* set for opengl */
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
}
-
-static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
+static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- int co[2];
-
- /* we don't want the clipping for cursor */
- if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- const float f5 = 0.25f * U.widget_unit;
- const float f10 = 0.5f * U.widget_unit;
- const float f20 = U.widget_unit;
-
- glLineWidth(1);
- setlinestyle(0);
- cpack(0xFF);
- circ((float)co[0], (float)co[1], f10);
- setlinestyle(4);
- cpack(0xFFFFFF);
- circ((float)co[0], (float)co[1], f10);
- setlinestyle(0);
-
- UI_ThemeColor(TH_VIEW_OVERLAY);
- sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]);
- sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]);
- sdrawline(co[0], co[1] - f20, co[0], co[1] - f5);
- sdrawline(co[0], co[1] + f5, co[0], co[1] + f20);
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ return false;
}
-}
-
-/* Draw a live substitute of the view icon, which is always shown
- * colors copied from transform_manipulator.c, we should keep these matching. */
-static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
-{
- const float k = U.rvisize * U.pixelsize; /* axis size */
- const float toll = 0.5; /* used to see when view is quasi-orthogonal */
- float startx = k + 1.0f; /* axis center in screen coordinates, x=y */
- float starty = k + 1.0f;
- float ydisp = 0.0; /* vertical displacement to allow obj info text */
- int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
- float vec[3];
- float dx, dy;
-
- int axis_order[3] = {0, 1, 2};
- int axis_i;
-
- startx += rect->xmin;
- starty += rect->ymin;
-
- axis_sort_v3(rv3d->viewinv[2], axis_order);
- /* thickness of lines is proportional to k */
- glLineWidth(2);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- for (axis_i = 0; axis_i < 3; axis_i++) {
- int i = axis_order[axis_i];
- const char axis_text[2] = {'x' + i, '\0'};
-
- zero_v3(vec);
- vec[i] = 1.0f;
- mul_qt_v3(rv3d->viewquat, vec);
- dx = vec[0] * k;
- dy = vec[1] * k;
-
- UI_ThemeColorShadeAlpha(TH_AXIS_X + i, 0, bright);
- glBegin(GL_LINES);
- glVertex2f(startx, starty + ydisp);
- glVertex2f(startx + dx, starty + dy + ydisp);
- glEnd();
-
- if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, axis_text, 1);
-
- /* BLF_draw_default disables blending */
- glEnable(GL_BLEND);
- }
+ if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
+ return false;
}
- glDisable(GL_BLEND);
-}
-
-#ifdef WITH_INPUT_NDOF
-/* draw center and axis of rotation for ongoing 3D mouse navigation */
-static void draw_rotation_guide(RegionView3D *rv3d)
-{
- float o[3]; /* center of rotation */
- float end[3]; /* endpoints for drawing */
-
- float color[4] = {0.0f, 0.4235f, 1.0f, 1.0f}; /* bright blue so it matches device LEDs */
-
- negate_v3_v3(o, rv3d->ofs);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPointSize(5);
- glEnable(GL_POINT_SMOOTH);
- glDepthMask(0); /* don't overwrite zbuf */
-
- if (rv3d->rot_angle != 0.0f) {
- /* -- draw rotation axis -- */
- float scaled_axis[3];
- const float scale = rv3d->dist;
- mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
-
-
- glBegin(GL_LINE_STRIP);
- color[3] = 0.0f; /* more transparent toward the ends */
- glColor4fv(color);
- add_v3_v3v3(end, o, scaled_axis);
- glVertex3fv(end);
-
-#if 0
- color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
- /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
-#endif
-
- color[3] = 0.5f; /* more opaque toward the center */
- glColor4fv(color);
- glVertex3fv(o);
-
- color[3] = 0.0f;
- glColor4fv(color);
- sub_v3_v3v3(end, o, scaled_axis);
- glVertex3fv(end);
- glEnd();
-
- /* -- draw ring around rotation center -- */
- {
-#define ROT_AXIS_DETAIL 13
-
- const float s = 0.05f * scale;
- const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
- float angle;
- int i;
-
- float q[4]; /* rotate ring so it's perpendicular to axis */
- const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
- if (!upright) {
- const float up[3] = {0.0f, 0.0f, 1.0f};
- float vis_angle, vis_axis[3];
-
- cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
- vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
- axis_angle_to_quat(q, vis_axis, vis_angle);
+ switch (v3d->stereo3d_camera) {
+ case STEREO_MONO_ID:
+ return false;
+ break;
+ case STEREO_3D_ID:
+ /* win will be NULL when calling this from the selection or draw loop. */
+ if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
+ return false;
}
-
- color[3] = 0.25f; /* somewhat faint */
- glColor4fv(color);
- glBegin(GL_LINE_LOOP);
- for (i = 0, angle = 0.0f; i < ROT_AXIS_DETAIL; ++i, angle += step) {
- float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
-
- if (!upright) {
- mul_qt_v3(q, p);
- }
-
- add_v3_v3(p, o);
- glVertex3fv(p);
+ if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
+ !BKE_scene_multiview_is_stereo3d(&scene->r))
+ {
+ return false;
}
- glEnd();
-
-#undef ROT_AXIS_DETAIL
- }
-
- color[3] = 1.0f; /* solid dot */
- }
- else
- color[3] = 0.5f; /* see-through dot */
-
- /* -- draw rotation center -- */
- glColor4fv(color);
- glBegin(GL_POINTS);
- glVertex3fv(o);
- glEnd();
-
-#if 0
- /* find screen coordinates for rotation center, then draw pretty icon */
- mul_m4_v3(rv3d->persinv, rot_center);
- UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
- /* ^^ just playing around, does not work */
-#endif
-
- glDisable(GL_BLEND);
- glDisable(GL_POINT_SMOOTH);
- glDepthMask(1);
-}
-#endif /* WITH_INPUT_NDOF */
-
-static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
-{
- BIFIconID icon;
-
- if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
- icon = ICON_AXIS_TOP;
- else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK))
- icon = ICON_AXIS_FRONT;
- else if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
- icon = ICON_AXIS_SIDE;
- else return;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
-
- glDisable(GL_BLEND);
-}
-
-static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
-{
- const char *name = NULL;
-
- switch (rv3d->view) {
- case RV3D_VIEW_FRONT:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
- else name = IFACE_("Front Persp");
- break;
- case RV3D_VIEW_BACK:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
- else name = IFACE_("Back Persp");
- break;
- case RV3D_VIEW_TOP:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
- else name = IFACE_("Top Persp");
- break;
- case RV3D_VIEW_BOTTOM:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
- else name = IFACE_("Bottom Persp");
- break;
- case RV3D_VIEW_RIGHT:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
- else name = IFACE_("Right Persp");
- break;
- case RV3D_VIEW_LEFT:
- if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
- else name = IFACE_("Left Persp");
break;
-
+ /* We always need the stereo calculation for left and right cameras. */
+ case STEREO_LEFT_ID:
+ case STEREO_RIGHT_ID:
default:
- if (rv3d->persp == RV3D_CAMOB) {
- if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
- Camera *cam;
- cam = v3d->camera->data;
- if (cam->type == CAM_PERSP) {
- name = IFACE_("Camera Persp");
- }
- else if (cam->type == CAM_ORTHO) {
- name = IFACE_("Camera Ortho");
- }
- else {
- BLI_assert(cam->type == CAM_PANO);
- name = IFACE_("Camera Pano");
- }
- }
- else {
- name = IFACE_("Object as Camera");
- }
- }
- else {
- name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
- }
break;
}
-
- return name;
+ return true;
}
-static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
-{
- RegionView3D *rv3d = ar->regiondata;
- const char *name = view3d_get_name(v3d, rv3d);
- /* increase size for unicode languages (Chinese in utf-8...) */
-#ifdef WITH_INTERNATIONAL
- char tmpstr[96];
-#else
- char tmpstr[32];
-#endif
- if (v3d->localvd) {
- BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
- name = tmpstr;
- }
+/* setup the view and win matrices for the multiview cameras
+ *
+ * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
+ * we have no winmatrix (i.e., projection matrix) defined at that time.
+ * Since the camera and the camera shift are needed for the winmat calculation
+ * we do a small hack to replace it temporarily so we don't need to change the
+ * view3d)main_region_setup_view() code to account for that.
+ */
+static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
+{
+ bool is_left;
+ const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
+ const char *viewname;
- UI_ThemeColor(TH_TEXT_HI);
-#ifdef WITH_INTERNATIONAL
- BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
-#else
- BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
-#endif
-}
+ /* show only left or right camera */
+ if (v3d->stereo3d_camera != STEREO_3D_ID)
+ v3d->multiview_eye = v3d->stereo3d_camera;
-/* draw info beside axes in bottom left-corner:
- * framenum, object name, bone name (if available), marker name (if available)
- */
+ is_left = v3d->multiview_eye == STEREO_LEFT_ID;
+ viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
-static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
-{
- const int cfra = CFRA;
- const char *msg_pin = " (Pinned)";
- const char *msg_sep = " : ";
+ /* update the viewport matrices with the new camera */
+ if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+ Camera *data;
+ float viewmat[4][4];
+ float shiftx;
- char info[300];
- const char *markern;
- char *s = info;
- short offset = 1.5f * UI_UNIT_X + rect->xmin;
+ data = (Camera *)v3d->camera->data;
+ shiftx = data->shiftx;
- s += sprintf(s, "(%d)", cfra);
+ BLI_lock_thread(LOCK_VIEW3D);
+ data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
- /*
- * info can contain:
- * - a frame (7 + 2)
- * - 3 object names (MAX_NAME)
- * - 2 BREAD_CRUMB_SEPARATORs (6)
- * - a SHAPE_KEY_PINNED marker and a trailing '\0' (9+1) - translated, so give some room!
- * - a marker name (MAX_NAME + 3)
- */
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
- /* get name of marker on current frame (if available) */
- markern = BKE_scene_find_marker_name(scene, cfra);
-
- /* check if there is an object */
- if (ob) {
- *s++ = ' ';
- s += BLI_strcpy_rlen(s, ob->id.name + 2);
+ data->shiftx = shiftx;
+ BLI_unlock_thread(LOCK_VIEW3D);
+ }
+ else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ float viewmat[4][4];
+ Object *view_ob = v3d->camera;
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
- /* name(s) to display depends on type of object */
- if (ob->type == OB_ARMATURE) {
- bArmature *arm = ob->data;
-
- /* show name of active bone too (if possible) */
- if (arm->edbo) {
- if (arm->act_edbone) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_edbone->name);
- }
- }
- else if (ob->mode & OB_MODE_POSE) {
- if (arm->act_bone) {
+ BLI_lock_thread(LOCK_VIEW3D);
+ v3d->camera = camera;
- if (arm->act_bone->layer & arm->layer) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_bone->name);
- }
- }
- }
- }
- else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
- Key *key = NULL;
- KeyBlock *kb = NULL;
+ BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
- /* try to display active bone and active shapekey too (if they exist) */
+ v3d->camera = view_ob;
+ BLI_unlock_thread(LOCK_VIEW3D);
+ }
+}
- if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
- Object *armobj = BKE_object_pose_armature_get(ob);
- if (armobj && armobj->mode & OB_MODE_POSE) {
- bArmature *arm = armobj->data;
- if (arm->act_bone) {
- if (arm->act_bone->layer & arm->layer) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_bone->name);
- }
- }
- }
- }
+/**
+ * Set the correct matrices
+ */
+void ED_view3d_draw_setup_view(
+ wmWindow *win, Scene *scene, ARegion *ar, View3D *v3d,
+ float viewmat[4][4], float winmat[4][4], const rcti *rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
- key = BKE_key_from_object(ob);
- if (key) {
- kb = BLI_findlink(&key->block, ob->shapenr - 1);
- if (kb) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, kb->name);
- if (ob->shapeflag & OB_SHAPE_LOCK) {
- s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
- }
- }
- }
- }
-
- /* color depends on whether there is a keyframe */
- if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL))
- UI_ThemeColor(TH_TIME_KEYFRAME);
- else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra))
- UI_ThemeColor(TH_TIME_GP_KEYFRAME);
- else
- UI_ThemeColor(TH_TEXT_HI);
+ /* Setup the view matrix. */
+ if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
+ view3d_stereo3d_setup(scene, v3d, ar, rect);
}
else {
- /* no object */
- if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra))
- UI_ThemeColor(TH_TIME_GP_KEYFRAME);
- else
- UI_ThemeColor(TH_TEXT_HI);
- }
-
- if (markern) {
- s += sprintf(s, " <%s>", markern);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, rect);
}
-
- if (U.uiflag & USER_SHOW_ROTVIEWICON)
- offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
-
- BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
+/* ******************** view border ***************** */
+
static void view3d_camera_border(
const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
rctf *r_viewborder, const bool no_shift, const bool no_zoom)
@@ -1023,7 +355,7 @@ void ED_view3d_calc_camera_border(
view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
}
-static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac)
+static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, float y2, float fac)
{
float x3, y3, x4, y4;
@@ -1032,29 +364,33 @@ static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float f
x4 = x1 + (1.0f - fac) * (x2 - x1);
y4 = y1 + (1.0f - fac) * (y2 - y1);
- glBegin(GL_LINES);
- glVertex2f(x1, y3);
- glVertex2f(x2, y3);
+ immBegin(PRIM_LINES, 8);
+
+ immVertex2f(shdr_pos, x1, y3);
+ immVertex2f(shdr_pos, x2, y3);
- glVertex2f(x1, y4);
- glVertex2f(x2, y4);
+ immVertex2f(shdr_pos, x1, y4);
+ immVertex2f(shdr_pos, x2, y4);
- glVertex2f(x3, y1);
- glVertex2f(x3, y2);
+ immVertex2f(shdr_pos, x3, y1);
+ immVertex2f(shdr_pos, x3, y2);
- glVertex2f(x4, y1);
- glVertex2f(x4, y2);
- glEnd();
+ immVertex2f(shdr_pos, x4, y1);
+ immVertex2f(shdr_pos, x4, y2);
+
+ immEnd();
}
/* harmonious triangle */
-static void drawviewborder_triangle(float x1, float x2, float y1, float y2, const char golden, const char dir)
+static void drawviewborder_triangle(
+ uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
{
float ofs;
float w = x2 - x1;
float h = y2 - y1;
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, 6);
+
if (w > h) {
if (golden) {
ofs = w * (1.0f - (1.0f / 1.61803399f));
@@ -1064,14 +400,14 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons
}
if (dir == 'B') SWAP(float, y1, y2);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
- glVertex2f(x2, y1);
- glVertex2f(x1 + (w - ofs), y2);
+ immVertex2f(shdr_pos, x2, y1);
+ immVertex2f(shdr_pos, x1 + (w - ofs), y2);
- glVertex2f(x1, y2);
- glVertex2f(x1 + ofs, y1);
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x1 + ofs, y1);
}
else {
if (golden) {
@@ -1082,16 +418,17 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons
}
if (dir == 'B') SWAP(float, x1, x2);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
- glVertex2f(x2, y1);
- glVertex2f(x1, y1 + ofs);
+ immVertex2f(shdr_pos, x2, y1);
+ immVertex2f(shdr_pos, x1, y1 + ofs);
- glVertex2f(x1, y2);
- glVertex2f(x2, y1 + (h - ofs));
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x2, y1 + (h - ofs));
}
- glEnd();
+
+ immEnd();
}
static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
@@ -1107,14 +444,14 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
return;
if (v3d->camera->type == OB_CAMERA)
ca = v3d->camera->data;
-
+
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
/* the offsets */
x1 = viewborder.xmin;
y1 = viewborder.ymin;
x2 = viewborder.xmax;
y2 = viewborder.ymax;
-
+
glLineWidth(1.0f);
/* apply offsets so the real 3D camera shows through */
@@ -1128,143 +465,153 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
y1i = (int)(y1 - 1.0001f);
x2i = (int)(x2 + (1.0f - 0.0001f));
y2i = (int)(y2 + (1.0f - 0.0001f));
-
- /* passepartout, specified in camera edit buttons */
- if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
- const float winx = (ar->winx + 1);
- const float winy = (ar->winy + 1);
-
- if (ca->passepartalpha == 1.0f) {
- glColor3f(0, 0, 0);
+
+ uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ /* First, solid lines. */
+ {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* passepartout, specified in camera edit buttons */
+ if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
+ const float winx = (ar->winx + 1);
+ const float winy = (ar->winy + 1);
+
+ float alpha = 1.0f;
+
+ if (ca->passepartalpha != 1.0f) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ alpha = ca->passepartalpha;
+ }
+
+ immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
+
+ if (x1i > 0.0f)
+ immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f);
+ if (x2i < winx)
+ immRectf(shdr_pos, x2i, winy, winx, 0.0f);
+ if (y2i < winy)
+ immRectf(shdr_pos, x1i, winy, x2i, y2i);
+ if (y2i > 0.0f)
+ immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
+
+ glDisable(GL_BLEND);
}
- else {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glColor4f(0, 0, 0, ca->passepartalpha);
+
+ immUniformThemeColor(TH_BACK);
+ imm_draw_line_box(shdr_pos, x1i, y1i, x2i, y2i);
+
+#ifdef VIEW3D_CAMERA_BORDER_HACK
+ if (view3d_camera_border_hack_test == true) {
+ immUniformColor3ubv(view3d_camera_border_hack_col);
+ imm_draw_line_box(shdr_pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
+ view3d_camera_border_hack_test = false;
}
+#endif
- if (x1i > 0.0f)
- glRectf(0.0, winy, x1i, 0.0);
- if (x2i < winx)
- glRectf(x2i, winy, winx, 0.0);
- if (y2i < winy)
- glRectf(x1i, winy, x2i, y2i);
- if (y2i > 0.0f)
- glRectf(x1i, y1i, x2i, 0.0);
-
- glDisable(GL_BLEND);
+ immUnbindProgram();
}
- setlinestyle(0);
+ /* And now, the dashed lines! */
+ {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
- UI_ThemeColor(TH_BACK);
-
- fdrawbox(x1i, y1i, x2i, y2i);
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
-#ifdef VIEW3D_CAMERA_BORDER_HACK
- if (view3d_camera_border_hack_test == true) {
- glColor3ubv(view3d_camera_border_hack_col);
- fdrawbox(x1i + 1, y1i + 1, x2i - 1, y2i - 1);
- view3d_camera_border_hack_test = false;
- }
-#endif
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- setlinestyle(3);
+ /* outer line not to confuse with object selection */
+ if (v3d->flag2 & V3D_LOCK_CAMERA) {
+ immUniformThemeColor(TH_REDALERT);
+ imm_draw_line_box(shdr_pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
+ }
- /* outer line not to confuse with object selecton */
- if (v3d->flag2 & V3D_LOCK_CAMERA) {
- UI_ThemeColor(TH_REDALERT);
- fdrawbox(x1i - 1, y1i - 1, x2i + 1, y2i + 1);
- }
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ imm_draw_line_box(shdr_pos, x1i, y1i, x2i, y2i);
- UI_ThemeColor(TH_VIEW_OVERLAY);
- fdrawbox(x1i, y1i, x2i, y2i);
+ /* border */
+ if (scene->r.mode & R_BORDER) {
+ float x3, y3, x4, y4;
- /* border */
- if (scene->r.mode & R_BORDER) {
- float x3, y3, x4, y4;
+ x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
+ y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
+ x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
+ y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
- x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
- y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
- x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
- y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
+ immUniformColor3f(1.0f, 0.25f, 0.25f);
+ imm_draw_line_box(shdr_pos, x3, y3, x4, y4);
+ }
- cpack(0x4040FF);
- sdrawbox(x3, y3, x4, y4);
- }
+ /* safety border */
+ if (ca) {
+ immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
- /* safety border */
- if (ca) {
- if (ca->dtx & CAM_DTX_CENTER) {
- float x3, y3;
+ if (ca->dtx & CAM_DTX_CENTER) {
+ float x3, y3;
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
+ x3 = x1 + 0.5f * (x2 - x1);
+ y3 = y1 + 0.5f * (y2 - y1);
- x3 = x1 + 0.5f * (x2 - x1);
- y3 = y1 + 0.5f * (y2 - y1);
+ immBegin(PRIM_LINES, 4);
- glBegin(GL_LINES);
- glVertex2f(x1, y3);
- glVertex2f(x2, y3);
+ immVertex2f(shdr_pos, x1, y3);
+ immVertex2f(shdr_pos, x2, y3);
- glVertex2f(x3, y1);
- glVertex2f(x3, y2);
- glEnd();
- }
+ immVertex2f(shdr_pos, x3, y1);
+ immVertex2f(shdr_pos, x3, y2);
- if (ca->dtx & CAM_DTX_CENTER_DIAG) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
+ immEnd();
+ }
- glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ if (ca->dtx & CAM_DTX_CENTER_DIAG) {
+ immBegin(PRIM_LINES, 4);
- glVertex2f(x1, y2);
- glVertex2f(x2, y1);
- glEnd();
- }
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
- if (ca->dtx & CAM_DTX_THIRDS) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_grid3(x1, x2, y1, y2, 1.0f / 3.0f);
- }
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x2, y1);
- if (ca->dtx & CAM_DTX_GOLDEN) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_grid3(x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
- }
+ immEnd();
+ }
- if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 0, 'A');
- }
+ if (ca->dtx & CAM_DTX_THIRDS) {
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f / 3.0f);
+ }
- if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 0, 'B');
- }
+ if (ca->dtx & CAM_DTX_GOLDEN) {
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
+ }
- if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 1, 'A');
- }
+ if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'A');
+ }
- if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 1, 'B');
- }
+ if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'B');
+ }
+
+ if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'A');
+ }
- if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
- UI_draw_safe_areas(
- x1, x2, y1, y2,
- scene->safe_areas.title,
- scene->safe_areas.action);
-
- if (ca->flag & CAM_SHOW_SAFE_CENTER) {
- UI_draw_safe_areas(
- x1, x2, y1, y2,
- scene->safe_areas.title_center,
- scene->safe_areas.action_center);
+ if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'B');
+ }
+
+ if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
+ UI_draw_safe_areas(shdr_pos, x1, x2, y1, y2,
+ scene->safe_areas.title, scene->safe_areas.action);
+
+ if (ca->flag & CAM_SHOW_SAFE_CENTER) {
+ UI_draw_safe_areas(shdr_pos, x1, x2, y1, y2,
+ scene->safe_areas.title_center, scene->safe_areas.action_center);
+ }
}
}
@@ -1300,1769 +647,1281 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
}
/* draw */
- UI_ThemeColorShade(TH_VIEW_OVERLAY, 100);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f);
+ immUniformThemeColorShade(TH_VIEW_OVERLAY, 100);
+
+ /* TODO Was using UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color).
+ * We'll probably need a new imm_draw_line_roundbox_dashed dor that - though in practice the
+ * 2.0f round corner effect was nearly not visible anyway... */
+ imm_draw_line_box(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
- }
- setlinestyle(0);
+ immUnbindProgram();
+ }
/* camera name - draw in highlighted text color */
if (ca && (ca->flag & CAM_SHOWNAME)) {
- UI_ThemeColor(TH_TEXT_HI);
- BLF_draw_default(
- x1i, y1i - (0.7f * U.widget_unit), 0.0f,
- v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ BLF_draw_default(x1i, y1i - (0.7f * U.widget_unit), 0.0f,
+ v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
}
}
-/* *********************** backdraw for selection *************** */
-
-static void backdrawview3d(Scene *scene, wmWindow *win, ARegion *ar, View3D *v3d)
+static void drawrenderborder(ARegion *ar, View3D *v3d)
{
- RegionView3D *rv3d = ar->regiondata;
- struct Base *base = scene->basact;
- int multisample_enabled;
+ /* use the same program for everything */
+ uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
+ glLineWidth(1.0f);
- if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
- BKE_paint_select_face_test(base->object)))
- {
- /* do nothing */
- }
- /* texture paint mode sampling */
- else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
- (v3d->drawtype > OB_WIRE))
- {
- /* do nothing */
- }
- else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
- V3D_IS_ZBUF(v3d))
- {
- /* do nothing */
- }
- else if (scene->obedit &&
- V3D_IS_ZBUF(v3d))
- {
- /* do nothing */
- }
- else {
- v3d->flag &= ~V3D_INVALID_BACKBUF;
- return;
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
- if (!(v3d->flag & V3D_INVALID_BACKBUF))
- return;
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
-#if 0
- if (test) {
- if (qtest()) {
- addafterqueue(ar->win, BACKBUFDRAW, 1);
- return;
- }
- }
-#endif
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniform4f("color", 1.0f, 0.25f, 0.25f, 1.0f);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
-
- /* dithering and AA break color coding, so disable */
- glDisable(GL_DITHER);
-
- multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
- if (multisample_enabled)
- glDisable(GL_MULTISAMPLE);
-
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- /* for multisample we use an offscreen FBO. multisample drawing can fail
- * with color coded selection drawing, and reading back depths from such
- * a buffer can also cause a few seconds freeze on OS X / NVidia. */
- int w = BLI_rcti_size_x(&ar->winrct);
- int h = BLI_rcti_size_y(&ar->winrct);
- char error[256];
-
- if (rv3d->gpuoffscreen) {
- if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
- GPU_offscreen_height(rv3d->gpuoffscreen) != h)
- {
- GPU_offscreen_free(rv3d->gpuoffscreen);
- rv3d->gpuoffscreen = NULL;
- }
- }
+ imm_draw_line_box(shdr_pos,
+ v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
+ v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
- if (!rv3d->gpuoffscreen) {
- rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, error);
+ immUnbindProgram();
+}
- if (!rv3d->gpuoffscreen)
- fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
- }
- }
+void ED_view3d_draw_depth(
+ struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d, bool alphaoverride)
+{
+ Scene *scene = DEG_get_scene(graph);
+ RegionView3D *rv3d = ar->regiondata;
- if (rv3d->gpuoffscreen)
- GPU_offscreen_bind(rv3d->gpuoffscreen, true);
- else
- glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+ short zbuf = v3d->zbuf;
+ short flag = v3d->flag;
+ float glalphaclip = U.glalphaclip;
+ int obcenter_dia = U.obcenter_dia;
+ /* temp set drawtype to solid */
+ /* Setting these temporarily is not nice */
+ v3d->flag &= ~V3D_SELECT_OUTLINE;
+ U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
+ U.obcenter_dia = 0;
- glClearColor(0.0, 0.0, 0.0, 0.0);
- if (v3d->zbuf) {
- glEnable(GL_DEPTH_TEST);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, NULL);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
}
- else {
- glClear(GL_COLOR_BUFFER_BIT);
- glDisable(GL_DEPTH_TEST);
+ /* get surface depth without bias */
+ rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
+
+ v3d->zbuf = true;
+ glEnable(GL_DEPTH_TEST);
+
+#ifdef WITH_OPENGL_LEGACY
+ if (IS_VIEWPORT_LEGACY(vc->v3d)) {
+ /* temp, calls into view3d_draw_legacy.c */
+ ED_view3d_draw_depth_loop(scene, ar, v3d);
}
-
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_set(rv3d);
-
- G.f |= G_BACKBUFSEL;
-
- if (base && (base->lay & v3d->lay))
- draw_object_backbufsel(scene, v3d, rv3d, base->object);
-
- if (rv3d->gpuoffscreen)
- GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
else
- ar->swap = 0; /* mark invalid backbuf for wm draw */
+#endif /* WITH_OPENGL_LEGACY */
+ {
+ DRW_draw_depth_loop(graph, ar, v3d);
+ }
- v3d->flag &= ~V3D_INVALID_BACKBUF;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+ rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
- G.f &= ~G_BACKBUFSEL;
- v3d->zbuf = false;
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_DITHER);
- if (multisample_enabled)
- glEnable(GL_MULTISAMPLE);
+ v3d->zbuf = zbuf;
+ if (!v3d->zbuf) glDisable(GL_DEPTH_TEST);
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_disable();
+ U.glalphaclip = glalphaclip;
+ v3d->flag = flag;
+ U.obcenter_dia = obcenter_dia;
}
-void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+/* ******************** background plates ***************** */
+
+static void view3d_draw_background_gradient(void)
{
- RegionView3D *rv3d = ar->regiondata;
+ /* TODO: finish 2D API & draw background with that */
- if (rv3d->gpuoffscreen) {
- GPU_offscreen_bind(rv3d->gpuoffscreen, true);
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
- glReadPixels(x, y, w, h, format, type, data);
- GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
- }
- else {
- glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
- }
-}
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+ unsigned char col_hi[3], col_lo[3];
-/* XXX depth reading exception, for code not using gpu offscreen */
-static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
-{
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
-}
+ UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo);
+ UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi);
-void ED_view3d_backbuf_validate(ViewContext *vc)
-{
- if (vc->v3d->flag & V3D_INVALID_BACKBUF)
- backdrawview3d(vc->scene, vc->win, vc->ar, vc->v3d);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+ immAttrib3ubv(color, col_lo);
+ immVertex2f(pos, -1.0f, -1.0f);
+ immVertex2f(pos, 1.0f, -1.0f);
+
+ immAttrib3ubv(color, col_hi);
+ immVertex2f(pos, 1.0f, 1.0f);
+ immVertex2f(pos, -1.0f, 1.0f);
+ immEnd();
+
+ immUnbindProgram();
}
-/**
- * allow for small values [0.5 - 2.5],
- * and large values, FLT_MAX by clamping by the area size
- */
-int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
+static void view3d_draw_background_none(void)
{
- return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
+ UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
}
-/* samples a single pixel (copied from vpaint) */
-unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y)
+static void view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- unsigned int col;
-
- if (x >= vc->ar->winx || y >= vc->ar->winy) {
- return 0;
- }
+ if (scene->world) {
+ GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
- ED_view3d_backbuf_validate(vc);
+ /* calculate full shader for background */
+ GPU_material_bind(gpumat, 1, 1, 1.0f, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
+
+ if (GPU_material_bound(gpumat)) {
+ /* TODO viewport (dfelinto): GPU_material_bind relies on immediate mode,
+ * we can't get rid of the following code without a bigger refactor
+ * or we dropping this functionality. */
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex2f(-1.0f, -1.0f);
+ glVertex2f(1.0f, -1.0f);
+ glVertex2f(-1.0f, 1.0f);
+ glVertex2f(1.0f, 1.0f);
+ glEnd();
- view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
- glReadBuffer(GL_BACK);
-
- if (ENDIAN_ORDER == B_ENDIAN) {
- BLI_endian_switch_uint32(&col);
+ GPU_material_unbind(gpumat);
+ return;
+ }
}
-
- return GPU_select_to_index(col);
-}
-/* reads full rect, converts indices */
-ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
-{
- struct ImBuf *ibuf_clip;
- /* clip */
- const rcti clip = {
- max_ii(xmin, 0), min_ii(xmax, vc->ar->winx - 1),
- max_ii(ymin, 0), min_ii(ymax, vc->ar->winy - 1)};
- const int size_clip[2] = {
- BLI_rcti_size_x(&clip) + 1,
- BLI_rcti_size_y(&clip) + 1};
-
- if (UNLIKELY((clip.xmin > clip.xmax) ||
- (clip.ymin > clip.ymax)))
- {
- return NULL;
- }
+ /* if any of the above fails */
+ view3d_draw_background_none();
+}
- ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect);
+/* ******************** other elements ***************** */
- ED_view3d_backbuf_validate(vc);
- view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect);
+#define DEBUG_GRID 0
- glReadBuffer(GL_BACK);
+static void gridline_range(double x0, double dx, double max, int *r_first, int *r_count)
+{
+ /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y
+ * x0 is gridline 0, the axis in screen space
+ * Area covers [0 .. max) pixels */
- if (ENDIAN_ORDER == B_ENDIAN) {
- IMB_convert_rgba_to_abgr(ibuf_clip);
- }
+ int first = (int)ceil(-x0 / dx);
+ int last = (int)floor((max - x0) / dx);
- GPU_select_to_index_array(ibuf_clip->rect, size_clip[0] * size_clip[1]);
-
- if ((clip.xmin == xmin) &&
- (clip.xmax == xmax) &&
- (clip.ymin == ymin) &&
- (clip.ymax == ymax))
- {
- return ibuf_clip;
+ if (first <= last) {
+ *r_first = first;
+ *r_count = last - first + 1;
}
else {
- /* put clipped result into a non-clipped buffer */
- struct ImBuf *ibuf_full;
- const int size[2] = {
- (xmax - xmin + 1),
- (ymax - ymin + 1)};
-
- ibuf_full = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
-
- IMB_rectcpy(
- ibuf_full, ibuf_clip,
- clip.xmin - xmin, clip.ymin - ymin,
- 0, 0,
- size_clip[0], size_clip[1]);
- IMB_freeImBuf(ibuf_clip);
- return ibuf_full;
+ *r_first = 0;
+ *r_count = 0;
}
+
+#if DEBUG_GRID
+ printf(" first %d * dx = %f\n", first, x0 + first * dx);
+ printf(" last %d * dx = %f\n", last, x0 + last * dx);
+ printf(" count = %d\n", *count_out);
+#endif
}
-/* smart function to sample a rect spiralling outside, nice for backbuf selection */
-unsigned int ED_view3d_backbuf_sample_rect(
- ViewContext *vc, const int mval[2], int size,
- unsigned int min, unsigned int max, float *r_dist)
+static int gridline_count(ARegion *ar, double x0, double y0, double dx)
{
- struct ImBuf *buf;
- const unsigned int *bufmin, *bufmax, *tbuf;
- int minx, miny;
- int a, b, rc, nr, amount, dirvec[4][2];
- unsigned int index = 0;
-
- amount = (size - 1) / 2;
-
- minx = mval[0] - (amount + 1);
- miny = mval[1] - (amount + 1);
- buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1);
- if (!buf) return 0;
-
- rc = 0;
-
- dirvec[0][0] = 1; dirvec[0][1] = 0;
- dirvec[1][0] = 0; dirvec[1][1] = -size;
- dirvec[2][0] = -1; dirvec[2][1] = 0;
- dirvec[3][0] = 0; dirvec[3][1] = size;
-
- bufmin = buf->rect;
- tbuf = buf->rect;
- bufmax = buf->rect + size * size;
- tbuf += amount * size + amount;
-
- for (nr = 1; nr <= size; nr++) {
-
- for (a = 0; a < 2; a++) {
- for (b = 0; b < nr; b++) {
- if (*tbuf && *tbuf >= min && *tbuf < max) {
- /* we got a hit */
-
- /* get x,y pixel coords from the offset
- * (manhatten distance in keeping with other screen-based selection) */
- *r_dist = (float)(
- abs(((int)(tbuf - buf->rect) % size) - (size / 2)) +
- abs(((int)(tbuf - buf->rect) / size) - (size / 2)));
-
- /* indices start at 1 here */
- index = (*tbuf - min) + 1;
- goto exit;
- }
-
- tbuf += (dirvec[rc][0] + dirvec[rc][1]);
-
- if (tbuf < bufmin || tbuf >= bufmax) {
- goto exit;
- }
- }
- rc++;
- rc &= 3;
- }
- }
+ /* x0 & y0 establish the "phase" of the grid within this 2D region
+ * dx is the frequency, shared by x & y directions
+ * pass in dx of smallest (highest precision) grid we want to draw */
-exit:
- IMB_freeImBuf(buf);
- return index;
-}
+#if DEBUG_GRID
+ printf(" %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx);
+#endif
+ int first, x_ct, y_ct;
-/* ************************************************************* */
+ gridline_range(x0, dx, ar->winx, &first, &x_ct);
+ gridline_range(y0, dx, ar->winy, &first, &y_ct);
-static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
-{
- if (BKE_image_is_stereo(ima)) {
- iuser->flag |= IMA_SHOW_STEREO;
+ int total_ct = x_ct + y_ct;
- if ((scene->r.scemode & R_MULTIVIEW) == 0) {
- iuser->multiview_eye = STEREO_LEFT_ID;
- }
- else if (v3d->stereo3d_camera != STEREO_3D_ID) {
- /* show only left or right camera */
- iuser->multiview_eye = v3d->stereo3d_camera;
- }
+#if DEBUG_GRID
+ printf(" %d + %d = %d gridlines\n", x_ct, y_ct, total_ct);
+#endif
- BKE_image_multiview_index(ima, iuser);
- }
- else {
- iuser->flag &= ~IMA_SHOW_STEREO;
- }
+ return total_ct;
}
-static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
- const bool do_foreground, const bool do_camera_frame)
+static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3])
{
- RegionView3D *rv3d = ar->regiondata;
- BGpic *bgpic;
- int fg_flag = do_foreground ? V3D_BGPIC_FOREGROUND : 0;
+ /* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw
+ * always skip exact x0 & y0 axes; they will be drawn later in color
+ *
+ * set grid color once, just before the first line is drawn
+ * it's harmless to set same color for every line, or every vertex
+ * but if no lines are drawn, color must not be set! */
- for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
- bgpic->iuser.scene = scene; /* Needed for render results. */
+#if DEBUG_GRID
+ printf(" %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod);
+#endif
- if ((bgpic->flag & V3D_BGPIC_FOREGROUND) != fg_flag)
- continue;
+ const float x_max = (float)ar->winx;
+ const float y_max = (float)ar->winy;
- if ((bgpic->view == 0) || /* zero for any */
- (bgpic->view & (1 << rv3d->view)) || /* check agaist flags */
- (rv3d->persp == RV3D_CAMOB && bgpic->view == (1 << RV3D_VIEW_CAMERA)))
- {
- float image_aspect[2];
- float fac, asp, zoomx, zoomy;
- float x1, y1, x2, y2, centx, centy;
-
- ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
- void *lock;
- rctf clip_rect;
-
- Image *ima = NULL;
- MovieClip *clip = NULL;
-
- /* disable individual images */
- if ((bgpic->flag & V3D_BGPIC_DISABLED))
- continue;
-
- freeibuf = NULL;
- releaseibuf = NULL;
- if (bgpic->source == V3D_BGPIC_IMAGE) {
- ima = bgpic->ima;
- if (ima == NULL)
- continue;
- BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0);
- if (ima->source == IMA_SRC_SEQUENCE && !(bgpic->iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
- ibuf = NULL; /* frame is out of range, dont show */
- }
- else {
- view3d_stereo_bgpic_setup(scene, v3d, ima, &bgpic->iuser);
- ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
- releaseibuf = ibuf;
- }
+ int first, ct;
+ int x_ct = 0, y_ct = 0; /* count of lines actually drawn */
+ int lines_skipped_for_next_unit = 0;
- image_aspect[0] = ima->aspx;
- image_aspect[1] = ima->aspy;
- }
- else if (bgpic->source == V3D_BGPIC_MOVIE) {
- /* TODO: skip drawing when out of frame range (as image sequences do above) */
+ /* draw vertical lines */
+ gridline_range(x0, dx, x_max, &first, &ct);
- if (bgpic->flag & V3D_BGPIC_CAMERACLIP) {
- if (scene->camera)
- clip = BKE_object_movieclip_get(scene, scene->camera, true);
- }
- else {
- clip = bgpic->clip;
- }
-
- if (clip == NULL)
- continue;
+ for (int i = first; i < first + ct; ++i) {
+ if (i == 0)
+ continue;
+ else if (skip_mod && (i % skip_mod) == 0) {
+ ++lines_skipped_for_next_unit;
+ continue;
+ }
- BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA);
- ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
+ if (x_ct == 0)
+ immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
- image_aspect[0] = clip->aspx;
- image_aspect[1] = clip->aspy;
+ float x = (float)(x0 + i * dx);
+ immVertex2f(pos, x, 0.0f);
+ immVertex2f(pos, x, y_max);
+ ++x_ct;
+ }
- /* working with ibuf from image and clip has got different workflow now.
- * ibuf acquired from clip is referenced by cache system and should
- * be dereferenced after usage. */
- freeibuf = ibuf;
- }
- else {
- /* perhaps when loading future files... */
- BLI_assert(0);
- copy_v2_fl(image_aspect, 1.0f);
- }
+ /* draw horizontal lines */
+ gridline_range(y0, dx, y_max, &first, &ct);
- if (ibuf == NULL)
- continue;
+ for (int i = first; i < first + ct; ++i) {
+ if (i == 0)
+ continue;
+ else if (skip_mod && (i % skip_mod) == 0) {
+ ++lines_skipped_for_next_unit;
+ continue;
+ }
- if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
- if (freeibuf)
- IMB_freeImBuf(freeibuf);
- if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, lock);
+ if (x_ct + y_ct == 0)
+ immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
- continue;
- }
+ float y = (float)(y0 + i * dx);
+ immVertex2f(pos, 0.0f, y);
+ immVertex2f(pos, x_max, y);
+ ++y_ct;
+ }
- if (ibuf->rect == NULL)
- IMB_rect_from_float(ibuf);
+#if DEBUG_GRID
+ int total_ct = x_ct + y_ct;
+ printf(" %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit);
+#endif
- if (rv3d->persp == RV3D_CAMOB) {
+ return lines_skipped_for_next_unit > 0;
+}
- if (do_camera_frame) {
- rctf vb;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
- x1 = vb.xmin;
- y1 = vb.ymin;
- x2 = vb.xmax;
- y2 = vb.ymax;
- }
- else {
- x1 = ar->winrct.xmin;
- y1 = ar->winrct.ymin;
- x2 = ar->winrct.xmax;
- y2 = ar->winrct.ymax;
- }
+#define GRID_MIN_PX_D 6.0
+#define GRID_MIN_PX_F 6.0f
- /* apply offset last - camera offset is different to offset in blender units */
- /* so this has some sane way of working - this matches camera's shift _exactly_ */
- {
- const float max_dim = max_ff(x2 - x1, y2 - y1);
- const float xof_scale = bgpic->xof * max_dim;
- const float yof_scale = bgpic->yof * max_dim;
-
- x1 += xof_scale;
- y1 += yof_scale;
- x2 += xof_scale;
- y2 += yof_scale;
- }
+static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
+{
+ RegionView3D *rv3d = ar->regiondata;
- centx = (x1 + x2) / 2.0f;
- centy = (y1 + y2) / 2.0f;
+#if DEBUG_GRID
+ printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy);
+#endif
- /* aspect correction */
- if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) {
- /* apply aspect from clip */
- const float w_src = ibuf->x * image_aspect[0];
- const float h_src = ibuf->y * image_aspect[1];
+ double fx = rv3d->persmat[3][0];
+ double fy = rv3d->persmat[3][1];
+ double fw = rv3d->persmat[3][3];
- /* destination aspect is already applied from the camera frame */
- const float w_dst = x1 - x2;
- const float h_dst = y1 - y2;
+ const double wx = 0.5 * ar->winx; /* use double precision to avoid rounding errors */
+ const double wy = 0.5 * ar->winy;
- const float asp_src = w_src / h_src;
- const float asp_dst = w_dst / h_dst;
+ double x = wx * fx / fw;
+ double y = wy * fy / fw;
- if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
- if ((asp_src > asp_dst) == ((bgpic->flag & V3D_BGPIC_CAMERA_CROP) != 0)) {
- /* fit X */
- const float div = asp_src / asp_dst;
- x1 = ((x1 - centx) * div) + centx;
- x2 = ((x2 - centx) * div) + centx;
- }
- else {
- /* fit Y */
- const float div = asp_dst / asp_src;
- y1 = ((y1 - centy) * div) + centy;
- y2 = ((y2 - centy) * div) + centy;
- }
- }
- }
- }
- else {
- float tvec[3];
- float sco[2];
- const float mval_f[2] = {1.0f, 0.0f};
- const float co_zero[3] = {0};
- float zfac;
-
- /* calc window coord */
- zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
- ED_view3d_win_to_delta(ar, mval_f, tvec, zfac);
- fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */
- fac = 1.0f / fac;
-
- asp = (float)ibuf->y / (float)ibuf->x;
-
- zero_v3(tvec);
- ED_view3d_project_float_v2_m4(ar, tvec, sco, rv3d->persmat);
-
- x1 = sco[0] + fac * (bgpic->xof - bgpic->size);
- y1 = sco[1] + asp * fac * (bgpic->yof - bgpic->size);
- x2 = sco[0] + fac * (bgpic->xof + bgpic->size);
- y2 = sco[1] + asp * fac * (bgpic->yof + bgpic->size);
-
- centx = (x1 + x2) / 2.0f;
- centy = (y1 + y2) / 2.0f;
- }
+ double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 };
+ mul_m4_v4d(rv3d->persmat, vec4);
+ fx = vec4[0];
+ fy = vec4[1];
+ fw = vec4[3];
- /* complete clip? */
- BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
- if (bgpic->rotation) {
- BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
- }
+ double dx = fabs(x - wx * fx / fw);
+ if (dx == 0) dx = fabs(y - wy * fy / fw);
- if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
- if (freeibuf)
- IMB_freeImBuf(freeibuf);
- if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, lock);
+ x += wx;
+ y += wy;
- continue;
- }
+ /* now x, y, and dx have their final values
+ * (x,y) is the world origin (0,0,0) mapped to Area-relative screen space
+ * dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */
- zoomx = (x2 - x1) / ibuf->x;
- zoomy = (y2 - y1) / ibuf->y;
+ glLineWidth(1.0f);
- /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
- if (zoomx < 1.0f || zoomy < 1.0f) {
- float tzoom = min_ff(zoomx, zoomy);
- int mip = 0;
+#if 0 /* TODO: write to UI/widget depth buffer, not scene depth */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer */
+#endif
- if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
- IMB_remakemipmap(ibuf, 0);
- ibuf->userflags &= ~IB_MIPMAP_INVALID;
- }
- else if (ibuf->mipmap[0] == NULL)
- IMB_makemipmap(ibuf, 0);
-
- while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
- tzoom *= 2.0f;
- zoomx *= 2.0f;
- zoomy *= 2.0f;
- mip++;
- }
- if (mip > 0)
- ibuf = ibuf->mipmap[mip - 1];
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- glDepthMask(0);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ unsigned char col[3], col2[3];
+ UI_GetThemeColor3ubv(TH_GRID, col);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- ED_region_pixelspace(ar);
+ if (unit->system) {
+ const void *usys;
+ int len;
- glTranslatef(centx, centy, 0.0);
- glRotatef(RAD2DEGF(-bgpic->rotation), 0.0f, 0.0f, 1.0f);
+ bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
- if (bgpic->flag & V3D_BGPIC_FLIP_X) {
- zoomx *= -1.0f;
- x1 = x2;
- }
- if (bgpic->flag & V3D_BGPIC_FLIP_Y) {
- zoomy *= -1.0f;
- y1 = y2;
- }
- glPixelZoom(zoomx, zoomy);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend);
+ bool first = true;
- /* could not use glaDrawPixelsAuto because it could fallback to
- * glaDrawPixelsSafe in some cases, which will end up in missing
- * alpha transparency for the background image (sergey)
- */
- glaDrawPixelsTex(x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
+ if (usys) {
+ int i = len;
+ while (i--) {
+ double scalar = bUnit_GetScaler(usys, i);
- glPixelZoom(1.0, 1.0);
- glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+ double dx_scalar = dx * scalar / (double)unit->scale_length;
+ if (dx_scalar < (GRID_MIN_PX_D * 2.0)) {
+ /* very very small grid items are less useful when dealing with units */
+ continue;
+ }
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ if (first) {
+ first = false;
- glDisable(GL_BLEND);
+ /* Store the smallest drawn grid size units name so users know how big each grid cell is */
+ *grid_unit = bUnit_GetNameDisplay(usys, i);
+ rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
- glDepthMask(1);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ int gridline_ct = gridline_count(ar, x, y, dx_scalar);
+ if (gridline_ct == 0)
+ goto drawgrid_cleanup; /* nothing to draw */
- if (freeibuf)
- IMB_freeImBuf(freeibuf);
- if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, lock);
- }
- }
-}
+ immBegin(PRIM_LINES, gridline_ct * 2);
+ }
-static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d,
- const bool do_foreground, const bool do_camera_frame)
-{
- RegionView3D *rv3d = ar->regiondata;
+ float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
+ /* tweak to have the fade a bit nicer */
+ blend_fac = (blend_fac * blend_fac) * 2.0f;
+ CLAMP(blend_fac, 0.3f, 1.0f);
- if ((v3d->flag & V3D_DISPBGPICS) == 0)
- return;
+ UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2);
- /* disabled - mango request, since footage /w only render is quite useful
- * and this option is easy to disable all background images at once */
-#if 0
- if (v3d->flag2 & V3D_RENDER_OVERRIDE)
- return;
+ const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar);
+#if DEBUG_GRID
+ printf("%s %f, ", bUnit_GetNameDisplay(usys, i), scalar);
+ if (i > 0)
+ printf("next unit is %d times larger\n", skip_mod);
+ else
+ printf("largest unit\n");
#endif
-
- if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
- if (rv3d->persp == RV3D_CAMOB) {
- view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+ if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2))
+ break;
+ }
}
}
else {
- view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
- }
-}
-
-/* ****************** View3d afterdraw *************** */
+ const double sublines = v3d->gridsubdiv;
+ const float sublines_fl = v3d->gridsubdiv;
-typedef struct View3DAfter {
- struct View3DAfter *next, *prev;
- struct Base *base;
- short dflag;
-} View3DAfter;
+ int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */
-/* temp storage of Objects that need to be drawn as last */
-void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag)
-{
- View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
- BLI_assert((base->flag & OB_FROMDUPLI) == 0);
- BLI_addtail(lb, v3da);
- v3da->base = base;
- v3da->dflag = dflag;
-}
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ if (dx < GRID_MIN_PX_D) {
+ rv3d->gridview *= sublines_fl;
+ dx *= sublines;
+ grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1;
+ }
+ }
+ }
+ else {
+ if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
+ rv3d->gridview /= sublines_fl;
+ dx /= sublines;
+ if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
+ rv3d->gridview /= sublines_fl;
+ dx /= sublines;
+ if (dx > (GRID_MIN_PX_D * 10.0)) {
+ grids_to_draw = 1;
+ }
+ }
+ }
+ }
-/* disables write in zbuffer and draws it over */
-static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
-{
- View3DAfter *v3da;
-
- glDepthMask(GL_FALSE);
- v3d->transp = true;
-
- while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
- draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
- MEM_freeN(v3da);
- }
- v3d->transp = false;
-
- glDepthMask(GL_TRUE);
-
-}
+ int gridline_ct = gridline_count(ar, x, y, dx);
+ if (gridline_ct == 0)
+ goto drawgrid_cleanup; /* nothing to draw */
-/* clears zbuffer and draws it over */
-static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
-{
- View3DAfter *v3da;
+ immBegin(PRIM_LINES, gridline_ct * 2);
- if (*clear && v3d->zbuf) {
- glClear(GL_DEPTH_BUFFER_BIT);
- *clear = false;
+ if (grids_to_draw == 2) {
+ UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2);
+ if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2))
+ drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col);
+ }
+ else if (grids_to_draw == 1) {
+ drawgrid_draw(ar, x, y, dx, 0, pos, color, col);
+ }
}
- v3d->xray = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
- MEM_freeN(v3da);
+ /* draw visible axes */
+ /* horizontal line */
+ if (0 <= y && y < ar->winy) {
+ UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X');
+ immAttrib3ub(color, col2[0], col2[1], col2[2]);
+ immVertex2f(pos, 0.0f, y);
+ immVertex2f(pos, (float)ar->winx, y);
}
- v3d->xray = false;
-}
-
-
-/* clears zbuffer and draws it over */
-static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
-{
- View3DAfter *v3da;
-
- if (clear && v3d->zbuf)
- glClear(GL_DEPTH_BUFFER_BIT);
- v3d->xray = true;
- v3d->transp = true;
-
- glDepthMask(GL_FALSE);
-
- while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
- draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
- MEM_freeN(v3da);
+ /* vertical line */
+ if (0 <= x && x < ar->winx) {
+ UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z');
+ immAttrib3ub(color, col2[0], col2[1], col2[2]);
+ immVertex2f(pos, x, 0.0f);
+ immVertex2f(pos, x, (float)ar->winy);
}
- v3d->transp = false;
- v3d->xray = false;
+ immEnd();
- glDepthMask(GL_TRUE);
+drawgrid_cleanup:
+ immUnbindProgram();
+
+#if 0 /* depth write is left enabled above */
+ glDepthMask(GL_TRUE); /* enable write in zbuffer */
+#endif
}
-/* clears zbuffer and draws it over,
- * note that in the select version we don't care about transparent flag as with regular drawing */
-static void view3d_draw_xray_select(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
+#undef DEBUG_GRID
+#undef GRID_MIN_PX_D
+#undef GRID_MIN_PX_F
+
+static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
{
- /* Not ideal, but we need to read from the previous depths before clearing
- * otherwise we could have a function to load the depths after drawing.
- *
- * Clearing the depth buffer isn't all that common between drawing objects so accept this for now.
- */
- if (U.gpu_select_pick_deph) {
- GPU_select_load_id(-1);
- }
+ /* draw only if there is something to draw */
+ if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
+ /* draw how many lines?
+ * trunc(v3d->gridlines / 2) * 4
+ * + 2 for xy axes (possibly with special colors)
+ * + 1 for z axis (the only line not in xy plane)
+ * even v3d->gridlines are honored, odd rounded down */
+ const int gridlines = v3d->gridlines / 2;
+ const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
+ const float grid = gridlines * grid_scale;
- View3DAfter *v3da;
- if (*clear && v3d->zbuf) {
- glClear(GL_DEPTH_BUFFER_BIT);
- *clear = false;
- }
+ const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1;
- v3d->xray = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- if (GPU_select_load_id(v3da->base->selcol)) {
- draw_object_select(scene, ar, v3d, v3da->base, v3da->dflag);
- }
- MEM_freeN(v3da);
- }
- v3d->xray = false;
-}
+ bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
+ bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
+ bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
-/* *********************** */
+ unsigned char col_grid[3], col_axis[3];
-/*
- * In most cases call draw_dupli_objects,
- * draw_dupli_objects_color was added because when drawing set dupli's
- * we need to force the color
- */
+ glLineWidth(1.0f);
-#if 0
-int dupli_ob_sort(void *arg1, void *arg2)
-{
- void *p1 = ((DupliObject *)arg1)->ob;
- void *p2 = ((DupliObject *)arg2)->ob;
- int val = 0;
- if (p1 < p2) val = -1;
- else if (p1 > p2) val = 1;
- return val;
-}
-#endif
+ UI_GetThemeColor3ubv(TH_GRID, col_grid);
+ if (!write_depth)
+ glDepthMask(GL_FALSE);
-static DupliObject *dupli_step(DupliObject *dob)
-{
- while (dob && dob->no_draw)
- dob = dob->next;
- return dob;
-}
+ if (show_floor) {
+ const unsigned vertex_ct = 2 * (gridlines * 4 + 2);
+ const int sublines = v3d->gridsubdiv;
-static void draw_dupli_objects_color(
- Scene *scene, ARegion *ar, View3D *v3d, Base *base,
- const short dflag, const int color)
-{
- RegionView3D *rv3d = ar->regiondata;
- ListBase *lb;
- LodLevel *savedlod;
- DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
- Base tbase = {NULL};
- BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
- GLuint displist = 0;
- unsigned char color_rgb[3];
- const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
- short transflag;
- bool use_displist = false; /* -1 is initialize */
- char dt;
- short dtx;
- DupliApplyData *apply_data;
-
- if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
- if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
-
- if (dflag & DRAW_CONSTCOLOR) {
- BLI_assert(color == TH_UNDEFINED);
- }
- else {
- UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
- }
+ unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3];
- tbase.flag = OB_FROMDUPLI | base->flag;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
- // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
- apply_data = duplilist_apply(base->object, scene, lb);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
- dob = dupli_step(lb->first);
- if (dob) dob_next = dupli_step(dob->next);
+ immBegin(PRIM_LINES, vertex_ct);
- for (; dob; dob_prev = dob, dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
- bool testbb = false;
+ /* draw normal grid lines */
+ UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
- tbase.object = dob->ob;
+ for (int a = 1; a <= gridlines; a++) {
+ /* skip emphasised divider lines */
+ if (a % sublines != 0) {
+ const float line = a * grid_scale;
- /* Make sure lod is updated from dupli's position */
- savedlod = dob->ob->currentlod;
+ immAttrib3ubv(color, col_grid_light);
-#ifdef WITH_GAMEENGINE
- if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
- }
-#endif
+ immVertex2f(pos, -grid, -line);
+ immVertex2f(pos, +grid, -line);
+ immVertex2f(pos, -grid, +line);
+ immVertex2f(pos, +grid, +line);
- /* extra service: draw the duplicator in drawtype of parent, minimum taken
- * to allow e.g. boundbox box objects in groups for LOD */
- dt = tbase.object->dt;
- tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
+ immVertex2f(pos, -line, -grid);
+ immVertex2f(pos, -line, +grid);
+ immVertex2f(pos, +line, -grid);
+ immVertex2f(pos, +line, +grid);
+ }
+ }
- /* inherit draw extra, but not if a boundbox under the assumption that this
- * is intended to speed up drawing, and drawing extra (especially wire) can
- * slow it down too much */
- dtx = tbase.object->dtx;
- if (tbase.object->dt != OB_BOUNDBOX)
- tbase.object->dtx = base->object->dtx;
+ /* draw emphasised grid lines */
+ UI_GetThemeColor3ubv(TH_BACK, col_bg);
+ /* emphasise division lines lighter instead of darker, if background is darker than grid */
+ UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
+ (col_grid[0] + col_grid[1] + col_grid[2] + 30 >
+ col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10);
- /* negative scale flag has to propagate */
- transflag = tbase.object->transflag;
+ if (sublines <= gridlines) {
+ immAttrib3ubv(color, col_grid_emphasise);
- if (is_negative_m4(dob->mat))
- tbase.object->transflag |= OB_NEG_SCALE;
- else
- tbase.object->transflag &= ~OB_NEG_SCALE;
-
- /* should move outside the loop but possible color is set in draw_object still */
- if ((dflag & DRAW_CONSTCOLOR) == 0) {
- glColor3ubv(color_rgb);
- }
-
- /* generate displist, test for new object */
- if (dob_prev && dob_prev->ob != dob->ob) {
- if (use_displist == true)
- glDeleteLists(displist, 1);
-
- use_displist = false;
- }
-
- if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
- bb = *bb_tmp; /* must make a copy */
- testbb = true;
- }
+ for (int a = sublines; a <= gridlines; a += sublines) {
+ const float line = a * grid_scale;
- if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
- /* generate displist */
- if (use_displist == false) {
-
- /* note, since this was added, its checked (dob->type == OB_DUPLIGROUP)
- * however this is very slow, it was probably needed for the NLA
- * offset feature (used in group-duplicate.blend but no longer works in 2.5)
- * so for now it should be ok to - campbell */
-
- if ( /* if this is the last no need to make a displist */
- (dob_next == NULL || dob_next->ob != dob->ob) ||
- /* lamp drawing messes with matrices, could be handled smarter... but this works */
- (dob->ob->type == OB_LAMP) ||
- (dob->type == OB_DUPLIGROUP && dob->animated) ||
- !bb_tmp ||
- draw_glsl_material(scene, dob->ob, v3d, dt) ||
- check_object_draw_texture(scene, v3d, dt) ||
- (v3d->flag2 & V3D_SOLID_MATCAP) != 0)
- {
- // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2);
- use_displist = false;
+ immVertex2f(pos, -grid, -line);
+ immVertex2f(pos, +grid, -line);
+ immVertex2f(pos, -grid, +line);
+ immVertex2f(pos, +grid, +line);
+
+ immVertex2f(pos, -line, -grid);
+ immVertex2f(pos, -line, +grid);
+ immVertex2f(pos, +line, -grid);
+ immVertex2f(pos, +line, +grid);
}
- else {
- // printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name + 2);
-
- /* disable boundbox check for list creation */
- BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 1);
- /* need this for next part of code */
- unit_m4(dob->ob->obmat); /* obmat gets restored */
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
- glEndList();
-
- use_displist = true;
- BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 0);
- }
}
-
- if (use_displist) {
- glPushMatrix();
- glMultMatrixf(dob->mat);
- glCallList(displist);
- glPopMatrix();
- }
- else {
- copy_m4_m4(dob->ob->obmat, dob->mat);
- GPU_begin_dupli_object(dob);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
- GPU_end_dupli_object();
+
+ /* draw X axis */
+ if (show_axis_x) {
+ show_axis_x = false; /* drawing now, won't need to draw later */
+ UI_make_axis_color(col_grid, col_axis, 'X');
+ immAttrib3ubv(color, col_axis);
}
- }
-
- tbase.object->dt = dt;
- tbase.object->dtx = dtx;
- tbase.object->transflag = transflag;
- tbase.object->currentlod = savedlod;
- }
+ else
+ immAttrib3ubv(color, col_grid_emphasise);
- if (apply_data) {
- duplilist_restore(lb, apply_data);
- duplilist_free_apply_data(apply_data);
- }
+ immVertex2f(pos, -grid, 0.0f);
+ immVertex2f(pos, +grid, 0.0f);
- free_object_duplilist(lb);
-
- if (use_displist)
- glDeleteLists(displist, 1);
-}
+ /* draw Y axis */
+ if (show_axis_y) {
+ show_axis_y = false; /* drawing now, won't need to draw later */
+ UI_make_axis_color(col_grid, col_axis, 'Y');
+ immAttrib3ubv(color, col_axis);
+ }
+ else
+ immAttrib3ubv(color, col_grid_emphasise);
-static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base)
-{
- /* define the color here so draw_dupli_objects_color can be called
- * from the set loop */
-
- int color = (base->flag & SELECT) ? TH_SELECT : TH_WIRE;
- /* debug */
- if (base->object->dup_group && base->object->dup_group->id.us < 1)
- color = TH_REDALERT;
-
- draw_dupli_objects_color(scene, ar, v3d, base, 0, color);
-}
+ immVertex2f(pos, 0.0f, -grid);
+ immVertex2f(pos, 0.0f, +grid);
-/* XXX warning, not using gpu offscreen here */
-void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
-{
- int x, y, w, h;
- rcti r;
- /* clamp rect by region */
+ immEnd();
+ immUnbindProgram();
- r.xmin = 0;
- r.xmax = ar->winx - 1;
- r.ymin = 0;
- r.ymax = ar->winy - 1;
+ /* done with XY plane */
+ }
- /* Constrain rect to depth bounds */
- BLI_rcti_isect(&r, rect, rect);
+ if (show_axis_x || show_axis_y || show_axis_z) {
+ /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */
- /* assign values to compare with the ViewDepths */
- x = rect->xmin;
- y = rect->ymin;
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
- w = BLI_rcti_size_x(rect);
- h = BLI_rcti_size_y(rect);
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+ immBegin(PRIM_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2);
- if (w <= 0 || h <= 0) {
- if (d->depths)
- MEM_freeN(d->depths);
- d->depths = NULL;
+ if (show_axis_x) {
+ UI_make_axis_color(col_grid, col_axis, 'X');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, -grid, 0.0f, 0.0f);
+ immVertex3f(pos, +grid, 0.0f, 0.0f);
+ }
- d->damaged = false;
- }
- else if (d->w != w ||
- d->h != h ||
- d->x != x ||
- d->y != y ||
- d->depths == NULL
- )
- {
- d->x = x;
- d->y = y;
- d->w = w;
- d->h = h;
+ if (show_axis_y) {
+ UI_make_axis_color(col_grid, col_axis, 'Y');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, 0.0f, -grid, 0.0f);
+ immVertex3f(pos, 0.0f, +grid, 0.0f);
+ }
- if (d->depths)
- MEM_freeN(d->depths);
+ if (show_axis_z) {
+ UI_make_axis_color(col_grid, col_axis, 'Z');
+ immAttrib3ubv(color, col_axis);
+ immVertex3f(pos, 0.0f, 0.0f, -grid);
+ immVertex3f(pos, 0.0f, 0.0f, +grid);
+ }
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
-
- d->damaged = true;
- }
+ immEnd();
+ immUnbindProgram();
+ }
- if (d->damaged) {
- /* XXX using special function here, it doesn't use the gpu offscreen system */
- view3d_opengl_read_Z_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
- d->damaged = false;
+ if (!write_depth)
+ glDepthMask(GL_TRUE);
}
}
-/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
-void ED_view3d_depth_update(ARegion *ar)
+/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
+float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
{
- RegionView3D *rv3d = ar->regiondata;
-
- /* Create storage for, and, if necessary, copy depth buffer */
- if (!rv3d->depths) rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
- if (rv3d->depths) {
- ViewDepths *d = rv3d->depths;
- if (d->w != ar->winx ||
- d->h != ar->winy ||
- !d->depths)
- {
- d->w = ar->winx;
- d->h = ar->winy;
- if (d->depths)
- MEM_freeN(d->depths);
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
- d->damaged = true;
- }
-
- if (d->damaged) {
- view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
-
- d->damaged = false;
- }
- }
-}
+ /* apply units */
+ if (scene->unit.system) {
+ const void *usys;
+ int len;
-/* utility function to find the closest Z value, use for autodepth */
-float view3d_depth_near(ViewDepths *d)
-{
- /* convert to float for comparisons */
- const float near = (float)d->depth_range[0];
- const float far_real = (float)d->depth_range[1];
- float far = far_real;
-
- const float *depths = d->depths;
- float depth = FLT_MAX;
- int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
-
- /* far is both the starting 'far' value
- * and the closest value found. */
- while (i--) {
- depth = *depths++;
- if ((depth < far) && (depth > near)) {
- far = depth;
+ bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
+
+ if (usys) {
+ int i = bUnit_GetBaseUnit(usys);
+ if (grid_unit)
+ *grid_unit = bUnit_GetNameDisplay(usys, i);
+ return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
}
}
- return far == far_real ? FLT_MAX : far;
+ return 1.0f;
}
-void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
+float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
{
- short zbuf = v3d->zbuf;
- RegionView3D *rv3d = ar->regiondata;
-
- /* Setup view matrix. */
- ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
-
- glClear(GL_DEPTH_BUFFER_BIT);
-
- v3d->zbuf = true;
- glEnable(GL_DEPTH_TEST);
-
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- ED_gpencil_draw_view3d(NULL, scene, v3d, ar, true);
- }
-
- v3d->zbuf = zbuf;
+ return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
}
-static void view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d)
+static bool is_cursor_visible(Scene *scene, SceneLayer *sl)
{
- Base *base;
-
- /* no need for color when drawing depth buffer */
- const short dflag_depth = DRAW_CONSTCOLOR;
-
- /* draw set first */
- if (scene->set) {
- Scene *sce_iter;
- for (SETLOOPER(scene->set, sce_iter, base)) {
- if (v3d->lay & base->lay) {
- draw_object(scene, ar, v3d, base, 0);
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(scene, ar, v3d, base, dflag_depth, TH_UNDEFINED);
- }
+ Object *ob = OBACT_NEW;
+
+ /* don't draw cursor in paint modes, but with a few exceptions */
+ if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ /* exception: object is in weight paint and has deforming armature in pose mode */
+ if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (BKE_object_pose_armature_get(ob) != NULL) {
+ return true;
}
}
- }
-
- for (base = scene->base.first; base; base = base->next) {
- if (v3d->lay & base->lay) {
- /* dupli drawing */
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(scene, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
+ else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ const Paint *p = BKE_paint_get_active(scene, sl);
+
+ if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
+ if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
+ return true;
+ }
}
- draw_object(scene, ar, v3d, base, dflag_depth);
}
+
+ /* no exception met? then don't draw cursor! */
+ return false;
}
-
- /* this isn't that nice, draw xray objects as if they are normal */
- if (v3d->afterdraw_transp.first ||
- v3d->afterdraw_xray.first ||
- v3d->afterdraw_xraytransp.first)
- {
- View3DAfter *v3da;
- int mask_orig;
- v3d->xray = true;
+ return true;
+}
+
+static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
+{
+ int co[2];
+
+ /* we don't want the clipping for cursor */
+ if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ const float f5 = 0.25f * U.widget_unit;
+ const float f10 = 0.5f * U.widget_unit;
+ const float f20 = U.widget_unit;
- /* transp materials can change the depth mask, see #21388 */
- glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+ glLineWidth(1.0f);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
- if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) {
- glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
- for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- }
- glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- /* draw 3 passes, transp/xray/xraytransp */
- v3d->xray = false;
- v3d->transp = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- MEM_freeN(v3da);
- }
+ const int segments = 16;
- v3d->xray = true;
- v3d->transp = false;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- MEM_freeN(v3da);
- }
+ immBegin(PRIM_LINE_LOOP, segments);
+
+ for (int i = 0; i < segments; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)segments);
+ float x = co[0] + f10 * cosf(angle);
+ float y = co[1] + f10 * sinf(angle);
- v3d->xray = true;
- v3d->transp = true;
- while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
- draw_object(scene, ar, v3d, v3da->base, dflag_depth);
- MEM_freeN(v3da);
+ if (i % 2 == 0)
+ immAttrib3ub(color, 255, 0, 0);
+ else
+ immAttrib3ub(color, 255, 255, 255);
+
+ immVertex2f(pos, x, y);
}
+ immEnd();
-
- v3d->xray = false;
- v3d->transp = false;
+ immUnbindProgram();
+
+ VertexFormat_clear(format);
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
- glDepthMask(mask_orig);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ unsigned char crosshair_color[3];
+ UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color);
+ immUniformColor3ubv(crosshair_color);
+
+ immBegin(PRIM_LINES, 8);
+ immVertex2f(pos, co[0] - f20, co[1]);
+ immVertex2f(pos, co[0] - f5, co[1]);
+ immVertex2f(pos, co[0] + f5, co[1]);
+ immVertex2f(pos, co[0] + f20, co[1]);
+ immVertex2f(pos, co[0], co[1] - f20);
+ immVertex2f(pos, co[0], co[1] - f5);
+ immVertex2f(pos, co[0], co[1] + f5);
+ immVertex2f(pos, co[0], co[1] + f20);
+ immEnd();
+
+ immUnbindProgram();
}
}
-void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride)
+static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
- short zbuf = v3d->zbuf;
- short flag = v3d->flag;
- float glalphaclip = U.glalphaclip;
- int obcenter_dia = U.obcenter_dia;
- /* temp set drawtype to solid */
-
- /* Setting these temporarily is not nice */
- v3d->flag &= ~V3D_SELECT_OUTLINE;
- U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
- U.obcenter_dia = 0;
-
- /* Setup view matrix. */
- ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
-
- glClear(GL_DEPTH_BUFFER_BIT);
-
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
- /* get surface depth without bias */
- rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
+ const float k = U.rvisize * U.pixelsize; /* axis size */
+ const int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
- v3d->zbuf = true;
- glEnable(GL_DEPTH_TEST);
+ const float startx = rect->xmin + k + 1.0f; /* axis center in screen coordinates, x=y */
+ const float starty = rect->ymin + k + 1.0f;
- view3d_draw_depth_loop(scene, ar, v3d);
+ float axis_pos[3][2];
+ unsigned char axis_col[3][4];
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_disable();
- }
- rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
-
- v3d->zbuf = zbuf;
- if (!v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ int axis_order[3] = {0, 1, 2};
+ axis_sort_v3(rv3d->viewinv[2], axis_order);
- U.glalphaclip = glalphaclip;
- v3d->flag = flag;
- U.obcenter_dia = obcenter_dia;
-}
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
-void ED_view3d_draw_select_loop(
- ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
- bool use_obedit_skip, bool use_nearest)
-{
- short code = 1;
- const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR;
+ /* get position of each axis tip on screen */
+ float vec[3] = { 0.0f };
+ vec[i] = 1.0f;
+ mul_qt_v3(rv3d->viewquat, vec);
+ axis_pos[i][0] = startx + vec[0] * k;
+ axis_pos[i][1] = starty + vec[1] * k;
- if (vc->obedit && vc->obedit->type == OB_MBALL) {
- draw_object(scene, ar, v3d, BASACT, dflag);
- }
- else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
- /* if not drawing sketch, draw bones */
- if (!BDR_drawSketchNames(vc)) {
- draw_object(scene, ar, v3d, BASACT, dflag);
- }
+ /* get color of each axis */
+ UI_GetThemeColorShade3ubv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
+ axis_col[i][3] = 255 * hypotf(vec[0], vec[1]); /* alpha */
}
- else {
- Base *base;
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & v3d->lay) {
+ /* draw axis lines */
+ glLineWidth(2.0f);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
- if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
- (use_obedit_skip && (scene->obedit->data == base->object->data)))
- {
- base->selcol = 0;
- }
- else {
- base->selcol = code;
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(PRIM_LINES, 6);
- if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) {
- ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
- }
- else {
- if (GPU_select_load_id(code)) {
- draw_object_select(scene, ar, v3d, base, dflag);
- }
- }
- code++;
- }
- }
- }
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
- if (use_nearest) {
- bool xrayclear = true;
- if (v3d->afterdraw_xray.first) {
- view3d_draw_xray_select(scene, ar, v3d, &xrayclear);
- }
- }
+ immAttrib4ubv(col, axis_col[i]);
+ immVertex2f(pos, startx, starty);
+ immVertex2fv(pos, axis_pos[i]);
}
-}
-typedef struct View3DShadow {
- struct View3DShadow *next, *prev;
- GPULamp *lamp;
-} View3DShadow;
+ immEnd();
+ immUnbindProgram();
+ glDisable(GL_LINE_SMOOTH);
-static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
- Object *ob, Object *par,
- float obmat[4][4], unsigned int lay,
- ListBase *shadows, SceneRenderLayer *srl)
-{
- GPULamp *lamp;
- Lamp *la = (Lamp *)ob->data;
- View3DShadow *shadow;
- unsigned int layers;
-
- lamp = GPU_lamp_from_blender(scene, ob, par);
-
- if (lamp) {
- GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
- GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
-
- layers = lay & v3d->lay;
- if (srl)
- layers &= srl->lay;
-
- if (layers &&
- GPU_lamp_has_shadow_buffer(lamp) &&
- /* keep last, may do string lookup */
- GPU_lamp_override_visible(lamp, srl, NULL))
- {
- shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
- shadow->lamp = lamp;
- BLI_addtail(shadows, shadow);
- }
- }
-}
+ /* draw axis names */
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
-static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
-{
- ListBase shadows;
- View3DShadow *shadow;
- Scene *sce_iter;
- Base *base;
- Object *ob;
- World *world = scene->world;
- SceneRenderLayer *srl = v3d->scenelock ? BLI_findlink(&scene->r.layers, scene->r.actlay) : NULL;
-
- BLI_listbase_clear(&shadows);
-
- /* update lamp transform and gather shadow lamps */
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
-
- if (ob->type == OB_LAMP)
- gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows, srl);
-
- if (ob->transflag & OB_DUPLI) {
- DupliObject *dob;
- ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
-
- for (dob = lb->first; dob; dob = dob->next)
- if (dob->ob->type == OB_LAMP)
- gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows, srl);
-
- free_object_duplilist(lb);
- }
- }
-
- /* render shadows after updating all lamps, nested object_duplilist
- * don't work correct since it's replacing object matrices */
- for (shadow = shadows.first; shadow; shadow = shadow->next) {
- /* this needs to be done better .. */
- float viewmat[4][4], winmat[4][4];
- int drawtype, lay, winsize, flag2 = v3d->flag2;
- ARegion ar = {NULL};
- RegionView3D rv3d = {{{0}}};
-
- drawtype = v3d->drawtype;
- lay = v3d->lay;
-
- v3d->drawtype = OB_SOLID;
- v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
- v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
- v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
-
- GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
-
- ar.regiondata = &rv3d;
- ar.regiontype = RGN_TYPE_WINDOW;
- rv3d.persp = RV3D_CAMOB;
- copy_m4_m4(rv3d.winmat, winmat);
- copy_m4_m4(rv3d.viewmat, viewmat);
- invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
- mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
- invert_m4_m4(rv3d.persinv, rv3d.viewinv);
-
- /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(
- scene, v3d, &ar, winsize, winsize, viewmat, winmat,
- false, false, true,
- NULL, NULL, NULL, NULL);
- GPU_lamp_shadow_buffer_unbind(shadow->lamp);
-
- v3d->drawtype = drawtype;
- v3d->lay = lay;
- v3d->flag2 = flag2;
- }
-
- BLI_freelistN(&shadows);
-
- /* update world values */
- if (world) {
- GPU_mist_update_enable(world->mode & WO_MIST);
- GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr);
- GPU_horizon_update_color(&world->horr);
- GPU_ambient_update_color(&world->ambr);
- GPU_zenith_update_color(&world->zenr);
+ const char axis_text[2] = {'x' + i, '\0'};
+ BLF_color4ubv(BLF_default(), axis_col[i]);
+ BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
}
}
-/* *********************** customdata **************** */
-
-CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
+#ifdef WITH_INPUT_NDOF
+/* draw center and axis of rotation for ongoing 3D mouse navigation */
+static void draw_rotation_guide(RegionView3D *rv3d)
{
- CustomDataMask mask = 0;
- const int drawtype = view3d_effective_drawtype(v3d);
+ float o[3]; /* center of rotation */
+ float end[3]; /* endpoints for drawing */
- if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL) ||
- ((drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX)))
- {
- mask |= CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
+ GLubyte color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
- if (BKE_scene_use_new_shading_nodes(scene)) {
- if (drawtype == OB_MATERIAL)
- mask |= CD_MASK_ORCO;
- }
- else {
- if ((scene->gm.matmode == GAME_MAT_GLSL && drawtype == OB_TEXTURE) ||
- (drawtype == OB_MATERIAL))
- {
- mask |= CD_MASK_ORCO;
- }
- }
- }
+ negate_v3_v3(o, rv3d->ofs);
- return mask;
-}
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDepthMask(GL_FALSE); /* don't overwrite zbuf */
-/* goes over all modes and view3d settings */
-CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
-{
- const Scene *scene = screen->scene;
- CustomDataMask mask = CD_MASK_BAREMESH;
- const ScrArea *sa;
-
- /* check if we need tfaces & mcols due to view mode */
- for (sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype == SPACE_VIEW3D) {
- mask |= ED_view3d_datamask(scene, sa->spacedata.first);
- }
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int col = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
- return mask;
-}
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
-/**
- * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
- */
-void ED_view3d_update_viewmat(
- Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
-{
- RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->rot_angle != 0.0f) {
+ /* -- draw rotation axis -- */
+ float scaled_axis[3];
+ const float scale = rv3d->dist;
+ mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
- /* setup window matrices */
- if (winmat)
- copy_m4_m4(rv3d->winmat, winmat);
- else
- view3d_winmatrix_set(ar, v3d, rect);
- /* setup view matrix */
- if (viewmat)
- copy_m4_m4(rv3d->viewmat, viewmat);
- else
- view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+ immBegin(PRIM_LINE_STRIP, 3);
+ color[3] = 0; /* more transparent toward the ends */
+ immAttrib4ubv(col, color);
+ add_v3_v3v3(end, o, scaled_axis);
+ immVertex3fv(pos, end);
- /* update utility matrices */
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
-
- /* calculate GLSL view dependent values */
+#if 0
+ color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
+ /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
+#endif
- /* store window coordinates scaling/offset */
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- rctf cameraborder;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
- rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
- rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
+ color[3] = 127; /* more opaque toward the center */
+ immAttrib4ubv(col, color);
+ immVertex3fv(pos, o);
+
+ color[3] = 0;
+ immAttrib4ubv(col, color);
+ sub_v3_v3v3(end, o, scaled_axis);
+ immVertex3fv(pos, end);
+ immEnd();
- rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
- rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
- }
- else {
- rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
- rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
- }
+ /* -- draw ring around rotation center -- */
+ {
+#define ROT_AXIS_DETAIL 13
- /**
- * Calculate pixel-size factor once, is used for lamps and object centers.
- * Used by #ED_view3d_pixel_size and typically not accessed directly.
- *
- * \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value,
- * passed to #RE_SetPixelSize, in ortho mode this is compatible with this value,
- * but in perspective mode its offset by the near-clip.
- *
- * 'RegionView3D.pixsize' is used for viewport drawing, not rendering.
- */
- {
- /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
- * because of float point precision problems at large values [#23908] */
- float v1[3], v2[3];
- float len_px, len_sc;
+ const float s = 0.05f * scale;
+ const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
- v1[0] = rv3d->persmat[0][0];
- v1[1] = rv3d->persmat[1][0];
- v1[2] = rv3d->persmat[2][0];
+ float q[4]; /* rotate ring so it's perpendicular to axis */
+ const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
+ if (!upright) {
+ const float up[3] = {0.0f, 0.0f, 1.0f};
+ float vis_angle, vis_axis[3];
- v2[0] = rv3d->persmat[0][1];
- v2[1] = rv3d->persmat[1][1];
- v2[2] = rv3d->persmat[2][1];
+ cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
+ vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
+ axis_angle_to_quat(q, vis_axis, vis_angle);
+ }
- len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
- len_sc = (float)MAX2(ar->winx, ar->winy);
+ immBegin(PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
+ color[3] = 63; /* somewhat faint */
+ immAttrib4ubv(col, color);
+ float angle = 0.0f;
+ for (int i = 0; i < ROT_AXIS_DETAIL; ++i, angle += step) {
+ float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
- rv3d->pixsize = len_px / len_sc;
+ if (!upright) {
+ mul_qt_v3(q, p);
+ }
+
+ add_v3_v3(p, o);
+ immVertex3fv(pos, p);
+ }
+ immEnd();
+
+#undef ROT_AXIS_DETAIL
+ }
+
+ color[3] = 255; /* solid dot */
}
+ else
+ color[3] = 127; /* see-through dot */
+
+ immUnbindProgram();
+
+ /* -- draw rotation center -- */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+ glPointSize(5.0f);
+ immBegin(PRIM_POINTS, 1);
+ immAttrib4ubv(col, color);
+ immVertex3fv(pos, o);
+ immEnd();
+ immUnbindProgram();
+
+#if 0
+ /* find screen coordinates for rotation center, then draw pretty icon */
+ mul_m4_v3(rv3d->persinv, rot_center);
+ UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
+ /* ^^ just playing around, does not work */
+#endif
+
+ glDisable(GL_BLEND);
+ glDepthMask(GL_TRUE);
}
+#endif /* WITH_INPUT_NDOF */
+
+/* ******************** info ***************** */
/**
- * Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects
- *
- * \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set.
- * \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here.
- */
-static void view3d_draw_objects(
- const bContext *C,
- Scene *scene, View3D *v3d, ARegion *ar,
- const char **grid_unit,
- const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
+* Render and camera border
+*/
+static void view3d_draw_border(const bContext *C, ARegion *ar)
{
+ Scene *scene = CTX_data_scene(C);
RegionView3D *rv3d = ar->regiondata;
- Base *base;
- const bool do_camera_frame = !draw_offscreen;
- const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
- const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
- /* only draw grids after in solid modes, else it hovers over mesh wires */
- const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE) && fx;
- bool do_composite_xray = false;
- bool xrayclear = true;
-
- if (!draw_offscreen) {
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
- }
-
- if (rv3d->rflag & RV3D_CLIPPING)
- view3d_draw_clipping(rv3d);
+ View3D *v3d = CTX_wm_view3d(C);
- /* set zbuffer after we draw clipping region */
- if (v3d->drawtype > OB_WIRE) {
- v3d->zbuf = true;
+ if (rv3d->persp == RV3D_CAMOB) {
+ drawviewborder(scene, ar, v3d);
}
- else {
- v3d->zbuf = false;
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ drawrenderborder(ar, v3d);
}
+}
- /* special case (depth for wire color) */
- if (v3d->drawtype <= OB_WIRE) {
- if (scene->obedit && scene->obedit->type == OB_MESH) {
- Mesh *me = scene->obedit->data;
- if (me->drawflag & ME_DRAWEIGHT) {
- v3d->zbuf = true;
+/**
+* Grease Pencil
+*/
+static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
+{
+ /* TODO viewport */
+}
+
+
+/**
+* Viewport Name
+*/
+static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
+{
+ const char *name = NULL;
+
+ switch (rv3d->view) {
+ case RV3D_VIEW_FRONT:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
+ else name = IFACE_("Front Persp");
+ break;
+ case RV3D_VIEW_BACK:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
+ else name = IFACE_("Back Persp");
+ break;
+ case RV3D_VIEW_TOP:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
+ else name = IFACE_("Top Persp");
+ break;
+ case RV3D_VIEW_BOTTOM:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
+ else name = IFACE_("Bottom Persp");
+ break;
+ case RV3D_VIEW_RIGHT:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
+ else name = IFACE_("Right Persp");
+ break;
+ case RV3D_VIEW_LEFT:
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
+ else name = IFACE_("Left Persp");
+ break;
+
+ default:
+ if (rv3d->persp == RV3D_CAMOB) {
+ if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
+ Camera *cam;
+ cam = v3d->camera->data;
+ if (cam->type == CAM_PERSP) {
+ name = IFACE_("Camera Persp");
+ }
+ else if (cam->type == CAM_ORTHO) {
+ name = IFACE_("Camera Ortho");
+ }
+ else {
+ BLI_assert(cam->type == CAM_PANO);
+ name = IFACE_("Camera Pano");
+ }
+ }
+ else {
+ name = IFACE_("Object as Camera");
+ }
+ }
+ else {
+ name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
}
- }
}
- if (v3d->zbuf) {
- glEnable(GL_DEPTH_TEST);
- }
+ return name;
+}
- /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
- * objects if done last */
- if (draw_grids) {
- /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
- rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit);
+static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ const char *name = view3d_get_name(v3d, rv3d);
+ /* increase size for unicode languages (Chinese in utf-8...) */
+#ifdef WITH_INTERNATIONAL
+ char tmpstr[96];
+#else
+ char tmpstr[32];
+#endif
- if (!draw_floor) {
- ED_region_pixelspace(ar);
- *grid_unit = NULL; /* drawgrid need this to detect/affect smallest valid unit... */
- drawgrid(&scene->unit, ar, v3d, grid_unit);
- /* XXX make function? replaces persp(1) */
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(rv3d->winmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(rv3d->viewmat);
- }
- else if (!draw_grids_after) {
- drawfloor(scene, v3d, grid_unit, true);
- }
+ if (v3d->localvd) {
+ BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
+ name = tmpstr;
}
- /* important to do before clipping */
- if (do_bgpic) {
- view3d_draw_bgpic_test(scene, ar, v3d, false, do_camera_frame);
- }
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
+#else
+ BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
+#endif
+}
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
+/**
+ * draw info beside axes in bottom left-corner:
+ * framenum, object name, bone name (if available), marker name (if available)
+ */
- /* draw set first */
- if (scene->set) {
- const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET;
- Scene *sce_iter;
- for (SETLOOPER(scene->set, sce_iter, base)) {
- if (v3d->lay & base->lay) {
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(scene, ar, v3d, base, dflag);
-
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(scene, ar, v3d, base, dflag, TH_UNDEFINED);
- }
- }
- }
+static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
+{
+ const int cfra = CFRA;
+ const char *msg_pin = " (Pinned)";
+ const char *msg_sep = " : ";
- /* Transp and X-ray afterdraw stuff for sets is done later */
- }
+ const int font_id = BLF_default();
+ char info[300];
+ char *s = info;
+ short offset = 1.5f * UI_UNIT_X + rect->xmin;
- if (draw_offscreen) {
- for (base = scene->base.first; base; base = base->next) {
- if (v3d->lay & base->lay) {
- /* dupli drawing */
- if (base->object->transflag & OB_DUPLI)
- draw_dupli_objects(scene, ar, v3d, base);
+ s += sprintf(s, "(%d)", cfra);
- draw_object(scene, ar, v3d, base, 0);
- }
- }
- }
- else {
- unsigned int lay_used = 0;
+ /*
+ * info can contain:
+ * - a frame (7 + 2)
+ * - 3 object names (MAX_NAME)
+ * - 2 BREAD_CRUMB_SEPARATORs (6)
+ * - a SHAPE_KEY_PINNED marker and a trailing '\0' (9+1) - translated, so give some room!
+ * - a marker name (MAX_NAME + 3)
+ */
- /* then draw not selected and the duplis, but skip editmode object */
- for (base = scene->base.first; base; base = base->next) {
- lay_used |= base->lay;
+ /* get name of marker on current frame (if available) */
+ const char *markern = BKE_scene_find_marker_name(scene, cfra);
- if (v3d->lay & base->lay) {
+ /* check if there is an object */
+ if (ob) {
+ *s++ = ' ';
+ s += BLI_strcpy_rlen(s, ob->id.name + 2);
- /* dupli drawing */
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects(scene, ar, v3d, base);
+ /* name(s) to display depends on type of object */
+ if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
+
+ /* show name of active bone too (if possible) */
+ if (arm->edbo) {
+ if (arm->act_edbone) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_edbone->name);
}
- if ((base->flag & SELECT) == 0) {
- if (base->object != scene->obedit)
- draw_object(scene, ar, v3d, base, 0);
+ }
+ else if (ob->mode & OB_MODE_POSE) {
+ if (arm->act_bone) {
+
+ if (arm->act_bone->layer & arm->layer) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_bone->name);
+ }
}
}
}
+ else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
+ /* try to display active bone and active shapekey too (if they exist) */
- /* mask out localview */
- v3d->lay_used = lay_used & ((1 << 20) - 1);
+ if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
+ Object *armobj = BKE_object_pose_armature_get(ob);
+ if (armobj && armobj->mode & OB_MODE_POSE) {
+ bArmature *arm = armobj->data;
+ if (arm->act_bone) {
+ if (arm->act_bone->layer & arm->layer) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_bone->name);
+ }
+ }
+ }
+ }
- /* draw selected and editmode */
- for (base = scene->base.first; base; base = base->next) {
- if (v3d->lay & base->lay) {
- if (base->object == scene->obedit || (base->flag & SELECT)) {
- draw_object(scene, ar, v3d, base, 0);
+ Key *key = BKE_key_from_object(ob);
+ if (key) {
+ KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
+ if (kb) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, kb->name);
+ if (ob->shapeflag & OB_SHAPE_LOCK) {
+ s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
+ }
}
}
}
- }
- /* perspective floor goes last to use scene depth and avoid writing to depth buffer */
- if (draw_grids_after) {
- drawfloor(scene, v3d, grid_unit, false);
+ /* color depends on whether there is a keyframe */
+ if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL))
+ UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
+ else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra))
+ UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
+ else
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+ }
+ else {
+ /* no object */
+ if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra))
+ UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
+ else
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
}
- /* must be before xray draw which clears the depth buffer */
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL;
-
- /* must be before xray draw which clears the depth buffer */
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- ED_gpencil_draw_view3d(wm, scene, v3d, ar, true);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ if (markern) {
+ s += sprintf(s, " <%s>", markern);
}
- /* transp and X-ray afterdraw stuff */
- if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
+ if (U.uiflag & USER_SHOW_ROTVIEWICON)
+ offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
+
+ BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
+}
- /* always do that here to cleanup depth buffers if none needed */
- if (fx) {
- do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
- GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
- }
+/* ******************** view loop ***************** */
- if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, &xrayclear);
- if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, xrayclear);
+/**
+* Information drawn on top of the solid plates and composed data
+*/
+void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
- if (fx && do_composite_xray) {
- GPU_fx_compositor_XRay_resolve(fx);
- }
+ /* correct projection matrix */
+ ED_region_pixelspace(ar);
- if (!draw_offscreen) {
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
- }
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ rcti rect;
+ ED_region_visible_rect(ar, &rect);
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_disable();
+ /* Leave room for previously drawn info. */
+ rect.ymax -= offset;
- /* important to do after clipping */
- if (do_bgpic) {
- view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
+ view3d_draw_border(C, ar);
+ view3d_draw_grease_pencil(C);
+
+ if (U.uiflag & USER_SHOW_ROTVIEWICON) {
+ draw_view_axis(rv3d, &rect);
}
- if (!draw_offscreen) {
- BIF_draw_manipulator(C);
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
+ ED_scene_draw_fps(scene, &rect);
+ }
+ else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
+ draw_viewport_name(ar, v3d, &rect);
}
- /* cleanup */
- if (v3d->zbuf) {
- v3d->zbuf = false;
- glDisable(GL_DEPTH_TEST);
+ if (U.uiflag & USER_DRAWVIEWINFO) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
+ draw_selected_name(scene, ob, &rect);
}
+#if 0 /* TODO */
+ if (grid_unit) { /* draw below the viewport name */
+ char numstr[32] = "";
- if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
- GPU_free_images_old();
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ if (v3d->grid != 1.0f) {
+ BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
+ }
+
+ BLF_draw_default_ascii(rect.xmin + U.widget_unit,
+ rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
+ numstr[0] ? numstr : grid_unit, sizeof(numstr));
}
+#endif
}
-static void view3d_main_region_setup_view(
- Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
+static void view3d_draw_view(const bContext *C, ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
+ ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL);
- ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat, rect);
-
- /* set for opengl */
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(rv3d->winmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(rv3d->viewmat);
+ /* Only 100% compliant on new spec goes bellow */
+ DRW_draw_view(C);
}
-/**
- * Store values from #RegionView3D, set when drawing.
- * This is needed when we draw with to a viewport using a different matrix (offscreen drawing for example).
- *
- * Values set by #ED_view3d_update_viewmat should be handled here.
- */
-struct RV3DMatrixStore {
- float winmat[4][4];
- float viewmat[4][4];
- float viewinv[4][4];
- float persmat[4][4];
- float persinv[4][4];
- float viewcamtexcofac[4];
- float pixsize;
-};
-
-struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
+void view3d_main_region_draw(const bContext *C, ARegion *ar)
{
- struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
- copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
- copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
- copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
- copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
- copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
- copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac);
- rv3dmat->pixsize = rv3d->pixsize;
- return (void *)rv3dmat;
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
+ /* XXX: In the future we should get RE from Layers/Depsgraph */
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+
+ /* Provisory Blender Internal drawing */
+ if (type->flag & RE_USE_LEGACY_PIPELINE) {
+ view3d_main_region_draw_legacy(C, ar);
+ return;
+ }
+
+ if (!rv3d->viewport) {
+ rv3d->viewport = GPU_viewport_create();
+ }
+
+ GPU_viewport_bind(rv3d->viewport, &ar->winrct);
+ view3d_draw_view(C, ar);
+ GPU_viewport_unbind(rv3d->viewport);
+
+ v3d->flag |= V3D_INVALID_BACKBUF;
}
-void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat)
+
+/* -------------------------------------------------------------------- */
+
+/** \name Offscreen Drawing
+ * \{ */
+
+static void view3d_stereo3d_setup_offscreen(
+ Scene *scene, View3D *v3d, ARegion *ar,
+ float winmat[4][4], const char *viewname)
{
- copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
- copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
- copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
- copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
- copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
- copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac);
- rv3d->pixsize = rv3dmat->pixsize;
+ /* update the viewport matrices with the new camera */
+ if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+ float viewmat[4][4];
+ const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
+
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
+ }
+ else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ float viewmat[4][4];
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+
+ BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
+ }
}
-void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
+void ED_view3d_draw_offscreen_init(Scene *scene, SceneLayer *sl, View3D *v3d)
{
- /* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
- gpu_update_lamps_shadows_world(scene, v3d);
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ if (type->flag & RE_USE_LEGACY_PIPELINE) {
+ /* shadow buffers, before we setup matrices */
+ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) {
+ VP_deprecated_gpu_update_lamps_shadows_world(scene, v3d);
+ }
+ }
}
/*
@@ -3070,79 +1929,13 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
*/
static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
- if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
- RegionView3D *rv3d = ar->regiondata;
- GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
-
- /* calculate full shader for background */
- GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
-
- bool material_not_bound = !GPU_material_bound(gpumat);
-
- if (material_not_bound) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- }
-
- /* Draw world */
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_ALWAYS);
- glBegin(GL_TRIANGLE_STRIP);
- glVertex3f(-1.0, -1.0, 1.0);
- glVertex3f(1.0, -1.0, 1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glVertex3f(1.0, 1.0, 1.0);
- glEnd();
-
- if (material_not_bound) {
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
+ glClear(GL_DEPTH_BUFFER_BIT);
- GPU_material_unbind(gpumat);
-
- glDepthFunc(GL_LEQUAL);
- glDisable(GL_DEPTH_TEST);
+ if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
+ VP_view3d_draw_background_world(scene, v3d, ar->regiondata);
}
else {
- if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_ALWAYS);
- glBegin(GL_QUADS);
- UI_ThemeColor(TH_LOW_GRAD);
- glVertex3f(-1.0, -1.0, 1.0);
- glVertex3f(1.0, -1.0, 1.0);
- UI_ThemeColor(TH_HIGH_GRAD);
- glVertex3f(1.0, 1.0, 1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glEnd();
- glDepthFunc(GL_LEQUAL);
- glDisable(GL_DEPTH_TEST);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
- else {
- UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
+ VP_view3d_draw_background_none();
}
}
@@ -3156,18 +1949,13 @@ void ED_view3d_draw_offscreen(
GPUFX *fx, GPUFXSettings *fx_settings,
GPUOffScreen *ofs)
{
- struct bThemeState theme_state;
- int bwinx, bwiny;
- rcti brect;
bool do_compositing = false;
RegionView3D *rv3d = ar->regiondata;
- glPushMatrix();
-
/* set temporary new size */
- bwinx = ar->winx;
- bwiny = ar->winy;
- brect = ar->winrct;
+ int bwinx = ar->winx;
+ int bwiny = ar->winy;
+ rcti brect = ar->winrct;
ar->winx = winx;
ar->winy = winy;
@@ -3176,6 +1964,7 @@ void ED_view3d_draw_offscreen(
ar->winrct.xmax = winx;
ar->winrct.ymax = winy;
+ struct bThemeState theme_state;
UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
@@ -3188,26 +1977,10 @@ void ED_view3d_draw_offscreen(
GPU_free_images_anim();
}
- /* setup view matrices before fx or unbinding the offscreen buffers will cause issues */
- if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
- view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname);
- else
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
-
- /* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag && fx) {
- GPUSSAOSettings *ssao = NULL;
-
- if (v3d->drawtype < OB_SOLID) {
- ssao = v3d->fx_settings.ssao;
- v3d->fx_settings.ssao = NULL;
- }
-
- do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
-
- if (ssao)
- v3d->fx_settings.ssao = ssao;
- }
+ gpuPushProjectionMatrix();
+ gpuLoadIdentity();
+ gpuPushMatrix();
+ gpuLoadIdentity();
/* clear opengl buffers */
if (do_sky) {
@@ -3218,28 +1991,55 @@ void ED_view3d_draw_offscreen(
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
+ if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
+ view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname);
+ else
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
+
/* main drawing call */
- view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ if (type->flag & RE_USE_LEGACY_PIPELINE) {
- /* post process */
- if (do_compositing) {
- if (!winmat)
- is_persp = rv3d->is_persp;
- GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs);
- }
+ /* framebuffer fx needed, we need to draw offscreen first */
+ if (v3d->fx_settings.fx_flag && fx) {
+ GPUSSAOSettings *ssao = NULL;
- if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
- /* draw grease-pencil stuff */
- ED_region_pixelspace(ar);
+ if (v3d->drawtype < OB_SOLID) {
+ ssao = v3d->fx_settings.ssao;
+ v3d->fx_settings.ssao = NULL;
+ }
+ do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- ED_gpencil_draw_view3d(NULL, scene, v3d, ar, false);
+ if (ssao)
+ v3d->fx_settings.ssao = ssao;
}
- /* freeing the images again here could be done after the operator runs, leaving for now */
- GPU_free_images_anim();
+ VP_deprecated_view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+
+ /* post process */
+ if (do_compositing) {
+ if (!winmat)
+ is_persp = rv3d->is_persp;
+ GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs);
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ /* draw grease-pencil stuff */
+ ED_region_pixelspace(ar);
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ ED_gpencil_draw_view3d(NULL, scene, v3d, ar, false);
+ }
+
+ /* freeing the images again here could be done after the operator runs, leaving for now */
+ GPU_free_images_anim();
+ }
+ }
+ else {
+ /* XXX, should take depsgraph as arg */
+ DRW_draw_render_loop_offscreen(scene->depsgraph, ar, v3d, ofs);
}
/* restore size */
@@ -3247,7 +2047,8 @@ void ED_view3d_draw_offscreen(
ar->winy = bwiny;
ar->winrct = brect;
- glPopMatrix();
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
UI_Theme_Restore(&theme_state);
@@ -3255,37 +2056,19 @@ void ED_view3d_draw_offscreen(
}
/**
- * Set the correct matrices
- */
-void ED_view3d_draw_setup_view(
- wmWindow *win, Scene *scene, ARegion *ar, View3D *v3d, float viewmat[4][4], float winmat[4][4], const rcti *rect)
-{
- RegionView3D *rv3d = ar->regiondata;
-
- /* Setup the view matrix. */
- if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
- view3d_stereo3d_setup(scene, v3d, ar, rect);
- }
- else {
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, rect);
- }
-}
-
-/**
* Utility func for ED_view3d_draw_offscreen
*
* \param ofs: Optional off-screen buffer, can be NULL.
* (avoids re-creating when doing multiple GL renders).
*/
ImBuf *ED_view3d_draw_offscreen_imbuf(
- Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey,
+ Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey,
unsigned int flag, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
/* output vars */
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
- ImBuf *ibuf;
const bool draw_sky = (alpha_mode == R_ADDSKY);
/* view state */
@@ -3308,12 +2091,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
}
}
- ED_view3d_draw_offscreen_init(scene, v3d);
+ ED_view3d_draw_offscreen_init(scene, sl, v3d);
GPU_offscreen_bind(ofs, true);
/* read in pixels & stamp */
- ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
+ ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
@@ -3369,8 +2152,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
/* use imbuf as temp storage, before writing into it from accumulation buffer */
unsigned char *rect_temp = ibuf->rect ? (void *)ibuf->rect : (void *)ibuf->rect_float;
unsigned int *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(int[4]), "accum1");
- unsigned int i;
- int j;
BLI_jitter_init(jit_ofs, samples);
@@ -3381,13 +2162,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
fx, &fx_settings, ofs);
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp);
- i = sizex * sizey * 4;
+ unsigned i = sizex * sizey * 4;
while (i--) {
accum_buffer[i] = rect_temp[i];
}
/* skip the first sample */
- for (j = 1; j < samples; j++) {
+ for (int j = 1; j < samples; j++) {
copy_m4_m4(winmat_jitter, winmat);
window_translate_m4(
winmat_jitter, rv3d->persmat,
@@ -3446,7 +2227,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
* \note used by the sequencer
*/
ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
- Scene *scene, Object *camera, int width, int height,
+ Scene *scene, SceneLayer *sl, Object *camera, int width, int height,
unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
@@ -3464,13 +2245,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
v3d.lay = scene->lay;
v3d.drawtype = drawtype;
v3d.flag2 = V3D_RENDER_OVERRIDE;
-
+
if (use_gpencil)
v3d.flag2 |= V3D_SHOW_GPENCIL;
if (use_solid_tex)
v3d.flag2 |= V3D_SOLID_TEX;
-
+
if (draw_background)
v3d.flag3 |= V3D_SHOW_WORLD;
@@ -3500,665 +2281,103 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(
- scene, &v3d, &ar, width, height, flag,
+ scene, sl, &v3d, &ar, width, height, flag,
draw_background, alpha_mode, samples, full_samples, viewname,
fx, ofs, err_out);
}
+/** \} */
-/**
- * \note The info that this uses is updated in #ED_refresh_viewport_fps,
- * which currently gets called during #SCREEN_OT_animation_step.
- */
-void ED_scene_draw_fps(Scene *scene, const rcti *rect)
-{
- ScreenFrameRateInfo *fpsi = scene->fps_info;
- float fps;
- char printable[16];
- int i, tot;
-
- if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime)
- return;
-
- printable[0] = '\0';
-
-#if 0
- /* this is too simple, better do an average */
- fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
-#else
- fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
-
- for (i = 0, tot = 0, fps = 0.0f; i < REDRAW_FRAME_AVERAGE; i++) {
- if (fpsi->redrawtimes_fps[i]) {
- fps += fpsi->redrawtimes_fps[i];
- tot++;
- }
- }
- if (tot) {
- fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
-
- //fpsi->redrawtime_index++;
- //if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE)
- // fpsi->redrawtime = 0;
-
- fps = fps / tot;
- }
-#endif
-
- /* is this more than half a frame behind? */
- if (fps + 0.5f < (float)(FPS)) {
- UI_ThemeColor(TH_REDALERT);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
- }
- else {
- UI_ThemeColor(TH_TEXT_HI);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
- }
-
-#ifdef WITH_INTERNATIONAL
- BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
-#else
- BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
-#endif
-}
-static bool view3d_main_region_do_render_draw(Scene *scene)
-{
- RenderEngineType *type = RE_engines_find(scene->r.engine);
+/* -------------------------------------------------------------------- */
- return (type && type->view_update && type->view_draw);
-}
+/** \name Legacy Interface
+ *
+ * This will be removed once the viewport gets replaced
+ * meanwhile it should keep the old viewport working.
+ *
+ * \{ */
-bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *rect)
+void VP_legacy_drawcursor(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
{
- RegionView3D *rv3d = ar->regiondata;
- rctf viewborder;
- bool use_border;
-
- /* test if there is a 3d view rendering */
- if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
- return false;
-
- /* test if there is a border render */
- if (rv3d->persp == RV3D_CAMOB)
- use_border = (scene->r.mode & R_BORDER) != 0;
- else
- use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
-
- if (!use_border)
- return false;
-
- /* compute border */
- if (rv3d->persp == RV3D_CAMOB) {
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
-
- rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
- rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
- rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
- rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
- }
- else {
- rect->xmin = v3d->render_border.xmin * ar->winx;
- rect->xmax = v3d->render_border.xmax * ar->winx;
- rect->ymin = v3d->render_border.ymin * ar->winy;
- rect->ymax = v3d->render_border.ymax * ar->winy;
+ if (is_cursor_visible(scene, sl)) {
+ drawcursor(scene, ar, v3d);
}
-
- BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
- BLI_rcti_isect(&ar->winrct, rect, rect);
-
- return true;
}
-static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
- ARegion *ar, View3D *v3d,
- bool clip_border, const rcti *border_rect)
+void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
- RenderEngineType *type;
- GLint scissor[4];
-
- /* create render engine */
- if (!rv3d->render_engine) {
- RenderEngine *engine;
-
- type = RE_engines_find(scene->r.engine);
-
- if (!(type->view_update && type->view_draw))
- return false;
-
- engine = RE_engine_create_ex(type, true);
-
- engine->tile_x = scene->r.tilex;
- engine->tile_y = scene->r.tiley;
-
- type->view_update(engine, C);
-
- rv3d->render_engine = engine;
- }
-
- /* setup view matrices */
- view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL, NULL);
-
- /* background draw */
- ED_region_pixelspace(ar);
-
- if (clip_border) {
- /* for border draw, we only need to clear a subset of the 3d view */
- if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
- glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(border_rect->xmin, border_rect->ymin,
- BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
- }
- else {
- return false;
- }
- }
-
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if (v3d->flag & V3D_DISPBGPICS)
- view3d_draw_bgpic_test(scene, ar, v3d, false, true);
- else
- fdrawcheckerboard(0, 0, ar->winx, ar->winy);
-
- /* render result draw */
- type = rv3d->render_engine->type;
- type->view_draw(rv3d->render_engine, C);
-
- if (v3d->flag & V3D_DISPBGPICS)
- view3d_draw_bgpic_test(scene, ar, v3d, true, true);
-
- if (clip_border) {
- /* restore scissor as it was before */
- glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
- }
-
- return true;
+ draw_view_axis(rv3d, rect);
}
-static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border)
+void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
{
- float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
-
- if (!rv3d->render_engine || !rv3d->render_engine->text[0])
- return;
-
- if (render_border) {
- /* draw darkened background color. no alpha because border render does
- * partial redraw and will not redraw the region behind this info bar */
- float alpha = 1.0f - fill_color[3];
- Camera *camera = ED_view3d_camera_data_get(v3d, rv3d);
-
- if (camera) {
- if (camera->flag & CAM_SHOWPASSEPARTOUT) {
- alpha *= (1.0f - camera->passepartalpha);
- }
- }
-
- UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
- mul_v3_fl(fill_color, alpha);
- fill_color[3] = 1.0f;
- }
-
- ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
+ draw_viewport_name(ar, v3d, rect);
}
-static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
+void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect)
{
- if ((scene->r.scemode & R_MULTIVIEW) == 0) {
- return false;
- }
-
- if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
- return false;
- }
-
- switch (v3d->stereo3d_camera) {
- case STEREO_MONO_ID:
- return false;
- break;
- case STEREO_3D_ID:
- /* win will be NULL when calling this from the selection or draw loop. */
- if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
- return false;
- }
- if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
- !BKE_scene_multiview_is_stereo3d(&scene->r))
- {
- return false;
- }
- break;
- /* We always need the stereo calculation for left and right cameras. */
- case STEREO_LEFT_ID:
- case STEREO_RIGHT_ID:
- default:
- break;
- }
- return true;
+ draw_selected_name(scene, ob, rect);
}
-/* setup the view and win matrices for the multiview cameras
- *
- * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
- * we have no winmatrix (i.e., projection matrix) defined at that time.
- * Since the camera and the camera shift are needed for the winmat calculation
- * we do a small hack to replace it temporarily so we don't need to change the
- * view3d)main_region_setup_view() code to account for that.
- */
-static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
+void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
{
- bool is_left;
- const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
- const char *viewname;
-
- /* show only left or right camera */
- if (v3d->stereo3d_camera != STEREO_3D_ID)
- v3d->multiview_eye = v3d->stereo3d_camera;
-
- is_left = v3d->multiview_eye == STEREO_LEFT_ID;
- viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
-
- /* update the viewport matrices with the new camera */
- if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
- Camera *data;
- float viewmat[4][4];
- float shiftx;
-
- data = (Camera *)v3d->camera->data;
- shiftx = data->shiftx;
-
- BLI_lock_thread(LOCK_VIEW3D);
- data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
-
- BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
-
- data->shiftx = shiftx;
- BLI_unlock_thread(LOCK_VIEW3D);
- }
- else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
- float viewmat[4][4];
- Object *view_ob = v3d->camera;
- Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
-
- BLI_lock_thread(LOCK_VIEW3D);
- v3d->camera = camera;
-
- BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
-
- v3d->camera = view_ob;
- BLI_unlock_thread(LOCK_VIEW3D);
- }
+ drawgrid(unit, ar, v3d, grid_unit);
}
-static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- float winmat[4][4], const char *viewname)
+void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
{
- /* update the viewport matrices with the new camera */
- if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
- float viewmat[4][4];
- const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
-
- BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
- }
- else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
- float viewmat[4][4];
- Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
-
- BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
- }
+ drawfloor(scene, v3d, grid_unit, write_depth);
}
-#ifdef WITH_GAMEENGINE
-static void update_lods(Scene *scene, float camera_pos[3])
+void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
- Scene *sce_iter;
- Base *base;
- Object *ob;
-
- for (SETLOOPER(scene, sce_iter, base)) {
- ob = base->object;
- BKE_object_lod_update(ob, camera_pos);
- }
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
}
-#endif
-static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, View3D *v3d,
- ARegion *ar, const char **grid_unit)
+bool VP_legacy_view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- wmWindow *win = CTX_wm_window(C);
- RegionView3D *rv3d = ar->regiondata;
- unsigned int lay_used = v3d->lay_used;
-
- /* post processing */
- bool do_compositing = false;
-
- /* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
- gpu_update_lamps_shadows_world(scene, v3d);
-
- /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */
- if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
- rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
- GPU_default_lights();
- }
-
- /* Setup the view matrix. */
- ED_view3d_draw_setup_view(CTX_wm_window(C), scene, ar, v3d, NULL, NULL, NULL);
-
- rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
-#ifdef WITH_GAMEENGINE
- if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) {
- rv3d->rflag |= RV3D_IS_GAME_ENGINE;
-
- /* Make sure LoDs are up to date */
- update_lods(scene, rv3d->viewinv[3]);
- }
-#endif
-
- /* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
- GPUFXSettings fx_settings;
- BKE_screen_gpu_fx_validate(&v3d->fx_settings);
- fx_settings = v3d->fx_settings;
- if (!rv3d->compositor)
- rv3d->compositor = GPU_fx_compositor_create();
-
- if (rv3d->persp == RV3D_CAMOB && v3d->camera)
- BKE_camera_to_gpu_dof(v3d->camera, &fx_settings);
- else {
- fx_settings.dof = NULL;
- }
-
- do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
- }
-
- /* clear the background */
- view3d_main_region_clear(scene, v3d, ar);
-
- /* enables anti-aliasing for 3D view drawing */
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- glEnable(GL_MULTISAMPLE);
- }
-
- /* main drawing call */
- view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
-
- /* post process */
- if (do_compositing) {
- GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
- }
-
- /* Disable back anti-aliasing */
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- glDisable(GL_MULTISAMPLE);
- }
-
- if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
- /* find header and force tag redraw */
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
- ED_region_tag_redraw(ar_header); /* can be NULL */
- }
-
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- BDR_drawSketch(C);
- }
-
-#ifdef WITH_INPUT_NDOF
- if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((rv3d->viewlock & RV3D_LOCKED) == 0) && (rv3d->persp != RV3D_CAMOB))
- /* TODO: draw something else (but not this) during fly mode */
- draw_rotation_guide(rv3d);
-#endif
+ return view3d_stereo3d_active(CTX_wm_window(C), scene, v3d, rv3d);
}
-static bool is_cursor_visible(Scene *scene)
+void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
{
- Object *ob = OBACT;
-
- /* don't draw cursor in paint modes, but with a few exceptions */
- if (ob && ob->mode & OB_MODE_ALL_PAINT) {
- /* exception: object is in weight paint and has deforming armature in pose mode */
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
- if (BKE_object_pose_armature_get(ob) != NULL) {
- return true;
- }
- }
- /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
- else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- const Paint *p = BKE_paint_get_active(scene);
-
- if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
- if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
- return true;
- }
- }
- }
-
- /* no exception met? then don't draw cursor! */
- return false;
- }
-
- return true;
+ view3d_stereo3d_setup(scene, v3d, ar, NULL);
}
-static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
- ARegion *ar, View3D *v3d,
- const char *grid_unit, bool render_border)
+bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- RegionView3D *rv3d = ar->regiondata;
- rcti rect;
-
- /* local coordinate visible rect inside region, to accomodate overlapping ui */
- ED_region_visible_rect(ar, &rect);
-
- if (rv3d->persp == RV3D_CAMOB) {
- drawviewborder(scene, ar, v3d);
- }
- else if (v3d->flag2 & V3D_RENDER_BORDER) {
- glLineWidth(1.0f);
- setlinestyle(3);
- cpack(0x4040FF);
-
- sdrawbox(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
- v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
-
- setlinestyle(0);
- }
-
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- ED_gpencil_draw_view3d(wm, scene, v3d, ar, false);
- }
-
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- Object *ob;
-
- /* 3d cursor */
- if (is_cursor_visible(scene)) {
- drawcursor(scene, ar, v3d);
- }
-
- if (U.uiflag & USER_SHOW_ROTVIEWICON)
- draw_view_axis(rv3d, &rect);
- else
- draw_view_icon(rv3d, &rect);
-
- ob = OBACT;
- if (U.uiflag & USER_DRAWVIEWINFO)
- draw_selected_name(scene, ob, &rect);
- }
-
- if (rv3d->render_engine) {
- view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border);
- return;
- }
-
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
- ED_scene_draw_fps(scene, &rect);
- }
- else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
- draw_viewport_name(ar, v3d, &rect);
- }
-
- if (grid_unit) { /* draw below the viewport name */
- char numstr[32] = "";
-
- UI_ThemeColor(TH_TEXT_HI);
- if (v3d->grid != 1.0f) {
- BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
- }
-
- BLF_draw_default_ascii(rect.xmin + U.widget_unit,
- rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
- numstr[0] ? numstr : grid_unit, sizeof(numstr));
- }
- }
+ return use_depth_doit(scene, v3d);
}
-void view3d_main_region_draw(const bContext *C, ARegion *ar)
+void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- const char *grid_unit = NULL;
- rcti border_rect;
- bool render_border, clip_border;
-
- /* if we only redraw render border area, skip opengl draw and also
- * don't do scissor because it's already set */
- render_border = ED_view3d_calc_render_border(scene, v3d, ar, &border_rect);
- clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect));
-
- /* draw viewport using opengl */
- if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) {
- view3d_main_region_draw_objects(C, scene, v3d, ar, &grid_unit);
-
-#ifdef DEBUG_DRAW
- bl_debug_draw();
-#endif
- if (G.debug & G_DEBUG_SIMDATA)
- draw_sim_debug_data(scene, v3d, ar);
-
- ED_region_pixelspace(ar);
- }
-
- /* draw viewport using external renderer */
- if (v3d->drawtype == OB_RENDER)
- view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
-
- view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border);
-
- v3d->flag |= V3D_INVALID_BACKBUF;
-
- BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_transp));
- BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xray));
- BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xraytransp));
+ drawviewborder(scene, ar, v3d);
}
-#ifdef DEBUG_DRAW
-/* debug drawing */
-#define _DEBUG_DRAW_QUAD_TOT 1024
-#define _DEBUG_DRAW_EDGE_TOT 1024
-static float _bl_debug_draw_quads[_DEBUG_DRAW_QUAD_TOT][4][3];
-static int _bl_debug_draw_quads_tot = 0;
-static float _bl_debug_draw_edges[_DEBUG_DRAW_QUAD_TOT][2][3];
-static int _bl_debug_draw_edges_tot = 0;
-static unsigned int _bl_debug_draw_quads_color[_DEBUG_DRAW_QUAD_TOT];
-static unsigned int _bl_debug_draw_edges_color[_DEBUG_DRAW_EDGE_TOT];
-static unsigned int _bl_debug_draw_color;
-
-void bl_debug_draw_quad_clear(void)
-{
- _bl_debug_draw_quads_tot = 0;
- _bl_debug_draw_edges_tot = 0;
- _bl_debug_draw_color = 0x00FF0000;
-}
-void bl_debug_color_set(const unsigned int color)
+void VP_drawrenderborder(ARegion *ar, View3D *v3d)
{
- _bl_debug_draw_color = color;
+ drawrenderborder(ar, v3d);
}
-void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3])
+
+void VP_view3d_draw_background_none(void)
{
- if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) {
- printf("%s: max quad count hit %d!", __func__, _bl_debug_draw_quads_tot);
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ view3d_draw_background_gradient();
}
else {
- float *pt = &_bl_debug_draw_quads[_bl_debug_draw_quads_tot][0][0];
- copy_v3_v3(pt, v0); pt += 3;
- copy_v3_v3(pt, v1); pt += 3;
- copy_v3_v3(pt, v2); pt += 3;
- copy_v3_v3(pt, v3); pt += 3;
- _bl_debug_draw_quads_color[_bl_debug_draw_quads_tot] = _bl_debug_draw_color;
- _bl_debug_draw_quads_tot++;
+ view3d_draw_background_none();
}
}
-void bl_debug_draw_edge_add(const float v0[3], const float v1[3])
+
+void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_EDGE_TOT) {
- printf("%s: max edge count hit %d!", __func__, _bl_debug_draw_edges_tot);
- }
- else {
- float *pt = &_bl_debug_draw_edges[_bl_debug_draw_edges_tot][0][0];
- copy_v3_v3(pt, v0); pt += 3;
- copy_v3_v3(pt, v1); pt += 3;
- _bl_debug_draw_edges_color[_bl_debug_draw_edges_tot] = _bl_debug_draw_color;
- _bl_debug_draw_edges_tot++;
- }
+ view3d_draw_background_world(scene, v3d, rv3d);
}
-static void bl_debug_draw(void)
+
+void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
- unsigned int color;
- if (_bl_debug_draw_quads_tot) {
- int i;
- color = _bl_debug_draw_quads_color[0];
- cpack(color);
- for (i = 0; i < _bl_debug_draw_quads_tot; i ++) {
- if (_bl_debug_draw_quads_color[i] != color) {
- color = _bl_debug_draw_quads_color[i];
- cpack(color);
- }
- glBegin(GL_LINE_LOOP);
- glVertex3fv(_bl_debug_draw_quads[i][0]);
- glVertex3fv(_bl_debug_draw_quads[i][1]);
- glVertex3fv(_bl_debug_draw_quads[i][2]);
- glVertex3fv(_bl_debug_draw_quads[i][3]);
- glEnd();
- }
- }
- if (_bl_debug_draw_edges_tot) {
- int i;
- color = _bl_debug_draw_edges_color[0];
- cpack(color);
- glBegin(GL_LINES);
- for (i = 0; i < _bl_debug_draw_edges_tot; i ++) {
- if (_bl_debug_draw_edges_color[i] != color) {
- color = _bl_debug_draw_edges_color[i];
- cpack(color);
- }
- glVertex3fv(_bl_debug_draw_edges[i][0]);
- glVertex3fv(_bl_debug_draw_edges[i][1]);
- }
- glEnd();
- color = _bl_debug_draw_edges_color[0];
- cpack(color);
- glPointSize(4.0);
- glBegin(GL_POINTS);
- for (i = 0; i < _bl_debug_draw_edges_tot; i ++) {
- if (_bl_debug_draw_edges_color[i] != color) {
- color = _bl_debug_draw_edges_color[i];
- cpack(color);
- }
- glVertex3fv(_bl_debug_draw_edges[i][0]);
- glVertex3fv(_bl_debug_draw_edges[i][1]);
- }
- glEnd();
- }
+ view3d_main_region_clear(scene, v3d, ar);
}
-#endif
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
new file mode 100644
index 00000000000..bc74475e8cc
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -0,0 +1,2161 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_draw_legacy.c
+ * \ingroup spview3d
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_customdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_group_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_key_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+#include "DNA_brush_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_jitter.h"
+#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
+#include "BLI_threads.h"
+
+#include "BKE_anim.h"
+#include "BKE_camera.h"
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_image.h"
+#include "BKE_key.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_global.h"
+#include "BKE_paint.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+#include "BKE_unit.h"
+#include "BKE_movieclip.h"
+
+#include "RE_engine.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
+
+#include "BIF_glutil.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BLF_api.h"
+#include "BLT_translation.h"
+
+#include "ED_armature.h"
+#include "ED_keyframing.h"
+#include "ED_gpencil.h"
+#include "ED_screen.h"
+#include "ED_space_api.h"
+#include "ED_screen_types.h"
+#include "ED_transform.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+
+#include "GPU_draw.h"
+#include "GPU_framebuffer.h"
+#include "GPU_lamp.h"
+#include "GPU_material.h"
+#include "GPU_compositing.h"
+#include "GPU_extensions.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_select.h"
+#include "GPU_matrix.h"
+
+#include "RE_engine.h"
+
+#include "DRW_engine.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* ********* custom clipping *********** */
+
+static void view3d_draw_clipping(RegionView3D *rv3d)
+{
+ BoundBox *bb = rv3d->clipbb;
+
+ if (bb) {
+ const unsigned int clipping_index[6][4] = {
+ {0, 1, 2, 3},
+ {0, 4, 5, 1},
+ {4, 7, 6, 5},
+ {7, 3, 2, 6},
+ {1, 5, 6, 2},
+ {7, 4, 0, 3}
+ };
+
+ /* fill in zero alpha for rendering & re-projection [#31530] */
+ unsigned char col[4];
+ UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
+ glColor4ubv(col);
+
+ glEnable(GL_BLEND);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, bb->vec);
+ glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisable(GL_BLEND);
+ }
+}
+
+void ED_view3d_clipping_set(RegionView3D *rv3d)
+{
+ double plane[4];
+ const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
+
+ for (unsigned a = 0; a < tot; a++) {
+ copy_v4db_v4fl(plane, rv3d->clip[a]);
+ glClipPlane(GL_CLIP_PLANE0 + a, plane);
+ glEnable(GL_CLIP_PLANE0 + a);
+ }
+}
+
+/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
+void ED_view3d_clipping_disable(void)
+{
+ for (unsigned a = 0; a < 6; a++) {
+ glDisable(GL_CLIP_PLANE0 + a);
+ }
+}
+void ED_view3d_clipping_enable(void)
+{
+ for (unsigned a = 0; a < 6; a++) {
+ glEnable(GL_CLIP_PLANE0 + a);
+ }
+}
+
+static bool view3d_clipping_test(const float co[3], const float clip[6][4])
+{
+ if (plane_point_side_v3(clip[0], co) > 0.0f)
+ if (plane_point_side_v3(clip[1], co) > 0.0f)
+ if (plane_point_side_v3(clip[2], co) > 0.0f)
+ if (plane_point_side_v3(clip[3], co) > 0.0f)
+ return false;
+
+ return true;
+}
+
+/* for 'local' ED_view3d_clipping_local must run first
+ * then all comparisons can be done in localspace */
+bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
+{
+ return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
+}
+
+/* ********* end custom clipping *********** */
+
+static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
+{
+ BIFIconID icon;
+
+ if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
+ icon = ICON_AXIS_TOP;
+ else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK))
+ icon = ICON_AXIS_FRONT;
+ else if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
+ icon = ICON_AXIS_SIDE;
+ else return;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
+
+ glDisable(GL_BLEND);
+}
+
+/* *********************** backdraw for selection *************** */
+
+static void backdrawview3d(Scene *scene, SceneLayer *sl, wmWindow *win, ARegion *ar, View3D *v3d)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ struct Base *base = sl->basact;
+ int multisample_enabled;
+
+ BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
+
+ if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
+ BKE_paint_select_face_test(base->object)))
+ {
+ /* do nothing */
+ }
+ /* texture paint mode sampling */
+ else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
+ (v3d->drawtype > OB_WIRE))
+ {
+ /* do nothing */
+ }
+ else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
+ V3D_IS_ZBUF(v3d))
+ {
+ /* do nothing */
+ }
+ else if (scene->obedit &&
+ V3D_IS_ZBUF(v3d))
+ {
+ /* do nothing */
+ }
+ else {
+ v3d->flag &= ~V3D_INVALID_BACKBUF;
+ return;
+ }
+
+ if (!(v3d->flag & V3D_INVALID_BACKBUF))
+ return;
+
+#if 0
+ if (test) {
+ if (qtest()) {
+ addafterqueue(ar->win, BACKBUFDRAW, 1);
+ return;
+ }
+ }
+#endif
+
+ if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
+
+ /* dithering and AA break color coding, so disable */
+ glDisable(GL_DITHER);
+
+ multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
+ if (multisample_enabled)
+ glDisable(GL_MULTISAMPLE);
+
+ if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ /* for multisample we use an offscreen FBO. multisample drawing can fail
+ * with color coded selection drawing, and reading back depths from such
+ * a buffer can also cause a few seconds freeze on OS X / NVidia. */
+ int w = BLI_rcti_size_x(&ar->winrct);
+ int h = BLI_rcti_size_y(&ar->winrct);
+ char error[256];
+
+ if (rv3d->gpuoffscreen) {
+ if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
+ GPU_offscreen_height(rv3d->gpuoffscreen) != h)
+ {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ rv3d->gpuoffscreen = NULL;
+ }
+ }
+
+ if (!rv3d->gpuoffscreen) {
+ rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, error);
+
+ if (!rv3d->gpuoffscreen)
+ fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
+ }
+ }
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_bind(rv3d->gpuoffscreen, true);
+ else
+ glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ else {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ ED_view3d_clipping_set(rv3d);
+
+ G.f |= G_BACKBUFSEL;
+
+ if (base && ((base->flag & BASE_VISIBLED) != 0))
+ draw_object_backbufsel(scene, v3d, rv3d, base->object);
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
+ else
+ ar->swap = 0; /* mark invalid backbuf for wm draw */
+
+ v3d->flag &= ~V3D_INVALID_BACKBUF;
+
+ G.f &= ~G_BACKBUFSEL;
+ v3d->zbuf = false;
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_DITHER);
+ if (multisample_enabled)
+ glEnable(GL_MULTISAMPLE);
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ ED_view3d_clipping_disable();
+}
+
+void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_bind(rv3d->gpuoffscreen, true);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glReadPixels(x, y, w, h, format, type, data);
+ GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
+ }
+ else {
+ glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
+ }
+}
+
+/* XXX depth reading exception, for code not using gpu offscreen */
+static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+{
+ glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
+}
+
+void ED_view3d_backbuf_validate(ViewContext *vc)
+{
+ if (vc->v3d->flag & V3D_INVALID_BACKBUF)
+ backdrawview3d(vc->scene, vc->scene_layer, vc->win, vc->ar, vc->v3d);
+}
+
+/**
+ * allow for small values [0.5 - 2.5],
+ * and large values, FLT_MAX by clamping by the area size
+ */
+int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
+{
+ return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
+}
+
+/* samples a single pixel (copied from vpaint) */
+unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y)
+{
+ if (x >= vc->ar->winx || y >= vc->ar->winy) {
+ return 0;
+ }
+
+ ED_view3d_backbuf_validate(vc);
+
+ unsigned int col;
+ view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
+ glReadBuffer(GL_BACK);
+
+ if (ENDIAN_ORDER == B_ENDIAN) {
+ BLI_endian_switch_uint32(&col);
+ }
+
+ return GPU_select_to_index(col);
+}
+
+/* reads full rect, converts indices */
+ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
+{
+ /* clip */
+ const rcti clip = {
+ max_ii(xmin, 0), min_ii(xmax, vc->ar->winx - 1),
+ max_ii(ymin, 0), min_ii(ymax, vc->ar->winy - 1)};
+ const int size_clip[2] = {
+ BLI_rcti_size_x(&clip) + 1,
+ BLI_rcti_size_y(&clip) + 1};
+
+ if (UNLIKELY((clip.xmin > clip.xmax) ||
+ (clip.ymin > clip.ymax)))
+ {
+ return NULL;
+ }
+
+ ImBuf *ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect);
+
+ ED_view3d_backbuf_validate(vc);
+
+ view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect);
+
+ glReadBuffer(GL_BACK);
+
+ if (ENDIAN_ORDER == B_ENDIAN) {
+ IMB_convert_rgba_to_abgr(ibuf_clip);
+ }
+
+ GPU_select_to_index_array(ibuf_clip->rect, size_clip[0] * size_clip[1]);
+
+ if ((clip.xmin == xmin) &&
+ (clip.xmax == xmax) &&
+ (clip.ymin == ymin) &&
+ (clip.ymax == ymax))
+ {
+ return ibuf_clip;
+ }
+ else {
+ /* put clipped result into a non-clipped buffer */
+ const int size[2] = {
+ (xmax - xmin + 1),
+ (ymax - ymin + 1)};
+
+ ImBuf *ibuf_full = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
+
+ IMB_rectcpy(
+ ibuf_full, ibuf_clip,
+ clip.xmin - xmin, clip.ymin - ymin,
+ 0, 0,
+ size_clip[0], size_clip[1]);
+ IMB_freeImBuf(ibuf_clip);
+ return ibuf_full;
+ }
+}
+
+/* smart function to sample a rect spiralling outside, nice for backbuf selection */
+unsigned int ED_view3d_backbuf_sample_rect(
+ ViewContext *vc, const int mval[2], int size,
+ unsigned int min, unsigned int max, float *r_dist)
+{
+ int dirvec[4][2];
+
+ const int amount = (size - 1) / 2;
+
+ const int minx = mval[0] - (amount + 1);
+ const int miny = mval[1] - (amount + 1);
+ ImBuf *buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1);
+ if (!buf) return 0;
+
+ unsigned index = 0;
+ int rc = 0;
+
+ dirvec[0][0] = 1; dirvec[0][1] = 0;
+ dirvec[1][0] = 0; dirvec[1][1] = -size;
+ dirvec[2][0] = -1; dirvec[2][1] = 0;
+ dirvec[3][0] = 0; dirvec[3][1] = size;
+
+ const unsigned *bufmin = buf->rect;
+ const unsigned *tbuf = buf->rect;
+ const unsigned *bufmax = buf->rect + size * size;
+ tbuf += amount * size + amount;
+
+ for (int nr = 1; nr <= size; nr++) {
+ for (int a = 0; a < 2; a++) {
+ for (int b = 0; b < nr; b++) {
+ if (*tbuf && *tbuf >= min && *tbuf < max) {
+ /* we got a hit */
+
+ /* get x,y pixel coords from the offset
+ * (manhatten distance in keeping with other screen-based selection) */
+ *r_dist = (float)(
+ abs(((int)(tbuf - buf->rect) % size) - (size / 2)) +
+ abs(((int)(tbuf - buf->rect) / size) - (size / 2)));
+
+ /* indices start at 1 here */
+ index = (*tbuf - min) + 1;
+ goto exit;
+ }
+
+ tbuf += (dirvec[rc][0] + dirvec[rc][1]);
+
+ if (tbuf < bufmin || tbuf >= bufmax) {
+ goto exit;
+ }
+ }
+ rc++;
+ rc &= 3;
+ }
+ }
+
+exit:
+ IMB_freeImBuf(buf);
+ return index;
+}
+
+
+/* ************************************************************* */
+
+static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
+{
+ if (BKE_image_is_stereo(ima)) {
+ iuser->flag |= IMA_SHOW_STEREO;
+
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ iuser->multiview_eye = STEREO_LEFT_ID;
+ }
+ else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ /* show only left or right camera */
+ iuser->multiview_eye = v3d->stereo3d_camera;
+ }
+
+ BKE_image_multiview_index(ima, iuser);
+ }
+ else {
+ iuser->flag &= ~IMA_SHOW_STEREO;
+ }
+}
+
+static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
+ const bool do_foreground, const bool do_camera_frame)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ int fg_flag = do_foreground ? V3D_BGPIC_FOREGROUND : 0;
+
+ for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
+ bgpic->iuser.scene = scene; /* Needed for render results. */
+
+ if ((bgpic->flag & V3D_BGPIC_FOREGROUND) != fg_flag)
+ continue;
+
+ if ((bgpic->view == 0) || /* zero for any */
+ (bgpic->view & (1 << rv3d->view)) || /* check agaist flags */
+ (rv3d->persp == RV3D_CAMOB && bgpic->view == (1 << RV3D_VIEW_CAMERA)))
+ {
+ float image_aspect[2];
+ float x1, y1, x2, y2, centx, centy;
+
+ void *lock;
+
+ Image *ima = NULL;
+
+ /* disable individual images */
+ if ((bgpic->flag & V3D_BGPIC_DISABLED))
+ continue;
+
+ ImBuf *ibuf = NULL;
+ ImBuf *freeibuf = NULL;
+ ImBuf *releaseibuf = NULL;
+ if (bgpic->source == V3D_BGPIC_IMAGE) {
+ ima = bgpic->ima;
+ if (ima == NULL)
+ continue;
+ BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0);
+ if (ima->source == IMA_SRC_SEQUENCE && !(bgpic->iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
+ ibuf = NULL; /* frame is out of range, dont show */
+ }
+ else {
+ view3d_stereo_bgpic_setup(scene, v3d, ima, &bgpic->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
+ releaseibuf = ibuf;
+ }
+
+ image_aspect[0] = ima->aspx;
+ image_aspect[1] = ima->aspy;
+ }
+ else if (bgpic->source == V3D_BGPIC_MOVIE) {
+ /* TODO: skip drawing when out of frame range (as image sequences do above) */
+ MovieClip *clip = NULL;
+
+ if (bgpic->flag & V3D_BGPIC_CAMERACLIP) {
+ if (scene->camera)
+ clip = BKE_object_movieclip_get(scene, scene->camera, true);
+ }
+ else {
+ clip = bgpic->clip;
+ }
+
+ if (clip == NULL)
+ continue;
+
+ BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA);
+ ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
+
+ image_aspect[0] = clip->aspx;
+ image_aspect[1] = clip->aspy;
+
+ /* working with ibuf from image and clip has got different workflow now.
+ * ibuf acquired from clip is referenced by cache system and should
+ * be dereferenced after usage. */
+ freeibuf = ibuf;
+ }
+ else {
+ /* perhaps when loading future files... */
+ BLI_assert(0);
+ copy_v2_fl(image_aspect, 1.0f);
+ }
+
+ if (ibuf == NULL)
+ continue;
+
+ if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
+ if (freeibuf)
+ IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+
+ continue;
+ }
+
+ if (ibuf->rect == NULL)
+ IMB_rect_from_float(ibuf);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+
+ if (do_camera_frame) {
+ rctf vb;
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
+ x1 = vb.xmin;
+ y1 = vb.ymin;
+ x2 = vb.xmax;
+ y2 = vb.ymax;
+ }
+ else {
+ x1 = ar->winrct.xmin;
+ y1 = ar->winrct.ymin;
+ x2 = ar->winrct.xmax;
+ y2 = ar->winrct.ymax;
+ }
+
+ /* apply offset last - camera offset is different to offset in blender units */
+ /* so this has some sane way of working - this matches camera's shift _exactly_ */
+ {
+ const float max_dim = max_ff(x2 - x1, y2 - y1);
+ const float xof_scale = bgpic->xof * max_dim;
+ const float yof_scale = bgpic->yof * max_dim;
+
+ x1 += xof_scale;
+ y1 += yof_scale;
+ x2 += xof_scale;
+ y2 += yof_scale;
+ }
+
+ centx = (x1 + x2) * 0.5f;
+ centy = (y1 + y2) * 0.5f;
+
+ /* aspect correction */
+ if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) {
+ /* apply aspect from clip */
+ const float w_src = ibuf->x * image_aspect[0];
+ const float h_src = ibuf->y * image_aspect[1];
+
+ /* destination aspect is already applied from the camera frame */
+ const float w_dst = x1 - x2;
+ const float h_dst = y1 - y2;
+
+ const float asp_src = w_src / h_src;
+ const float asp_dst = w_dst / h_dst;
+
+ if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
+ if ((asp_src > asp_dst) == ((bgpic->flag & V3D_BGPIC_CAMERA_CROP) != 0)) {
+ /* fit X */
+ const float div = asp_src / asp_dst;
+ x1 = ((x1 - centx) * div) + centx;
+ x2 = ((x2 - centx) * div) + centx;
+ }
+ else {
+ /* fit Y */
+ const float div = asp_dst / asp_src;
+ y1 = ((y1 - centy) * div) + centy;
+ y2 = ((y2 - centy) * div) + centy;
+ }
+ }
+ }
+ }
+ else {
+ float tvec[3];
+ float sco[2];
+ const float mval_f[2] = {1.0f, 0.0f};
+ const float co_zero[3] = {0};
+
+ /* calc window coord */
+ float zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, tvec, zfac);
+ float fac = 1.0f / max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */
+ float asp = (float)ibuf->y / (float)ibuf->x;
+
+ zero_v3(tvec);
+ ED_view3d_project_float_v2_m4(ar, tvec, sco, rv3d->persmat);
+
+ x1 = sco[0] + fac * (bgpic->xof - bgpic->size);
+ y1 = sco[1] + asp * fac * (bgpic->yof - bgpic->size);
+ x2 = sco[0] + fac * (bgpic->xof + bgpic->size);
+ y2 = sco[1] + asp * fac * (bgpic->yof + bgpic->size);
+
+ centx = (x1 + x2) / 2.0f;
+ centy = (y1 + y2) / 2.0f;
+ }
+
+ /* complete clip? */
+ rctf clip_rect;
+ BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
+ if (bgpic->rotation) {
+ BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
+ }
+
+ if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
+ if (freeibuf)
+ IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+
+ continue;
+ }
+
+ float zoomx = (x2 - x1) / ibuf->x;
+ float zoomy = (y2 - y1) / ibuf->y;
+
+ /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
+ if (zoomx < 1.0f || zoomy < 1.0f) {
+ float tzoom = min_ff(zoomx, zoomy);
+ int mip = 0;
+
+ if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
+ IMB_remakemipmap(ibuf, 0);
+ ibuf->userflags &= ~IB_MIPMAP_INVALID;
+ }
+ else if (ibuf->mipmap[0] == NULL)
+ IMB_makemipmap(ibuf, 0);
+
+ while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
+ tzoom *= 2.0f;
+ zoomx *= 2.0f;
+ zoomy *= 2.0f;
+ mip++;
+ }
+ if (mip > 0)
+ ibuf = ibuf->mipmap[mip - 1];
+ }
+
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ gpuPushProjectionMatrix();
+ gpuPushMatrix();
+ ED_region_pixelspace(ar);
+
+ gpuTranslate2f(centx, centy);
+ gpuRotate2D(RAD2DEGF(-bgpic->rotation));
+
+ if (bgpic->flag & V3D_BGPIC_FLIP_X) {
+ zoomx *= -1.0f;
+ x1 = x2;
+ }
+ if (bgpic->flag & V3D_BGPIC_FLIP_Y) {
+ zoomy *= -1.0f;
+ y1 = y2;
+ }
+
+ float col[4] = {1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend};
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect,
+ zoomx, zoomy, col);
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(GL_TRUE);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ if (freeibuf)
+ IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+ }
+ }
+}
+
+static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d,
+ const bool do_foreground, const bool do_camera_frame)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if ((v3d->flag & V3D_DISPBGPICS) == 0)
+ return;
+
+ /* disabled - mango request, since footage /w only render is quite useful
+ * and this option is easy to disable all background images at once */
+#if 0
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE)
+ return;
+#endif
+
+ if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+ }
+ }
+ else {
+ view3d_draw_bgpic(scene, ar, v3d, do_foreground, do_camera_frame);
+ }
+}
+
+/* ****************** View3d afterdraw *************** */
+
+typedef struct View3DAfter {
+ struct View3DAfter *next, *prev;
+ struct BaseLegacy *base;
+ short dflag;
+} View3DAfter;
+
+/* temp storage of Objects that need to be drawn as last */
+void ED_view3d_after_add(ListBase *lb, BaseLegacy *base, const short dflag)
+{
+ View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
+ BLI_assert((base->flag_legacy & OB_FROMDUPLI) == 0);
+ BLI_addtail(lb, v3da);
+ v3da->base = base;
+ v3da->dflag = dflag;
+}
+
+/* disables write in zbuffer and draws it over */
+static void view3d_draw_transp(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
+{
+ View3DAfter *v3da;
+
+ glDepthMask(GL_FALSE);
+ v3d->transp = true;
+
+ while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
+ draw_object(scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ MEM_freeN(v3da);
+ }
+ v3d->transp = false;
+
+ glDepthMask(GL_TRUE);
+
+}
+
+/* clears zbuffer and draws it over */
+static void view3d_draw_xray(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
+{
+ if (*clear && v3d->zbuf) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ *clear = false;
+ }
+
+ v3d->xray = true;
+ View3DAfter *v3da;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
+ draw_object(scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ MEM_freeN(v3da);
+ }
+ v3d->xray = false;
+}
+
+
+/* clears zbuffer and draws it over */
+static void view3d_draw_xraytransp(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, const bool clear)
+{
+ if (clear && v3d->zbuf)
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ v3d->xray = true;
+ v3d->transp = true;
+
+ glDepthMask(GL_FALSE);
+
+ View3DAfter *v3da;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
+ draw_object(scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ MEM_freeN(v3da);
+ }
+
+ v3d->transp = false;
+ v3d->xray = false;
+
+ glDepthMask(GL_TRUE);
+}
+
+/* clears zbuffer and draws it over,
+ * note that in the select version we don't care about transparent flag as with regular drawing */
+static void view3d_draw_xray_select(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
+{
+ /* Not ideal, but we need to read from the previous depths before clearing
+ * otherwise we could have a function to load the depths after drawing.
+ *
+ * Clearing the depth buffer isn't all that common between drawing objects so accept this for now.
+ */
+ if (U.gpu_select_pick_deph) {
+ GPU_select_load_id(-1);
+ }
+
+ View3DAfter *v3da;
+ if (*clear && v3d->zbuf) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ *clear = false;
+ }
+
+ v3d->xray = true;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
+ if (GPU_select_load_id(v3da->base->selcol)) {
+ draw_object_select(scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ }
+ MEM_freeN(v3da);
+ }
+ v3d->xray = false;
+}
+
+/* *********************** */
+
+/*
+ * In most cases call draw_dupli_objects,
+ * draw_dupli_objects_color was added because when drawing set dupli's
+ * we need to force the color
+ */
+
+#if 0
+int dupli_ob_sort(void *arg1, void *arg2)
+{
+ void *p1 = ((DupliObject *)arg1)->ob;
+ void *p2 = ((DupliObject *)arg2)->ob;
+ int val = 0;
+ if (p1 < p2) val = -1;
+ else if (p1 > p2) val = 1;
+ return val;
+}
+#endif
+
+
+static DupliObject *dupli_step(DupliObject *dob)
+{
+ while (dob && dob->no_draw)
+ dob = dob->next;
+ return dob;
+}
+
+static void draw_dupli_objects_color(
+ Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base,
+ const short dflag, const int color)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ ListBase *lb;
+ LodLevel *savedlod;
+ Base tbase = {NULL};
+ BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
+ unsigned char color_rgb[3];
+ const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
+ short transflag;
+ char dt;
+ short dtx;
+ DupliApplyData *apply_data;
+
+ if ((base->flag & BASE_VISIBLED) == 0) return;
+ if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
+
+ if (dflag & DRAW_CONSTCOLOR) {
+ BLI_assert(color == TH_UNDEFINED);
+ }
+ else {
+ UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
+ }
+
+ tbase.flag_legacy = OB_FROMDUPLI | base->flag_legacy;
+ tbase.flag = base->flag;
+ lb = object_duplilist(G.main->eval_ctx, scene, base->object);
+ // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
+
+ apply_data = duplilist_apply(base->object, scene, lb);
+
+ DupliObject *dob_next = NULL;
+ DupliObject *dob = dupli_step(lb->first);
+ if (dob) dob_next = dupli_step(dob->next);
+
+ for (; dob; dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
+ bool testbb = false;
+
+ tbase.object = dob->ob;
+
+ /* Make sure lod is updated from dupli's position */
+ savedlod = dob->ob->currentlod;
+
+#ifdef WITH_GAMEENGINE
+ if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
+ BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
+ }
+#endif
+
+ /* extra service: draw the duplicator in drawtype of parent, minimum taken
+ * to allow e.g. boundbox box objects in groups for LOD */
+ dt = tbase.object->dt;
+ tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
+
+ /* inherit draw extra, but not if a boundbox under the assumption that this
+ * is intended to speed up drawing, and drawing extra (especially wire) can
+ * slow it down too much */
+ dtx = tbase.object->dtx;
+ if (tbase.object->dt != OB_BOUNDBOX)
+ tbase.object->dtx = base->object->dtx;
+
+ /* negative scale flag has to propagate */
+ transflag = tbase.object->transflag;
+
+ if (is_negative_m4(dob->mat))
+ tbase.object->transflag |= OB_NEG_SCALE;
+ else
+ tbase.object->transflag &= ~OB_NEG_SCALE;
+
+ /* should move outside the loop but possible color is set in draw_object still */
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ glColor3ubv(color_rgb);
+ }
+
+ if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
+ bb = *bb_tmp; /* must make a copy */
+ testbb = true;
+ }
+
+ if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ GPU_begin_dupli_object(dob);
+ draw_object(scene, sl, ar, v3d, &tbase, dflag_dupli);
+ GPU_end_dupli_object();
+ }
+
+ tbase.object->dt = dt;
+ tbase.object->dtx = dtx;
+ tbase.object->transflag = transflag;
+ tbase.object->currentlod = savedlod;
+ }
+
+ if (apply_data) {
+ duplilist_restore(lb, apply_data);
+ duplilist_free_apply_data(apply_data);
+ }
+
+ free_object_duplilist(lb);
+}
+
+void draw_dupli_objects(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base)
+{
+ /* define the color here so draw_dupli_objects_color can be called
+ * from the set loop */
+
+ int color = (base->flag & BASE_SELECTED) ? TH_SELECT : TH_WIRE;
+ /* debug */
+ if (base->object->dup_group && base->object->dup_group->id.us < 1)
+ color = TH_REDALERT;
+
+ draw_dupli_objects_color(scene, sl, ar, v3d, base, 0, color);
+}
+
+/* XXX warning, not using gpu offscreen here */
+void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
+{
+ /* clamp rect by region */
+ rcti r = {
+ .xmin = 0,
+ .xmax = ar->winx - 1,
+ .ymin = 0,
+ .ymax = ar->winy - 1
+ };
+
+ /* Constrain rect to depth bounds */
+ BLI_rcti_isect(&r, rect, rect);
+
+ /* assign values to compare with the ViewDepths */
+ int x = rect->xmin;
+ int y = rect->ymin;
+
+ int w = BLI_rcti_size_x(rect);
+ int h = BLI_rcti_size_y(rect);
+
+ if (w <= 0 || h <= 0) {
+ if (d->depths)
+ MEM_freeN(d->depths);
+ d->depths = NULL;
+
+ d->damaged = false;
+ }
+ else if (d->w != w ||
+ d->h != h ||
+ d->x != x ||
+ d->y != y ||
+ d->depths == NULL
+ )
+ {
+ d->x = x;
+ d->y = y;
+ d->w = w;
+ d->h = h;
+
+ if (d->depths)
+ MEM_freeN(d->depths);
+
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
+
+ d->damaged = true;
+ }
+
+ if (d->damaged) {
+ /* XXX using special function here, it doesn't use the gpu offscreen system */
+ view3d_opengl_read_Z_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
+ glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+ d->damaged = false;
+ }
+}
+
+/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
+void ED_view3d_depth_update(ARegion *ar)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* Create storage for, and, if necessary, copy depth buffer */
+ if (!rv3d->depths) rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
+ if (rv3d->depths) {
+ ViewDepths *d = rv3d->depths;
+ if (d->w != ar->winx ||
+ d->h != ar->winy ||
+ !d->depths)
+ {
+ d->w = ar->winx;
+ d->h = ar->winy;
+ if (d->depths)
+ MEM_freeN(d->depths);
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
+ d->damaged = true;
+ }
+
+ if (d->damaged) {
+ view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
+ glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+
+ d->damaged = false;
+ }
+ }
+}
+
+/* utility function to find the closest Z value, use for autodepth */
+float view3d_depth_near(ViewDepths *d)
+{
+ /* convert to float for comparisons */
+ const float near = (float)d->depth_range[0];
+ const float far_real = (float)d->depth_range[1];
+ float far = far_real;
+
+ const float *depths = d->depths;
+ float depth = FLT_MAX;
+ int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
+
+ /* far is both the starting 'far' value
+ * and the closest value found. */
+ while (i--) {
+ depth = *depths++;
+ if ((depth < far) && (depth > near)) {
+ far = depth;
+ }
+ }
+
+ return far == far_real ? FLT_MAX : far;
+}
+
+void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
+{
+ bool zbuf = v3d->zbuf;
+
+ /* Setup view matrix. */
+ ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, NULL);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ v3d->zbuf = true;
+ glEnable(GL_DEPTH_TEST);
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ ED_gpencil_draw_view3d(NULL, scene, v3d, ar, true);
+ }
+
+ v3d->zbuf = zbuf;
+ if (!zbuf) glDisable(GL_DEPTH_TEST);
+}
+
+void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d)
+{
+ Base *base;
+ SceneLayer *sl = BKE_scene_layer_context_active(scene);
+ /* no need for color when drawing depth buffer */
+ const short dflag_depth = DRAW_CONSTCOLOR;
+
+ /* draw set first */
+ if (scene->set) {
+ Scene *sce_iter;
+ for (SETLOOPER(scene->set, sce_iter, base)) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ draw_object(scene, sl, ar, v3d, base, 0);
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ }
+ }
+ }
+ }
+
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ }
+ draw_object(scene, sl, ar, v3d, base, dflag_depth);
+ }
+ }
+
+ /* this isn't that nice, draw xray objects as if they are normal */
+ if (v3d->afterdraw_transp.first ||
+ v3d->afterdraw_xray.first ||
+ v3d->afterdraw_xraytransp.first)
+ {
+ View3DAfter *v3da;
+ int mask_orig;
+
+ v3d->xray = true;
+
+ /* transp materials can change the depth mask, see #21388 */
+ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+
+
+ if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) {
+ glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
+ for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) {
+ draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth);
+ }
+ glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
+ }
+
+ /* draw 3 passes, transp/xray/xraytransp */
+ v3d->xray = false;
+ v3d->transp = true;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
+ draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth);
+ MEM_freeN(v3da);
+ }
+
+ v3d->xray = true;
+ v3d->transp = false;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
+ draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth);
+ MEM_freeN(v3da);
+ }
+
+ v3d->xray = true;
+ v3d->transp = true;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
+ draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth);
+ MEM_freeN(v3da);
+ }
+
+
+ v3d->xray = false;
+ v3d->transp = false;
+
+ glDepthMask(mask_orig);
+ }
+}
+
+void ED_view3d_draw_select_loop(
+ ViewContext *vc, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar,
+ bool use_obedit_skip, bool use_nearest)
+{
+ short code = 1;
+ const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR;
+
+ if (vc->obedit && vc->obedit->type == OB_MBALL) {
+ draw_object(scene, sl, ar, v3d, BASACT_NEW, dflag);
+ }
+ else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
+ /* if not drawing sketch, draw bones */
+ if (!BDR_drawSketchNames(vc)) {
+ draw_object(scene, sl, ar, v3d, BASACT_NEW, dflag);
+ }
+ }
+ else {
+ Base *base;
+
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ if (((base->flag & BASE_SELECTABLED) == 0) ||
+ (use_obedit_skip && (scene->obedit->data == base->object->data)))
+ {
+ base->selcol = 0;
+ }
+ else {
+ base->selcol = code;
+
+ if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) {
+ ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
+ }
+ else {
+ if (GPU_select_load_id(code)) {
+ draw_object(scene, sl, ar, v3d, base, dflag);
+ }
+ }
+ code++;
+ }
+ }
+ }
+
+ if (use_nearest) {
+ bool xrayclear = true;
+ if (v3d->afterdraw_xray.first) {
+ view3d_draw_xray_select(scene, sl, ar, v3d, &xrayclear);
+ }
+ }
+ }
+}
+
+typedef struct View3DShadow {
+ struct View3DShadow *next, *prev;
+ GPULamp *lamp;
+} View3DShadow;
+
+static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
+ Object *ob, Object *par,
+ float obmat[4][4], unsigned int lay,
+ ListBase *shadows, SceneRenderLayer *srl)
+{
+ GPULamp *lamp = GPU_lamp_from_blender(scene, ob, par);
+
+ if (lamp) {
+ Lamp *la = (Lamp *)ob->data;
+
+ GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
+ GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
+
+ unsigned int layers = lay & v3d->lay;
+ if (srl)
+ layers &= srl->lay;
+
+ if (layers &&
+ GPU_lamp_has_shadow_buffer(lamp) &&
+ /* keep last, may do string lookup */
+ GPU_lamp_override_visible(lamp, srl, NULL))
+ {
+ View3DShadow *shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
+ shadow->lamp = lamp;
+ BLI_addtail(shadows, shadow);
+ }
+ }
+}
+
+static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
+{
+ ListBase shadows;
+ Scene *sce_iter;
+ Base *base;
+ World *world = scene->world;
+ SceneRenderLayer *srl = v3d->scenelock ? BLI_findlink(&scene->r.layers, scene->r.actlay) : NULL;
+
+ BLI_listbase_clear(&shadows);
+
+ /* update lamp transform and gather shadow lamps */
+ for (SETLOOPER(scene, sce_iter, base)) {
+ Object *ob = base->object;
+
+ if (ob->type == OB_LAMP)
+ gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows, srl);
+
+ if (ob->transflag & OB_DUPLI) {
+ DupliObject *dob;
+ ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
+
+ for (dob = lb->first; dob; dob = dob->next)
+ if (dob->ob->type == OB_LAMP)
+ gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows, srl);
+
+ free_object_duplilist(lb);
+ }
+ }
+
+ /* render shadows after updating all lamps, nested object_duplilist
+ * don't work correct since it's replacing object matrices */
+ for (View3DShadow *shadow = shadows.first; shadow; shadow = shadow->next) {
+ /* this needs to be done better .. */
+ float viewmat[4][4], winmat[4][4];
+ ARegion ar = {NULL};
+ RegionView3D rv3d = {{{0}}};
+
+ int drawtype = v3d->drawtype;
+ int lay = v3d->lay;
+ int flag2 = v3d->flag2;
+
+ v3d->drawtype = OB_SOLID;
+ v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
+ v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
+ v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
+
+ int winsize;
+ GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
+
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+ rv3d.persp = RV3D_CAMOB;
+ copy_m4_m4(rv3d.winmat, winmat);
+ copy_m4_m4(rv3d.viewmat, viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize, winsize, viewmat, winmat,
+ false, false, true,
+ NULL, NULL, NULL, NULL);
+ GPU_lamp_shadow_buffer_unbind(shadow->lamp);
+
+ v3d->drawtype = drawtype;
+ v3d->lay = lay;
+ v3d->flag2 = flag2;
+ }
+
+ BLI_freelistN(&shadows);
+
+ /* update world values */
+ if (world) {
+ GPU_mist_update_enable(world->mode & WO_MIST);
+ GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr);
+ GPU_horizon_update_color(&world->horr);
+ GPU_ambient_update_color(&world->ambr);
+ GPU_zenith_update_color(&world->zenr);
+ }
+}
+
+/* *********************** customdata **************** */
+
+CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
+{
+ CustomDataMask mask = 0;
+ const int drawtype = view3d_effective_drawtype(v3d);
+
+ if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL) ||
+ ((drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX)))
+ {
+ mask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
+
+ if (BKE_scene_use_new_shading_nodes(scene)) {
+ if (drawtype == OB_MATERIAL)
+ mask |= CD_MASK_ORCO;
+ }
+ else {
+ if ((scene->gm.matmode == GAME_MAT_GLSL && drawtype == OB_TEXTURE) ||
+ (drawtype == OB_MATERIAL))
+ {
+ mask |= CD_MASK_ORCO;
+ }
+ }
+ }
+
+ return mask;
+}
+
+/* goes over all modes and view3d settings */
+CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
+{
+ const Scene *scene = screen->scene;
+ CustomDataMask mask = CD_MASK_BAREMESH;
+
+ /* check if we need tfaces & mcols due to view mode */
+ for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ mask |= ED_view3d_datamask(scene, sa->spacedata.first);
+ }
+ }
+
+ return mask;
+}
+
+/**
+ * Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects
+ *
+ * \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set.
+ * \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here.
+ */
+static void view3d_draw_objects(
+ const bContext *C,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
+{
+ SceneLayer *sl = C ? CTX_data_scene_layer(C) : BKE_scene_layer_render_active(scene);
+ RegionView3D *rv3d = ar->regiondata;
+ Base *base;
+ const bool do_camera_frame = !draw_offscreen;
+ const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
+ const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
+ /* only draw grids after in solid modes, else it hovers over mesh wires */
+ const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE) && fx;
+ bool do_composite_xray = false;
+ bool xrayclear = true;
+
+ if (!draw_offscreen) {
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ view3d_draw_clipping(rv3d);
+
+ /* set zbuffer after we draw clipping region */
+ v3d->zbuf = VP_legacy_use_depth(scene, v3d);
+
+ if (v3d->zbuf) {
+ glEnable(GL_DEPTH_TEST);
+ }
+
+ /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
+ * objects if done last */
+ if (draw_grids) {
+ /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
+ rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit);
+
+ if (!draw_floor) {
+ ED_region_pixelspace(ar);
+ *grid_unit = NULL; /* drawgrid need this to detect/affect smallest valid unit... */
+ VP_legacy_drawgrid(&scene->unit, ar, v3d, grid_unit);
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
+ }
+ else if (!draw_grids_after) {
+ VP_legacy_drawfloor(scene, v3d, grid_unit, true);
+ }
+ }
+
+ /* important to do before clipping */
+ if (do_bgpic) {
+ view3d_draw_bgpic_test(scene, ar, v3d, false, do_camera_frame);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
+
+ /* draw set first */
+ if (scene->set) {
+ const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET;
+ Scene *sce_iter;
+ for (SETLOOPER(scene->set, sce_iter, base)) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
+ draw_object(scene, sl, ar, v3d, base, dflag);
+
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(scene, sl, ar, v3d, base, dflag, TH_UNDEFINED);
+ }
+ }
+ }
+
+ /* Transp and X-ray afterdraw stuff for sets is done later */
+ }
+
+ if (draw_offscreen) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI)
+ draw_dupli_objects(scene, sl, ar, v3d, base);
+
+ draw_object(scene, sl, ar, v3d, base, 0);
+ }
+ }
+ }
+ else {
+ unsigned int lay_used = 0;
+
+ /* then draw not selected and the duplis, but skip editmode object */
+ for (base = sl->object_bases.first; base; base = base->next) {
+ lay_used |= base->lay;
+
+ if ((base->flag & BASE_VISIBLED) != 0) {
+
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(scene, sl, ar, v3d, base);
+ }
+ if ((base->flag & BASE_SELECTED) == 0) {
+ if (base->object != scene->obedit)
+ draw_object(scene, sl, ar, v3d, base, 0);
+ }
+ }
+ }
+
+ /* mask out localview */
+ v3d->lay_used = lay_used & ((1 << 20) - 1);
+
+ /* draw selected and editmode */
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) {
+ draw_object(scene, sl, ar, v3d, base, 0);
+ }
+ }
+ }
+ }
+
+ /* perspective floor goes last to use scene depth and avoid writing to depth buffer */
+ if (draw_grids_after) {
+ VP_legacy_drawfloor(scene, v3d, grid_unit, false);
+ }
+
+ /* must be before xray draw which clears the depth buffer */
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL;
+
+ /* must be before xray draw which clears the depth buffer */
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ ED_gpencil_draw_view3d(wm, scene, v3d, ar, true);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+
+ /* transp and X-ray afterdraw stuff */
+ if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, sl, ar, v3d);
+
+ /* always do that here to cleanup depth buffers if none needed */
+ if (fx) {
+ do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
+ GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
+ }
+
+ if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, sl, ar, v3d, &xrayclear);
+ if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, sl, ar, v3d, xrayclear);
+
+ if (fx && do_composite_xray) {
+ GPU_fx_compositor_XRay_resolve(fx);
+ }
+
+ if (!draw_offscreen) {
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ ED_view3d_clipping_disable();
+
+ /* important to do after clipping */
+ if (do_bgpic) {
+ view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
+ }
+
+ /* cleanup */
+ if (v3d->zbuf) {
+ v3d->zbuf = false;
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ GPU_free_images_old();
+ }
+}
+
+/**
+ * Store values from #RegionView3D, set when drawing.
+ * This is needed when we draw with to a viewport using a different matrix (offscreen drawing for example).
+ *
+ * Values set by #ED_view3d_update_viewmat should be handled here.
+ */
+struct RV3DMatrixStore {
+ float winmat[4][4];
+ float viewmat[4][4];
+ float viewinv[4][4];
+ float persmat[4][4];
+ float persinv[4][4];
+ float viewcamtexcofac[4];
+ float pixsize;
+};
+
+struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
+{
+ struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
+ copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
+ copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
+ copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
+ copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
+ copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
+ copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac);
+ rv3dmat->pixsize = rv3d->pixsize;
+ return (void *)rv3dmat;
+}
+
+void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt)
+{
+ struct RV3DMatrixStore *rv3dmat = rv3dmat_pt;
+ copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
+ copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
+ copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
+ copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
+ copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
+ copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac);
+ rv3d->pixsize = rv3dmat->pixsize;
+}
+
+/**
+ * \note The info that this uses is updated in #ED_refresh_viewport_fps,
+ * which currently gets called during #SCREEN_OT_animation_step.
+ */
+void ED_scene_draw_fps(Scene *scene, const rcti *rect)
+{
+ ScreenFrameRateInfo *fpsi = scene->fps_info;
+ char printable[16];
+
+ if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime)
+ return;
+
+ printable[0] = '\0';
+
+#if 0
+ /* this is too simple, better do an average */
+ fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
+#else
+ fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
+
+ float fps = 0.0f;
+ int tot = 0;
+ for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) {
+ if (fpsi->redrawtimes_fps[i]) {
+ fps += fpsi->redrawtimes_fps[i];
+ tot++;
+ }
+ }
+ if (tot) {
+ fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
+
+ //fpsi->redrawtime_index++;
+ //if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE)
+ // fpsi->redrawtime = 0;
+
+ fps = fps / tot;
+ }
+#endif
+
+ const int font_id = BLF_default();
+
+ /* is this more than half a frame behind? */
+ if (fps + 0.5f < (float)(FPS)) {
+ UI_FontThemeColor(font_id, TH_REDALERT);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
+ }
+ else {
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
+ }
+
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
+#else
+ BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
+#endif
+}
+
+static bool view3d_main_region_do_render_draw(Scene *scene)
+{
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+
+ return (type && type->view_update && type->render_to_view);
+}
+
+bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ bool use_border;
+
+ /* test if there is a 3d view rendering */
+ if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
+ return false;
+
+ /* test if there is a border render */
+ if (rv3d->persp == RV3D_CAMOB)
+ use_border = (scene->r.mode & R_BORDER) != 0;
+ else
+ use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
+
+ if (!use_border)
+ return false;
+
+ /* compute border */
+ if (rv3d->persp == RV3D_CAMOB) {
+ rctf viewborder;
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
+
+ rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
+ rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
+ rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
+ rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
+ }
+ else {
+ rect->xmin = v3d->render_border.xmin * ar->winx;
+ rect->xmax = v3d->render_border.xmax * ar->winx;
+ rect->ymin = v3d->render_border.ymin * ar->winy;
+ rect->ymax = v3d->render_border.ymax * ar->winy;
+ }
+
+ BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
+ BLI_rcti_isect(&ar->winrct, rect, rect);
+
+ return true;
+}
+
+/**
+ * IMPORTANT: this is deprecated, any changes made in this function should
+ * be mirrored in view3d_draw_render_draw() in view3d_draw.c
+ */
+static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ bool clip_border, const rcti *border_rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ RenderEngineType *type;
+ GLint scissor[4];
+
+ /* create render engine */
+ if (!rv3d->render_engine) {
+ RenderEngine *engine;
+
+ type = RE_engines_find(scene->r.engine);
+
+ if (!(type->view_update && type->render_to_view))
+ return false;
+
+ engine = RE_engine_create_ex(type, true);
+
+ engine->tile_x = scene->r.tilex;
+ engine->tile_y = scene->r.tiley;
+
+ type->view_update(engine, C);
+
+ rv3d->render_engine = engine;
+ }
+
+ /* setup view matrices */
+ VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
+
+ /* background draw */
+ ED_region_pixelspace(ar);
+
+ if (clip_border) {
+ /* for border draw, we only need to clear a subset of the 3d view */
+ if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
+ glScissor(border_rect->xmin, border_rect->ymin,
+ BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
+ }
+ else {
+ return false;
+ }
+ }
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (v3d->flag & V3D_DISPBGPICS)
+ view3d_draw_bgpic_test(scene, ar, v3d, false, true);
+ else
+ imm_draw_checker_box(0, 0, ar->winx, ar->winy);
+
+ /* render result draw */
+ type = rv3d->render_engine->type;
+ type->render_to_view(rv3d->render_engine, C);
+
+ if (v3d->flag & V3D_DISPBGPICS)
+ view3d_draw_bgpic_test(scene, ar, v3d, true, true);
+
+ if (clip_border) {
+ /* restore scissor as it was before */
+ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+ }
+
+ return true;
+}
+
+static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border)
+{
+ float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
+
+ if (!rv3d->render_engine || !rv3d->render_engine->text[0])
+ return;
+
+ if (render_border) {
+ /* draw darkened background color. no alpha because border render does
+ * partial redraw and will not redraw the region behind this info bar */
+ float alpha = 1.0f - fill_color[3];
+ Camera *camera = ED_view3d_camera_data_get(v3d, rv3d);
+
+ if (camera) {
+ if (camera->flag & CAM_SHOWPASSEPARTOUT) {
+ alpha *= (1.0f - camera->passepartalpha);
+ }
+ }
+
+ UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
+ mul_v3_fl(fill_color, alpha);
+ fill_color[3] = 1.0f;
+ }
+
+ ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
+}
+
+#ifdef WITH_GAMEENGINE
+static void update_lods(Scene *scene, float camera_pos[3])
+{
+ Scene *sce_iter;
+ Base *base;
+
+ for (SETLOOPER(scene, sce_iter, base)) {
+ Object *ob = base->object;
+ BKE_object_lod_update(ob, camera_pos);
+ }
+}
+#endif
+
+static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d,
+ ARegion *ar, const char **grid_unit)
+{
+ wmWindow *win = CTX_wm_window(C);
+ RegionView3D *rv3d = ar->regiondata;
+ unsigned int lay_used = v3d->lay_used;
+
+ /* post processing */
+ bool do_compositing = false;
+
+ /* shadow buffers, before we setup matrices */
+ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype))
+ gpu_update_lamps_shadows_world(scene, v3d);
+
+ /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */
+ if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
+ rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
+ GPU_default_lights();
+ }
+
+ /* setup the view matrix */
+ if (VP_legacy_view3d_stereo3d_active(C, scene, v3d, rv3d))
+ VP_legacy_view3d_stereo3d_setup(scene, v3d, ar);
+ else
+ VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
+
+ rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
+#ifdef WITH_GAMEENGINE
+ if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) {
+ rv3d->rflag |= RV3D_IS_GAME_ENGINE;
+
+ /* Make sure LoDs are up to date */
+ update_lods(scene, rv3d->viewinv[3]);
+ }
+#endif
+
+ /* framebuffer fx needed, we need to draw offscreen first */
+ if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
+ BKE_screen_gpu_fx_validate(&v3d->fx_settings);
+ GPUFXSettings fx_settings = v3d->fx_settings;
+ if (!rv3d->compositor)
+ rv3d->compositor = GPU_fx_compositor_create();
+
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera)
+ BKE_camera_to_gpu_dof(v3d->camera, &fx_settings);
+ else {
+ fx_settings.dof = NULL;
+ }
+
+ do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
+ }
+
+ /* enables anti-aliasing for 3D view drawing */
+ if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ glEnable(GL_MULTISAMPLE);
+ }
+
+ /* main drawing call */
+ view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
+
+ /* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
+ /* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
+ * later become _IN_SCENE (and draw _3D separate) */
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
+
+ /* post process */
+ if (do_compositing) {
+ GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
+ }
+
+ /* Disable back anti-aliasing */
+ if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ glDisable(GL_MULTISAMPLE);
+ }
+
+ if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
+ /* find header and force tag redraw */
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+ ED_region_tag_redraw(ar_header); /* can be NULL */
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ BDR_drawSketch(C);
+ }
+}
+
+static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ const char *grid_unit, bool render_border)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ RegionView3D *rv3d = ar->regiondata;
+ rcti rect;
+
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ ED_region_visible_rect(ar, &rect);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ VP_drawviewborder(scene, ar, v3d);
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ VP_drawrenderborder(ar, v3d);
+ }
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ ED_gpencil_draw_view3d(wm, scene, v3d, ar, false);
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ VP_legacy_drawcursor(scene, sl, ar, v3d); /* 3D cursor */
+
+ if (U.uiflag & USER_SHOW_ROTVIEWICON)
+ VP_legacy_draw_view_axis(rv3d, &rect);
+ else
+ draw_view_icon(rv3d, &rect);
+
+ if (U.uiflag & USER_DRAWVIEWINFO) {
+ Object *ob = OBACT_NEW;
+ VP_legacy_draw_selected_name(scene, ob, &rect);
+ }
+ }
+
+ if (rv3d->render_engine) {
+ view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border);
+ return;
+ }
+
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
+ ED_scene_draw_fps(scene, &rect);
+ }
+ else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
+ VP_legacy_draw_viewport_name(ar, v3d, &rect);
+ }
+
+ if (grid_unit) { /* draw below the viewport name */
+ char numstr[32] = "";
+
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ if (v3d->grid != 1.0f) {
+ BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
+ }
+
+ BLF_draw_default_ascii(rect.xmin + U.widget_unit,
+ rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
+ numstr[0] ? numstr : grid_unit, sizeof(numstr));
+ }
+ }
+}
+
+void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ const char *grid_unit = NULL;
+ rcti border_rect;
+
+ /* if we only redraw render border area, skip opengl draw and also
+ * don't do scissor because it's already set */
+ bool render_border = ED_view3d_calc_render_border(scene, v3d, ar, &border_rect);
+ bool clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect));
+
+ gpuPushProjectionMatrix();
+ gpuLoadIdentityProjectionMatrix();
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ /* draw viewport using opengl */
+ if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) {
+ VP_view3d_main_region_clear(scene, v3d, ar); /* background */
+ view3d_main_region_draw_objects(C, scene, sl, v3d, ar, &grid_unit);
+
+ if (G.debug & G_DEBUG_SIMDATA)
+ draw_sim_debug_data(scene, v3d, ar);
+
+ glDisable(GL_DEPTH_TEST);
+ ED_region_pixelspace(ar);
+ }
+
+ /* draw viewport using external renderer */
+ if (v3d->drawtype == OB_RENDER)
+ view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
+
+ VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
+
+ ED_region_pixelspace(ar);
+
+ view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border);
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
+
+ v3d->flag |= V3D_INVALID_BACKBUF;
+
+ BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_transp));
+ BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xray));
+ BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xraytransp));
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Deprecated Interface
+ *
+ * New viewport sometimes has a check for new/old viewport code.
+ * Use these functions so new viewport can *optionally* call.
+ *
+ * \{ */
+
+
+void VP_deprecated_view3d_draw_objects(
+ const bContext *C,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
+{
+ view3d_draw_objects(C, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen, fx);
+}
+
+void VP_deprecated_gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
+{
+ gpu_update_lamps_shadows_world(scene, v3d);
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 4e3f279e12e..adbdc1a6908 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -60,9 +60,7 @@
#include "BKE_action.h"
#include "BKE_depsgraph.h" /* for ED_view3d_camera_lock_sync */
-
#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -79,6 +77,8 @@
#include "ED_gpencil.h"
#include "ED_view3d.h"
+#include "DEG_depsgraph_query.h"
+
#include "UI_resources.h"
#include "PIL_time.h" /* smoothview */
@@ -621,7 +621,8 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
bool is_set = false;
Scene *scene = CTX_data_scene(C);
- Object *ob_act = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob_act = OBACT_NEW;
if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
@@ -658,14 +659,13 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
}
else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
/* object mode use boundbox centers */
- View3D *v3d = CTX_wm_view3d(C);
Base *base;
unsigned int tot = 0;
float select_center[3];
zero_v3(select_center);
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASE(v3d, base)) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if (TESTBASE_NEW(base)) {
/* use the boundbox if we can */
Object *ob = base->object;
@@ -736,6 +736,7 @@ static void viewops_data_create_ex(
/* we need the depth info before changing any viewport options */
if (orbit_mode & VIEWOPS_ORBIT_DEPTH) {
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
float fallback_depth_pt[3];
view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
@@ -743,7 +744,7 @@ static void viewops_data_create_ex(
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
vod->use_dyn_ofs = ED_view3d_autodist(
- vod->scene, vod->ar, vod->v3d,
+ graph, vod->ar, vod->v3d,
event->mval, vod->dyn_ofs, true, fallback_depth_pt);
}
else {
@@ -862,8 +863,9 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
static void viewops_data_free(bContext *C, wmOperator *op)
{
ARegion *ar;
+#if 0
Paint *p = BKE_paint_get_active_from_context(C);
-
+#endif
if (op->customdata) {
ViewOpsData *vod = op->customdata;
ar = vod->ar;
@@ -879,7 +881,9 @@ static void viewops_data_free(bContext *C, wmOperator *op)
ar = CTX_wm_region(C);
}
+#if 0
if (p && (p->flags & PAINT_FAST_NAVIGATE))
+#endif
ED_region_tag_redraw(ar);
}
/** \} */
@@ -2976,6 +2980,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base;
float *curs;
const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
@@ -2999,8 +3004,8 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in
INIT_MINMAX(min, max);
}
- for (base = scene->base.first; base; base = base->next) {
- if (BASE_VISIBLE(v3d, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (BASE_VISIBLE_NEW(base)) {
changed = true;
if (skip_camera && base->object == v3d->camera) {
@@ -3060,9 +3065,10 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
Object *obedit = CTX_data_edit_object(C);
float min[3], max[3];
bool ok = false, ok_dist = true;
@@ -3082,8 +3088,8 @@ static int viewselected_exec(bContext *C, wmOperator *op)
/* hard-coded exception, we look for the one selected armature */
/* this is weak code this way, we should make a generic active/selection callback interface once... */
Base *base;
- for (base = scene->base.first; base; base = base->next) {
- if (TESTBASELIB(v3d, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (TESTBASELIB_NEW(base)) {
if (base->object->type == OB_ARMATURE)
if (base->object->mode & OB_MODE_POSE)
break;
@@ -3116,7 +3122,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ok = paintface_minmax(ob, min, max);
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
- ok = PE_minmax(scene, min, max);
+ ok = PE_minmax(scene, sl, min, max);
}
else if (ob &&
(ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)))
@@ -3128,8 +3134,8 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
else {
Base *base;
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASE(v3d, base)) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if (TESTBASE_NEW(base)) {
if (skip_camera && base->object == v3d->camera) {
continue;
@@ -3306,10 +3312,10 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
if (rv3d) {
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
float new_ofs[3];
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
@@ -3317,7 +3323,7 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, event->mval, new_ofs, false, NULL)) {
+ if (ED_view3d_autodist(graph, ar, v3d, event->mval, new_ofs, false, NULL)) {
/* pass */
}
else {
@@ -3575,7 +3581,6 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
int gesture_mode;
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
@@ -3589,9 +3594,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
float new_ofs[3];
/* ZBuffer depth vars */
- bglMats mats;
float depth_close = FLT_MAX;
- double cent[2], p[3];
+ float p[3];
/* note; otherwise opengl won't work */
view3d_operator_needs_opengl(C);
@@ -3605,8 +3609,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
ED_view3d_dist_range_get(v3d, dist_range);
/* Get Z Depths, needed for perspective, nice for ortho */
- bgl_get_mats(&mats);
- ED_view3d_draw_depth(scene, ar, v3d, true);
+ ED_view3d_draw_depth(CTX_data_depsgraph(C), ar, v3d, true);
{
/* avoid allocating the whole depth buffer */
@@ -3621,11 +3624,11 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(depth_temp.depths);
}
- cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2;
- cent[1] = (((double)rect.ymin) + ((double)rect.ymax)) / 2;
+ float centx = (((float)rect.xmin) + ((float)rect.xmax)) / 2;
+ float centy = (((float)rect.ymin) + ((float)rect.ymax)) / 2;
if (rv3d->is_persp) {
- double p_corner[3];
+ float p_corner[3];
/* no depths to use, we cant do anything! */
if (depth_close == FLT_MAX) {
@@ -3633,23 +3636,14 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* convert border to 3d coordinates */
- if ((!gluUnProject(cent[0], cent[1], depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport,
- &p[0], &p[1], &p[2])) ||
- (!gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport,
- &p_corner[0], &p_corner[1], &p_corner[2])))
+ if ((!ED_view3d_unproject(ar, centx, centy, depth_close, p)) ||
+ (!ED_view3d_unproject(ar, rect.xmin, rect.ymin, depth_close, p_corner)))
{
return OPERATOR_CANCELLED;
}
- dvec[0] = p[0] - p_corner[0];
- dvec[1] = p[1] - p_corner[1];
- dvec[2] = p[2] - p_corner[2];
-
- new_ofs[0] = -p[0];
- new_ofs[1] = -p[1];
- new_ofs[2] = -p[2];
+ sub_v3_v3v3(dvec, p, p_corner);
+ negate_v3_v3(new_ofs, p);
new_dist = len_v3(dvec);
@@ -3664,13 +3658,9 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_dist = rv3d->dist;
/* convert the drawn rectangle into 3d space */
- if (depth_close != FLT_MAX && gluUnProject(cent[0], cent[1], depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport,
- &p[0], &p[1], &p[2]))
+ if (depth_close != FLT_MAX && ED_view3d_unproject(ar, centx, centy, depth_close, p))
{
- new_ofs[0] = -p[0];
- new_ofs[1] = -p[1];
- new_ofs[2] = -p[2];
+ negate_v3_v3(new_ofs, p);
}
else {
float mval_f[2];
@@ -3907,6 +3897,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
ARegion *ar;
RegionView3D *rv3d;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
static int perspo = RV3D_PERSP;
int viewnum, nextperspo;
bool align_active;
@@ -3941,7 +3932,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
/* lastview - */
if (rv3d->persp != RV3D_CAMOB) {
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
if (!rv3d->smooth_timer) {
/* store settings of current view before allowing overwriting with camera view
@@ -4635,9 +4626,8 @@ void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
static int view3d_clipping_exec(bContext *C, wmOperator *op)
{
+ ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- ViewContext vc;
- bglMats mats;
rcti rect;
WM_operator_properties_border_to_rcti(op, &rect);
@@ -4645,12 +4635,8 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op)
rv3d->rflag |= RV3D_CLIPPING;
rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
- /* note; otherwise opengl won't work */
- view3d_operator_needs_opengl(C);
-
- view3d_set_viewcontext(C, &vc);
- view3d_get_transformation(vc.ar, vc.rv3d, NULL, &mats); /* NULL because we don't want it in object space */
- ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, &mats, &rect);
+ /* NULL object because we don't want it in object space */
+ ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, ar, NULL, &rect);
return OPERATOR_FINISHED;
}
@@ -4702,7 +4688,6 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* note: cannot use event->mval here (called by object_add() */
void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
{
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = ar->regiondata;
@@ -4724,9 +4709,11 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
+ struct Depsgraph *graph = CTX_data_depsgraph(C);
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, mval, fp, true, NULL))
+ if (ED_view3d_autodist(graph, ar, v3d, mval, fp, true, NULL)) {
depth_used = true;
+ }
}
if (depth_used == false) {
@@ -4798,45 +4785,6 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* ***************** manipulator op ******************* */
-
-static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- View3D *v3d = CTX_wm_view3d(C);
-
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
- if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
-
- /* note; otherwise opengl won't work */
- view3d_operator_needs_opengl(C);
-
- if (BIF_do_manipulator(C, event, op) == 0)
- return OPERATOR_PASS_THROUGH;
-
- return OPERATOR_FINISHED;
-}
-
-void VIEW3D_OT_manipulator(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "3D Manipulator";
- ot->description = "Manipulate selected item by axis";
- ot->idname = "VIEW3D_OT_manipulator";
-
- /* api callbacks */
- ot->invoke = manipulator_invoke;
-
- ot->poll = ED_operator_view3d_active;
-
- /* properties to pass to transform */
- Transform_Properties(ot, P_CONSTRAINT);
-
- prop = RNA_def_boolean(ot->srna, "use_planar_constraint", false, "Planar Constraint", "Limit the transformation to the "
- "two axes that have not been clicked (translate/scale only)");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
-}
-
static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
@@ -4940,22 +4888,17 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
* \param fallback_depth_pt: Use this points depth when no depth can be found.
*/
bool ED_view3d_autodist(
- Scene *scene, ARegion *ar, View3D *v3d,
+ struct Depsgraph *graph, ARegion *ar, View3D *v3d,
const int mval[2], float mouse_worldloc[3],
const bool alphaoverride, const float fallback_depth_pt[3])
{
- bglMats mats; /* ZBuffer depth vars */
float depth_close;
- double cent[2], p[3];
int margin_arr[] = {0, 2, 4};
int i;
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(scene, ar, v3d, alphaoverride);
-
- /* call after in case settings have been modified since last drawing, see: T47089 */
- bgl_get_mats(&mats);
+ ED_view3d_draw_depth(graph, ar, v3d, alphaoverride);
/* Attempt with low margin's first */
i = 0;
@@ -4965,15 +4908,11 @@ bool ED_view3d_autodist(
} while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
if (depth_ok) {
- cent[0] = (double)mval[0] + 0.5;
- cent[1] = (double)mval[1] + 0.5;
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
- if (gluUnProject(cent[0], cent[1], depth_close,
- mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
+ if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc))
{
- mouse_worldloc[0] = (float)p[0];
- mouse_worldloc[1] = (float)p[1];
- mouse_worldloc[2] = (float)p[2];
return true;
}
}
@@ -4987,16 +4926,21 @@ bool ED_view3d_autodist(
}
}
-void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
+void ED_view3d_autodist_init(
+ struct Depsgraph *graph,
+ ARegion *ar, View3D *v3d, int mode)
{
/* Get Z Depths, needed for perspective, nice for ortho */
switch (mode) {
case 0:
- ED_view3d_draw_depth(scene, ar, v3d, true);
+ ED_view3d_draw_depth(graph, ar, v3d, true);
break;
case 1:
+ {
+ Scene *scene = DEG_get_scene(graph);
ED_view3d_draw_depth_gpencil(scene, ar, v3d);
break;
+ }
}
}
@@ -5004,9 +4948,7 @@ void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
int margin, float *force_depth)
{
- bglMats mats; /* ZBuffer depth vars, could cache? */
float depth;
- double cent[2], p[3];
/* Get Z Depths, needed for perspective, nice for ortho */
if (force_depth)
@@ -5017,21 +4959,9 @@ bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_world
if (depth == FLT_MAX)
return false;
- cent[0] = (double)mval[0] + 0.5;
- cent[1] = (double)mval[1] + 0.5;
-
- bgl_get_mats(&mats);
-
- if (!gluUnProject(cent[0], cent[1], depth,
- mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
- {
- return false;
- }
-
- mouse_worldloc[0] = (float)p[0];
- mouse_worldloc[1] = (float)p[1];
- mouse_worldloc[2] = (float)p[2];
- return true;
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+ return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
}
bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 04a6aa215f4..1a8ac374e75 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -56,6 +56,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "GPU_immediate.h"
+
#include "view3d_intern.h" /* own include */
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
@@ -257,36 +259,45 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
x2 = xoff + 0.55f * fly->width;
y2 = yoff + 0.55f * fly->height;
- UI_ThemeColor(TH_VIEW_OVERLAY);
- glBegin(GL_LINES);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+
+ immBegin(PRIM_LINES, 16);
+
/* bottom left */
- glVertex2f(x1, y1);
- glVertex2f(x1, y1 + 5);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y1 + 5);
- glVertex2f(x1, y1);
- glVertex2f(x1 + 5, y1);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1 + 5, y1);
/* top right */
- glVertex2f(x2, y2);
- glVertex2f(x2, y2 - 5);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2, y2 - 5);
- glVertex2f(x2, y2);
- glVertex2f(x2 - 5, y2);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2 - 5, y2);
/* top left */
- glVertex2f(x1, y2);
- glVertex2f(x1, y2 - 5);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x1, y2 - 5);
- glVertex2f(x1, y2);
- glVertex2f(x1 + 5, y2);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x1 + 5, y2);
/* bottom right */
- glVertex2f(x2, y1);
- glVertex2f(x2, y1 + 5);
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y1 + 5);
+
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2 - 5, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2 - 5, y1);
- glEnd();
+ immEnd();
+ immUnbindProgram();
}
static void fly_update_header(bContext *C, wmOperator *op, FlyInfo *fly)
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index bf1bdf68619..6d1393a2905 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -284,9 +284,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
PointerRNA v3dptr, toolsptr, sceneptr;
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
Object *obedit = CTX_data_edit_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
uiBlock *block;
@@ -334,9 +335,6 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiItemMenuEnumO(row, C, "OBJECT_OT_mode_set", "mode", name, icon);
}
- /* Draw type */
- uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
if (!ob || ELEM(ob->mode, OB_MODE_OBJECT, OB_MODE_POSE, OB_MODE_WEIGHT_PAINT)) {
@@ -371,11 +369,6 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
if (obedit == NULL && v3d->localvd == NULL) {
- unsigned int ob_lay = ob ? ob->lay : 0;
-
- /* Layers */
- uiTemplateLayers(layout, v3d->scenelock ? &sceneptr : &v3dptr, "layers", &v3dptr, "layers_used", ob_lay);
-
/* Scene lock */
uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 7a106a27833..99449a40a8c 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -38,6 +38,7 @@
struct ARegion;
struct ARegionType;
struct BoundBox;
+struct Batch;
struct DerivedMesh;
struct Object;
struct SmokeDomainSettings;
@@ -46,9 +47,11 @@ struct bContext;
struct bMotionPath;
struct bPoseChannel;
struct Mesh;
+struct SceneLayer;
struct wmOperatorType;
struct wmWindowManager;
struct wmKeyConfig;
+struct wmManipulatorGroupType;
/* drawing flags: */
enum {
@@ -99,7 +102,6 @@ void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
-void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
@@ -142,13 +144,25 @@ void draw_motion_paths_cleanup(View3D *v3d);
/* drawobject.c */
-void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, const short dflag);
-void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag);
+void draw_object(Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, BaseLegacy *base, const short dflag);
+void draw_object_select(Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, Base *base, const short dflag);
-bool draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const char dt);
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline);
+void draw_mesh_object_outline(View3D *v3d, Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
+
+bool draw_glsl_material(Scene *scene, struct SceneLayer *sl, struct Object *ob, View3D *v3d, const char dt);
+void draw_object_instance(Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
-void drawaxes(const float viewmat_local[4][4], float size, char drawtype);
+
+void draw_object_wire_color(Scene *scene, struct SceneLayer *, Base *base, unsigned char r_ob_wire_col[4]);
+void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]);
+void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4],
+ const bool is_obact);
+void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const short dflag, const unsigned char ob_wire_col[4]);
+void drawspeaker(const unsigned char ob_wire_col[3]);
+void draw_bounding_volume(struct Object *ob, char type, const unsigned char ob_wire_col[4]);
+void draw_rigidbody_shape(struct Object *ob, const unsigned char ob_wire_col[4]);
void view3d_cached_text_draw_begin(void);
void view3d_cached_text_draw_add(const float co[3],
@@ -169,12 +183,12 @@ enum {
int view3d_effective_drawtype(const struct View3D *v3d);
/* drawarmature.c */
-bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
+bool draw_armature(Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
const short dt, const short dflag, const unsigned char ob_wire_col[4],
const bool is_outline);
/* drawmesh.c */
-void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
+void draw_mesh_textured(Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
void draw_mesh_face_select(
struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm,
@@ -195,16 +209,24 @@ void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
/* view3d_draw.c */
void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
-void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
+void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset);
+
+void ED_view3d_draw_depth(
+ struct Depsgraph *graph,
+ struct ARegion *ar, View3D *v3d, bool alphaoverride);
+
+/* view3d_draw_legacy.c */
+void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar);
void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
+
void ED_view3d_draw_select_loop(
- ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
+ ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar,
bool use_obedit_skip, bool use_nearest);
-void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);\
+void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d);
+
+void ED_view3d_after_add(ListBase *lb, BaseLegacy *base, const short dflag);
-void circf(float x, float y, float rad);
-void circ(float x, float y, float rad);
void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect);
float view3d_depth_near(struct ViewDepths *d);
@@ -219,7 +241,6 @@ void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
void VIEW3D_OT_camera_to_view(struct wmOperatorType *ot);
void VIEW3D_OT_camera_to_view_selected(struct wmOperatorType *ot);
void VIEW3D_OT_object_as_camera(struct wmOperatorType *ot);
-void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
@@ -297,6 +318,12 @@ ARegion *view3d_has_tools_region(ScrArea *sa);
extern const char *view3d_context_dir[]; /* doc access */
+/* view3d_widgets.c */
+void VIEW3D_WGT_lamp (struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_camera (struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_force_field (struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_armature_facemaps(struct wmManipulatorGroupType *wgt);
+
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
const float min[3], const float max[3],
@@ -315,5 +342,30 @@ extern unsigned char view3d_camera_border_hack_col[3];
extern bool view3d_camera_border_hack_test;
#endif
-#endif /* __VIEW3D_INTERN_H__ */
+/* temporary for legacy viewport to work */
+void VP_legacy_drawcursor(Scene *scene, struct SceneLayer *sl, ARegion *ar, View3D *v3d);
+void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect);
+void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect);
+void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect);
+void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit);
+void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth);
+void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
+bool VP_legacy_view3d_stereo3d_active(const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar);
+void draw_dupli_objects(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base);
+bool VP_legacy_use_depth(Scene *scene, View3D *v3d);
+void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d);
+void VP_drawrenderborder(ARegion *ar, View3D *v3d);
+void VP_view3d_draw_background_none(void);
+void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar);
+
+/* temporary legacy calls, only when there is a switch between new/old draw calls */
+void VP_deprecated_gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d);
+void VP_deprecated_view3d_draw_objects(
+ const struct bContext *C,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen, struct GPUFX *fx);
+#endif /* __VIEW3D_INTERN_H__ */
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index d71639c35d2..6f05dd353d7 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -119,8 +119,8 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "autoselect"))
flag |= FILE_AUTOSELECT;
- if (RNA_boolean_get(op->ptr, "active_layer"))
- flag |= FILE_ACTIVELAY;
+ if (RNA_boolean_get(op->ptr, "active_collection"))
+ flag |= FILE_ACTIVE_COLLECTION;
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
if (BKE_copybuffer_paste(C, str, flag, op->reports)) {
@@ -152,7 +152,7 @@ static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select pasted objects");
- RNA_def_boolean(ot->srna, "active_layer", true, "Active Layer", "Put pasted objects on the active layer");
+ RNA_def_boolean(ot->srna, "active_collection", true, "Active Collection", "Put pasted objects on the active collection");
}
/* ************************** registration **********************************/
@@ -193,7 +193,6 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_render_border);
WM_operatortype_append(VIEW3D_OT_clear_render_border);
WM_operatortype_append(VIEW3D_OT_zoom_border);
- WM_operatortype_append(VIEW3D_OT_manipulator);
WM_operatortype_append(VIEW3D_OT_enable_manipulator);
WM_operatortype_append(VIEW3D_OT_cursor3d);
WM_operatortype_append(VIEW3D_OT_select_lasso);
@@ -201,7 +200,6 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_camera_to_view);
WM_operatortype_append(VIEW3D_OT_camera_to_view_selected);
WM_operatortype_append(VIEW3D_OT_object_as_camera);
- WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_game_start);
WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_walk);
@@ -240,23 +238,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
- /* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", true);
-
- /* Using KM_ANY here to allow holding modifiers before starting to transform. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
@@ -372,8 +353,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", true);
-
- WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
#ifdef WITH_INPUT_NDOF
/* note: positioned here so keymaps show keyboard keys if assigned */
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 65a6dee2f6c..f8b02f0b405 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -36,14 +36,13 @@
#include "BLI_sys_types.h" /* int64_t */
-#include "BIF_gl.h" /* bglMats */
-#include "BIF_glutil.h" /* bglMats */
-
#include "BLI_math_vector.h"
#include "BKE_camera.h"
#include "BKE_screen.h"
+#include "GPU_matrix.h"
+
#include "ED_view3d.h" /* own include */
#define BL_NEAR_CLIP 0.001
@@ -656,16 +655,22 @@ void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, float obm
}
/**
- * Uses window coordinates (x,y) and depth component z to find a point in
- * modelspace */
-void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z)
+ * Convert between region relative coordinates (x,y) and depth component z and
+ * a point in world space. */
+void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3])
{
- double ux, uy, uz;
+ // viewport is set up to make coordinates relative to the region, not window
+ RegionView3D *rv3d = ar->regiondata;
+ int viewport[4] = {0, 0, ar->winx, ar->winy};
- gluUnProject(x, y, z, mats->modelview, mats->projection,
- (GLint *)mats->viewport, &ux, &uy, &uz);
+ gpuProject(world, rv3d->viewmat, rv3d->winmat, viewport, region);
+}
+
+bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+ int viewport[4] = {0, 0, ar->winx, ar->winy};
+ float region[3] = {regionx, regiony, regionz};
- out[0] = ux;
- out[1] = uy;
- out[2] = uz;
+ return gpuUnProject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
}
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index aefe30bbe32..aecde1b1657 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -43,6 +43,9 @@
#include "BIF_gl.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -280,7 +283,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), 0,
+ CTX_data_main(C), CTX_data_scene(C), CTX_data_scene_layer(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
@@ -426,12 +429,11 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
#define ARC_STEPS 24
const int arc_steps = ARC_STEPS;
int i;
- //unsigned int color_act = 0x666600;
- unsigned int color_act = 0xffffff;
- unsigned int color_base = 0x0;
- unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80};
+ const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
unsigned char color_text[3];
unsigned char color_wire[3];
+ float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
/* anti-aliased lines for more consistent appearance */
glEnable(GL_LINE_SMOOTH);
@@ -456,28 +458,37 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
glEnable(GL_BLEND);
- cpack(is_act ? color_act : color_base);
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j++) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- cpack(0xaaaaaa);
- setlinestyle(3);
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j++) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- setlinestyle(0);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(PRIM_LINE_STRIP, 3);
+
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[1]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* arc */
{
float dir_tmp[3];
float co_tmp[3];
- float arc_ss_coords[ARC_STEPS + 1][2];
+ float arc_ss_coord[2];
float dir_a[3];
float dir_b[3];
@@ -501,46 +512,19 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
copy_v3_v3(dir_tmp, dir_a);
- glColor3ubv(color_wire);
+ immUniformColor3ubv(color_wire);
+
+ immBegin(PRIM_LINE_STRIP, arc_steps + 1);
for (j = 0; j <= arc_steps; j++) {
madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
- ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP);
+ ED_view3d_project_float_global(ar, co_tmp, arc_ss_coord, V3D_PROJ_TEST_NOP);
mul_qt_v3(quat, dir_tmp);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords);
- glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- /* text */
- {
- char numstr[256];
- float numstr_size[2];
- float pos[2];
- const int prec = 2; /* XXX, todo, make optional */
-
- ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
-
- BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
-
- pos[0] = co_ss[1][0] + (cap_size * 2.0f);
- pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
+ immVertex2fv(shdr_pos, arc_ss_coord);
+ }
- /* draw text (bg) */
- glColor4ubv(color_back);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(
- pos[0] - bg_margin, pos[1] - bg_margin,
- pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
- bg_radius);
- /* draw text */
- glColor3ubv(color_text);
- BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
- BLF_rotation(blf_mono_font, 0.0f);
- BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ immEnd();
}
/* capping */
@@ -561,75 +545,84 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
glEnable(GL_BLEND);
- glColor3ubv(color_wire);
+ immUniformColor3ubv(color_wire);
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, 8);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
/* angle vertex */
- glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
- glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
- glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
- glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
- glEnd();
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+
+ immEnd();
glDisable(GL_BLEND);
}
- }
- else {
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j += 2) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- cpack(0xaaaaaa);
- setlinestyle(3);
- glBegin(GL_LINE_STRIP);
- for (j = 0; j < 3; j += 2) {
- glVertex2fv(co_ss[j]);
- }
- glEnd();
- setlinestyle(0);
- sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
+ immUnbindProgram();
/* text */
{
char numstr[256];
float numstr_size[2];
- const int prec = 6; /* XXX, todo, make optional */
- float pos[2];
+ float posit[2];
+ const int prec = 2; /* XXX, todo, make optional */
ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
- mid_v2_v2v2(pos, co_ss[0], co_ss[2]);
-
- /* center text */
- pos[0] -= numstr_size[0] / 2.0f;
- pos[1] -= numstr_size[1] / 2.0f;
+ posit[0] = co_ss[1][0] + (cap_size * 2.0f);
+ posit[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
/* draw text (bg) */
- glColor4ubv(color_back);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(pos[0] - bg_margin, pos[1] - bg_margin,
- pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
- bg_radius);
+ UI_draw_roundbox_aa(true,
+ posit[0] - bg_margin, posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1],
+ bg_radius, color_back);
/* draw text */
- glColor3ubv(color_text);
- BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_rotation(blf_mono_font, 0.0f);
BLF_draw(blf_mono_font, numstr, sizeof(numstr));
}
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(PRIM_LINES, 2);
+
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
/* capping */
{
@@ -639,22 +632,56 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
normalize_v2(rot_90_vec);
glEnable(GL_BLEND);
- glColor3ubv(color_wire);
- glBegin(GL_LINES);
+ immUniformColor3ubv(color_wire);
+
+ immBegin(PRIM_LINES, 4);
+
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
- glVertex2fv(cap);
+ immVertex2fv(shdr_pos, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
- glVertex2fv(cap);
- glEnd();
+ immVertex2fv(shdr_pos, cap);
+
+ immEnd();
glDisable(GL_BLEND);
}
+
+ immUnbindProgram();
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ const int prec = 6; /* XXX, todo, make optional */
+ float posit[2];
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+
+ mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
+
+ /* center text */
+ posit[0] -= numstr_size[0] / 2.0f;
+ posit[1] -= numstr_size[1] / 2.0f;
+
+ /* draw text (bg) */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ posit[0] - bg_margin, posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1],
+ bg_radius, color_back);
+ /* draw text */
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
}
}
@@ -673,8 +700,14 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
float co_ss[3];
ED_view3d_project_float_global(ar, ruler_item->co[ruler_item->co_index], co_ss, V3D_PROJ_TEST_NOP);
- cpack(color_act);
- circ(co_ss[0], co_ss[1], size * U.pixelsize);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color_act);
+
+ imm_draw_circle_wire(pos, co_ss[0], co_ss[1], size * U.pixelsize, 32);
+
+ immUnbindProgram();
}
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 7d927766bbd..a15e4baced2 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -64,18 +64,16 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
+#include "BKE_scene.h"
#include "BKE_tracking.h"
#include "BKE_utildefines.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -95,6 +93,7 @@
#include "UI_interface.h"
#include "GPU_draw.h"
+#include "GPU_matrix.h"
#include "view3d_intern.h" /* own include */
@@ -110,7 +109,9 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
{
memset(vc, 0, sizeof(ViewContext));
vc->ar = CTX_wm_region(C);
+ vc->depsgraph = CTX_data_depsgraph(C);
vc->scene = CTX_data_scene(C);
+ vc->scene_layer = CTX_data_scene_layer(C);
vc->v3d = CTX_wm_view3d(C);
vc->win = CTX_wm_window(C);
vc->rv3d = CTX_wm_region_view3d(C);
@@ -118,34 +119,6 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
vc->obedit = CTX_data_edit_object(C);
}
-/*
- * ob == NULL if you want global matrices
- * */
-void view3d_get_transformation(const ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats)
-{
- float cpy[4][4];
- int i, j;
-
- if (ob) {
- mul_m4_m4m4(cpy, rv3d->viewmat, ob->obmat);
- }
- else {
- copy_m4_m4(cpy, rv3d->viewmat);
- }
-
- for (i = 0; i < 4; ++i) {
- for (j = 0; j < 4; ++j) {
- mats->projection[i * 4 + j] = rv3d->winmat[i][j];
- mats->modelview[i * 4 + j] = cpy[i][j];
- }
- }
-
- mats->viewport[0] = ar->winrct.xmin;
- mats->viewport[1] = ar->winrct.ymin;
- mats->viewport[2] = ar->winx;
- mats->viewport[3] = ar->winy;
-}
-
/* ********************** view3d_select: selection manipulations ********************* */
/* local prototypes */
@@ -401,13 +374,13 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[]
}
}
-static void object_deselect_all_visible(Scene *scene, View3D *v3d)
+static void object_deselect_all_visible(SceneLayer *sl)
{
Base *base;
- for (base = scene->base.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- ED_base_object_select(base, BA_DESELECT);
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (BASE_SELECTABLE_NEW(base)) {
+ ED_object_base_select(base, BA_DESELECT);
}
}
}
@@ -418,15 +391,14 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons
Base *base;
if (extend == false && select)
- object_deselect_all_visible(vc->scene, vc->v3d);
+ object_deselect_all_visible(vc->scene_layer);
- for (base = vc->scene->base.first; base; base = base->next) {
- if (BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */
+ for (base = vc->scene_layer->object_bases.first; base; base = base->next) {
+ if (BASE_SELECTABLE_NEW(base)) { /* use this to avoid un-needed lasso lookups */
if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) {
if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
- base->object->flag = base->flag;
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
}
if (vc->obact == base->object && (base->object->mode & OB_MODE_POSE)) {
@@ -503,7 +475,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
/* for non zbuf projections, don't change the GL state */
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- glLoadMatrixf(vc->rv3d->viewmat);
+ gpuLoadMatrix(vc->rv3d->viewmat);
bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
@@ -1019,8 +991,8 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
if (!toggle) {
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
- if (base->flag & SELECT) {
- ED_base_object_select(base, BA_DESELECT);
+ if ((base->flag & BASE_SELECTED) != 0) {
+ ED_object_base_select(base, BA_DESELECT);
changed = true;
}
}
@@ -1031,8 +1003,8 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
{
/* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */
if (STREQ(name, base->object->id.name + 2)) {
- ED_base_object_activate(C, base);
- ED_base_object_select(base, BA_SELECT);
+ ED_object_base_activate(C, base);
+ ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -1076,14 +1048,12 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first");
}
-static void deselectall_except(Scene *scene, Base *b) /* deselect all except b */
+static void deselectall_except(SceneLayer *sl, Base *b) /* deselect all except b */
{
- Base *base;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->flag & SELECT) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (base->flag & BASE_SELECTED) {
if (b != base) {
- ED_base_object_select(base, BA_DESELECT);
+ ED_object_base_select(base, BA_DESELECT);
}
}
}
@@ -1096,7 +1066,8 @@ static Base *object_mouse_select_menu(
short baseCount = 0;
bool ok;
LinkNode *linklist = NULL;
-
+
+ /* handle base->selcol */
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
ok = false;
@@ -1294,8 +1265,7 @@ finally:
static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits,
Base *startbase, bool has_bones, bool do_nearest)
{
- Scene *scene = vc->scene;
- View3D *v3d = vc->v3d;
+ SceneLayer *sl = vc->scene_layer;
Base *base, *basact = NULL;
int a;
@@ -1315,7 +1285,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
}
else {
/* only exclude active object when it is selected... */
- if (BASACT && (BASACT->flag & SELECT) && hits > 1) notcol = BASACT->selcol;
+ if (BASACT_NEW && (BASACT_NEW->flag & BASE_SELECTED) && hits > 1) notcol = BASACT_NEW->selcol;
for (a = 0; a < hits; a++) {
if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) {
@@ -1325,9 +1295,9 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
}
}
- base = FIRSTBASE;
+ base = FIRSTBASE_NEW;
while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
+ if (BASE_SELECTABLE_NEW(base)) {
if (base->selcol == selcol) break;
}
base = base->next;
@@ -1340,13 +1310,13 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
while (base) {
/* skip objects with select restriction, to prevent prematurely ending this loop
* with an un-selectable choice */
- if (base->object->restrictflag & OB_RESTRICT_SELECT) {
+ if ((base->flag & BASE_SELECTABLED) == 0) {
base = base->next;
- if (base == NULL) base = FIRSTBASE;
+ if (base == NULL) base = FIRSTBASE_NEW;
if (base == startbase) break;
}
- if (BASE_SELECTABLE(v3d, base)) {
+ if (BASE_SELECTABLE_NEW(base)) {
for (a = 0; a < hits; a++) {
if (has_bones) {
/* skip non-bone objects */
@@ -1365,7 +1335,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
if (basact) break;
base = base->next;
- if (base == NULL) base = FIRSTBASE;
+ if (base == NULL) base = FIRSTBASE_NEW;
if (base == startbase) break;
}
}
@@ -1390,7 +1360,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
if (hits > 0) {
const bool has_bones = selectbuffer_has_bones(buffer, hits);
- basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.scene->base.first, has_bones, do_nearest);
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.scene_layer->object_bases.first, has_bones, do_nearest);
}
return basact;
@@ -1422,8 +1392,8 @@ static bool ed_object_select_pick(
{
ViewContext vc;
ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL;
bool is_obedit;
float dist = ED_view3d_select_dist_px() * 1.3333f;
@@ -1442,8 +1412,8 @@ static bool ed_object_select_pick(
}
/* always start list from basact in wire mode */
- startbase = FIRSTBASE;
- if (BASACT && BASACT->next) startbase = BASACT->next;
+ startbase = FIRSTBASE_NEW;
+ if (BASACT_NEW && BASACT_NEW->next) startbase = BASACT_NEW->next;
/* This block uses the control key to make the object selected by its center point rather than its contents */
/* in editmode do not activate */
@@ -1456,13 +1426,13 @@ static bool ed_object_select_pick(
else {
base = startbase;
while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
+ if (BASE_SELECTABLE_NEW(base)) {
float screen_co[2];
if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
- if (base == BASACT) dist_temp += 10.0f;
+ if (base == BASACT_NEW) dist_temp += 10.0f;
if (dist_temp < dist) {
dist = dist_temp;
basact = base;
@@ -1471,7 +1441,7 @@ static bool ed_object_select_pick(
}
base = base->next;
- if (base == NULL) base = FIRSTBASE;
+ if (base == NULL) base = FIRSTBASE_NEW;
if (base == startbase) break;
}
}
@@ -1501,7 +1471,7 @@ static bool ed_object_select_pick(
if (has_bones && basact) {
if (basact->object->type == OB_CAMERA) {
- if (BASACT == basact) {
+ if (BASACT_NEW == basact) {
int i, hitresult;
bool changed = false;
@@ -1539,8 +1509,8 @@ static bool ed_object_select_pick(
changed = true;
}
- basact->flag |= SELECT;
- basact->object->flag = basact->flag;
+ basact->flag |= BASE_SELECTED;
+ BKE_scene_object_base_flag_sync_from_base(basact);
retval = true;
@@ -1558,27 +1528,27 @@ static bool ed_object_select_pick(
}
}
}
- else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
+ else if (ED_do_pose_selectbuffer(scene, sl, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
/* then bone is found */
/* we make the armature selected:
* not-selected active object in posemode won't work well for tools */
- basact->flag |= SELECT;
- basact->object->flag = basact->flag;
+ basact->flag |= BASE_SELECTED;
+ BKE_scene_base_flag_sync_from_base(basact);
retval = true;
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if (BASACT && (BASACT->object->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (BASACT_NEW && (BASACT_NEW->object->mode & OB_MODE_WEIGHT_PAINT)) {
/* prevent activating */
basact = NULL;
}
}
/* prevent bone selecting to pass on to object selecting */
- if (basact == BASACT)
+ if (basact == BASACT_NEW)
basact = NULL;
}
}
@@ -1590,37 +1560,37 @@ static bool ed_object_select_pick(
if (vc.obedit) {
/* only do select */
- deselectall_except(scene, basact);
- ED_base_object_select(basact, BA_SELECT);
+ deselectall_except(sl, basact);
+ ED_object_base_select(basact, BA_SELECT);
}
/* also prevent making it active on mouse selection */
- else if (BASE_SELECTABLE(v3d, basact)) {
+ else if (BASE_SELECTABLE_NEW(basact)) {
- oldbasact = BASACT;
+ oldbasact = BASACT_NEW;
if (extend) {
- ED_base_object_select(basact, BA_SELECT);
+ ED_object_base_select(basact, BA_SELECT);
}
else if (deselect) {
- ED_base_object_select(basact, BA_DESELECT);
+ ED_object_base_select(basact, BA_DESELECT);
}
else if (toggle) {
- if (basact->flag & SELECT) {
+ if (basact->flag & BASE_SELECTED) {
if (basact == oldbasact) {
- ED_base_object_select(basact, BA_DESELECT);
+ ED_object_base_select(basact, BA_DESELECT);
}
}
else {
- ED_base_object_select(basact, BA_SELECT);
+ ED_object_base_select(basact, BA_SELECT);
}
}
else {
- deselectall_except(scene, basact);
- ED_base_object_select(basact, BA_SELECT);
+ deselectall_except(sl, basact);
+ ED_object_base_select(basact, BA_SELECT);
}
if ((oldbasact != basact) && (is_obedit == false)) {
- ED_base_object_activate(C, basact); /* adds notifier */
+ ED_object_base_activate(C, basact); /* adds notifier */
}
}
@@ -1877,7 +1847,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
/* for non zbuf projections, don't change the GL state */
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- glLoadMatrixf(vc->rv3d->viewmat);
+ gpuLoadMatrix(vc->rv3d->viewmat);
bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
@@ -2050,7 +2020,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
CTX_DATA_END;
}
else {
- object_deselect_all_visible(vc->scene, vc->v3d);
+ object_deselect_all_visible(vc->scene_layer);
}
}
@@ -2073,8 +2043,8 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
Base *base;
col = vbuffer + 3;
- for (base = vc->scene->base.first; base && hits; base = base->next) {
- if (BASE_SELECTABLE(vc->v3d, base)) {
+ for (base = vc->scene_layer->object_bases.first; base && hits; base = base->next) {
+ if (BASE_SELECTABLE_NEW(base)) {
while (base->selcol == (*col & 0xFFFF)) { /* we got an object */
if (*col & 0xFFFF0000) { /* we got a bone */
bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY));
@@ -2094,7 +2064,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
}
}
else if (!bone_only) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
col += 4; /* next color */
@@ -2805,22 +2775,22 @@ static void obedit_circle_select(ViewContext *vc, const bool select, const int m
static bool object_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
{
- Scene *scene = vc->scene;
+ SceneLayer *sl = vc->scene_layer;
const float radius_squared = rad * rad;
const float mval_fl[2] = {mval[0], mval[1]};
bool changed = false;
- const int select_flag = select ? SELECT : 0;
+ const int select_flag = select ? BASE_SELECTED : 0;
Base *base;
- for (base = FIRSTBASE; base; base = base->next) {
- if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) {
+ for (base = FIRSTBASE_NEW; base; base = base->next) {
+ if (BASE_SELECTABLE_NEW(base) && ((base->flag & BASE_SELECTED) != select_flag)) {
float screen_co[2];
if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
- ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
changed = true;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index eda4d51e7e8..93554c374d9 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -51,10 +51,12 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BIF_gl.h"
+#include "DEG_depsgraph.h"
+
#include "BIF_glutil.h"
#include "GPU_select.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -62,6 +64,8 @@
#include "ED_screen.h"
#include "ED_armature.h"
+#include "DRW_engine.h"
+
#ifdef WITH_GAMEENGINE
# include "BLI_listbase.h"
@@ -96,10 +100,8 @@ void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar)
RegionView3D *rv3d = ar->regiondata;
wmSubWindowSet(win, ar->swinid);
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(rv3d->winmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(rv3d->viewmat);
+ gpuLoadProjectionMatrix(rv3d->winmat);
+ gpuLoadMatrix(rv3d->viewmat);
}
}
@@ -539,6 +541,7 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
Object *camera_ob = v3d ? v3d->camera : scene->camera;
@@ -551,7 +554,7 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
}
/* this function does all the important stuff */
- if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co, &r_scale)) {
+ if (BKE_camera_view_frame_fit_to_scene(scene, sl, camera_ob, r_co, &r_scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
@@ -725,40 +728,35 @@ void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb,
}
}
-void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect)
+void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
{
- float modelview[4][4];
- double xs, ys, p[3];
- int val, flip_sign, a;
-
- /* near zero floating point values can give issues with gluUnProject
- * in side view on some implementations */
- if (fabs(mats->modelview[0]) < 1e-6) mats->modelview[0] = 0.0;
- if (fabs(mats->modelview[5]) < 1e-6) mats->modelview[5] = 0.0;
-
- /* Set up viewport so that gluUnProject will give correct values */
- mats->viewport[0] = 0;
- mats->viewport[1] = 0;
+ /* init in case unproject fails */
+ memset(bb->vec, 0, sizeof(bb->vec));
/* four clipping planes and bounding volume */
/* first do the bounding volume */
- for (val = 0; val < 4; val++) {
- xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
- ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
+ for (int val = 0; val < 4; val++) {
+ float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
+ float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
- gluUnProject(xs, ys, 0.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
- copy_v3fl_v3db(bb->vec[val], p);
+ ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
+ ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
+ }
+
+ /* optionally transform to object space */
+ if (ob) {
+ float imat[4][4];
+ invert_m4_m4(imat, ob->obmat);
- gluUnProject(xs, ys, 1.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
- copy_v3fl_v3db(bb->vec[4 + val], p);
+ for (int val = 0; val < 8; val++) {
+ mul_m4_v3(imat, bb->vec[val]);
+ }
}
/* verify if we have negative scale. doing the transform before cross
* product flips the sign of the vector compared to doing cross product
* before transform then, so we correct for that. */
- for (a = 0; a < 16; a++)
- ((float *)modelview)[a] = mats->modelview[a];
- flip_sign = is_negative_m4(modelview);
+ int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
}
@@ -934,14 +932,14 @@ void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect)
}
if (is_ortho) {
- wmOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ gpuOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
else {
- wmFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ gpuFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
/* update matrix in 3d view region */
- glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat);
+ gpuGetProjectionMatrix(rv3d->winmat);
}
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
@@ -1117,6 +1115,7 @@ int view3d_opengl_select(
ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
eV3DSelectMode select_mode)
{
+ Depsgraph *graph = vc->depsgraph;
Scene *scene = vc->scene;
View3D *v3d = vc->v3d;
ARegion *ar = vc->ar;
@@ -1186,7 +1185,16 @@ int view3d_opengl_select(
GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
- ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
+#ifdef WITH_OPENGL_LEGACY
+ if (IS_VIEWPORT_LEGACY(vc->v3d)) {
+ ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
+ }
+ else
+#else
+ {
+ DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
+ }
+#endif /* WITH_OPENGL_LEGACY */
hits = GPU_select_end();
@@ -1194,7 +1202,16 @@ int view3d_opengl_select(
if (do_passes) {
GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
- ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
+#ifdef WITH_OPENGL_LEGACY
+ if (IS_VIEWPORT_LEGACY(vc->v3d)) {
+ ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
+ }
+ else
+#else
+ {
+ DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
+ }
+#endif /* WITH_OPENGL_LEGACY */
GPU_select_end();
}
@@ -1216,42 +1233,6 @@ finally:
return hits;
}
-/* ********************** local view operator ******************** */
-
-static unsigned int free_localbit(Main *bmain)
-{
- unsigned int lay;
- ScrArea *sa;
- bScreen *sc;
-
- lay = 0;
-
- /* sometimes we loose a localview: when an area is closed */
- /* check all areas: which localviews are in use? */
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl = sa->spacedata.first;
- for (; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *) sl;
- lay |= v3d->lay;
- }
- }
- }
- }
-
- if ((lay & 0x01000000) == 0) return 0x01000000;
- if ((lay & 0x02000000) == 0) return 0x02000000;
- if ((lay & 0x04000000) == 0) return 0x04000000;
- if ((lay & 0x08000000) == 0) return 0x08000000;
- if ((lay & 0x10000000) == 0) return 0x10000000;
- if ((lay & 0x20000000) == 0) return 0x20000000;
- if ((lay & 0x40000000) == 0) return 0x40000000;
- if ((lay & 0x80000000) == 0) return 0x80000000;
-
- return 0;
-}
-
int ED_view3d_scene_layer_set(int lay, const int *values, int *active)
{
int i, tot = 0;
@@ -1290,269 +1271,6 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active)
return lay;
}
-static bool view3d_localview_init(
- wmWindowManager *wm, wmWindow *win,
- Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx,
- ReportList *reports)
-{
- View3D *v3d = sa->spacedata.first;
- Base *base;
- float min[3], max[3], box[3], mid[3];
- float size = 0.0f;
- unsigned int locallay;
- bool ok = false;
-
- if (v3d->localvd) {
- return ok;
- }
-
- INIT_MINMAX(min, max);
-
- locallay = free_localbit(bmain);
-
- if (locallay == 0) {
- BKE_report(reports, RPT_ERROR, "No more than 8 local views");
- ok = false;
- }
- else {
- if (scene->obedit) {
- BKE_object_minmax(scene->obedit, min, max, false);
-
- ok = true;
-
- BASACT->lay |= locallay;
- scene->obedit->lay = BASACT->lay;
- }
- else {
- for (base = FIRSTBASE; base; base = base->next) {
- if (TESTBASE(v3d, base)) {
- BKE_object_minmax(base->object, min, max, false);
- base->lay |= locallay;
- base->object->lay = base->lay;
- ok = true;
- }
- }
- }
-
- sub_v3_v3v3(box, max, min);
- size = max_fff(box[0], box[1], box[2]);
- }
-
- if (ok == true) {
- ARegion *ar;
-
- v3d->localvd = MEM_mallocN(sizeof(View3D), "localview");
-
- memcpy(v3d->localvd, v3d, sizeof(View3D));
-
- mid_v3_v3v3(mid, min, max);
-
- copy_v3_v3(v3d->cursor, mid);
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
- bool ok_dist = true;
-
- /* new view values */
- Object *camera_old = NULL;
- float dist_new, ofs_new[3];
-
- rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
- memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
-
- negate_v3_v3(ofs_new, mid);
-
- if (rv3d->persp == RV3D_CAMOB) {
- rv3d->persp = RV3D_PERSP;
- camera_old = v3d->camera;
- }
-
- if (rv3d->persp == RV3D_ORTHO) {
- if (size < 0.0001f) {
- ok_dist = false;
- }
- }
-
- if (ok_dist) {
- dist_new = ED_view3d_radius_to_dist(v3d, ar, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
- if (rv3d->persp == RV3D_PERSP) {
- /* don't zoom closer than the near clipping plane */
- dist_new = max_ff(dist_new, v3d->near * 1.5f);
- }
- }
-
- ED_view3d_smooth_view_ex(
- wm, win, sa, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old,
- .ofs = ofs_new, .quat = rv3d->viewquat,
- .dist = ok_dist ? &dist_new : NULL, .lens = &v3d->lens});
- }
- }
-
- v3d->lay = locallay;
- }
- else {
- /* clear flags */
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->lay & locallay) {
- base->lay -= locallay;
- if (base->lay == 0) base->lay = v3d->layact;
- if (base->object != scene->obedit) base->flag |= SELECT;
- base->object->lay = base->lay;
- }
- }
- }
-
- DAG_on_visible_update(bmain, false);
-
- return ok;
-}
-
-static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
-{
- const bool free = true;
- ARegion *ar;
- View3D *v3d = sa->spacedata.first;
- Object *camera_old, *camera_new;
-
- if (v3d->localvd == NULL) return;
-
- camera_old = v3d->camera;
- camera_new = v3d->localvd->camera;
-
- v3d->near = v3d->localvd->near;
- v3d->far = v3d->localvd->far;
- v3d->lay = v3d->localvd->lay;
- v3d->layact = v3d->localvd->layact;
- v3d->drawtype = v3d->localvd->drawtype;
- v3d->camera = v3d->localvd->camera;
-
- if (free) {
- MEM_freeN(v3d->localvd);
- v3d->localvd = NULL;
- }
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->localvd) {
- Object *camera_old_rv3d, *camera_new_rv3d;
-
- camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : NULL;
- camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
-
- rv3d->view = rv3d->localvd->view;
- rv3d->persp = rv3d->localvd->persp;
- rv3d->camzoom = rv3d->localvd->camzoom;
-
- ED_view3d_smooth_view_ex(
- wm, win, sa,
- v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old_rv3d, .camera = camera_new_rv3d,
- .ofs = rv3d->localvd->ofs, .quat = rv3d->localvd->viewquat,
- .dist = &rv3d->localvd->dist});
-
- if (free) {
- MEM_freeN(rv3d->localvd);
- rv3d->localvd = NULL;
- }
- }
-
- ED_view3d_shade_update(bmain, scene, v3d, sa);
- }
- }
-}
-
-static bool view3d_localview_exit(
- wmWindowManager *wm, wmWindow *win,
- Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
-{
- View3D *v3d = sa->spacedata.first;
- struct Base *base;
- unsigned int locallay;
-
- if (v3d->localvd) {
-
- locallay = v3d->lay & 0xFF000000;
-
- restore_localviewdata(wm, win, bmain, scene, sa, smooth_viewtx);
-
- /* for when in other window the layers have changed */
- if (v3d->scenelock) v3d->lay = scene->lay;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->lay & locallay) {
- base->lay -= locallay;
- if (base->lay == 0) base->lay = v3d->layact;
- if (base->object != scene->obedit) {
- base->flag |= SELECT;
- base->object->flag |= SELECT;
- }
- base->object->lay = base->lay;
- }
- }
-
- DAG_on_visible_update(bmain, false);
-
- return true;
- }
- else {
- return false;
- }
-}
-
-static int localview_exec(bContext *C, wmOperator *op)
-{
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = CTX_wm_view3d(C);
- bool changed;
-
- if (v3d->localvd) {
- changed = view3d_localview_exit(wm, win, bmain, scene, sa, smooth_viewtx);
- }
- else {
- changed = view3d_localview_init(wm, win, bmain, scene, sa, smooth_viewtx, op->reports);
- }
-
- if (changed) {
- DAG_id_type_tag(bmain, ID_OB);
- ED_area_tag_redraw(sa);
-
- /* unselected objects become selected when exiting */
- if (v3d->localvd == NULL) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
-}
-
-void VIEW3D_OT_localview(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Local View";
- ot->description = "Toggle display of selected object(s) separately and centered in view";
- ot->idname = "VIEW3D_OT_localview";
-
- /* api callbacks */
- ot->exec = localview_exec;
- ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
-
- ot->poll = ED_operator_view3d_active;
-}
-
#ifdef WITH_GAMEENGINE
static ListBase queue_back;
@@ -1591,7 +1309,6 @@ static void RestoreState(bContext *C, wmWindow *win)
win->queue = queue_back;
GPU_state_init();
- GPU_set_tpage(NULL, 0, 0);
glPopAttrib();
}
@@ -1634,10 +1351,6 @@ static void game_set_commmandline_options(GameData *gm)
SYS_WriteCommandLineInt(syshandle, "blender_material", test);
test = (gm->matmode == GAME_MAT_GLSL);
SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", test);
- test = (gm->flag & GAME_DISPLAY_LISTS);
- SYS_WriteCommandLineInt(syshandle, "displaylists", test);
-
-
}
}
@@ -1766,7 +1479,7 @@ static int game_engine_exec(bContext *C, wmOperator *op)
//XXX restore_all_scene_cfra(scene_cfra_store);
BKE_scene_set_background(CTX_data_main(C), startscene);
- //XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ //XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_POST);
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 542dc410bc3..e0c8ad2ed6b 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -57,6 +57,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "GPU_immediate.h"
+
#include "view3d_intern.h" /* own include */
#ifdef WITH_INPUT_NDOF
@@ -247,6 +249,7 @@ typedef struct WalkInfo {
View3D *v3d;
ARegion *ar;
Scene *scene;
+ SceneLayer *scene_layer;
wmTimer *timer; /* needed for redraws */
@@ -338,24 +341,33 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *a
yoff = walk->ar->winy / 2;
}
- UI_ThemeColor(TH_VIEW_OVERLAY);
- glBegin(GL_LINES);
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+
+ immBegin(PRIM_LINES, 8);
+
/* North */
- glVertex2i(xoff, yoff + inner_length);
- glVertex2i(xoff, yoff + outter_length);
+ immVertex2i(pos, xoff, yoff + inner_length);
+ immVertex2i(pos, xoff, yoff + outter_length);
/* East */
- glVertex2i(xoff + inner_length, yoff);
- glVertex2i(xoff + outter_length, yoff);
+ immVertex2i(pos, xoff + inner_length, yoff);
+ immVertex2i(pos, xoff + outter_length, yoff);
/* South */
- glVertex2i(xoff, yoff - inner_length);
- glVertex2i(xoff, yoff - outter_length);
+ immVertex2i(pos, xoff, yoff - inner_length);
+ immVertex2i(pos, xoff, yoff - outter_length);
/* West */
- glVertex2i(xoff - inner_length, yoff);
- glVertex2i(xoff - outter_length, yoff);
- glEnd();
+ immVertex2i(pos, xoff - inner_length, yoff);
+ immVertex2i(pos, xoff - outter_length, yoff);
+
+ immEnd();
+ immUnbindProgram();
}
static void walk_update_header(bContext *C, wmOperator *op, WalkInfo *walk)
@@ -500,6 +512,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->v3d = CTX_wm_view3d(C);
walk->ar = CTX_wm_region(C);
walk->scene = CTX_data_scene(C);
+ walk->scene_layer = CTX_data_scene_layer(C);
#ifdef NDOF_WALK_DEBUG
puts("\n-- walk begin --");
@@ -588,7 +601,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->rv3d->rflag |= RV3D_NAVIGATING;
walk->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), walk->scene, 0,
+ CTX_data_main(C), walk->scene, walk->scene_layer, 0,
walk->ar, walk->v3d);
walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index b7de49d8158..1a41d9ac95a 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -58,10 +58,6 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-if(WITH_LEGACY_DEPSGRAPH)
- add_definitions(-DWITH_LEGACY_DEPSGRAPH)
-endif()
-
add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_transform "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d786c755529..b29c75d566b 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -64,9 +64,12 @@
#include "BKE_mask.h"
#include "BKE_report.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
#include "ED_image.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
@@ -1598,8 +1601,16 @@ typedef enum {
LEFT,
RIGHT
} ArrowDirection;
+
+#define POS_INDEX 0
+/* NOTE: this --^ is a bit hackish, but simplifies VertexFormat usage among functions
+ * private to this file - merwin
+ */
+
static void drawArrow(ArrowDirection d, short offset, short length, short size)
{
+ immBegin(PRIM_LINES, 6);
+
switch (d) {
case LEFT:
offset = -offset;
@@ -1607,14 +1618,12 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size)
size = -size;
ATTR_FALLTHROUGH;
case RIGHT:
- glBegin(GL_LINES);
- glVertex2s(offset, 0);
- glVertex2s(offset + length, 0);
- glVertex2s(offset + length, 0);
- glVertex2s(offset + length - size, -size);
- glVertex2s(offset + length, 0);
- glVertex2s(offset + length - size, size);
- glEnd();
+ immVertex2f(POS_INDEX, offset, 0);
+ immVertex2f(POS_INDEX, offset + length, 0);
+ immVertex2f(POS_INDEX, offset + length, 0);
+ immVertex2f(POS_INDEX, offset + length - size, -size);
+ immVertex2f(POS_INDEX, offset + length, 0);
+ immVertex2f(POS_INDEX, offset + length - size, size);
break;
case DOWN:
@@ -1623,45 +1632,45 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size)
size = -size;
ATTR_FALLTHROUGH;
case UP:
- glBegin(GL_LINES);
- glVertex2s(0, offset);
- glVertex2s(0, offset + length);
- glVertex2s(0, offset + length);
- glVertex2s(-size, offset + length - size);
- glVertex2s(0, offset + length);
- glVertex2s(size, offset + length - size);
- glEnd();
+ immVertex2f(POS_INDEX, 0, offset);
+ immVertex2f(POS_INDEX, 0, offset + length);
+ immVertex2f(POS_INDEX, 0, offset + length);
+ immVertex2f(POS_INDEX, -size, offset + length - size);
+ immVertex2f(POS_INDEX, 0, offset + length);
+ immVertex2f(POS_INDEX, size, offset + length - size);
break;
}
+
+ immEnd();
}
static void drawArrowHead(ArrowDirection d, short size)
{
+ immBegin(PRIM_LINES, 4);
+
switch (d) {
case LEFT:
size = -size;
ATTR_FALLTHROUGH;
case RIGHT:
- glBegin(GL_LINES);
- glVertex2s(0, 0);
- glVertex2s(-size, -size);
- glVertex2s(0, 0);
- glVertex2s(-size, size);
- glEnd();
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, -size, -size);
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, -size, size);
break;
case DOWN:
size = -size;
ATTR_FALLTHROUGH;
case UP:
- glBegin(GL_LINES);
- glVertex2s(0, 0);
- glVertex2s(-size, -size);
- glVertex2s(0, 0);
- glVertex2s(size, -size);
- glEnd();
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, -size, -size);
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, size, -size);
break;
}
+
+ immEnd();
}
static void drawArc(float size, float angle_start, float angle_end, int segments)
@@ -1670,14 +1679,14 @@ static void drawArc(float size, float angle_start, float angle_end, int segments
float angle;
int a;
- glBegin(GL_LINE_STRIP);
+ immBegin(PRIM_LINE_STRIP, segments + 1);
for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
- glVertex2f(cosf(angle) * size, sinf(angle) * size);
+ immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
}
- glVertex2f(cosf(angle_end) * size, sinf(angle_end) * size);
+ immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
- glEnd();
+ immEnd();
}
static int helpline_poll(bContext *C)
@@ -1693,12 +1702,9 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
{
TransInfo *t = (TransInfo *)customdata;
- if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) {
+ if (t->helpline != HLP_NONE) {
float vecrot[3], cent[2];
- int mval[2];
-
- mval[0] = x;
- mval[1] = y;
+ float mval[3] = { x, y, 0.0f };
copy_v3_v3(vecrot, t->center);
if (t->flag & T_EDIT) {
@@ -1712,42 +1718,67 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO);
- glPushMatrix();
+ gpuPushMatrix();
+
+ /* Dashed lines first. */
+ if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
+ BLI_assert(shdr_pos == POS_INDEX);
+
+ glLineWidth(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(POS_INDEX, cent);
+ immVertex2f(POS_INDEX, (float)t->mval[0], (float)t->mval[1]);
+ immEnd();
+
+ immUnbindProgram();
+ }
+
+ /* And now, solid lines. */
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ UNUSED_VARS_NDEBUG(pos); /* silence warning */
+ BLI_assert(pos == POS_INDEX);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
switch (t->helpline) {
case HLP_SPRING:
- UI_ThemeColor(TH_VIEW_OVERLAY);
-
- setlinestyle(3);
- glLineWidth(1);
- glBegin(GL_LINES);
- glVertex2iv(t->mval);
- glVertex2fv(cent);
- glEnd();
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- glTranslate2iv(mval);
- glRotatef(-RAD2DEGF(atan2f(cent[0] - t->mval[0], cent[1] - t->mval[1])), 0, 0, 1);
+ gpuTranslate3fv(mval);
+ gpuRotateAxis(-RAD2DEGF(atan2f(cent[0] - t->mval[0], cent[1] - t->mval[1])), 'Z');
- setlinestyle(0);
- glLineWidth(3.0);
+ glLineWidth(3.0f);
drawArrow(UP, 5, 10, 5);
drawArrow(DOWN, 5, 10, 5);
break;
case HLP_HARROW:
- UI_ThemeColor(TH_VIEW_OVERLAY);
-
- glTranslate2iv(mval);
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ gpuTranslate3fv(mval);
- glLineWidth(3.0);
+ glLineWidth(3.0f);
drawArrow(RIGHT, 5, 10, 5);
drawArrow(LEFT, 5, 10, 5);
break;
case HLP_VARROW:
- UI_ThemeColor(TH_VIEW_OVERLAY);
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- glTranslate2iv(mval);
+ gpuTranslate3fv(mval);
- glLineWidth(3.0);
+ glLineWidth(3.0f);
drawArrow(UP, 5, 10, 5);
drawArrow(DOWN, 5, 10, 5);
break;
@@ -1758,33 +1789,26 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
float dist = hypotf(dx, dy);
float delta_angle = min_ff(15.0f / dist, (float)M_PI / 4.0f);
float spacing_angle = min_ff(5.0f / dist, (float)M_PI / 12.0f);
- UI_ThemeColor(TH_VIEW_OVERLAY);
- setlinestyle(3);
- glLineWidth(1);
- glBegin(GL_LINES);
- glVertex2iv(t->mval);
- glVertex2fv(cent);
- glEnd();
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- glTranslatef(cent[0] - t->mval[0] + mval[0], cent[1] - t->mval[1] + mval[1], 0);
+ gpuTranslate3f(cent[0] - t->mval[0] + mval[0], cent[1] - t->mval[1] + mval[1], 0);
- setlinestyle(0);
- glLineWidth(3.0);
+ glLineWidth(3.0f);
drawArc(dist, angle - delta_angle, angle - spacing_angle, 10);
drawArc(dist, angle + spacing_angle, angle + delta_angle, 10);
- glPushMatrix();
+ gpuPushMatrix();
- glTranslatef(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
- glRotatef(RAD2DEGF(angle - delta_angle), 0, 0, 1);
+ gpuTranslate3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
+ gpuRotateAxis(RAD2DEGF(angle - delta_angle), 'Z');
drawArrowHead(DOWN, 5);
- glPopMatrix();
+ gpuPopMatrix();
- glTranslatef(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
- glRotatef(RAD2DEGF(angle + delta_angle), 0, 0, 1);
+ gpuTranslate3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
+ gpuRotateAxis(RAD2DEGF(angle + delta_angle), 'Z');
drawArrowHead(UP, 5);
break;
@@ -1794,18 +1818,18 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
unsigned char col[3], col2[3];
UI_GetThemeColor3ubv(TH_GRID, col);
- glTranslate2iv(mval);
+ gpuTranslate3fv(mval);
- glLineWidth(3.0);
+ glLineWidth(3.0f);
UI_make_axis_color(col, col2, 'X');
- glColor3ubv((GLubyte *)col2);
+ immUniformColor3ubv((GLubyte *)col2);
drawArrow(RIGHT, 5, 10, 5);
drawArrow(LEFT, 5, 10, 5);
UI_make_axis_color(col, col2, 'Y');
- glColor3ubv((GLubyte *)col2);
+ immUniformColor3ubv((GLubyte *)col2);
drawArrow(UP, 5, 10, 5);
drawArrow(DOWN, 5, 10, 5);
@@ -1813,7 +1837,8 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
}
}
- glPopMatrix();
+ immUnbindProgram();
+ gpuPopMatrix();
}
}
@@ -1821,7 +1846,7 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi
{
TransInfo *t = arg;
- glLineWidth(1.0);
+ glLineWidth(1.0f);
drawConstraint(t);
drawPropCircle(C, t);
@@ -1841,8 +1866,9 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
int xco, yco;
ED_region_visible_rect(ar, &rect);
-
- BLF_width_and_height_default(printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
+
+ const int font_id = BLF_default();
+ BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
yco = (rect.ymax - U.widget_unit);
@@ -1850,7 +1876,9 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
/* warning text (to clarify meaning of overlays)
* - original color was red to match the icon, but that clashes badly with a less nasty border
*/
- UI_ThemeColorShade(TH_TEXT_HI, -50);
+ unsigned char color[3];
+ UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color);
+ BLF_color3ubv(font_id, color);
#ifdef WITH_INTERNATIONAL
BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
#else
@@ -1873,7 +1901,8 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo
{
TransInfo *t = arg;
Scene *scene = t->scene;
- Object *ob = OBACT;
+ SceneLayer *sl = t->scene_layer;
+ Object *ob = OBACT_NEW;
/* draw autokeyframing hint in the corner
* - only draw if enabled (advanced users may be distracted/annoyed),
@@ -3406,7 +3435,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
constraintTransLim(t, td);
}
-static void applyResize(TransInfo *t, const int mval[2])
+static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td;
float mat[3][3];
@@ -3417,15 +3446,7 @@ static void applyResize(TransInfo *t, const int mval[2])
copy_v3_v3(t->values, t->auto_values);
}
else {
- float ratio;
-
- /* for manipulator, center handle, the scaling can't be done relative to center */
- if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
- ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
- }
- else {
- ratio = t->values[0];
- }
+ float ratio = t->values[0];
copy_v3_fl(t->values, ratio);
@@ -5253,23 +5274,14 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
td->loc[1] = oldy;
}
-static void applyBoneSize(TransInfo *t, const int mval[2])
+static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
float size[3], mat[3][3];
- float ratio;
+ float ratio = t->values[0];
int i;
char str[UI_MAX_DRAW_STR];
-
- // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
- /* for manipulator, center handle, the scaling can't be done relative to center */
- if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
- ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
- }
- else {
- ratio = t->values[0];
- }
-
+
copy_v3_fl(size, ratio);
snapGridIncrement(t, size);
@@ -6861,10 +6873,12 @@ static void drawEdgeSlide(TransInfo *t)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT | GL_POINT_BIT);
- glPushMatrix();
+ gpuPushMatrix();
+ gpuMultMatrix(t->obedit->obmat);
- glMultMatrixf(t->obedit->obmat);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (sld->use_even == true) {
float co_a[3], co_b[3], co_mark[3];
@@ -6878,39 +6892,35 @@ static void drawEdgeSlide(TransInfo *t)
add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
glLineWidth(line_size);
- UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- glBegin(GL_LINES);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBeginAtMost(PRIM_LINES, 4);
if (curr_sv->v_side[0]) {
- glVertex3fv(curr_sv->v_side[0]->co);
- glVertex3fv(curr_sv->v_co_orig);
+ immVertex3fv(pos, curr_sv->v_side[0]->co);
+ immVertex3fv(pos, curr_sv->v_co_orig);
}
if (curr_sv->v_side[1]) {
- glVertex3fv(curr_sv->v_side[1]->co);
- glVertex3fv(curr_sv->v_co_orig);
+ immVertex3fv(pos, curr_sv->v_side[1]->co);
+ immVertex3fv(pos, curr_sv->v_co_orig);
}
- glEnd();
+ immEnd();
- UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
+ immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
glPointSize(ctrl_size);
- glBegin(GL_POINTS);
+ immBegin(PRIM_POINTS, 1);
if (sld->flipped) {
- if (curr_sv->v_side[1]) glVertex3fv(curr_sv->v_side[1]->co);
+ if (curr_sv->v_side[1]) immVertex3fv(pos, curr_sv->v_side[1]->co);
}
else {
- if (curr_sv->v_side[0]) glVertex3fv(curr_sv->v_side[0]->co);
+ if (curr_sv->v_side[0]) immVertex3fv(pos, curr_sv->v_side[0]->co);
}
- glEnd();
+ immEnd();
- UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
+ immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
glPointSize(guide_size);
- glBegin(GL_POINTS);
-#if 0
- interp_v3_v3v3(co_mark, co_b, co_a, fac);
- glVertex3fv(co_mark);
-#endif
+ immBegin(PRIM_POINTS, 1);
interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
- glVertex3fv(co_mark);
- glEnd();
+ immVertex3fv(pos, co_mark);
+ immEnd();
}
else {
if (is_clamp == false) {
@@ -6920,8 +6930,8 @@ static void drawEdgeSlide(TransInfo *t)
const int alpha_shade = -160;
glLineWidth(line_size);
- UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- glBegin(GL_LINES);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBegin(PRIM_LINES, sld->totsv * 2);
sv = sld->sv;
for (i = 0; i < sld->totsv; i++, sv++) {
@@ -6939,18 +6949,19 @@ static void drawEdgeSlide(TransInfo *t)
add_v3_v3(a, sv->v_co_orig);
add_v3_v3(b, sv->v_co_orig);
- glVertex3fv(a);
- glVertex3fv(b);
+ immVertex3fv(pos, a);
+ immVertex3fv(pos, b);
}
- glEnd();
+ immEnd();
}
else {
BLI_assert(0);
}
}
- glPopMatrix();
- glPopAttrib();
+ immUnbindProgram();
+
+ gpuPopMatrix();
glDisable(GL_BLEND);
@@ -7474,19 +7485,22 @@ static void drawVertSlide(TransInfo *t)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT | GL_POINT_BIT);
- glPushMatrix();
-
- glMultMatrixf(t->obedit->obmat);
+ gpuPushMatrix();
+ gpuMultMatrix(t->obedit->obmat);
glLineWidth(line_size);
- UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- glBegin(GL_LINES);
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+
+ immBegin(PRIM_LINES, sld->totsv * 2);
if (is_clamp) {
sv = sld->sv;
for (i = 0; i < sld->totsv; i++, sv++) {
- glVertex3fv(sv->co_orig_3d);
- glVertex3fv(sv->co_link_orig_3d[sv->co_link_curr]);
+ immVertex3fv(shdr_pos, sv->co_orig_3d);
+ immVertex3fv(shdr_pos, sv->co_link_orig_3d[sv->co_link_curr]);
}
}
else {
@@ -7499,21 +7513,21 @@ static void drawVertSlide(TransInfo *t)
add_v3_v3(a, sv->co_orig_3d);
add_v3_v3(b, sv->co_orig_3d);
- glVertex3fv(a);
- glVertex3fv(b);
+ immVertex3fv(shdr_pos, a);
+ immVertex3fv(shdr_pos, b);
}
}
- glEnd();
+ immEnd();
glPointSize(ctrl_size);
- glBegin(GL_POINTS);
- glVertex3fv((sld->flipped && sld->use_even) ?
+ immBegin(PRIM_POINTS, 1);
+ immVertex3fv(shdr_pos, (sld->flipped && sld->use_even) ?
curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
curr_sv->co_orig_3d);
- glEnd();
+ immEnd();
- glDisable(GL_BLEND);
+ immUnbindProgram();
/* direction from active vertex! */
if ((t->mval[0] != t->mouse.imval[0]) ||
@@ -7537,19 +7551,28 @@ static void drawVertSlide(TransInfo *t)
add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
- glLineWidth(1);
- setlinestyle(1);
+ glLineWidth(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- cpack(0xffffff);
- glBegin(GL_LINES);
- glVertex3fv(curr_sv->co_orig_3d);
- glVertex3fv(co_dest_3d);
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, curr_sv->co_orig_3d);
+ immVertex3fv(shdr_pos, co_dest_3d);
+ immEnd();
- glEnd();
+ immUnbindProgram();
}
- glPopMatrix();
- glPopAttrib();
+ gpuPopMatrix();
if (v3d && v3d->zbuf)
glEnable(GL_DEPTH_TEST);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index d60eb2f0778..5544b08bbe9 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -50,6 +50,7 @@ struct Object;
struct View3D;
struct ScrArea;
struct Scene;
+struct SceneLayer;
struct bConstraint;
struct wmKeyMap;
struct wmKeyConfig;
@@ -464,6 +465,7 @@ typedef struct TransInfo {
struct ScrArea *sa;
struct ARegion *ar;
struct Scene *scene;
+ struct SceneLayer *scene_layer;
struct ToolSettings *settings;
struct wmTimer *animtimer;
struct wmKeyMap *keymap; /* so we can do lookups for header text */
@@ -496,8 +498,7 @@ typedef struct TransInfo {
#define T_CAMERA (1 << 4)
// trans on points, having no rotation/scale
#define T_POINTS (1 << 6)
- // for manipulator exceptions, like scaling using center point, drawing help lines
-#define T_USES_MANIPULATOR (1 << 7)
+/* empty slot - (1 << 7) */
/* restrictions flags */
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
@@ -634,7 +635,10 @@ void flushTransMasking(TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
void restoreBones(TransInfo *t);
-/*********************** exported from transform_manipulator.c ********** */
+/*********************** transform_manipulator.c ********** */
+
+#define MANIPULATOR_AXIS_LINE_WIDTH 2.0
+
bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
/*********************** TransData Creation and General Handling *********** */
@@ -649,7 +653,7 @@ bool transdata_check_local_islands(TransInfo *t, short around);
int count_set_pose_transflags(int *out_mode, short around, struct Object *ob);
/* auto-keying stuff used by special_aftertrans_update */
-void autokeyframe_ob_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode);
+void autokeyframe_ob_cb_func(struct bContext *C, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct Object *ob, int tmode);
void autokeyframe_pose_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode, short targetless_ik);
/*********************** Constraints *****************************/
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index d7b670b6476..7b658d9c636 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -40,9 +40,11 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
@@ -704,8 +706,6 @@ void drawConstraint(TransInfo *t)
return;
if (!(tc->mode & CON_APPLY))
return;
- if (t->flag & T_USES_MANIPULATOR)
- return;
if (t->flag & T_NO_CONSTRAINT)
return;
@@ -715,7 +715,6 @@ void drawConstraint(TransInfo *t)
else {
if (tc->mode & CON_SELECT) {
float vec[3];
- char col2[3] = {255, 255, 255};
int depth_test_enabled;
convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1]));
@@ -725,18 +724,29 @@ void drawConstraint(TransInfo *t)
drawLine(t, t->center_global, tc->mtx[1], 'Y', 0);
drawLine(t, t->center_global, tc->mtx[2], 'Z', 0);
- glColor3ubv((GLubyte *)col2);
-
depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
if (depth_test_enabled)
glDisable(GL_DEPTH_TEST);
- setlinestyle(1);
- glBegin(GL_LINES);
- glVertex3fv(t->center_global);
- glVertex3fv(vec);
- glEnd();
- setlinestyle(0);
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ immUniform1f("dash_width", 2.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(shdr_pos, t->center_global);
+ immVertex3fv(shdr_pos, vec);
+ immEnd();
+
+ immUnbindProgram();
if (depth_test_enabled)
glEnable(GL_DEPTH_TEST);
@@ -762,8 +772,6 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
float tmat[4][4], imat[4][4];
int depth_test_enabled;
- UI_ThemeColor(TH_GRID);
-
if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
copy_m4_m4(tmat, rv3d->viewmat);
invert_m4_m4(imat, tmat);
@@ -773,13 +781,13 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
unit_m4(imat);
}
- glPushMatrix();
+ gpuPushMatrix();
if (t->spacetype == SPACE_VIEW3D) {
/* pass */
}
else if (t->spacetype == SPACE_IMAGE) {
- glScalef(1.0f / t->aspect[0], 1.0f / t->aspect[1], 1.0f);
+ gpuScale2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
}
else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) {
/* only scale y */
@@ -789,21 +797,28 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
float ysize = BLI_rctf_size_y(datamask);
float xmask = BLI_rcti_size_x(mask);
float ymask = BLI_rcti_size_y(mask);
- glScalef(1.0f, (ysize / xsize) * (xmask / ymask), 1.0f);
+ gpuScale2f(1.0f, (ysize / xsize) * (xmask / ymask));
}
depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
if (depth_test_enabled)
glDisable(GL_DEPTH_TEST);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_GRID);
+
set_inverted_drawing(1);
- drawcircball(GL_LINE_LOOP, t->center_global, t->prop_size, imat);
+ imm_drawcircball(t->center_global, t->prop_size, imat, pos);
set_inverted_drawing(0);
+ immUnbindProgram();
+
if (depth_test_enabled)
glEnable(GL_DEPTH_TEST);
- glPopMatrix();
+ gpuPopMatrix();
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 071800a87d1..54c943661c0 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -72,6 +72,7 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_layer.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -285,13 +286,13 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
static void createTransTexspace(TransInfo *t)
{
- Scene *scene = t->scene;
+ SceneLayer *sl = t->scene_layer;
TransData *td;
Object *ob;
ID *id;
short *texflag;
- ob = OBACT;
+ ob = OBACT_NEW;
if (ob == NULL) { // Shouldn't logically happen, but still...
t->total = 0;
@@ -828,9 +829,6 @@ static void pose_grab_with_ik_clear(Object *ob)
bKinematicConstraint *data;
bPoseChannel *pchan;
bConstraint *con, *next;
-#ifdef WITH_LEGACY_DEPSGRAPH
- bool need_dependency_update = false;
-#endif
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* clear all temporary lock flags */
@@ -845,9 +843,6 @@ static void pose_grab_with_ik_clear(Object *ob)
data = con->data;
if (data->flag & CONSTRAINT_IK_TEMP) {
/* iTaSC needs clear for removed constraints */
-#ifdef WITH_LEGACY_DEPSGRAPH
- need_dependency_update = true;
-#endif
BIK_clear_data(ob->pose);
BLI_remlink(&pchan->constraints, con);
@@ -862,13 +857,8 @@ static void pose_grab_with_ik_clear(Object *ob)
}
}
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!DEG_depsgraph_use_legacy() && need_dependency_update)
-#endif
- {
- /* TODO(sergey): Consider doing partial update only. */
- DAG_relations_tag_update(G.main);
- }
+ /* TODO(sergey): Consider doing partial update only. */
+ DAG_relations_tag_update(G.main);
}
/* adds the IK to pchan - returns if added */
@@ -1021,13 +1011,8 @@ static short pose_grab_with_ik(Object *ob)
/* iTaSC needs clear for new IK constraints */
if (tot_ik) {
BIK_clear_data(ob->pose);
-#ifdef WITH_LEGACY_DEPSGRAPH
- if (!DEG_depsgraph_use_legacy())
-#endif
- {
- /* TODO(sergey): Consuder doing partial update only. */
- DAG_relations_tag_update(G.main);
- }
+ /* TODO(sergey): Consuder doing partial update only. */
+ DAG_relations_tag_update(G.main);
}
return (tot_ik) ? 1 : 0;
@@ -1815,7 +1800,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
Base *base = CTX_data_active_base(C);
Object *ob = CTX_data_active_object(C);
ParticleEditSettings *pset = PE_settings(t->scene);
- PTCacheEdit *edit = PE_get_current(t->scene, ob);
+ PTCacheEdit *edit = PE_get_current(t->scene, t->scene_layer, ob);
ParticleSystem *psys = NULL;
ParticleSystemModifierData *psmd = NULL;
PTCacheEditPoint *point;
@@ -1932,8 +1917,9 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
void flushTransParticles(TransInfo *t)
{
Scene *scene = t->scene;
- Object *ob = OBACT;
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ SceneLayer *sl = t->scene_layer;
+ Object *ob = OBACT_NEW;
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd = NULL;
PTCacheEditPoint *point;
@@ -1972,7 +1958,7 @@ void flushTransParticles(TransInfo *t)
point->flag |= PEP_EDIT_RECALC;
}
- PE_update_object(scene, OBACT, 1);
+ PE_update_object(scene, sl, OBACT_NEW, 1);
}
/* ********************* mesh ****************** */
@@ -2867,7 +2853,6 @@ static void createTransUVs(bContext *C, TransInfo *t)
const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (!ED_space_image_show_uvedit(sima, t->obedit))
return;
@@ -2891,10 +2876,9 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
BMLoop *l;
- if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (!uvedit_face_visible_test(scene, ima, efa)) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
continue;
}
@@ -5448,12 +5432,11 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
/* it deselects Bases, so we have to call the clear function always after */
static void set_trans_object_base_flags(TransInfo *t)
{
- Scene *scene = t->scene;
- View3D *v3d = t->view;
+ SceneLayer *sl = t->scene_layer;
/*
* if Base selected and has parent selected:
- * base->flag = BA_WAS_SEL
+ * base->flag_legacy = BA_WAS_SEL
*/
Base *base;
@@ -5462,32 +5445,32 @@ static void set_trans_object_base_flags(TransInfo *t)
return;
/* makes sure base flags and object flags are identical */
- BKE_scene_base_flag_to_objects(t->scene);
+ BKE_scene_base_flag_to_objects(t->scene_layer);
/* Make sure depsgraph is here. */
DAG_scene_relations_update(G.main, t->scene);
/* handle pending update events, otherwise they got copied below */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
if (base->object->recalc & OB_RECALC_ALL) {
/* TODO(sergey): Ideally, it's not needed. */
BKE_object_handle_update(G.main->eval_ctx, t->scene, base->object);
}
}
- for (base = scene->base.first; base; base = base->next) {
- base->flag &= ~BA_WAS_SEL;
+ for (base = sl->object_bases.first; base; base = base->next) {
+ base->flag_legacy &= ~BA_WAS_SEL;
- if (TESTBASELIB_BGMODE(v3d, scene, base)) {
+ if (TESTBASELIB_BGMODE_NEW(base)) {
Object *ob = base->object;
Object *parsel = ob->parent;
/* if parent selected, deselect */
while (parsel) {
- if (parsel->flag & SELECT) {
- Base *parbase = BKE_scene_base_find(scene, parsel);
+ Base *parbase = BKE_scene_layer_base_find(sl, parsel);
+ if (parbase->flag & BASE_SELECTED) {
if (parbase) { /* in rare cases this can fail */
- if (TESTBASELIB_BGMODE(v3d, scene, parbase)) {
+ if (TESTBASELIB_BGMODE_NEW(parbase)) {
break;
}
}
@@ -5500,29 +5483,24 @@ static void set_trans_object_base_flags(TransInfo *t)
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
(t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL))
{
- base->flag |= BA_TRANSFORM_CHILD;
+ base->flag_legacy |= BA_TRANSFORM_CHILD;
}
else {
- base->flag &= ~SELECT;
- base->flag |= BA_WAS_SEL;
+ base->flag &= ~BASE_SELECTED;
+ base->flag_legacy |= BA_WAS_SEL;
}
}
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
- /* all recalc flags get flushed to all layers, so a layer flip later on works fine */
-#ifdef WITH_LEGACY_DEPSGRAPH
- DAG_scene_flush_update(G.main, t->scene, -1, 0);
-#endif
-
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
if (base->object->recalc & OB_RECALC_OB)
- base->flag |= BA_HAS_RECALC_OB;
+ base->flag_legacy |= BA_HAS_RECALC_OB;
if (base->object->recalc & OB_RECALC_DATA)
- base->flag |= BA_HAS_RECALC_DATA;
+ base->flag_legacy |= BA_HAS_RECALC_DATA;
}
}
@@ -5544,8 +5522,7 @@ static bool mark_children(Object *ob)
static int count_proportional_objects(TransInfo *t)
{
int total = 0;
- Scene *scene = t->scene;
- View3D *v3d = t->view;
+ SceneLayer *sl = t->scene_layer;
Base *base;
/* rotations around local centers are allowed to propagate, so we take all objects */
@@ -5553,8 +5530,8 @@ static int count_proportional_objects(TransInfo *t)
(t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL)))
{
/* mark all parents */
- for (base = scene->base.first; base; base = base->next) {
- if (TESTBASELIB_BGMODE(v3d, scene, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (TESTBASELIB_BGMODE_NEW(base)) {
Object *parent = base->object->parent;
/* flag all parents */
@@ -5566,22 +5543,24 @@ static int count_proportional_objects(TransInfo *t)
}
/* mark all children */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
/* all base not already selected or marked that is editable */
- if ((base->object->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
- (BASE_EDITABLE_BGMODE(v3d, scene, base)))
+ if ((base->object->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
+ (base->flag & BASE_SELECTED) == 0 &&
+ (BASE_EDITABLE_BGMODE_NEW(base)))
{
mark_children(base->object);
}
}
}
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
/* if base is not selected, not a parent of selection or not a child of selection and it is editable */
- if ((ob->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
- (BASE_EDITABLE_BGMODE(v3d, scene, base)))
+ if ((ob->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
+ (base->flag & BASE_SELECTED) == 0 &&
+ (BASE_EDITABLE_BGMODE_NEW(base)))
{
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
@@ -5593,17 +5572,14 @@ static int count_proportional_objects(TransInfo *t)
/* all recalc flags get flushed to all layers, so a layer flip later on works fine */
DAG_scene_relations_update(G.main, t->scene);
-#ifdef WITH_LEGACY_DEPSGRAPH
- DAG_scene_flush_update(G.main, t->scene, -1, 0);
-#endif
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
if (base->object->recalc & OB_RECALC_OB)
- base->flag |= BA_HAS_RECALC_OB;
+ base->flag_legacy |= BA_HAS_RECALC_OB;
if (base->object->recalc & OB_RECALC_DATA)
- base->flag |= BA_HAS_RECALC_DATA;
+ base->flag_legacy |= BA_HAS_RECALC_DATA;
}
return total;
@@ -5611,14 +5587,15 @@ static int count_proportional_objects(TransInfo *t)
static void clear_trans_object_base_flags(TransInfo *t)
{
- Scene *sce = t->scene;
+ SceneLayer *sl = t->scene_layer;
Base *base;
- for (base = sce->base.first; base; base = base->next) {
- if (base->flag & BA_WAS_SEL)
- base->flag |= SELECT;
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (base->flag_legacy & BA_WAS_SEL) {
+ base->flag |= BASE_SELECTED;
+ }
- base->flag &= ~(BA_WAS_SEL | BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA | BA_TEMP_TAG | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT);
+ base->flag_legacy &= ~(BA_WAS_SEL | BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA | BA_TEMP_TAG | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT);
}
}
@@ -5626,7 +5603,7 @@ static void clear_trans_object_base_flags(TransInfo *t)
* tmode: should be a transform mode
*/
// NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases
-void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, int tmode)
+void autokeyframe_ob_cb_func(bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, Object *ob, int tmode)
{
ID *id = &ob->id;
FCurve *fcu;
@@ -5675,7 +5652,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
}
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
if (v3d->around == V3D_AROUND_ACTIVE) {
- if (ob != OBACT)
+ if (ob != OBACT_NEW)
do_loc = true;
}
else if (v3d->around == V3D_AROUND_CURSOR)
@@ -5686,7 +5663,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
}
else if (tmode == TFM_RESIZE) {
if (v3d->around == V3D_AROUND_ACTIVE) {
- if (ob != OBACT)
+ if (ob != OBACT_NEW)
do_loc = true;
}
else if (v3d->around == V3D_AROUND_CURSOR)
@@ -6405,10 +6382,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
else if (t->options & CTX_PAINT_CURVE) {
/* pass */
}
- else if ((t->scene->basact) &&
- (ob = t->scene->basact->object) &&
+ else if ((t->scene_layer->basact) &&
+ (ob = t->scene_layer->basact->object) &&
(ob->mode & OB_MODE_PARTICLE_EDIT) &&
- PE_get_current(t->scene, ob))
+ PE_get_current(t->scene, t->scene_layer, ob))
{
/* do nothing */
}
@@ -6449,7 +6426,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
/* Set autokey if necessary */
if (!canceled) {
- autokeyframe_ob_cb_func(C, t->scene, (View3D *)t->view, ob, t->mode);
+ autokeyframe_ob_cb_func(C, t->scene, t->scene_layer, (View3D *)t->view, ob, t->mode);
}
/* restore rigid body transform */
@@ -6484,8 +6461,6 @@ int special_transform_moving(TransInfo *t)
static void createTransObject(bContext *C, TransInfo *t)
{
- Scene *scene = t->scene;
-
TransData *td = NULL;
TransDataExtension *tx;
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
@@ -6535,15 +6510,16 @@ static void createTransObject(bContext *C, TransInfo *t)
CTX_DATA_END;
if (is_prop_edit) {
- View3D *v3d = t->view;
+ SceneLayer *sl = t->scene_layer;
Base *base;
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
/* if base is not selected, not a parent of selection or not a child of selection and it is editable */
- if ((ob->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
- BASE_EDITABLE_BGMODE(v3d, scene, base))
+ if ((ob->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
+ (base->flag & BASE_SELECTED) == 0 &&
+ BASE_EDITABLE_BGMODE_NEW(base))
{
td->protectflag = ob->protectflag;
td->ext = tx;
@@ -7990,7 +7966,8 @@ static void createTransGPencil(bContext *C, TransInfo *t)
void createTransData(bContext *C, TransInfo *t)
{
Scene *scene = t->scene;
- Object *ob = OBACT;
+ SceneLayer *sl = t->scene_layer;
+ Object *ob = OBACT_NEW;
/* if tests must match recalcData for correct updates */
if (t->options & CTX_TEXTURE) {
@@ -8155,17 +8132,16 @@ void createTransData(bContext *C, TransInfo *t)
* lines below just check is also visible */
Object *ob_armature = modifiers_isDeformedByArmature(ob);
if (ob_armature && ob_armature->mode & OB_MODE_POSE) {
- Base *base_arm = BKE_scene_base_find(t->scene, ob_armature);
+ Base *base_arm = BKE_scene_layer_base_find(t->scene_layer, ob_armature);
if (base_arm) {
- View3D *v3d = t->view;
- if (BASE_VISIBLE(v3d, base_arm)) {
+ if (BASE_VISIBLE_NEW(base_arm)) {
createTransPose(t, ob_armature);
}
}
}
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) {
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, sl, ob))) {
createTransParticleVerts(C, t);
t->flag |= T_POINTS;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index f78a23be7b8..0009ae13117 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -62,8 +62,8 @@
#include "RNA_access.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "BIK_api.h"
@@ -315,7 +315,7 @@ static bool fcu_test_selected(FCurve *fcu)
/* helper for recalcData() - for Action Editor transforms */
static void recalcData_actedit(TransInfo *t)
{
- Scene *scene = t->scene;
+ SceneLayer *sl= t->scene_layer;
SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
bAnimContext ac = {NULL};
@@ -326,7 +326,8 @@ static void recalcData_actedit(TransInfo *t)
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.scene = t->scene;
- ac.obact = OBACT;
+ ac.scene_layer = t->scene_layer;
+ ac.obact = OBACT_NEW;
ac.sa = t->sa;
ac.ar = t->ar;
ac.sl = (t->sa) ? t->sa->spacedata.first : NULL;
@@ -363,7 +364,7 @@ static void recalcData_actedit(TransInfo *t)
static void recalcData_graphedit(TransInfo *t)
{
SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first;
- Scene *scene;
+ SceneLayer *sl = t->scene_layer;
ListBase anim_data = {NULL, NULL};
bAnimContext ac = {NULL};
@@ -374,8 +375,9 @@ static void recalcData_graphedit(TransInfo *t)
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
- scene = ac.scene = t->scene;
- ac.obact = OBACT;
+ ac.scene = t->scene;
+ ac.scene_layer = t->scene_layer;
+ ac.obact = OBACT_NEW;
ac.sa = t->sa;
ac.ar = t->ar;
ac.sl = (t->sa) ? t->sa->spacedata.first : NULL;
@@ -709,7 +711,7 @@ static void recalcData_spaceclip(TransInfo *t)
/* helper for recalcData() - for object transforms, typically in the 3D view */
static void recalcData_objects(TransInfo *t)
{
- Base *base = t->scene->basact;
+ Base *base = t->scene_layer->basact;
if (t->obedit) {
if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
@@ -896,7 +898,7 @@ static void recalcData_objects(TransInfo *t)
else
BKE_pose_where_is(t->scene, ob);
}
- else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, base->object)) {
+ else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, t->scene_layer, base->object)) {
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
@@ -926,7 +928,7 @@ static void recalcData_objects(TransInfo *t)
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
animrecord_check_state(t->scene, &ob->id, t->animtimer);
- autokeyframe_ob_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode);
+ autokeyframe_ob_cb_func(t->context, t->scene, t->scene_layer, (View3D *)t->view, ob, t->mode);
}
/* sets recalc flags fully, instead of flushing existing ones
@@ -1032,11 +1034,10 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
if (t->spacetype == SPACE_VIEW3D) {
View3D *v3d = t->view;
- glPushMatrix();
-
- //if (t->obedit) glLoadMatrixf(t->obedit->obmat); // sets opengl viewing
-
-
+ gpuPushMatrix();
+
+ // if (t->obedit) gpuLoadMatrix(t->obedit->obmat); // sets opengl viewing
+
copy_v3_v3(v3, dir);
mul_v3_fl(v3, v3d->far);
@@ -1050,15 +1051,20 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
UI_GetThemeColor3ubv(TH_GRID, col);
}
UI_make_axis_color(col, col2, axis);
- glColor3ubv(col2);
-
- setlinestyle(0);
- glBegin(GL_LINES);
- glVertex3fv(v1);
- glVertex3fv(v2);
- glEnd();
-
- glPopMatrix();
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(col2);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immEnd();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
}
}
@@ -1104,6 +1110,7 @@ static int initTransInfo_edit_pet_to_flag(const int proportional)
void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event)
{
Scene *sce = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
ARegion *ar = CTX_wm_region(C);
ScrArea *sa = CTX_wm_area(C);
@@ -1113,6 +1120,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
PropertyRNA *prop;
t->scene = sce;
+ t->scene_layer = sl;
t->sa = sa;
t->ar = ar;
t->obedit = obedit;
@@ -1220,7 +1228,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
/* turn manipulator off during transform */
- // FIXME: but don't do this when USING the manipulator...
if (t->flag & T_MODAL) {
t->twtype = v3d->twtype;
v3d->twtype = 0;
@@ -1767,8 +1774,8 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
}
else if (t->flag & T_POSE) {
- Scene *scene = t->scene;
- Object *ob = OBACT;
+ SceneLayer *sl = t->scene_layer;
+ Object *ob = OBACT_NEW;
if (ob) {
bPoseChannel *pchan = BKE_pose_channel_active(ob);
if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) {
@@ -1778,7 +1785,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
}
else if (t->options & CTX_PAINT_CURVE) {
- Paint *p = BKE_paint_get_active(t->scene);
+ Paint *p = BKE_paint_get_active(t->scene, t->scene_layer);
Brush *br = p->brush;
PaintCurve *pc = br->paint_curve;
copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]);
@@ -1787,9 +1794,10 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
else {
/* object mode */
- Scene *scene = t->scene;
- Object *ob = OBACT;
- if (ob && (!select_only || (ob->flag & SELECT))) {
+ SceneLayer *sl = t->scene_layer;
+ Object *ob = OBACT_NEW;
+ Base *base = BASACT_NEW;
+ if (ob && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) {
copy_v3_v3(r_center, ob->obmat[3]);
ok = true;
}
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index ab2a0225abc..009cb2bac63 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -39,6 +39,7 @@
#include "DNA_curve_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_manipulator_types.h"
#include "DNA_meta_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
@@ -67,16 +68,22 @@
#include "ED_armature.h"
#include "ED_curve.h"
+#include "ED_object.h"
#include "ED_particle.h"
#include "ED_view3d.h"
#include "ED_gpencil.h"
+#include "ED_screen.h"
#include "UI_resources.h"
/* local module include */
#include "transform.h"
+#include "MEM_guardedalloc.h"
+
#include "GPU_select.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
/* return codes for select, and drawing flags */
@@ -88,25 +95,350 @@
#define MAN_ROT_X (1 << 3)
#define MAN_ROT_Y (1 << 4)
#define MAN_ROT_Z (1 << 5)
-#define MAN_ROT_V (1 << 6)
-#define MAN_ROT_T (1 << 7)
-#define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z | MAN_ROT_V | MAN_ROT_T)
+#define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z)
#define MAN_SCALE_X (1 << 8)
#define MAN_SCALE_Y (1 << 9)
#define MAN_SCALE_Z (1 << 10)
#define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z)
-/* color codes */
-
-#define MAN_RGB 0
-#define MAN_GHOST 1
-#define MAN_MOVECOL 2
-
/* threshold for testing view aligned manipulator axis */
#define TW_AXIS_DOT_MIN 0.02f
#define TW_AXIS_DOT_MAX 0.1f
+/* axes as index */
+enum {
+ MAN_AXIS_TRANS_X = 0,
+ MAN_AXIS_TRANS_Y,
+ MAN_AXIS_TRANS_Z,
+ MAN_AXIS_TRANS_C,
+
+ MAN_AXIS_ROT_X,
+ MAN_AXIS_ROT_Y,
+ MAN_AXIS_ROT_Z,
+ MAN_AXIS_ROT_C,
+ MAN_AXIS_ROT_T, /* trackball rotation */
+
+ MAN_AXIS_SCALE_X,
+ MAN_AXIS_SCALE_Y,
+ MAN_AXIS_SCALE_Z,
+ MAN_AXIS_SCALE_C,
+
+ /* special */
+ MAN_AXIS_TRANS_XY,
+ MAN_AXIS_TRANS_YZ,
+ MAN_AXIS_TRANS_ZX,
+
+ MAN_AXIS_SCALE_XY,
+ MAN_AXIS_SCALE_YZ,
+ MAN_AXIS_SCALE_ZX,
+
+ MAN_AXIS_LAST,
+};
+
+/* axis types */
+enum {
+ MAN_AXES_ALL = 0,
+ MAN_AXES_TRANSLATE,
+ MAN_AXES_ROTATE,
+ MAN_AXES_SCALE,
+};
+
+typedef struct ManipulatorGroup {
+ bool all_hidden;
+
+ struct wmManipulator *translate_x,
+ *translate_y,
+ *translate_z,
+ *translate_xy,
+ *translate_yz,
+ *translate_zx,
+ *translate_c,
+
+ *rotate_x,
+ *rotate_y,
+ *rotate_z,
+ *rotate_c,
+ *rotate_t, /* trackball rotation */
+
+ *scale_x,
+ *scale_y,
+ *scale_z,
+ *scale_xy,
+ *scale_yz,
+ *scale_zx,
+ *scale_c;
+} ManipulatorGroup;
+
+
+/* **************** Utilities **************** */
+
+/* loop over axes */
+#define MAN_ITER_AXES_BEGIN(axis, axis_idx) \
+ { \
+ wmManipulator *axis; \
+ int axis_idx; \
+ for (axis_idx = 0; axis_idx < MAN_AXIS_LAST; axis_idx++) { \
+ axis = manipulator_get_axis_from_index(man, axis_idx);
+
+#define MAN_ITER_AXES_END \
+ } \
+ } ((void)0)
+
+static wmManipulator *manipulator_get_axis_from_index(const ManipulatorGroup *man, const short axis_idx)
+{
+ BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST));
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ return man->translate_x;
+ case MAN_AXIS_TRANS_Y:
+ return man->translate_y;
+ case MAN_AXIS_TRANS_Z:
+ return man->translate_z;
+ case MAN_AXIS_TRANS_XY:
+ return man->translate_xy;
+ case MAN_AXIS_TRANS_YZ:
+ return man->translate_yz;
+ case MAN_AXIS_TRANS_ZX:
+ return man->translate_zx;
+ case MAN_AXIS_TRANS_C:
+ return man->translate_c;
+ case MAN_AXIS_ROT_X:
+ return man->rotate_x;
+ case MAN_AXIS_ROT_Y:
+ return man->rotate_y;
+ case MAN_AXIS_ROT_Z:
+ return man->rotate_z;
+ case MAN_AXIS_ROT_C:
+ return man->rotate_c;
+ case MAN_AXIS_ROT_T:
+ return man->rotate_t;
+ case MAN_AXIS_SCALE_X:
+ return man->scale_x;
+ case MAN_AXIS_SCALE_Y:
+ return man->scale_y;
+ case MAN_AXIS_SCALE_Z:
+ return man->scale_z;
+ case MAN_AXIS_SCALE_XY:
+ return man->scale_xy;
+ case MAN_AXIS_SCALE_YZ:
+ return man->scale_yz;
+ case MAN_AXIS_SCALE_ZX:
+ return man->scale_zx;
+ case MAN_AXIS_SCALE_C:
+ return man->scale_c;
+ }
+
+ return NULL;
+}
+
+static short manipulator_get_axis_type(const ManipulatorGroup *man, const wmManipulator *axis)
+{
+ if (ELEM(axis, man->translate_x, man->translate_y, man->translate_z, man->translate_c,
+ man->translate_xy, man->translate_yz, man->translate_zx))
+ {
+ return MAN_AXES_TRANSLATE;
+ }
+ else if (ELEM(axis, man->rotate_x, man->rotate_y, man->rotate_z, man->rotate_c, man->rotate_t)) {
+ return MAN_AXES_ROTATE;
+ }
+ else {
+ return MAN_AXES_SCALE;
+ }
+}
+
+/* get index within axis type, so that x == 0, y == 1 and z == 2, no matter which axis type */
+static unsigned int manipulator_index_normalize(const int axis_idx)
+{
+ if (axis_idx > MAN_AXIS_TRANS_ZX) {
+ return axis_idx - 16;
+ }
+ else if (axis_idx > MAN_AXIS_SCALE_C) {
+ return axis_idx - 13;
+ }
+ else if (axis_idx > MAN_AXIS_ROT_T) {
+ return axis_idx - 9;
+ }
+ else if (axis_idx > MAN_AXIS_TRANS_C) {
+ return axis_idx - 4;
+ }
+
+ return axis_idx;
+}
+
+static bool manipulator_is_axis_visible(
+ const View3D *v3d, const RegionView3D *rv3d,
+ const float idot[3], const int axis_type, const int axis_idx)
+{
+ const unsigned int aidx_norm = manipulator_index_normalize(axis_idx);
+ /* don't draw axis perpendicular to the view */
+ if (aidx_norm < 3 && idot[aidx_norm] < TW_AXIS_DOT_MIN) {
+ return false;
+ }
+
+ if ((axis_type == MAN_AXES_TRANSLATE && !(v3d->twtype & V3D_MANIP_TRANSLATE)) ||
+ (axis_type == MAN_AXES_ROTATE && !(v3d->twtype & V3D_MANIP_ROTATE)) ||
+ (axis_type == MAN_AXES_SCALE && !(v3d->twtype & V3D_MANIP_SCALE)))
+ {
+ return false;
+ }
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ return (rv3d->twdrawflag & MAN_TRANS_X);
+ case MAN_AXIS_TRANS_Y:
+ return (rv3d->twdrawflag & MAN_TRANS_Y);
+ case MAN_AXIS_TRANS_Z:
+ return (rv3d->twdrawflag & MAN_TRANS_Z);
+ case MAN_AXIS_TRANS_C:
+ return (rv3d->twdrawflag & MAN_TRANS_C);
+ case MAN_AXIS_ROT_X:
+ return (rv3d->twdrawflag & MAN_ROT_X);
+ case MAN_AXIS_ROT_Y:
+ return (rv3d->twdrawflag & MAN_ROT_Y);
+ case MAN_AXIS_ROT_Z:
+ return (rv3d->twdrawflag & MAN_ROT_Z);
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_ROT_T:
+ return (rv3d->twdrawflag & MAN_ROT_C);
+ case MAN_AXIS_SCALE_X:
+ return (rv3d->twdrawflag & MAN_SCALE_X);
+ case MAN_AXIS_SCALE_Y:
+ return (rv3d->twdrawflag & MAN_SCALE_Y);
+ case MAN_AXIS_SCALE_Z:
+ return (rv3d->twdrawflag & MAN_SCALE_Z);
+ case MAN_AXIS_SCALE_C:
+ return (rv3d->twdrawflag & MAN_SCALE_C && (v3d->twtype & V3D_MANIP_TRANSLATE) == 0);
+ case MAN_AXIS_TRANS_XY:
+ return (rv3d->twdrawflag & MAN_TRANS_X &&
+ rv3d->twdrawflag & MAN_TRANS_Y &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_TRANS_YZ:
+ return (rv3d->twdrawflag & MAN_TRANS_Y &&
+ rv3d->twdrawflag & MAN_TRANS_Z &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_TRANS_ZX:
+ return (rv3d->twdrawflag & MAN_TRANS_Z &&
+ rv3d->twdrawflag & MAN_TRANS_X &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_SCALE_XY:
+ return (rv3d->twdrawflag & MAN_SCALE_X &&
+ rv3d->twdrawflag & MAN_SCALE_Y &&
+ (v3d->twtype & V3D_MANIP_TRANSLATE) == 0 &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_SCALE_YZ:
+ return (rv3d->twdrawflag & MAN_SCALE_Y &&
+ rv3d->twdrawflag & MAN_SCALE_Z &&
+ (v3d->twtype & V3D_MANIP_TRANSLATE) == 0 &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_SCALE_ZX:
+ return (rv3d->twdrawflag & MAN_SCALE_Z &&
+ rv3d->twdrawflag & MAN_SCALE_X &&
+ (v3d->twtype & V3D_MANIP_TRANSLATE) == 0 &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ }
+ return false;
+}
+
+static void manipulator_get_axis_color(
+ const int axis_idx, const float idot[3],
+ float r_col[4], float r_col_hi[4])
+{
+ /* alpha values for normal/highlighted states */
+ const float alpha = 0.6f;
+ const float alpha_hi = 1.0f;
+ float alpha_fac;
+
+ const int axis_idx_norm = manipulator_index_normalize(axis_idx);
+ /* get alpha fac based on axis angle, to fade axis out when hiding it because it points towards view */
+ if (axis_idx_norm < 3) {
+ const float idot_axis = idot[axis_idx_norm];
+ alpha_fac = (idot_axis > TW_AXIS_DOT_MAX) ?
+ 1.0f : (idot_axis < TW_AXIS_DOT_MIN) ?
+ 0.0f : ((idot_axis - TW_AXIS_DOT_MIN) / (TW_AXIS_DOT_MAX - TW_AXIS_DOT_MIN));
+ }
+ else {
+ /* trackball rotation axis is a special case, we only draw a slight overlay */
+ alpha_fac = (axis_idx == MAN_AXIS_ROT_T) ? 0.1f : 1.0f;
+ }
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ UI_GetThemeColor4fv(TH_AXIS_X, r_col);
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ UI_GetThemeColor4fv(TH_AXIS_Y, r_col);
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ UI_GetThemeColor4fv(TH_AXIS_Z, r_col);
+ break;
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ copy_v4_fl(r_col, 1.0f);
+ break;
+ }
+
+ copy_v4_v4(r_col_hi, r_col);
+
+ r_col[3] = alpha * alpha_fac;
+ r_col_hi[3] = alpha_hi * alpha_fac;
+}
+
+static void manipulator_get_axis_constraint(const int axis_idx, int r_axis[3])
+{
+ zero_v3_int(r_axis);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ r_axis[0] = 1;
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ r_axis[0] = r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ r_axis[1] = r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ r_axis[2] = r_axis[0] = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/* **************** Preparation Stuff **************** */
+
/* transform widget center calc helper for below */
static void calc_tw_center(Scene *scene, const float co[3])
{
@@ -265,11 +597,12 @@ static int calc_manipulator_stats(const bContext *C)
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
Base *base;
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
int a, totsel = 0;
@@ -334,8 +667,6 @@ static int calc_manipulator_stats(const bContext *C)
}
else if (obedit) {
ob = obedit;
- if ((ob->lay & v3d->lay) == 0) return 0;
-
if (obedit->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMEditSelection ese;
@@ -518,8 +849,6 @@ static int calc_manipulator_stats(const bContext *C)
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
bool ok = false;
- if ((ob->lay & v3d->lay) == 0) return 0;
-
if ((v3d->around == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
/* doesn't check selection or visibility intentionally */
Bone *bone = pchan->bone;
@@ -557,7 +886,7 @@ static int calc_manipulator_stats(const bContext *C)
/* pass */
}
else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
PTCacheEditPoint *point;
PTCacheEditKey *ek;
int k;
@@ -583,11 +912,12 @@ static int calc_manipulator_stats(const bContext *C)
else {
/* we need the one selected object, if its not active */
- ob = OBACT;
- if (ob && !(ob->flag & SELECT)) ob = NULL;
+ base = BASACT_NEW;
+ ob = OBACT_NEW;
+ if (base && ((base->flag & BASE_SELECTED) == 0)) ob = NULL;
- for (base = scene->base.first; base; base = base->next) {
- if (TESTBASELIB(v3d, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (TESTBASELIB_NEW(base)) {
if (ob == NULL)
ob = base->object;
calc_tw_center(scene, base->object->obmat[3]);
@@ -671,1304 +1001,389 @@ static int calc_manipulator_stats(const bContext *C)
return totsel;
}
-/* don't draw axis perpendicular to the view */
-static void test_manipulator_axis(const bContext *C)
+static void manipulator_get_idot(RegionView3D *rv3d, float r_idot[3])
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
float view_vec[3], axis_vec[3];
- float idot;
- int i;
-
- const int twdrawflag_axis[3] = {
- (MAN_TRANS_X | MAN_SCALE_X),
- (MAN_TRANS_Y | MAN_SCALE_Y),
- (MAN_TRANS_Z | MAN_SCALE_Z)};
-
ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
-
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
normalize_v3_v3(axis_vec, rv3d->twmat[i]);
- rv3d->tw_idot[i] = idot = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
- if (idot < TW_AXIS_DOT_MIN) {
- rv3d->twdrawflag &= ~twdrawflag_axis[i];
- }
- }
-}
-
-
-/* ******************** DRAWING STUFFIES *********** */
-
-static float screen_aligned(RegionView3D *rv3d, float mat[4][4])
-{
- glTranslate3fv(mat[3]);
-
- /* sets view screen aligned */
- glRotatef(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]);
-
- return len_v3(mat[0]); /* draw scale */
-}
-
-
-/* radring = radius of doughnut rings
- * radhole = radius hole
- * start = starting segment (based on nrings)
- * end = end segment
- * nsides = amount of points in ring
- * nrigns = amount of rings
- */
-static void partial_doughnut(float radring, float radhole, int start, int end, int nsides, int nrings)
-{
- float theta, phi, theta1;
- float cos_theta, sin_theta;
- float cos_theta1, sin_theta1;
- float ring_delta, side_delta;
- int i, j, do_caps = true;
-
- if (start == 0 && end == nrings) do_caps = false;
-
- ring_delta = 2.0f * (float)M_PI / (float)nrings;
- side_delta = 2.0f * (float)M_PI / (float)nsides;
-
- theta = (float)M_PI + 0.5f * ring_delta;
- cos_theta = cosf(theta);
- sin_theta = sinf(theta);
-
- for (i = nrings - 1; i >= 0; i--) {
- theta1 = theta + ring_delta;
- cos_theta1 = cosf(theta1);
- sin_theta1 = sinf(theta1);
-
- if (do_caps && i == start) { // cap
- glBegin(GL_POLYGON);
- phi = 0.0;
- for (j = nsides; j >= 0; j--) {
- float cos_phi, sin_phi, dist;
-
- phi += side_delta;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- dist = radhole + radring * cos_phi;
-
- glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
- }
- glEnd();
- }
- if (i >= start && i <= end) {
- glBegin(GL_QUAD_STRIP);
- phi = 0.0;
- for (j = nsides; j >= 0; j--) {
- float cos_phi, sin_phi, dist;
-
- phi += side_delta;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- dist = radhole + radring * cos_phi;
-
- glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
- glVertex3f(cos_theta * dist, -sin_theta * dist, radring * sin_phi);
- }
- glEnd();
- }
-
- if (do_caps && i == end) { // cap
- glBegin(GL_POLYGON);
- phi = 0.0;
- for (j = nsides; j >= 0; j--) {
- float cos_phi, sin_phi, dist;
-
- phi -= side_delta;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- dist = radhole + radring * cos_phi;
-
- glVertex3f(cos_theta * dist, -sin_theta * dist, radring * sin_phi);
- }
- glEnd();
- }
-
-
- theta = theta1;
- cos_theta = cos_theta1;
- sin_theta = sin_theta1;
+ r_idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
}
}
-static char axisBlendAngle(float idot)
+static void manipulator_prepare_mat(const bContext *C, View3D *v3d, RegionView3D *rv3d)
{
- if (idot > TW_AXIS_DOT_MAX) {
- return 255;
- }
- else if (idot < TW_AXIS_DOT_MIN) {
- return 0;
- }
- else {
- return (char)(255.0f * (idot - TW_AXIS_DOT_MIN) / (TW_AXIS_DOT_MAX - TW_AXIS_DOT_MIN));
- }
-}
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
-/* three colors can be set:
- * gray for ghosting
- * moving: in transform theme color
- * else the red/green/blue
- */
-static void manipulator_setcolor(View3D *v3d, char axis, int colcode, unsigned char alpha)
-{
- unsigned char col[4] = {0};
- col[3] = alpha;
+ switch (v3d->around) {
+ case V3D_AROUND_CENTER_BOUNDS:
+ case V3D_AROUND_ACTIVE:
+ {
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Object *ob = OBACT_NEW;
- if (colcode == MAN_GHOST) {
- col[3] = 70;
- }
- else if (colcode == MAN_MOVECOL) {
- UI_GetThemeColor3ubv(TH_TRANSFORM, col);
- }
- else {
- switch (axis) {
- case 'C':
- UI_GetThemeColor3ubv(TH_TRANSFORM, col);
- if (v3d->twmode == V3D_MANIP_LOCAL) {
- col[0] = col[0] > 200 ? 255 : col[0] + 55;
- col[1] = col[1] > 200 ? 255 : col[1] + 55;
- col[2] = col[2] > 200 ? 255 : col[2] + 55;
+ if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
+ ((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
+ (!(ob->mode & OB_MODE_POSE)))
+ {
+ copy_v3_v3(rv3d->twmat[3], ob->obmat[3]);
}
- else if (v3d->twmode == V3D_MANIP_NORMAL) {
- col[0] = col[0] < 55 ? 0 : col[0] - 55;
- col[1] = col[1] < 55 ? 0 : col[1] - 55;
- col[2] = col[2] < 55 ? 0 : col[2] - 55;
+ else {
+ mid_v3_v3v3(rv3d->twmat[3], scene->twmin, scene->twmax);
}
break;
- case 'X':
- UI_GetThemeColor3ubv(TH_AXIS_X, col);
- break;
- case 'Y':
- UI_GetThemeColor3ubv(TH_AXIS_Y, col);
- break;
- case 'Z':
- UI_GetThemeColor3ubv(TH_AXIS_Z, col);
- break;
- default:
- BLI_assert(0);
- break;
}
+ case V3D_AROUND_LOCAL_ORIGINS:
+ case V3D_AROUND_CENTER_MEAN:
+ copy_v3_v3(rv3d->twmat[3], scene->twcent);
+ break;
+ case V3D_AROUND_CURSOR:
+ copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d));
+ break;
}
-
- glColor4ubv(col);
}
-static void manipulator_axis_order(RegionView3D *rv3d, int r_axis_order[3])
+/**
+ * Sets up \a r_start and \a r_len to define arrow line range.
+ * Needed to adjust line drawing for combined manipulator axis types.
+ */
+static void manipulator_line_range(const View3D *v3d, const short axis_type, float *r_start, float *r_len)
{
- float axis_values[3];
- float vec[3];
-
- ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], vec);
-
- axis_values[0] = -dot_v3v3(rv3d->twmat[0], vec);
- axis_values[1] = -dot_v3v3(rv3d->twmat[1], vec);
- axis_values[2] = -dot_v3v3(rv3d->twmat[2], vec);
+ const float ofs = 0.2f;
- axis_sort_v3(axis_values, r_axis_order);
-}
+ *r_start = 0.2f;
+ *r_len = 1.0f;
-/* viewmatrix should have been set OK, also no shademode! */
-static void draw_manipulator_axes_single(View3D *v3d, RegionView3D *rv3d, int colcode,
- int flagx, int flagy, int flagz, int axis,
- const bool is_picksel)
-{
- switch (axis) {
- case 0:
- /* axes */
- if (flagx) {
- if (is_picksel) {
- if (flagx & MAN_SCALE_X) GPU_select_load_id(MAN_SCALE_X);
- else if (flagx & MAN_TRANS_X) GPU_select_load_id(MAN_TRANS_X);
- }
- else {
- manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
- }
- glBegin(GL_LINES);
- glVertex3f(0.2f, 0.0f, 0.0f);
- glVertex3f(1.0f, 0.0f, 0.0f);
- glEnd();
+ switch (axis_type) {
+ case MAN_AXES_TRANSLATE:
+ if (v3d->twtype & V3D_MANIP_SCALE) {
+ *r_start = *r_len - ofs + 0.075f;
}
- break;
- case 1:
- if (flagy) {
- if (is_picksel) {
- if (flagy & MAN_SCALE_Y) GPU_select_load_id(MAN_SCALE_Y);
- else if (flagy & MAN_TRANS_Y) GPU_select_load_id(MAN_TRANS_Y);
- }
- else {
- manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
- }
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.2f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
+ if (v3d->twtype & V3D_MANIP_ROTATE) {
+ *r_len += ofs;
}
break;
- case 2:
- if (flagz) {
- if (is_picksel) {
- if (flagz & MAN_SCALE_Z) GPU_select_load_id(MAN_SCALE_Z);
- else if (flagz & MAN_TRANS_Z) GPU_select_load_id(MAN_TRANS_Z);
- }
- else {
- manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
- }
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.2f);
- glVertex3f(0.0f, 0.0f, 1.0f);
- glEnd();
+ case MAN_AXES_SCALE:
+ if (v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
+ *r_len -= ofs + 0.025f;
}
break;
}
-}
-static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode,
- int flagx, int flagy, int flagz,
- const int axis_order[3], const bool is_picksel)
-{
- int i;
- for (i = 0; i < 3; i++) {
- draw_manipulator_axes_single(v3d, rv3d, colcode, flagx, flagy, flagz, axis_order[i], is_picksel);
- }
-}
-static void preOrthoFront(const bool ortho, float twmat[4][4], int axis)
-{
- if (ortho == false) {
- float omat[4][4];
- copy_m4_m4(omat, twmat);
- orthogonalize_m4(omat, axis);
- glPushMatrix();
- glMultMatrixf(omat);
- glFrontFace(is_negative_m4(omat) ? GL_CW : GL_CCW);
- }
+ *r_len -= *r_start;
}
-static void postOrtho(const bool ortho)
-{
- if (ortho == false) {
- glPopMatrix();
- }
-}
+/* **************** Actual Widget Stuff **************** */
-BLI_INLINE bool manipulator_rotate_is_visible(const int drawflags)
+static ManipulatorGroup *manipulatorgroup_init(wmManipulatorGroup *wgroup)
{
- return (drawflags & (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z));
+ ManipulatorGroup *man;
+
+ man = MEM_callocN(sizeof(ManipulatorGroup), "manipulator_data");
+
+ /* add/init widgets - order matters! */
+ man->rotate_t = MANIPULATOR_dial_new(wgroup, "rotate_t", MANIPULATOR_DIAL_STYLE_RING_FILLED);
+
+ man->scale_c = MANIPULATOR_dial_new(wgroup, "scale_c", MANIPULATOR_DIAL_STYLE_RING);
+ man->scale_x = MANIPULATOR_arrow_new(wgroup, "scale_x", MANIPULATOR_ARROW_STYLE_BOX);
+ man->scale_y = MANIPULATOR_arrow_new(wgroup, "scale_y", MANIPULATOR_ARROW_STYLE_BOX);
+ man->scale_z = MANIPULATOR_arrow_new(wgroup, "scale_z", MANIPULATOR_ARROW_STYLE_BOX);
+ man->scale_xy = MANIPULATOR_primitive_new(wgroup, "scale_xy", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->scale_yz = MANIPULATOR_primitive_new(wgroup, "scale_yz", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->scale_zx = MANIPULATOR_primitive_new(wgroup, "scale_zx", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+
+ man->rotate_x = MANIPULATOR_dial_new(wgroup, "rotate_x", MANIPULATOR_DIAL_STYLE_RING_CLIPPED);
+ man->rotate_y = MANIPULATOR_dial_new(wgroup, "rotate_y", MANIPULATOR_DIAL_STYLE_RING_CLIPPED);
+ man->rotate_z = MANIPULATOR_dial_new(wgroup, "rotate_z", MANIPULATOR_DIAL_STYLE_RING_CLIPPED);
+ /* init screen aligned widget last here, looks better, behaves better */
+ man->rotate_c = MANIPULATOR_dial_new(wgroup, "rotate_c", MANIPULATOR_DIAL_STYLE_RING);
+
+ man->translate_c = MANIPULATOR_dial_new(wgroup, "translate_c", MANIPULATOR_DIAL_STYLE_RING);
+ man->translate_x = MANIPULATOR_arrow_new(wgroup, "translate_x", MANIPULATOR_ARROW_STYLE_NORMAL);
+ man->translate_y = MANIPULATOR_arrow_new(wgroup, "translate_y", MANIPULATOR_ARROW_STYLE_NORMAL);
+ man->translate_z = MANIPULATOR_arrow_new(wgroup, "translate_z", MANIPULATOR_ARROW_STYLE_NORMAL);
+ man->translate_xy = MANIPULATOR_primitive_new(wgroup, "translate_xy", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->translate_yz = MANIPULATOR_primitive_new(wgroup, "translate_yz", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->translate_zx = MANIPULATOR_primitive_new(wgroup, "translate_zx", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+
+ return man;
}
-static void draw_manipulator_rotate(
- View3D *v3d, RegionView3D *rv3d, const int drawflags, const int combo,
- const bool is_moving, const bool is_picksel)
+/**
+ * Custom handler for manipulator widgets
+ */
+static int manipulator_handler(bContext *C, const wmEvent *UNUSED(event), wmManipulator *widget, const int UNUSED(flag))
{
- double plane[4];
- float matt[4][4];
- float size, unitmat[4][4];
- float cywid = 0.33f * 0.01f * (float)U.tw_handlesize;
- float cusize = cywid * 0.65f;
- int arcs = (G.debug_value != 2);
- const int colcode = (is_moving) ? MAN_MOVECOL : MAN_RGB;
- bool ortho;
-
- /* skip drawing if all axes are locked */
- if (manipulator_rotate_is_visible(drawflags) == false) return;
-
- /* Init stuff */
- glDisable(GL_DEPTH_TEST);
- unit_m4(unitmat);
-
- /* prepare for screen aligned draw */
- size = len_v3(rv3d->twmat[0]);
- glPushMatrix();
- glTranslate3fv(rv3d->twmat[3]);
-
- if (arcs) {
- /* clipplane makes nice handles, calc here because of multmatrix but with translate! */
- copy_v3db_v3fl(plane, rv3d->viewinv[2]);
- plane[3] = -0.02f * size; // clip just a bit more
- glClipPlane(GL_CLIP_PLANE0, plane);
- }
- /* sets view screen aligned */
- glRotatef(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]);
-
- /* Screen aligned help circle */
- if (arcs) {
- if (is_picksel == false) {
- UI_ThemeColorShade(TH_BACK, -30);
- drawcircball(GL_LINE_LOOP, unitmat[3], size, unitmat);
- }
- }
-
- /* Screen aligned trackball rot circle */
- if (drawflags & MAN_ROT_T) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_T);
- else UI_ThemeColor(TH_TRANSFORM);
-
- drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f * size, unitmat);
- }
-
- /* Screen aligned view rot circle */
- if (drawflags & MAN_ROT_V) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_V);
- else UI_ThemeColor(TH_TRANSFORM);
- drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f * size, unitmat);
-
- if (is_moving) {
- float vec[3];
- vec[0] = 0; // XXX (float)(t->mouse.imval[0] - t->center2d[0]);
- vec[1] = 0; // XXX (float)(t->mouse.imval[1] - t->center2d[1]);
- vec[2] = 0.0f;
- normalize_v3_length(vec, 1.2f * size);
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3fv(vec);
- glEnd();
- }
- }
- glPopMatrix();
-
-
- ortho = is_orthogonal_m4(rv3d->twmat);
-
- /* apply the transform delta */
- if (is_moving) {
- copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3]
- // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat);
- if (ortho) {
- glMultMatrixf(matt);
- glFrontFace(is_negative_m4(matt) ? GL_CW : GL_CCW);
- }
- }
- else {
- if (ortho) {
- glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW);
- glMultMatrixf(rv3d->twmat);
- }
- }
-
- /* axes */
- if (arcs == 0) {
- if (!is_picksel) {
- if ((combo & V3D_MANIP_SCALE) == 0) {
- /* axis */
- if ((drawflags & MAN_ROT_X) || (is_moving && (drawflags & MAN_ROT_Z))) {
- preOrthoFront(ortho, rv3d->twmat, 2);
- manipulator_setcolor(v3d, 'X', colcode, 255);
- glBegin(GL_LINES);
- glVertex3f(0.2f, 0.0f, 0.0f);
- glVertex3f(1.0f, 0.0f, 0.0f);
- glEnd();
- postOrtho(ortho);
- }
- if ((drawflags & MAN_ROT_Y) || (is_moving && (drawflags & MAN_ROT_X))) {
- preOrthoFront(ortho, rv3d->twmat, 0);
- manipulator_setcolor(v3d, 'Y', colcode, 255);
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.2f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glEnd();
- postOrtho(ortho);
- }
- if ((drawflags & MAN_ROT_Z) || (is_moving && (drawflags & MAN_ROT_Y))) {
- preOrthoFront(ortho, rv3d->twmat, 1);
- manipulator_setcolor(v3d, 'Z', colcode, 255);
- glBegin(GL_LINES);
- glVertex3f(0.0f, 0.0f, 0.2f);
- glVertex3f(0.0f, 0.0f, 1.0f);
- glEnd();
- postOrtho(ortho);
- }
- }
- }
- }
-
- if (arcs == 0 && is_moving) {
-
- /* Z circle */
- if (drawflags & MAN_ROT_Z) {
- preOrthoFront(ortho, matt, 2);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, 255);
- drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat);
- postOrtho(ortho);
- }
- /* X circle */
- if (drawflags & MAN_ROT_X) {
- preOrthoFront(ortho, matt, 0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- else manipulator_setcolor(v3d, 'X', colcode, 255);
- glRotatef(90.0, 0.0, 1.0, 0.0);
- drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat);
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- postOrtho(ortho);
- }
- /* Y circle */
- if (drawflags & MAN_ROT_Y) {
- preOrthoFront(ortho, matt, 1);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, 255);
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat);
- glRotatef(90.0, 1.0, 0.0, 0.0);
- postOrtho(ortho);
- }
- }
- // donut arcs
- if (arcs) {
- glEnable(GL_CLIP_PLANE0);
-
- /* Z circle */
- if (drawflags & MAN_ROT_Z) {
- preOrthoFront(ortho, rv3d->twmat, 2);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, 255);
- partial_doughnut(cusize / 4.0f, 1.0f, 0, 48, 8, 48);
- postOrtho(ortho);
- }
- /* X circle */
- if (drawflags & MAN_ROT_X) {
- preOrthoFront(ortho, rv3d->twmat, 0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- else manipulator_setcolor(v3d, 'X', colcode, 255);
- glRotatef(90.0, 0.0, 1.0, 0.0);
- partial_doughnut(cusize / 4.0f, 1.0f, 0, 48, 8, 48);
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- postOrtho(ortho);
- }
- /* Y circle */
- if (drawflags & MAN_ROT_Y) {
- preOrthoFront(ortho, rv3d->twmat, 1);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, 255);
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- partial_doughnut(cusize / 4.0f, 1.0f, 0, 48, 8, 48);
- glRotatef(90.0, 1.0, 0.0, 0.0);
- postOrtho(ortho);
- }
-
- glDisable(GL_CLIP_PLANE0);
- }
-
- if (arcs == 0) {
-
- /* Z handle on X axis */
- if (drawflags & MAN_ROT_Z) {
- preOrthoFront(ortho, rv3d->twmat, 2);
- glPushMatrix();
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, 255);
-
- partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64);
-
- glPopMatrix();
- postOrtho(ortho);
- }
-
- /* Y handle on X axis */
- if (drawflags & MAN_ROT_Y) {
- preOrthoFront(ortho, rv3d->twmat, 1);
- glPushMatrix();
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, 255);
-
- glRotatef(90.0, 1.0, 0.0, 0.0);
- glRotatef(90.0, 0.0, 0.0, 1.0);
- partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64);
-
- glPopMatrix();
- postOrtho(ortho);
- }
-
- /* X handle on Z axis */
- if (drawflags & MAN_ROT_X) {
- preOrthoFront(ortho, rv3d->twmat, 0);
- glPushMatrix();
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- else manipulator_setcolor(v3d, 'X', colcode, 255);
-
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- glRotatef(90.0, 0.0, 0.0, 1.0);
- partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64);
-
- glPopMatrix();
- postOrtho(ortho);
- }
+ const ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+ if (calc_manipulator_stats(C)) {
+ manipulator_prepare_mat(C, v3d, rv3d);
+ WM_manipulator_set_origin(widget, rv3d->twmat[3]);
}
- /* restore */
- glLoadMatrixf(rv3d->viewmat);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-
-}
+ ED_region_tag_redraw(ar);
-static void drawsolidcube(float size)
-{
- const float cube[8][3] = {
- {-1.0, -1.0, -1.0},
- {-1.0, -1.0, 1.0},
- {-1.0, 1.0, 1.0},
- {-1.0, 1.0, -1.0},
- { 1.0, -1.0, -1.0},
- { 1.0, -1.0, 1.0},
- { 1.0, 1.0, 1.0},
- { 1.0, 1.0, -1.0},
- };
- float n[3] = {0.0f};
-
- glPushMatrix();
- glScalef(size, size, size);
-
- glBegin(GL_QUADS);
- n[0] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
- n[0] = 0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[1] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
- n[1] = 0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[0] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
- n[0] = 0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[1] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
- n[1] = 0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[2] = 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
- n[2] = 0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[2] = -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
- glEnd();
-
- glPopMatrix();
+ return OPERATOR_PASS_THROUGH;
}
-
-static void draw_manipulator_scale(
- View3D *v3d, RegionView3D *rv3d, const int drawflags, const int combo, const int colcode,
- const bool is_moving, const bool is_picksel)
+static void WIDGETGROUP_manipulator_init(const bContext *UNUSED(C), wmManipulatorGroup *wgroup)
{
- float cywid = 0.25f * 0.01f * (float)U.tw_handlesize;
- float cusize = cywid * 0.75f, dz;
- int axis_order[3] = {2, 0, 1};
- int i;
-
- /* when called while moving in mixed mode, do not draw when... */
- if ((drawflags & MAN_SCALE_C) == 0) return;
-
- manipulator_axis_order(rv3d, axis_order);
-
- glDisable(GL_DEPTH_TEST);
-
- /* not in combo mode */
- if ((combo & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) == 0) {
- float size, unitmat[4][4];
- int shift = 0; // XXX
-
- /* center circle, do not add to selection when shift is pressed (planar constraint) */
- if (is_picksel && shift == 0) GPU_select_load_id(MAN_SCALE_C);
- else manipulator_setcolor(v3d, 'C', colcode, 255);
-
- glPushMatrix();
- size = screen_aligned(rv3d, rv3d->twmat);
- unit_m4(unitmat);
- drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f * size, unitmat);
- glPopMatrix();
-
- dz = 1.0;
- }
- else {
- dz = 1.0f - 4.0f * cusize;
- }
-
- if (is_moving) {
- float matt[4][4];
-
- copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3]
- // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat);
- glMultMatrixf(matt);
- glFrontFace(is_negative_m4(matt) ? GL_CW : GL_CCW);
- }
- else {
- glMultMatrixf(rv3d->twmat);
- glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW);
- }
-
- /* axis */
+ ManipulatorGroup *man = manipulatorgroup_init(wgroup);
+ wgroup->customdata = man;
- /* in combo mode, this is always drawn as first type */
- draw_manipulator_axes(v3d, rv3d, colcode,
- drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z,
- axis_order, is_picksel);
+ /* *** set properties for axes *** */
-
- for (i = 0; i < 3; i++) {
- switch (axis_order[i]) {
- case 0: /* X cube */
- if (drawflags & MAN_SCALE_X) {
- glTranslatef(dz, 0.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_SCALE_X);
- else manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
- drawsolidcube(cusize);
- glTranslatef(-dz, 0.0, 0.0);
- }
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ const short axis_type = manipulator_get_axis_type(man, axis);
+ int constraint_axis[3] = {1, 0, 0};
+ PointerRNA *ptr;
+
+ manipulator_get_axis_constraint(axis_idx, constraint_axis);
+
+ /* custom handler! */
+ WM_manipulator_set_custom_handler(axis, manipulator_handler);
+
+ switch(axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_SCALE_Z:
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH);
break;
- case 1: /* Y cube */
- if (drawflags & MAN_SCALE_Y) {
- glTranslatef(0.0, dz, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_SCALE_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
- drawsolidcube(cusize);
- glTranslatef(0.0, -dz, 0.0);
- }
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_ROT_Z:
+ /* increased line width for better display */
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH + 1.0f);
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_VALUE, true);
break;
- case 2: /* Z cube */
- if (drawflags & MAN_SCALE_Z) {
- glTranslatef(0.0, 0.0, dz);
- if (is_picksel) GPU_select_load_id(MAN_SCALE_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
- drawsolidcube(cusize);
- glTranslatef(0.0, 0.0, -dz);
- }
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_XY:
+ case MAN_AXIS_SCALE_YZ:
+ case MAN_AXIS_SCALE_ZX:
+ {
+ const float ofs_ax = 11.0f;
+ const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
+ WM_manipulator_set_scale(axis, 0.07f);
+ WM_manipulator_set_offset(axis, ofs);
break;
- }
- }
-
-#if 0 // XXX
- /* if shiftkey, center point as last, for selectbuffer order */
- if (is_picksel) {
- int shift = 0; // XXX
-
- if (shift) {
- glTranslatef(0.0, -dz, 0.0);
- GPU_select_load_id(MAN_SCALE_C);
- /* TODO: set glPointSize before drawing center point */
- glBegin(GL_POINTS);
- glVertex3f(0.0, 0.0, 0.0);
- glEnd();
- }
- }
-#endif
-
- /* restore */
- glLoadMatrixf(rv3d->viewmat);
-
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- glFrontFace(GL_CCW);
-}
-
-
-static void draw_cone(GLUquadricObj *qobj, float len, float width)
-{
- glTranslatef(0.0, 0.0, -0.5f * len);
- gluCylinder(qobj, width, 0.0, len, 8, 1);
- gluQuadricOrientation(qobj, GLU_INSIDE);
- gluDisk(qobj, 0.0, width, 8, 1);
- gluQuadricOrientation(qobj, GLU_OUTSIDE);
- glTranslatef(0.0, 0.0, 0.5f * len);
-}
-
-static void draw_cylinder(GLUquadricObj *qobj, float len, float width)
-{
-
- width *= 0.8f; // just for beauty
-
- glTranslatef(0.0, 0.0, -0.5f * len);
- gluCylinder(qobj, width, width, len, 8, 1);
- gluQuadricOrientation(qobj, GLU_INSIDE);
- gluDisk(qobj, 0.0, width, 8, 1);
- gluQuadricOrientation(qobj, GLU_OUTSIDE);
- glTranslatef(0.0, 0.0, len);
- gluDisk(qobj, 0.0, width, 8, 1);
- glTranslatef(0.0, 0.0, -0.5f * len);
-}
-
-
-static void draw_manipulator_translate(
- View3D *v3d, RegionView3D *rv3d, int drawflags, int combo, int colcode,
- const bool UNUSED(is_moving), const bool is_picksel)
-{
- GLUquadricObj *qobj;
- float cylen = 0.01f * (float)U.tw_handlesize;
- float cywid = 0.25f * cylen, dz, size;
- float unitmat[4][4];
- int shift = 0; // XXX
- int axis_order[3] = {0, 1, 2};
- int i;
-
- /* when called while moving in mixed mode, do not draw when... */
- if ((drawflags & MAN_TRANS_C) == 0) return;
-
- manipulator_axis_order(rv3d, axis_order);
-
- // XXX if (moving) glTranslate3fv(t->vec);
- glDisable(GL_DEPTH_TEST);
-
- /* center circle, do not add to selection when shift is pressed (planar constraint) */
- if (is_picksel && shift == 0) GPU_select_load_id(MAN_TRANS_C);
- else manipulator_setcolor(v3d, 'C', colcode, 255);
-
- glPushMatrix();
- size = screen_aligned(rv3d, rv3d->twmat);
- unit_m4(unitmat);
- drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f * size, unitmat);
- glPopMatrix();
-
- /* and now apply matrix, we move to local matrix drawing */
- glMultMatrixf(rv3d->twmat);
-
- /* axis */
- GPU_select_load_id(-1);
-
- // translate drawn as last, only axis when no combo with scale, or for ghosting
- if ((combo & V3D_MANIP_SCALE) == 0 || colcode == MAN_GHOST) {
- draw_manipulator_axes(v3d, rv3d, colcode,
- drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z,
- axis_order, is_picksel);
- }
-
-
- /* offset in combo mode, for rotate a bit more */
- if (combo & (V3D_MANIP_ROTATE)) dz = 1.0f + 2.0f * cylen;
- else if (combo & (V3D_MANIP_SCALE)) dz = 1.0f + 0.5f * cylen;
- else dz = 1.0f;
-
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
-
- for (i = 0; i < 3; i++) {
- switch (axis_order[i]) {
- case 0: /* Z Cone */
- if (drawflags & MAN_TRANS_Z) {
- glTranslatef(0.0, 0.0, dz);
- if (is_picksel) GPU_select_load_id(MAN_TRANS_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
- draw_cone(qobj, cylen, cywid);
- glTranslatef(0.0, 0.0, -dz);
+ }
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH);
+ if (axis_idx == MAN_AXIS_ROT_T) {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_HOVER, true);
}
- break;
- case 1: /* X Cone */
- if (drawflags & MAN_TRANS_X) {
- glTranslatef(dz, 0.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_TRANS_X);
- else manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- draw_cone(qobj, cylen, cywid);
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- glTranslatef(-dz, 0.0, 0.0);
+ else if (axis_idx == MAN_AXIS_ROT_C) {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_VALUE, true);
}
- break;
- case 2: /* Y Cone */
- if (drawflags & MAN_TRANS_Y) {
- glTranslatef(0.0, dz, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_TRANS_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- draw_cone(qobj, cylen, cywid);
- glRotatef(90.0, 1.0, 0.0, 0.0);
- glTranslatef(0.0, -dz, 0.0);
+ else {
+ WM_manipulator_set_scale(axis, 0.2f);
}
break;
}
- }
-
- gluDeleteQuadric(qobj);
- glLoadMatrixf(rv3d->viewmat);
-
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-
-}
-
-static void draw_manipulator_rotate_cyl(
- View3D *v3d, RegionView3D *rv3d, int drawflags, const int combo, const int colcode,
- const bool is_moving, const bool is_picksel)
-{
- GLUquadricObj *qobj;
- float size;
- float cylen = 0.01f * (float)U.tw_handlesize;
- float cywid = 0.25f * cylen;
- int axis_order[3] = {2, 0, 1};
- int i;
-
- /* skip drawing if all axes are locked */
- if (manipulator_rotate_is_visible(drawflags) == false) return;
-
- manipulator_axis_order(rv3d, axis_order);
-
- /* prepare for screen aligned draw */
- glPushMatrix();
- size = screen_aligned(rv3d, rv3d->twmat);
-
- glDisable(GL_DEPTH_TEST);
-
- qobj = gluNewQuadric();
-
- /* Screen aligned view rot circle */
- if (drawflags & MAN_ROT_V) {
- float unitmat[4][4];
-
- unit_m4(unitmat);
-
- if (is_picksel) GPU_select_load_id(MAN_ROT_V);
- UI_ThemeColor(TH_TRANSFORM);
- drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f * size, unitmat);
-
- if (is_moving) {
- float vec[3];
- vec[0] = 0; // XXX (float)(t->mouse.imval[0] - t->center2d[0]);
- vec[1] = 0; // XXX (float)(t->mouse.imval[1] - t->center2d[1]);
- vec[2] = 0.0f;
- normalize_v3_length(vec, 1.2f * size);
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3fv(vec);
- glEnd();
- }
- }
- glPopMatrix();
-
- /* apply the transform delta */
- if (is_moving) {
- float matt[4][4];
- copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3]
- // XXX if (t->flag & T_USES_MANIPULATOR) {
- // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat);
- // XXX }
- glMultMatrixf(matt);
- }
- else {
- glMultMatrixf(rv3d->twmat);
- }
-
- glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW);
-
- /* axis */
- if (is_picksel == false) {
-
- // only draw axis when combo didn't draw scale axes
- if ((combo & V3D_MANIP_SCALE) == 0) {
- draw_manipulator_axes(v3d, rv3d, colcode,
- drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z,
- axis_order, is_picksel);
- }
-
- /* only has to be set when not in picking */
- gluQuadricDrawStyle(qobj, GLU_FILL);
- }
- for (i = 0; i < 3; i++) {
- switch (axis_order[i]) {
- case 0: /* X cylinder */
- if (drawflags & MAN_ROT_X) {
- glTranslatef(1.0, 0.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- glRotatef(90.0, 0.0, 1.0, 0.0);
- manipulator_setcolor(v3d, 'X', colcode, 255);
- draw_cylinder(qobj, cylen, cywid);
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- glTranslatef(-1.0, 0.0, 0.0);
- }
+ switch (axis_type) {
+ case MAN_AXES_TRANSLATE:
+ ptr = WM_manipulator_set_operator(axis, "TRANSFORM_OT_translate");
break;
- case 1: /* Y cylinder */
- if (drawflags & MAN_ROT_Y) {
- glTranslatef(0.0, 1.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- manipulator_setcolor(v3d, 'Y', colcode, 255);
- draw_cylinder(qobj, cylen, cywid);
- glRotatef(90.0, 1.0, 0.0, 0.0);
- glTranslatef(0.0, -1.0, 0.0);
- }
+ case MAN_AXES_ROTATE:
+ ptr = WM_manipulator_set_operator(
+ axis, (axis_idx == MAN_AXIS_ROT_T) ?
+ "TRANSFORM_OT_trackball" : "TRANSFORM_OT_rotate");
break;
- case 2: /* Z cylinder */
- if (drawflags & MAN_ROT_Z) {
- glTranslatef(0.0, 0.0, 1.0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- manipulator_setcolor(v3d, 'Z', colcode, 255);
- draw_cylinder(qobj, cylen, cywid);
- glTranslatef(0.0, 0.0, -1.0);
- }
+ case MAN_AXES_SCALE:
+ ptr = WM_manipulator_set_operator(axis, "TRANSFORM_OT_resize");
break;
}
+ if (RNA_struct_find_property(ptr, "constraint_axis"))
+ RNA_boolean_set_array(ptr, "constraint_axis", constraint_axis);
+ RNA_boolean_set(ptr, "release_confirm", 1);
}
-
- /* restore */
-
- gluDeleteQuadric(qobj);
- glLoadMatrixf(rv3d->viewmat);
-
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-
+ MAN_ITER_AXES_END;
}
-
-/* ********************************************* */
-
-/* main call, does calc centers & orientation too */
-static int drawflags = 0xFFFF; // only for the calls below, belongs in scene...?
-
-void BIF_draw_manipulator(const bContext *C)
+static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGroup *wgroup)
{
+ ManipulatorGroup *man = wgroup->customdata;
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
- int totsel;
- const bool is_picksel = false;
+ /* skip, we don't draw anything anyway */
+ if ((man->all_hidden = (calc_manipulator_stats(C) == 0)))
+ return;
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return;
+ manipulator_prepare_mat(C, v3d, rv3d);
- if ((v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) == 0) return;
+ /* *** set properties for axes *** */
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
{
- v3d->twflag &= ~V3D_DRAW_MANIPULATOR;
-
- totsel = calc_manipulator_stats(C);
- if (totsel == 0) return;
-
- v3d->twflag |= V3D_DRAW_MANIPULATOR;
-
- /* now we can define center */
- switch (v3d->around) {
- case V3D_AROUND_CENTER_BOUNDS:
- case V3D_AROUND_ACTIVE:
+ const short axis_type = manipulator_get_axis_type(man, axis);
+ const int aidx_norm = manipulator_index_normalize(axis_idx);
+
+ WM_manipulator_set_origin(axis, rv3d->twmat[3]);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_SCALE_Z:
{
- bGPdata *gpd = CTX_data_gpencil_data(C);
- Object *ob = OBACT;
+ float start_co[3] = {0.0f, 0.0f, 0.0f};
+ float len;
- if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
- ((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
- (ob && !(ob->mode & OB_MODE_POSE)))
- {
- copy_v3_v3(rv3d->twmat[3], ob->obmat[3]);
- }
- else {
- mid_v3_v3v3(rv3d->twmat[3], scene->twmin, scene->twmax);
- }
+ manipulator_line_range(v3d, axis_type, &start_co[2], &len);
+
+ MANIPULATOR_arrow_set_direction(axis, rv3d->twmat[aidx_norm]);
+ MANIPULATOR_arrow_set_line_len(axis, len);
+ WM_manipulator_set_offset(axis, start_co);
break;
}
- case V3D_AROUND_LOCAL_ORIGINS:
- case V3D_AROUND_CENTER_MEAN:
- copy_v3_v3(rv3d->twmat[3], scene->twcent);
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_ROT_Z:
+ MANIPULATOR_dial_set_up_vector(axis, rv3d->twmat[aidx_norm]);
break;
- case V3D_AROUND_CURSOR:
- copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d));
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_XY:
+ case MAN_AXIS_SCALE_YZ:
+ case MAN_AXIS_SCALE_ZX:
+ MANIPULATOR_primitive_set_direction(axis, rv3d->twmat[aidx_norm - 1 < 0 ? 2 : aidx_norm - 1]);
+ MANIPULATOR_primitive_set_up_vector(axis, rv3d->twmat[aidx_norm + 1 > 2 ? 0 : aidx_norm + 1]);
break;
}
-
- mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size);
- }
-
- /* when looking through a selected camera, the manipulator can be at the
- * exact same position as the view, skip so we don't break selection */
- if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
- return;
-
- test_manipulator_axis(C);
- drawflags = rv3d->twdrawflag; /* set in calc_manipulator_stats */
-
- if (v3d->twflag & V3D_DRAW_MANIPULATOR) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glLineWidth(1.0f);
-
- if (v3d->twtype & V3D_MANIP_ROTATE) {
- if (G.debug_value == 3) {
- if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT))
- draw_manipulator_rotate_cyl(v3d, rv3d, drawflags, v3d->twtype, MAN_MOVECOL, true, is_picksel);
- else
- draw_manipulator_rotate_cyl(v3d, rv3d, drawflags, v3d->twtype, MAN_RGB, false, is_picksel);
- }
- else {
- draw_manipulator_rotate(v3d, rv3d, drawflags, v3d->twtype, false, is_picksel);
- }
- }
- if (v3d->twtype & V3D_MANIP_SCALE) {
- draw_manipulator_scale(v3d, rv3d, drawflags, v3d->twtype, MAN_RGB, false, is_picksel);
- }
- if (v3d->twtype & V3D_MANIP_TRANSLATE) {
- draw_manipulator_translate(v3d, rv3d, drawflags, v3d->twtype, MAN_RGB, false, is_picksel);
- }
-
- glDisable(GL_BLEND);
}
+ MAN_ITER_AXES_END;
}
-static int manipulator_selectbuf(Scene *scene, ScrArea *sa, ARegion *ar, const int mval[2], float hotspot)
+static void WIDGETGROUP_manipulator_draw_prepare(const bContext *C, wmManipulatorGroup *wgroup)
{
+ ManipulatorGroup *man = wgroup->customdata;
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
- rcti rect;
- GLuint buffer[64]; // max 4 items per select, so large enuf
- short hits;
- const bool is_picksel = true;
- const bool do_passes = GPU_select_query_check_active();
+ float idot[3];
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
- if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
- return 0;
-
- rect.xmin = mval[0] - hotspot;
- rect.xmax = mval[0] + hotspot;
- rect.ymin = mval[1] - hotspot;
- rect.ymax = mval[1] + hotspot;
-
- ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, &rect);
-
- if (do_passes)
- GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
- else
- GPU_select_begin(buffer, 64, &rect, GPU_SELECT_ALL, 0);
-
- /* do the drawing */
- if (v3d->twtype & V3D_MANIP_ROTATE) {
- if (G.debug_value == 3) draw_manipulator_rotate_cyl(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- else draw_manipulator_rotate(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, false, is_picksel);
+ if (man->all_hidden || fabsf(ED_view3d_pixel_size(rv3d, rv3d->twmat[3])) < 1e-6f) {
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_HIDDEN, true);
+ }
+ MAN_ITER_AXES_END;
+ return;
}
- if (v3d->twtype & V3D_MANIP_SCALE)
- draw_manipulator_scale(v3d, rv3d, MAN_SCALE_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- if (v3d->twtype & V3D_MANIP_TRANSLATE)
- draw_manipulator_translate(v3d, rv3d, MAN_TRANS_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
-
- hits = GPU_select_end();
+ manipulator_get_idot(rv3d, idot);
- if (do_passes) {
- GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
+ /* *** set properties for axes *** */
- /* do the drawing */
- if (v3d->twtype & V3D_MANIP_ROTATE) {
- if (G.debug_value == 3) draw_manipulator_rotate_cyl(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- else draw_manipulator_rotate(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, false, is_picksel);
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ const short axis_type = manipulator_get_axis_type(man, axis);
+ /* XXX maybe unset _HIDDEN flag on redraw? */
+ if (manipulator_is_axis_visible(v3d, rv3d, idot, axis_type, axis_idx)) {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_HIDDEN, false);
+ }
+ else {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_HIDDEN, true);
+ continue;
}
- if (v3d->twtype & V3D_MANIP_SCALE)
- draw_manipulator_scale(v3d, rv3d, MAN_SCALE_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- if (v3d->twtype & V3D_MANIP_TRANSLATE)
- draw_manipulator_translate(v3d, rv3d, MAN_TRANS_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- GPU_select_end();
- }
+ float col[4], col_hi[4];
+ manipulator_get_axis_color(axis_idx, idot, col, col_hi);
+ WM_manipulator_set_colors(axis, col, col_hi);
- ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, NULL);
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ MANIPULATOR_dial_set_up_vector(axis, rv3d->viewinv[2]);
+ break;
+ }
+ }
+ MAN_ITER_AXES_END;
+}
- if (hits == 1) return buffer[3];
- else if (hits > 1) {
- GLuint val, dep, mindep = 0, mindeprot = 0, minval = 0, minvalrot = 0;
- int a;
+static bool WIDGETGROUP_manipulator_poll(const struct bContext *C, struct wmManipulatorGroupType *UNUSED(wgrouptype))
+{
+ /* it's a given we only use this in 3D view */
+ const ScrArea *sa = CTX_wm_area(C);
+ const View3D *v3d = sa->spacedata.first;
- /* we compare the hits in buffer, but value centers highest */
- /* we also store the rotation hits separate (because of arcs) and return hits on other widgets if there are */
+ return (((v3d->twflag & V3D_USE_MANIPULATOR) != 0) &&
+ ((v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) != 0));
+}
- for (a = 0; a < hits; a++) {
- dep = buffer[4 * a + 1];
- val = buffer[4 * a + 3];
+void TRANSFORM_WGT_manipulator(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Transform Manipulator";
- if (val == MAN_TRANS_C) {
- return MAN_TRANS_C;
- }
- else if (val == MAN_SCALE_C) {
- return MAN_SCALE_C;
- }
- else {
- if (val & MAN_ROT_C) {
- if (minvalrot == 0 || dep < mindeprot) {
- mindeprot = dep;
- minvalrot = val;
- }
- }
- else {
- if (minval == 0 || dep < mindep) {
- mindep = dep;
- minval = val;
- }
- }
- }
- }
+ wgt->poll = WIDGETGROUP_manipulator_poll;
+ wgt->init = WIDGETGROUP_manipulator_init;
+ wgt->refresh = WIDGETGROUP_manipulator_refresh;
+ wgt->draw_prepare = WIDGETGROUP_manipulator_draw_prepare;
- if (minval)
- return minval;
- else
- return minvalrot;
- }
- return 0;
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_IS_3D | WM_MANIPULATORGROUPTYPE_SCALE_3D);
}
-static const char *manipulator_get_operator_name(int man_val)
+
+/* -------------------------------------------------------------------- */
+/* Custom Object Manipulator (unfinished - unsure if this will stay) */
+#if 0
+static void WIDGETGROUP_object_manipulator_init(const bContext *C, wmManipulatorGroup *wgroup)
{
- if (man_val & MAN_TRANS_C) {
- return "TRANSFORM_OT_translate";
- }
- else if (man_val == MAN_ROT_T) {
- return "TRANSFORM_OT_trackball";
- }
- else if (man_val & MAN_ROT_C) {
- return "TRANSFORM_OT_rotate";
- }
- else if (man_val & MAN_SCALE_C) {
- return "TRANSFORM_OT_resize";
+ Object *ob = ED_object_active_context((bContext *)C);
+
+ if (ob->wgroup == NULL) {
+ ob->wgroup = wgroup;
}
- return NULL;
+ WIDGETGROUP_manipulator_init(C, wgroup);
}
-/* return 0; nothing happened */
-int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
+static bool WIDGETGROUP_object_manipulator_poll(const bContext *C, wmManipulatorGroupType *wgrouptype)
{
- Scene *scene = CTX_data_scene(C);
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- ARegion *ar = CTX_wm_region(C);
- int constraint_axis[3] = {0, 0, 0};
- int val;
- const bool use_planar = RNA_boolean_get(op->ptr, "use_planar_constraint");
-
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return 0;
- if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return 0;
-
- /* Force orientation */
- RNA_enum_set(op->ptr, "constraint_orientation", v3d->twmode);
-
- // find the hotspots first test narrow hotspot
- val = manipulator_selectbuf(scene, sa, ar, event->mval, 0.5f * (float)U.tw_hotspot);
- if (val) {
- wmOperatorType *ot;
- PointerRNA props_ptr;
- PropertyRNA *prop;
- const char *opname;
-
- // drawflags still global, for drawing call above
- drawflags = manipulator_selectbuf(scene, sa, ar, event->mval, 0.2f * (float)U.tw_hotspot);
- if (drawflags == 0) drawflags = val;
-
- /* Planar constraint doesn't make sense for rotation, give other keymaps a chance */
- if ((drawflags & MAN_ROT_C) && use_planar) {
- return 0;
- }
-
- opname = manipulator_get_operator_name(drawflags);
- ot = WM_operatortype_find(opname, true);
- WM_operator_properties_create_ptr(&props_ptr, ot);
+ Object *ob = ED_object_active_context((bContext *)C);
- if (drawflags & MAN_TRANS_C) {
- switch (drawflags) {
- case MAN_TRANS_C:
- break;
- case MAN_TRANS_X:
- if (use_planar) {
- constraint_axis[1] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[0] = 1;
- break;
- case MAN_TRANS_Y:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[1] = 1;
- break;
- case MAN_TRANS_Z:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[1] = 1;
- }
- else
- constraint_axis[2] = 1;
- break;
- }
- RNA_boolean_set_array(&props_ptr, "constraint_axis", constraint_axis);
- }
- else if (drawflags & MAN_SCALE_C) {
- switch (drawflags) {
- case MAN_SCALE_X:
- if (use_planar) {
- constraint_axis[1] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[0] = 1;
- break;
- case MAN_SCALE_Y:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[1] = 1;
- break;
- case MAN_SCALE_Z:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[1] = 1;
- }
- else
- constraint_axis[2] = 1;
- break;
- }
- RNA_boolean_set_array(&props_ptr, "constraint_axis", constraint_axis);
- }
- else if (drawflags == MAN_ROT_T) {
- /* pass */
- }
- else if (drawflags & MAN_ROT_C) {
- switch (drawflags) {
- case MAN_ROT_X:
- constraint_axis[0] = 1;
- break;
- case MAN_ROT_Y:
- constraint_axis[1] = 1;
- break;
- case MAN_ROT_Z:
- constraint_axis[2] = 1;
- break;
- }
- RNA_boolean_set_array(&props_ptr, "constraint_axis", constraint_axis);
+ if (ED_operator_object_active((bContext *)C)) {
+ if (STREQ(wgrouptype->idname, ob->id.name)) {
+ return true;
}
+ }
+ return false;
+}
- /* pass operator properties on to transform operators */
- prop = RNA_struct_find_property(op->ptr, "use_accurate");
- if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(&props_ptr, prop, RNA_property_boolean_get(op->ptr, prop));
- }
- prop = RNA_struct_find_property(op->ptr, "release_confirm");
- if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(&props_ptr, prop, RNA_property_boolean_get(op->ptr, prop));
- }
- prop = RNA_struct_find_property(op->ptr, "constraint_orientation");
- if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(&props_ptr, prop, RNA_property_enum_get(op->ptr, prop));
- }
+/* XXX should this really be in transform_manipulator.c? */
+void TRANSFORM_WGT_object(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Object Widgets";
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
- WM_operator_properties_free(&props_ptr);
- }
- /* after transform, restore drawflags */
- drawflags = 0xFFFF;
+ wgt->poll = WIDGETGROUP_object_manipulator_poll;
+ wgt->init = WIDGETGROUP_object_manipulator_init;
+ wgt->refresh = WIDGETGROUP_manipulator_refresh;
+ wgt->draw_prepare = WIDGETGROUP_manipulator_draw_prepare;
- return val;
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_IS_3D | WM_MANIPULATORGROUPTYPE_SCALE_3D);
}
-
+#endif
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 23158495b44..c9e40865164 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -586,10 +586,10 @@ static unsigned int bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const
int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
{
- Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Base *base;
- Object *ob = OBACT;
+ Object *ob = OBACT_NEW;
int result = ORIENTATION_NONE;
const bool activeOnly = (around == V3D_AROUND_ACTIVE);
@@ -1016,16 +1016,16 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
}
else {
/* we need the one selected object, if its not active */
- View3D *v3d = CTX_wm_view3d(C);
- ob = OBACT;
- if (ob && (ob->flag & SELECT)) {
+ base = BASACT_NEW;
+ ob = OBACT_NEW;
+ if (base && ((base->flag & BASE_SELECTED) != 0)) {
/* pass */
}
else {
/* first selected */
ob = NULL;
- for (base = scene->base.first; base; base = base->next) {
- if (TESTBASELIB(v3d, base)) {
+ for (base = sl->object_bases.first; base; base = base->next) {
+ if (TESTBASELIB_NEW(base)) {
ob = base->object;
break;
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 318d2718969..18996de068b 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -49,7 +49,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
@@ -78,7 +78,7 @@
#include "transform.h"
/* this should be passed as an arg for use in snap functions */
-#undef BASACT
+#undef BASACT_NEW
/* use half of flt-max so we can scale up without an exception */
@@ -163,36 +163,42 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
invert_m4_m4(imat, rv3d->viewmat);
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
for (p = t->tsnap.points.first; p; p = p->next) {
if (p == t->tsnap.selectedPoint) {
- glColor4ubv(selectedCol);
+ immUniformColor4ubv(selectedCol);
}
else {
- glColor4ubv(col);
+ immUniformColor4ubv(col);
}
- drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat);
+ imm_drawcircball(p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat, pos);
}
if (t->tsnap.status & POINT_INIT) {
- glColor4ubv(activeCol);
+ immUniformColor4ubv(activeCol);
- drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat);
+ imm_drawcircball(t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat, pos);
}
/* draw normal if needed */
if (usingSnappingNormal(t) && validSnappingNormal(t)) {
- glColor4ubv(activeCol);
+ immUniformColor4ubv(activeCol);
- glBegin(GL_LINES);
- glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
- glVertex3f(t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0],
- t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1],
- t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]);
- glEnd();
+ immBegin(PRIM_LINES, 2);
+ immVertex3f(pos, t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
+ immVertex3f(pos, t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0],
+ t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1],
+ t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]);
+ immEnd();
}
-
+
+ immUnbindProgram();
+
if (v3d->zbuf)
glEnable(GL_DEPTH_TEST);
}
@@ -200,35 +206,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_IMAGE) {
if (validSnap(t)) {
/* This will not draw, and Im nor sure why - campbell */
-#if 0
- float xuser_asp, yuser_asp;
- int wi, hi;
- float w, h;
-
- calc_image_view(G.sima, 'f'); // float
- myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
- glLoadIdentity();
-
- ED_space_image_get_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp);
- ED_space_image_width(t->sa->spacedata.first, &wi, &hi);
- w = (((float)wi) / IMG_SIZE_FALLBACK) * G.sima->zoom * xuser_asp;
- h = (((float)hi) / IMG_SIZE_FALLBACK) * G.sima->zoom * yuser_asp;
-
- cpack(0xFFFFFF);
- glTranslate2fv(t->tsnap.snapPoint);
-
- //glRectf(0, 0, 1, 1);
-
- setlinestyle(0);
- cpack(0x0);
- fdrawline(-0.020 / w, 0, -0.1 / w, 0);
- fdrawline(0.1 / w, 0, 0.020 / w, 0);
- fdrawline(0, -0.020 / h, 0, -0.1 / h);
- fdrawline(0, 0.1 / h, 0, 0.020 / h);
-
- glTranslatef(-t->tsnap.snapPoint[0], -t->tsnap.snapPoint[1], 0.0f);
- setlinestyle(0);
-#endif
+ /* TODO: see 2.7x for non-working code */
}
}
else if (t->spacetype == SPACE_NODE) {
@@ -241,23 +219,29 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
glEnable(GL_BLEND);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
for (p = t->tsnap.points.first; p; p = p->next) {
if (p == t->tsnap.selectedPoint) {
- glColor4ubv(selectedCol);
+ immUniformColor4ubv(selectedCol);
}
else {
- glColor4ubv(col);
+ immUniformColor4ubv(col);
}
- ED_node_draw_snap(&ar->v2d, p->co, size, 0);
+ ED_node_draw_snap(&ar->v2d, p->co, size, 0, pos);
}
if (t->tsnap.status & POINT_INIT) {
- glColor4ubv(activeCol);
+ immUniformColor4ubv(activeCol);
- ED_node_draw_snap(&ar->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder);
+ ED_node_draw_snap(&ar->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder, pos);
}
-
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
}
@@ -519,8 +503,8 @@ static void initSnappingMode(TransInfo *t)
{
ToolSettings *ts = t->settings;
Object *obedit = t->obedit;
- Scene *scene = t->scene;
- Base *base_act = scene->basact;
+ SceneLayer *sl = t->scene_layer;
+ Base *base_act = sl->basact;
if (t->spacetype == SPACE_NODE) {
/* force project off when not supported */
@@ -601,7 +585,7 @@ static void initSnappingMode(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
if (t->tsnap.object_context == NULL) {
t->tsnap.object_context = ED_transform_snap_object_context_create_view3d(
- G.main, t->scene, 0,
+ G.main, t->scene, t->scene_layer, 0,
t->ar, t->view);
ED_transform_snap_object_context_set_editmesh_callbacks(
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index b33528b4149..58474bedb52 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -101,6 +101,7 @@ typedef struct SnapObjectData_EditMesh {
struct SnapObjectContext {
Main *bmain;
Scene *scene;
+ SceneLayer *scene_layer;
int flag;
/* Optional: when performing screen-space projection.
@@ -1770,7 +1771,7 @@ static bool snapObjectsRay(
*
* To solve that problem, we do it first as an exception.
* */
- Base *base_act = sctx->scene->basact;
+ Base *base_act = sctx->scene_layer->basact;
if (base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT) {
Object *ob = base_act->object;
@@ -1791,11 +1792,11 @@ static bool snapObjectsRay(
ignore_object_active = true;
break;
}
- for (Base *base = sctx->scene->base.first; base != NULL; base = base->next) {
- if ((BASE_VISIBLE_BGMODE(sctx->v3d_data.v3d, sctx->scene, base)) &&
- (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 &&
+ for (Base *base = sctx->scene_layer->object_bases.first; base != NULL; base = base->next) {
+ if ((BASE_VISIBLE_NEW(base)) &&
+ (base->flag_legacy & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 &&
- !((ignore_object_selected && (base->flag & (SELECT | BA_WAS_SEL))) ||
+ !((ignore_object_selected && (((base->flag & BASE_SELECTED) != 0) || ((base->flag_legacy & BA_WAS_SEL)))) ||
(ignore_object_active && base == base_act)))
{
Object *ob = base->object;
@@ -1840,7 +1841,7 @@ static bool snapObjectsRay(
* \{ */
SnapObjectContext *ED_transform_snap_object_context_create(
- Main *bmain, Scene *scene, int flag)
+ Main *bmain, Scene *scene, SceneLayer *sl, int flag)
{
SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__);
@@ -1848,6 +1849,7 @@ SnapObjectContext *ED_transform_snap_object_context_create(
sctx->bmain = bmain;
sctx->scene = scene;
+ sctx->scene_layer = sl;
sctx->cache.object_map = BLI_ghash_ptr_new(__func__);
sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
@@ -1856,11 +1858,11 @@ SnapObjectContext *ED_transform_snap_object_context_create(
}
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- Main *bmain, Scene *scene, int flag,
+ Main *bmain, Scene *scene, SceneLayer *sl, int flag,
/* extra args for view3d */
const ARegion *ar, const View3D *v3d)
{
- SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, flag);
+ SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, sl, flag);
sctx->use_v3d = true;
sctx->v3d_data.ar = ar;
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 1f1a778cac7..490683e9360 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -70,6 +70,8 @@
#include "ED_space_api.h"
#include "ED_util.h"
+#include "GPU_immediate.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
@@ -86,7 +88,8 @@ void ED_editors_init(bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
Main *bmain = CTX_data_main(C);
Scene *sce = CTX_data_scene(C);
- Object *ob, *obact = (sce && sce->basact) ? sce->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob, *obact = (sl && sl->basact) ? sl->basact->object : NULL;
ID *data;
/* This is called during initialization, so we don't want to store any reports */
@@ -312,16 +315,28 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info
{
wmWindow *win = CTX_wm_window(C);
const float *mval_src = (float *)arg_info;
- const int mval_dst[2] = {win->eventstate->x - ar->winrct.xmin,
- win->eventstate->y - ar->winrct.ymin};
-
- UI_ThemeColor(TH_VIEW_OVERLAY);
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex2iv(mval_dst);
- glVertex2fv(mval_src);
- glEnd();
- setlinestyle(0);
+ const float mval_dst[2] = {win->eventstate->x - ar->winrct.xmin,
+ win->eventstate->y - ar->winrct.ymin};
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* "simple" mode */
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2fv(shdr_pos, mval_src);
+ immVertex2fv(shdr_pos, mval_dst);
+ immEnd();
+
+ immUnbindProgram();
}
/**
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 4e021d4833e..f5830e451e3 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -101,7 +101,7 @@ void ED_undo_push(bContext *C, const char *str)
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if (U.undosteps == 0) return;
- PE_undo_push(CTX_data_scene(C), str);
+ PE_undo_push(CTX_data_scene(C), CTX_data_scene_layer(C), str);
}
else if (obact && obact->mode & OB_MODE_SCULPT) {
/* do nothing for now */
@@ -120,6 +120,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
wmWindow *win = CTX_wm_window(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
ScrArea *sa = CTX_wm_area(C);
@@ -180,9 +181,9 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if (step == 1)
- PE_undo(scene);
+ PE_undo(scene, sl);
else
- PE_redo(scene);
+ PE_redo(scene, sl);
}
else if (U.uiflag & USER_GLOBALUNDO) {
// note python defines not valid here anymore.
@@ -297,7 +298,7 @@ bool ED_undo_is_valid(const bContext *C, const char *undoname)
return 1;
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
- return PE_undo_is_valid(CTX_data_scene(C));
+ return PE_undo_is_valid(CTX_data_scene(C), CTX_data_scene_layer(C));
}
if (U.uiflag & USER_GLOBALUNDO) {
@@ -536,7 +537,7 @@ static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem)
const char *name = NULL;
if (undosys == UNDOSYSTEM_PARTICLE) {
- name = PE_undo_get_name(CTX_data_scene(C), i, &active);
+ name = PE_undo_get_name(CTX_data_scene(C), CTX_data_scene_layer(C), i, &active);
}
else if (undosys == UNDOSYSTEM_EDITMODE) {
name = undo_editmode_get_name(C, i, &active);
@@ -619,7 +620,7 @@ static int undo_history_exec(bContext *C, wmOperator *op)
int item = RNA_int_get(op->ptr, "item");
if (undosys == UNDOSYSTEM_PARTICLE) {
- PE_undo_number(CTX_data_scene(C), item);
+ PE_undo_number(CTX_data_scene(C), CTX_data_scene_layer(C), item);
}
else if (undosys == UNDOSYSTEM_EDITMODE) {
undo_editmode_number(C, item + 1);
diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt
index 543ef0e0663..a933717fe98 100644
--- a/source/blender/editors/uvedit/CMakeLists.txt
+++ b/source/blender/editors/uvedit/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../../blenlib
../../blentranslation
../../bmesh
+ ../../depsgraph
../../gpu
../../makesdna
../../makesrna
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index ab415c0cb83..6b4dd0f0210 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -66,17 +66,14 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
BMFace *f;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
int tot = 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
zero_v2(center);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, f, tf))
+ if (!uvedit_face_visible_test(scene, ima, f))
continue;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -102,14 +99,11 @@ static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float del
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
- MTexPoly *tf;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, f, tf))
+ if (!uvedit_face_visible_test(scene, ima, f))
continue;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 15be6ab3b78..8ef287b7f4d 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -33,6 +33,8 @@
#include <stdlib.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -52,9 +54,15 @@
#include "BKE_scene.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
#include "ED_image.h"
#include "ED_mesh.h"
#include "ED_uvedit.h"
@@ -65,12 +73,7 @@
#include "uvedit_intern.h"
-#include "GPU_basic_shader.h"
-
-/* use editmesh tessface */
-#define USE_EDBM_LOOPTRIS
-
-static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset);
+static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset, const uint shdr_pos);
void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
{
@@ -81,38 +84,59 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
mul_v2_fl(zoom, 256.0f * UI_DPI_FAC);
x_fac = zoom[0];
y_fac = zoom[1];
-
- cpack(0xFFFFFF);
- glTranslate2fv(cursor);
- fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac);
- fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
- fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
- fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f);
-
- setlinestyle(4);
- cpack(0xFF);
- fdrawline(-0.05f * x_fac, 0.0f, 0.0f, 0.05f * y_fac);
- fdrawline(0.0f, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
- fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
- fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f);
-
-
- setlinestyle(0.0f);
- cpack(0x0);
- fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f);
- fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f);
- fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
- fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
-
- setlinestyle(1);
- cpack(0xFFFFFF);
- fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f);
- fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f);
- fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
- fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
-
- glTranslatef(-cursor[0], -cursor[1], 0.0);
- setlinestyle(0);
+
+ gpuTranslate2fv(cursor);
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 8.0f);
+
+ immBegin(PRIM_LINES, 8);
+
+ immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f);
+ immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac);
+
+ immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac);
+ immVertex2f(shdr_pos, 0.05f * x_fac, 0.0f);
+
+ immVertex2f(shdr_pos, 0.05f * x_fac, 0.0f);
+ immVertex2f(shdr_pos, 0.0f, -0.05f * y_fac);
+
+ immVertex2f(shdr_pos, 0.0f, -0.05f * y_fac);
+ immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f);
+
+ immEnd();
+
+ immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 2.0f);
+
+ immBegin(PRIM_LINES, 8);
+
+ immVertex2f(shdr_pos, -0.020f * x_fac, 0.0f);
+ immVertex2f(shdr_pos, -0.1f * x_fac, 0.0f);
+
+ immVertex2f(shdr_pos, 0.1f * x_fac, 0.0f);
+ immVertex2f(shdr_pos, 0.020f * x_fac, 0.0f);
+
+ immVertex2f(shdr_pos, 0.0f, -0.020f * y_fac);
+ immVertex2f(shdr_pos, 0.0f, -0.1f * y_fac);
+
+ immVertex2f(shdr_pos, 0.0f, 0.1f * y_fac);
+ immVertex2f(shdr_pos, 0.0f, 0.020f * y_fac);
+
+ immEnd();
+
+ immUnbindProgram();
+
+ gpuTranslate2f(-cursor[0], -cursor[1]);
}
static int draw_uvs_face_check(Scene *scene)
@@ -141,41 +165,32 @@ static void draw_uvs_shadow(Object *obedit)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- /* draws the mesh when painting */
- UI_ThemeColor(TH_UV_SHADOW);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset);
- }
-}
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-static int draw_uvs_dm_shadow(DerivedMesh *dm)
-{
- /* draw shadow mesh - this is the mesh with the modifier applied */
+ /* draws the mesh when painting */
+ immUniformThemeColor(TH_UV_SHADOW);
- if (dm && dm->drawUVEdges && CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
- UI_ThemeColor(TH_UV_SHADOW);
- dm->drawUVEdges(dm);
- return 1;
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
}
- return 0;
+ immUnbindProgram();
}
-static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTexPoly *activetf)
+static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, const BMFace *efa_act)
{
BMesh *bm = em->bm;
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
Image *ima = sima->image;
float aspx, aspy, col[4];
int i;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
BLI_buffer_declare_static(vec2f, tf_uvorig_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
@@ -191,7 +206,6 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
const int efa_len = efa->len;
float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len);
float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -203,28 +217,37 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
totarea += BM_face_calc_area(efa);
totuvarea += area_poly_v2((const float (*)[2])tf_uv, efa->len);
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
else {
- if (tf == activetf)
- activetf = NULL;
+ if (efa == efa_act) {
+ efa_act = NULL;
+ }
BM_elem_flag_disable(efa, BM_ELEM_TAG);
}
}
-
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
if (totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
col[0] = 1.0;
col[1] = col[2] = 0.0;
- glColor3fv(col);
+
+ immUniformColor3fv(col);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- glBegin(GL_POLYGON);
+ immBegin(PRIM_TRIANGLE_FAN, efa->len);
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
- glEnd();
+
+ immEnd();
}
}
}
@@ -254,18 +277,23 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
areadiff = 1.0f - (area / uvarea);
weight_to_rgb(col, areadiff);
- glColor3fv(col);
+ immUniformColor3fv(col);
- /* TODO: USE_EDBM_LOOPTRIS */
- glBegin(GL_POLYGON);
+ /* TODO: use editmesh tessface */
+ immBegin(PRIM_TRIANGLE_FAN, efa->len);
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
- glEnd();
+
+ immEnd();
}
}
}
+
+ immUnbindProgram();
+
break;
}
case SI_UVDT_STRETCH_ANGLE:
@@ -278,11 +306,15 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
BLI_buffer_declare_static(vec2f, auv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
col[3] = 0.5f; /* hard coded alpha, not that nice */
-
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
const int efa_len = efa->len;
float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len);
float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
@@ -319,24 +351,26 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]);
}
- /* TODO: USE_EDBM_LOOPTRIS */
- glBegin(GL_POLYGON);
+ /* TODO: use editmesh tessface */
+ immBegin(PRIM_TRIANGLE_FAN, efa->len);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
weight_to_rgb(col, 1.0f - pow2f(1.0f - a));
- glColor3fv(col);
- glVertex2fv(luv->uv);
+ immAttrib3fv(color, col);
+ immVertex2fv(pos, luv->uv);
}
- glEnd();
+ immEnd();
}
else {
- if (tf == activetf)
- activetf = NULL;
+ if (efa == efa_act)
+ efa_act = NULL;
BM_elem_flag_disable(efa, BM_ELEM_TAG);
}
}
+ immUnbindProgram();
+
BLI_buffer_free(&uvang_buf);
BLI_buffer_free(&ang_buf);
BLI_buffer_free(&av_buf);
@@ -350,58 +384,74 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
BLI_buffer_free(&tf_uvorig_buf);
}
-static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset)
+static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset, const uint shdr_pos)
{
BMIter liter;
BMLoop *l;
MLoopUV *luv;
- glBegin(GL_LINE_LOOP);
+ immBegin(PRIM_LINE_LOOP, efa->len);
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(shdr_pos, luv->uv);
}
- glEnd();
+
+ immEnd();
}
-static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly)
+static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos)
{
MLoopUV *mloopuv;
int i;
- glBegin(GL_LINE_LOOP);
+ immBegin(PRIM_LINE_LOOP, mpoly->totloop);
+
mloopuv = &me->mloopuv[mpoly->loopstart];
for (i = mpoly->totloop; i != 0; i--, mloopuv++) {
- glVertex2fv(mloopuv->uv);
+ immVertex2fv(pos, mloopuv->uv);
}
- glEnd();
+
+ immEnd();
}
-static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const int other_uv_filter)
+static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos)
{
Mesh *me = ob->data;
MPoly *mpoly = me->mpoly;
- MTexPoly *mtpoly = me->mtpoly;
int a;
if (me->mloopuv == NULL) {
return;
}
- for (a = me->totpoly; a != 0; a--, mpoly++, mtpoly++) {
+ Image **image_array = NULL;
+
+ if (other_uv_filter == SI_FILTER_SAME_IMAGE) {
+ image_array = BKE_object_material_edit_image_get_array(ob);
+ }
+
+ for (a = me->totpoly; a != 0; a--, mpoly++) {
if (other_uv_filter == SI_FILTER_ALL) {
/* Nothing to compare, all UV faces are visible. */
}
else if (other_uv_filter == SI_FILTER_SAME_IMAGE) {
- if (mtpoly->tpage != curimage) {
+ if (mpoly[a].mat_nr >= ob->totcol) {
+ continue;
+ }
+ if (image_array[mpoly[a].mat_nr] != curimage) {
continue;
}
}
- draw_uvs_lineloop_mpoly(me, mpoly);
+ draw_uvs_lineloop_mpoly(me, mpoly, pos);
+ }
+
+ if (image_array) {
+ MEM_freeN(image_array);
}
}
-static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter)
+static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos)
{
Mesh *me = ob->data;
MPoly *mpoly = me->mpoly;
@@ -453,41 +503,43 @@ static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, c
}
}
- draw_uvs_lineloop_mpoly(me, mpoly);
+ draw_uvs_lineloop_mpoly(me, mpoly, pos);
}
}
static void draw_uvs_other_mesh(Object *ob, const Image *curimage, const bool new_shading_nodes,
- const int other_uv_filter)
+ const int other_uv_filter, unsigned int pos)
{
if (new_shading_nodes) {
- draw_uvs_other_mesh_new_shading(ob, curimage, other_uv_filter);
+ draw_uvs_other_mesh_new_shading(ob, curimage, other_uv_filter, pos);
}
else {
- draw_uvs_other_mesh_texface(ob, curimage, other_uv_filter);
+ draw_uvs_other_mesh_texface(ob, curimage, other_uv_filter, pos);
}
}
-static void draw_uvs_other(Scene *scene, Object *obedit, const Image *curimage, const bool new_shading_nodes,
+static void draw_uvs_other(SceneLayer *sl, Object *obedit, const Image *curimage, const bool new_shading_nodes,
const int other_uv_filter)
{
- Base *base;
-
- UI_ThemeColor(TH_UV_OTHERS);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- for (base = scene->base.first; base; base = base->next) {
- Object *ob = base->object;
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- if (!(base->flag & SELECT)) continue;
- if (!(base->lay & scene->lay)) continue;
- if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
+ immUniformThemeColor(TH_UV_OTHERS);
- if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) {
- draw_uvs_other_mesh(ob, curimage, new_shading_nodes, other_uv_filter);
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if (((base->flag & BASE_SELECTED) != 0) &&
+ ((base->flag & BASE_VISIBLED) != 0))
+ {
+ Object *ob = base->object;
+ if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) {
+ draw_uvs_other_mesh(ob, curimage, new_shading_nodes, other_uv_filter, pos);
+ }
}
}
+ immUnbindProgram();
}
-static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
+static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, SceneLayer *sl, Object *ob)
{
const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
Image *curimage = ED_space_image(sima);
@@ -495,11 +547,9 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
Material *ma;
if (sima->flag & SI_DRAW_OTHER) {
- draw_uvs_other(scene, ob, curimage, new_shading_nodes, sima->other_uv_filter);
+ draw_uvs_other(sl, ob, curimage, new_shading_nodes, sima->other_uv_filter);
}
- UI_ThemeColor(TH_UV_SHADOW);
-
ma = give_current_material(ob, ob->actcol);
if (me->mloopuv) {
@@ -512,24 +562,33 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
mloopuv = me->mloopuv;
}
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_UV_SHADOW);
+
mloopuv_base = mloopuv;
for (a = me->totpoly; a > 0; a--, mpoly++) {
if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
continue;
- glBegin(GL_LINE_LOOP);
+
+ immBegin(PRIM_LINE_LOOP, mpoly->totloop);
mloopuv = mloopuv_base + mpoly->loopstart;
for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
- glVertex2fv(mloopuv->uv);
+ immVertex2fv(pos, mloopuv->uv);
}
- glEnd();
+
+ immEnd();
}
+
+ immUnbindProgram();
}
}
-#ifdef USE_EDBM_LOOPTRIS
-static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset)
+static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset, unsigned int pos)
{
unsigned int i = *r_loop_index;
BMFace *f = em->looptris[i][0]->f;
@@ -537,16 +596,15 @@ static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const i
unsigned int j;
for (j = 0; j < 3; j++) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
i++;
} while (i != em->tottri && (f == em->looptris[i][0]->f));
*r_loop_index = i - 1;
}
-#endif
/* draws uv's in the image space */
-static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
+static void draw_uvs(SpaceImage *sima, Scene *scene, SceneLayer *sl, Object *obedit, Depsgraph *depsgraph)
{
const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
ToolSettings *ts;
@@ -554,26 +612,19 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
BMEditMesh *em = me->edit_btmesh;
BMesh *bm = em->bm;
BMFace *efa, *efa_act;
-#ifndef USE_EDBM_LOOPTRIS
- BMFace *activef;
-#endif
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf, *activetf = NULL;
MLoopUV *luv;
- DerivedMesh *finaldm, *cagedm;
unsigned char col1[4], col2[4];
float pointsize;
int drawfaces, interpedges;
Image *ima = sima->image;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
- activetf = EDBM_mtexpoly_active_get(em, &efa_act, false, false); /* will be set to NULL if hidden */
-#ifndef USE_EDBM_LOOPTRIS
- activef = BM_mesh_active_face_get(bm, false, false);
-#endif
+ unsigned int pos;
+
+ efa_act = EDBM_uv_active_face_get(em, false, false); /* will be set to NULL if hidden */
ts = scene->toolsettings;
drawfaces = draw_uvs_face_check(scene);
@@ -595,38 +646,30 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
}
}
else {
- curimage = (activetf) ? activetf->tpage : ima;
+ curimage = (efa_act) ? BKE_object_material_edit_image_get(obedit, efa_act->mat_nr) : ima;
}
- draw_uvs_other(scene, obedit, curimage, new_shading_nodes, sima->other_uv_filter);
+ draw_uvs_other(sl, obedit, curimage, new_shading_nodes, sima->other_uv_filter);
}
/* 1. draw shadow mesh */
if (sima->flag & SI_DRAWSHADOW) {
- DM_update_materials(em->derivedFinal, obedit);
- /* first try existing derivedmesh */
- if (!draw_uvs_dm_shadow(em->derivedFinal)) {
- /* create one if it does not exist */
- cagedm = editbmesh_get_derived_cage_and_final(
- scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH | CD_MASK_MTFACE,
- &finaldm);
-
- /* when sync selection is enabled, all faces are drawn (except for hidden)
- * so if cage is the same as the final, theres no point in drawing this */
- if (!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
- draw_uvs_dm_shadow(finaldm);
-
- /* release derivedmesh again */
- if (cagedm != finaldm) cagedm->release(cagedm);
- finaldm->release(finaldm);
+ Object *ob_cage = DEG_get_object(depsgraph, obedit);
+ /* XXX TODO: Need to check if shadow mesh is different than original mesh. */
+ bool is_cage_like_final_meshes = (ob_cage == obedit);
+
+ /* When sync selection is enabled, all faces are drawn (except for hidden)
+ * so if cage is the same as the final, there is no point in drawing this. */
+ if (((ts->uv_flag & UV_SYNC_SELECTION) == 0) || is_cage_like_final_meshes) {
+ draw_uvs_shadow(ob_cage);
}
}
-
+
/* 2. draw colored faces */
if (sima->flag & SI_DRAW_STRETCH) {
- draw_uvs_stretch(sima, scene, em, activetf);
+ draw_uvs_stretch(sima, scene, em, efa_act);
}
else if (!(sima->flag & SI_NO_DRAWFACES)) {
/* draw transparent faces */
@@ -635,79 +678,47 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-#ifdef USE_EDBM_LOOPTRIS
- {
- unsigned int i;
- for (i = 0; i < em->tottri; i++) {
- efa = em->looptris[i][0]->f;
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
- const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset);
- BM_elem_flag_enable(efa, BM_ELEM_TAG);
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- if (tf == activetf) {
- /* only once */
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
- UI_ThemeColor4(TH_EDITMESH_ACTIVE);
- }
- else {
- glColor4ubv((GLubyte *)(is_select ? col2 : col1));
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glBegin(GL_TRIANGLES);
- draw_uvs_looptri(em, &i, cd_loop_uv_offset);
- glEnd();
+ for (unsigned int i = 0; i < em->tottri; i++) {
+ efa = em->looptris[i][0]->f;
+ if (uvedit_face_visible_test(scene, ima, efa)) {
+ const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset);
+ BM_elem_flag_enable(efa, BM_ELEM_TAG);
- if (tf == activetf) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- }
+ if (efa == efa_act) {
+ /* only once */
+ immUniformThemeColor(TH_EDITMESH_ACTIVE);
}
else {
- BM_elem_flag_disable(efa, BM_ELEM_TAG);
+ immUniformColor4ubv(is_select ? col2 : col1);
}
- }
- }
-#else
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
- BM_elem_flag_enable(efa, BM_ELEM_TAG);
- if (tf == activetf) continue; /* important the temp boolean is set above */
- if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset))
- glColor4ubv((GLubyte *)col2);
- else
- glColor4ubv((GLubyte *)col1);
-
- glBegin(GL_POLYGON);
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
- }
- glEnd();
+ immBegin(PRIM_TRIANGLES, (em->looptris[i][0]->f->len - 2) * 3);
+ draw_uvs_looptri(em, &i, cd_loop_uv_offset, pos);
+ immEnd();
}
else {
- if (tf == activetf)
- activetf = NULL;
BM_elem_flag_disable(efa, BM_ELEM_TAG);
}
}
-#endif
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
}
else {
/* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
else {
- if (tf == activetf)
- activetf = NULL;
+ if (efa == efa_act)
+ efa_act = NULL;
BM_elem_flag_disable(efa, BM_ELEM_TAG);
}
}
@@ -715,30 +726,8 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
}
/* 3. draw active face stippled */
-#ifndef USE_EDBM_LOOPTRIS
- if (activef) {
- tf = BM_ELEM_CD_GET_VOID_P(activef, cd_poly_tex_offset);
- if (uvedit_face_visible_test(scene, ima, activef, tf)) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- UI_ThemeColor4(TH_EDITMESH_ACTIVE);
-
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
-
- glBegin(GL_POLYGON);
- BM_ITER_ELEM (l, &liter, activef, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
- }
- glEnd();
+ /* (removed during OpenGL upgrade, reimplement if needed) */
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- glDisable(GL_BLEND);
- }
- }
-#endif
-
/* 4. draw edges */
if (sima->flag & SI_SMOOTH_UV) {
@@ -751,104 +740,150 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
switch (sima->dt_uv) {
case SI_UVDT_DASH:
+ {
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.56f, 0.56f, 0.56f, 1.0f}, {0.07f, 0.07f, 0.07f, 1.0f}}, 2);
+ immUniform1f("dash_width", 4.0f);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (tf) {
- cpack(0x111111);
+ draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, shdr_pos);
+ }
- draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset);
+ immUnbindProgram();
- setlinestyle(2);
- cpack(0x909090);
+ break;
+ }
+ case SI_UVDT_BLACK: /* black/white */
+ case SI_UVDT_WHITE:
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
- draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- setlinestyle(0);
- }
+ if (sima->dt_uv == SI_UVDT_WHITE) {
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
}
- break;
- case SI_UVDT_BLACK: /* black/white */
- case SI_UVDT_WHITE:
- if (sima->dt_uv == SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f);
- else glColor3f(0.0f, 0.0f, 0.0f);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset);
+ draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
}
+
+ immUnbindProgram();
+
break;
case SI_UVDT_OUTLINE:
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
glLineWidth(3);
- cpack(0x0);
-
+ imm_cpack(0x0);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset);
+ draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
}
-
+
+ immUnbindProgram();
+
glLineWidth(1);
UI_GetThemeColor4ubv(TH_WIRE_EDIT, col2);
- glColor4ubv((unsigned char *)col2);
if (me->drawflag & ME_DRAWEDGES) {
- int sel, lastsel = -1;
+ int sel;
UI_GetThemeColor4ubv(TH_EDGE_SELECT, col1);
+ VertexFormat *format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 4, NORMALIZE_INT_TO_FLOAT);
+
if (interpedges) {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- glBegin(GL_LINE_LOOP);
+ immBegin(PRIM_LINE_LOOP, efa->len);
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
- glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
+ immAttrib4ubv(color, sel ? (GLubyte *)col1 : (GLubyte *)col2);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
- glEnd();
+
+ immEnd();
}
+
+ immUnbindProgram();
}
else {
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ int lastsel = -1;
+
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- glBegin(GL_LINES);
+ immBegin(PRIM_LINES, efa->len * 2);
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
sel = uvedit_edge_select_test(scene, l, cd_loop_uv_offset);
if (sel != lastsel) {
- glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
+ immAttrib4ubv(color, sel ? (GLubyte *)col1 : (GLubyte *)col2);
lastsel = sel;
}
+
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
luv = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
- glEnd();
+
+ immEnd();
}
+
+ immUnbindProgram();
}
}
else {
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv(col2);
+
/* no nice edges */
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset);
+ draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
}
+
+ immUnbindProgram();
}
-
+
break;
}
@@ -861,50 +896,80 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
if (drawfaces) {
float cent[2];
-
+ bool col_set = false;
+
+ VertexFormat *format = immVertexFormat();
+ pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
glPointSize(pointsize);
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, bm->totface);
/* unselected faces */
- UI_ThemeColor(TH_WIRE);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ /* Only set color for the first face */
+ if (!col_set) {
+ UI_GetThemeColor3ubv(TH_WIRE, col1);
+ immAttrib3ubv(color, col1);
+
+ col_set = true;
+ }
+
uv_poly_center(efa, cent, cd_loop_uv_offset);
- glVertex2fv(cent);
+ immVertex2fv(pos, cent);
}
}
+ col_set = false;
+
/* selected faces */
- UI_ThemeColor(TH_FACE_DOT);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ /* Only set color for the first face */
+ if (!col_set) {
+ UI_GetThemeColor3ubv(TH_FACE_DOT, col1);
+ immAttrib3ubv(color, col1);
+
+ col_set = true;
+ }
+
uv_poly_center(efa, cent, cd_loop_uv_offset);
- glVertex2fv(cent);
+ immVertex2fv(pos, cent);
}
}
- glEnd();
+ immEnd();
+
+ immUnbindProgram();
}
/* 6. draw uv vertices */
if (drawfaces != 2) { /* 2 means Mesh Face Mode */
+ pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* unselected uvs */
- UI_ThemeColor(TH_VERTEX);
+ immUniformThemeColor(TH_VERTEX);
pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
glPointSize(pointsize);
-
- glBegin(GL_POINTS);
+
+ immBeginAtMost(PRIM_POINTS, bm->totloop);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -912,17 +977,19 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
}
- glEnd();
+
+ immEnd();
/* pinned uvs */
/* give odd pointsizes odd pin pointsizes */
glPointSize(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0));
- cpack(0xFF);
+ imm_cpack(0xFF);
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, bm->totloop);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -931,16 +998,18 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_PINNED)
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
}
- glEnd();
+
+ immEnd();
/* selected uvs */
- UI_ThemeColor(TH_VERTEX_SELECT);
+ immUniformThemeColor(TH_VERTEX_SELECT);
glPointSize(pointsize);
- glBegin(GL_POINTS);
+ immBeginAtMost(PRIM_POINTS, bm->totloop);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -949,10 +1018,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
- glVertex2fv(luv->uv);
+ immVertex2fv(pos, luv->uv);
}
}
- glEnd();
+
+ immEnd();
+
+ immUnbindProgram();
}
}
@@ -967,13 +1039,13 @@ static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bo
if ((sima->mode == SI_MODE_PAINT) && obedit && obedit->type == OB_MESH) {
struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
- *show_shadow = EDBM_mtexpoly_check(em);
+ *show_shadow = EDBM_uv_check(em);
}
*show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
}
-void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact)
+void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, SceneLayer *sl, Object *obedit, Object *obact, Depsgraph *depsgraph)
{
ToolSettings *toolsettings = scene->toolsettings;
bool show_uvedit, show_uvshadow, show_texpaint_uvshadow;
@@ -985,9 +1057,9 @@ void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *ob
if (show_uvshadow)
draw_uvs_shadow(obedit);
else if (show_uvedit)
- draw_uvs(sima, scene, obedit);
+ draw_uvs(sima, scene, sl, obedit, depsgraph);
else
- draw_uvs_texpaint(sima, scene, obact);
+ draw_uvs_texpaint(sima, scene, sl, obact);
if (show_uvedit && !(toolsettings->use_uv_sculpt))
ED_image_draw_cursor(ar, sima->cursor);
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index e028c08091c..6ca46941404 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -32,7 +32,6 @@
#ifndef __UVEDIT_INTERN_H__
#define __UVEDIT_INTERN_H__
-struct MTexPoly;
struct Image;
struct Object;
struct Scene;
@@ -53,7 +52,6 @@ void uv_poly_center(struct BMFace *f, float r_cent[2], const int cd_loop_uv_off
typedef struct NearestHit {
struct BMFace *efa;
- struct MTexPoly *tf;
struct BMLoop *l;
struct MLoopUV *luv, *luv_next;
int lindex; /* index of loop within face */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 193b006cf0d..9d1c36aff31 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -106,7 +106,7 @@ bool ED_uvedit_test(Object *obedit)
return 0;
em = BKE_editmesh_from_object(obedit);
- ret = EDBM_mtexpoly_check(em);
+ ret = EDBM_uv_check(em);
return ret;
}
@@ -182,7 +182,6 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
{
BMEditMesh *em;
BMIter iter;
- MTexPoly *tf;
bool update = false;
const bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION);
@@ -206,8 +205,6 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
BMFace *efa;
int cd_loop_uv_offset;
- int cd_poly_tex_offset;
-
/* old shading system, assign image to selected faces */
#ifdef USE_SWITCH_ASPECT
float prev_aspect[2], fprev_aspect;
@@ -221,31 +218,22 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
#endif
/* ensure we have a uv map */
- if (!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) {
- BM_data_layer_add(em->bm, &em->bm->pdata, CD_MTEXPOLY);
+ if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) {
BM_data_layer_add(em->bm, &em->bm->ldata, CD_MLOOPUV);
/* make UVs all nice 0-1 */
- ED_mesh_uv_loop_reset_ex(obedit->data, CustomData_get_active_layer_index(&em->bm->pdata, CD_MTEXPOLY));
+ ED_mesh_uv_loop_reset_ex(obedit->data, CustomData_get_active_layer_index(&em->bm->ldata, CD_MLOOPUV));
update = true;
}
cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* now assign to all visible faces */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (uvedit_face_visible_test(scene, previma, efa, tf) &&
+ if (uvedit_face_visible_test(scene, previma, efa) &&
(selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset)))
{
- if (ima) {
- tf->tpage = ima;
-
- if (ima->id.us == 0) id_us_plus(&ima->id);
- else id_lib_extern(&ima->id);
-
#ifdef USE_SWITCH_ASPECT
+ if (ima) {
/* we also need to correct the aspect of uvs */
if (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) {
/* do nothing */
@@ -261,11 +249,9 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
luv->uv[0] /= faspect;
}
}
-#endif
- }
- else {
- tf->tpage = NULL;
}
+#endif
+ BKE_object_material_edit_image_set(obedit, efa->mat_nr, ima);
update = true;
}
@@ -279,43 +265,6 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
}
-/* dotile - 1, set the tile flag (from the space image)
- * 2, set the tile index for the faces. */
-static bool uvedit_set_tile(Object *obedit, Image *ima, int curtile)
-{
- BMEditMesh *em;
- BMFace *efa;
- BMIter iter;
- MTexPoly *tf;
- int cd_poly_tex_offset;
-
- /* verify if we have something to do */
- if (!ima || !ED_uvedit_test(obedit))
- return false;
-
- if ((ima->tpageflag & IMA_TILES) == 0)
- return false;
-
- /* skip assigning these procedural images... */
- if (ima->type == IMA_TYPE_R_RESULT || ima->type == IMA_TYPE_COMPOSITE)
- return false;
-
- em = BKE_editmesh_from_object(obedit);
-
- cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
-
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
- tf->tile = curtile; /* set tile index */
- }
-
- DAG_id_tag_update(obedit->data, 0);
-
- return true;
-}
-
/*********************** space conversion *********************/
static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist)
@@ -346,14 +295,17 @@ bool uvedit_face_visible_nolocal(Scene *scene, BMFace *efa)
return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
-bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa, MTexPoly *tf)
+bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa)
{
ToolSettings *ts = scene->toolsettings;
- if (ts->uv_flag & UV_SHOW_SAME_IMAGE)
- return (tf->tpage == ima) ? uvedit_face_visible_nolocal(scene, efa) : false;
- else
+ if (ts->uv_flag & UV_SHOW_SAME_IMAGE) {
+ const Image *face_image = BKE_object_material_edit_image_get(scene->obedit, efa->mat_nr);
+ return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false;
+ }
+ else {
return uvedit_face_visible_nolocal(scene, efa);
+ }
}
bool uvedit_face_select_test(Scene *scene, BMFace *efa,
@@ -646,18 +598,15 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2],
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
INIT_MINMAX2(r_min, r_max);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -696,17 +645,14 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
unsigned int sel = 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
zero_v2(co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -747,7 +693,6 @@ static bool uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2
void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit)
{
- MTexPoly *tf;
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -756,7 +701,6 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
int i;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
mindist_squared = 1e10f;
memset(hit, 0, sizeof(*hit));
@@ -764,8 +708,7 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -775,7 +718,6 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
dist_squared = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
if (dist_squared < mindist_squared) {
- hit->tf = tf;
hit->efa = efa;
hit->l = l;
@@ -791,13 +733,11 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit)
{
- MTexPoly *tf;
BMFace *efa;
BMIter iter;
float mindist, dist, cent[2];
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
mindist = 1e10f;
memset(hit, 0, sizeof(*hit));
@@ -808,8 +748,7 @@ static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const
hit->luv = hit->luv_next = NULL;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
uv_poly_center(efa, cent, cd_loop_uv_offset);
@@ -817,7 +756,6 @@ static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const
dist = len_manhattan_v2v2(co, cent);
if (dist < mindist) {
- hit->tf = tf;
hit->efa = efa;
mindist = dist;
}
@@ -841,13 +779,11 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
float mindist, dist;
int i;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/*this will fill in hit.vert1 and hit.vert2*/
uv_find_nearest_edge(scene, ima, em, co, hit);
@@ -860,8 +796,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -883,7 +818,6 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
hit->l = l;
hit->luv = luv;
hit->luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- hit->tf = tf;
hit->efa = efa;
hit->lindex = i;
}
@@ -897,20 +831,17 @@ bool ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
float mindist, dist;
bool found = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
mindist = 1e10f;
copy_v2_v2(r_uv, co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1020,7 +951,6 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
BMFace *efa;
BMIter iter, liter;
BMLoop *l;
- MTexPoly *tf;
UvVertMap *vmap;
UvMapVert *iterv_curr;
UvMapVert *iterv_next;
@@ -1028,7 +958,6 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
bool looking, select;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* setup */
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
@@ -1061,9 +990,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
/* find correct valence edges which are not tagged yet, but connect to tagged one */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
/* check face not hidden and not tagged */
if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l)))
@@ -1123,7 +1050,6 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
UvVertMap *vmap;
UvMapVert *vlist, *iterv, *startv;
@@ -1132,7 +1058,6 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
char *flag;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
@@ -1147,9 +1072,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
if (!hit) {
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
if (select_faces) {
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
stack[stacksize] = a;
@@ -1313,12 +1236,9 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
BMLoop *l;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, l->f, tf))
+ if (!uvedit_face_visible_test(scene, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1344,7 +1264,6 @@ static int uv_select_more_less(bContext *C, const bool select)
ToolSettings *ts = scene->toolsettings;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (select) {
@@ -1367,9 +1286,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
#define IS_SEL 1
#define IS_UNSEL 2
@@ -1412,9 +1329,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -1481,11 +1396,9 @@ static void uv_weld_align(bContext *C, int tool)
SpaceImage *sima;
Scene *scene;
Image *ima;
- MTexPoly *tf;
float cent[2], min[2], max[2];
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
scene = CTX_data_scene(C);
ima = CTX_data_edit_image(C);
@@ -1499,9 +1412,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1523,8 +1434,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1543,8 +1453,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1572,9 +1481,7 @@ static void uv_weld_align(bContext *C, int tool)
/* tag verts with a selected UV */
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, l->f, tf))
+ if (!uvedit_face_visible_test(scene, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1662,9 +1569,7 @@ static void uv_weld_align(bContext *C, int tool)
/* go over all verts except for endpoints */
for (i = 0; i < BLI_array_count(eve_line); i++) {
BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
- tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, l->f, tf))
+ if (!uvedit_face_visible_test(scene, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1750,7 +1655,6 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
Image *ima;
- MTexPoly *tf;
int uv_a_index;
int uv_b_index;
float *uv_a;
@@ -1761,7 +1665,6 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
BMLoop *l;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
sima = CTX_wm_space_image(C);
scene = CTX_data_scene(C);
@@ -1775,8 +1678,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
/* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1838,8 +1740,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
BLI_array_declare(loop_arr_unselected);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1929,11 +1830,9 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -1957,9 +1856,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1975,9 +1872,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2066,7 +1961,6 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
NearestHit hit;
int i, selectmode, sticky, sync, *hitv = NULL;
@@ -2076,7 +1970,6 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
float penalty[2];
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* notice 'limit' is the same no matter the zoom level, since this is like
* remove doubles and could annoying if it joined points when zoomed out.
@@ -2228,8 +2121,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2264,8 +2156,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
/* select sticky uvs */
if (sticky != SI_STICKY_DISABLE) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2521,12 +2412,10 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled");
@@ -2538,9 +2427,8 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
bool is_sel = false;
bool is_unsel = false;
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
/* are we all selected? */
@@ -2681,7 +2569,6 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- /* MTexPoly *tf; */
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_VERTEX) {
@@ -2770,7 +2657,6 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- /* MTexPoly *tf; */
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
@@ -2854,7 +2740,6 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
rctf rectf;
bool changed, pinned, select, extend;
@@ -2863,7 +2748,6 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
(ts->uv_selectmode == UV_SELECT_FACE);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* get rectangle from operator */
WM_operator_properties_border_to_rctf(op, &rectf);
@@ -2888,8 +2772,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
/* assume not touched */
BM_elem_flag_disable(efa, BM_ELEM_TAG);
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
uv_poly_center(efa, cent, cd_loop_uv_offset);
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -2908,8 +2791,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
changed = true;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tf))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -3110,13 +2992,11 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
(ts->uv_selectmode == UV_SELECT_FACE));
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BMIter iter, liter;
BMFace *efa;
BMLoop *l;
- MTexPoly *tf;
int screen_uv[2];
bool changed = false;
rcti rect;
@@ -3152,8 +3032,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
}
else { /* Vert Sel */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (uvedit_face_visible_test(scene, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -3302,16 +3181,13 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tface;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tface))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3332,16 +3208,13 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *mtexpoly;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- mtexpoly = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, mtexpoly))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3363,17 +3236,14 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
BMFace *f;
BMLoop *l, *lsub;
BMIter iter, liter, lsubiter;
- MTexPoly *tface;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- tface = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
- if (uvedit_face_visible_test(scene, ima, f, tface)) {
+ if (uvedit_face_visible_test(scene, ima, f)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
@@ -3421,22 +3291,19 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tface;
MLoopUV *luv;
int width = 0, height = 0;
float w, h;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
ED_space_image_get_size(sima, &width, &height);
w = (float)width;
h = (float)height;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tface))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3526,16 +3393,13 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tface;
MLoopUV *luv;
const bool clear = RNA_boolean_get(op->ptr, "clear");
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tface))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3584,15 +3448,12 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tface;
MLoopUV *luv;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!uvedit_face_visible_test(scene, ima, efa, tface))
+ if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3656,13 +3517,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
- MTexPoly *tf;
const bool swap = RNA_boolean_get(op->ptr, "unselected");
Image *ima = sima ? sima->image : NULL;
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
EDBM_mesh_hide(em, swap);
@@ -3674,9 +3533,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int hide = 0;
- tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
- if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
+ if (!uvedit_face_visible_test(scene, ima, efa)) {
continue;
}
@@ -3953,73 +3810,6 @@ static void UV_OT_cursor_set(wmOperatorType *ot)
"Cursor location in normalized (0.0-1.0) coordinates", -10.0f, 10.0f);
}
-/********************** set tile operator **********************/
-
-static int set_tile_exec(bContext *C, wmOperator *op)
-{
- Image *ima = CTX_data_edit_image(C);
- int tile[2];
- Object *obedit = CTX_data_edit_object(C);
-
- RNA_int_get_array(op->ptr, "tile", tile);
-
- if (uvedit_set_tile(obedit, ima, tile[0] + ima->xrep * tile[1])) {
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
-
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_CANCELLED;
-}
-
-static int set_tile_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
- ARegion *ar = CTX_wm_region(C);
- float fx, fy;
- int tile[2];
-
- if (!ima || !(ima->tpageflag & IMA_TILES))
- return OPERATOR_CANCELLED;
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fx, &fy);
-
- if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
- fx = fx * ima->xrep;
- fy = fy * ima->yrep;
-
- tile[0] = fx;
- tile[1] = fy;
-
- sima->curtile = tile[1] * ima->xrep + tile[0];
- RNA_int_set_array(op->ptr, "tile", tile);
- }
-
- return set_tile_exec(C, op);
-}
-
-static void UV_OT_tile_set(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Set Tile";
- ot->description = "Set UV image tile coordinates";
- ot->idname = "UV_OT_tile_set";
-
- /* api callbacks */
- ot->exec = set_tile_exec;
- ot->invoke = set_tile_invoke;
- ot->poll = ED_operator_image_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_int_vector(ot->srna, "tile", 2, NULL, 0, INT_MAX, "Tile", "Tile coordinate", 0, 10);
-}
-
-
static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
{
UvVertMap *vmap;
@@ -4037,7 +3827,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
em = me->edit_btmesh;
bm = em->bm;
- if (!EDBM_mtexpoly_check(em)) {
+ if (!EDBM_uv_check(em)) {
return OPERATOR_CANCELLED;
}
@@ -4274,7 +4064,6 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_hide);
WM_operatortype_append(UV_OT_cursor_set);
- WM_operatortype_append(UV_OT_tile_set);
}
void ED_keymap_uvedit(wmKeyConfig *keyconf)
@@ -4354,7 +4143,6 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
/* cursor */
WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "UV_OT_tile_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
/* menus */
WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index d5233f0ed28..d6e77e3081e 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -63,6 +63,8 @@
#include "ED_screen.h"
#include "ED_space_api.h"
+#include "GPU_batch.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -1538,63 +1540,118 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
normalize_v2(normal);
}
+static void stitch_draw_vbo(VertexBuffer *vbo, PrimitiveType prim_type, const float col[4])
+{
+ Batch *batch = Batch_create(prim_type, vbo, NULL);
+ Batch_set_builtin_program(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ Batch_Uniform4fv(batch, "color", col);
+ Batch_draw(batch);
+ Batch_discard_all(batch);
+}
+
+/* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */
static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
- int i, index = 0;
+ int j, index = 0;
+ unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0;
StitchState *state = (StitchState *)arg;
StitchPreviewer *stitch_preview = state->stitch_preview;
+ VertexBuffer *vbo, *vbo_line;
+ float col[4];
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id;
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ }
glEnable(GL_BLEND);
- UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3);
-
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
- for (i = 0; i < stitch_preview->num_polys; i++) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
- glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
- glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
-#if 0
- glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
- UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
- glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
-#endif
-
- index += stitch_preview->uvs_per_polygon[i];
+ /* Static Tris */
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col);
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, stitch_preview->num_static_tris * 3);
+ for (int i = 0; i < stitch_preview->num_static_tris * 3; i++)
+ VertexBuffer_set_attrib(vbo, pos_id, i, &stitch_preview->static_tris[i*2]);
+ stitch_draw_vbo(vbo, PRIM_TRIANGLES, col);
+
+
+ /* Preview Polys */
+ for (int i = 0; i < stitch_preview->num_polys; i++)
+ num_line += stitch_preview->uvs_per_polygon[i];
+
+ num_tri = num_line - 2 * stitch_preview->num_polys;
+
+ /* we need to convert the polys into triangles / lines */
+ vbo = VertexBuffer_create_with_format(&format);
+ vbo_line = VertexBuffer_create_with_format(&format);
+
+ VertexBuffer_allocate_data(vbo, num_tri * 3);
+ VertexBuffer_allocate_data(vbo_line, num_line * 2);
+
+ for (int i = 0; i < stitch_preview->num_polys; i++) {
+ BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3);
+
+ /* Start line */
+ VertexBuffer_set_attrib(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
+ VertexBuffer_set_attrib(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]);
+
+ for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) {
+ VertexBuffer_set_attrib(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]);
+ VertexBuffer_set_attrib(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j+0)*2]);
+ VertexBuffer_set_attrib(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j+1)*2]);
+
+ VertexBuffer_set_attrib(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j+0)*2]);
+ VertexBuffer_set_attrib(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j+1)*2]);
+ }
+
+ /* Closing line */
+ VertexBuffer_set_attrib(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
+ VertexBuffer_set_attrib(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j*2]); /* j = uvs_per_polygon[i] - 1*/
+
+ index += stitch_preview->uvs_per_polygon[i] * 2;
}
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col);
+ stitch_draw_vbo(vbo, PRIM_TRIANGLES, col);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col);
+ stitch_draw_vbo(vbo_line, PRIM_LINES, col);
+
glDisable(GL_BLEND);
- /* draw vert preview */
+
+ /* draw stitch vert/lines preview */
if (state->mode == STITCH_VERT) {
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f);
- UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, stitch_preview->num_stitchable);
+ for (int i = 0; i < stitch_preview->num_stitchable; i++)
+ VertexBuffer_set_attrib(vbo, pos_id, i, &stitch_preview->preview_stitchable[i*2]);
+ stitch_draw_vbo(vbo, PRIM_POINTS, col);
- UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, stitch_preview->num_unstitchable);
+ for (int i = 0; i < stitch_preview->num_unstitchable; i++)
+ VertexBuffer_set_attrib(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i*2]);
+ stitch_draw_vbo(vbo, PRIM_POINTS, col);
}
else {
- UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
- glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable);
-
- UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
- glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, stitch_preview->num_stitchable * 2);
+ for (int i = 0; i < stitch_preview->num_stitchable * 2; i++)
+ VertexBuffer_set_attrib(vbo, pos_id, i, &stitch_preview->preview_stitchable[i*2]);
+ stitch_draw_vbo(vbo, PRIM_LINES, col);
+
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, stitch_preview->num_unstitchable * 2);
+ for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++)
+ VertexBuffer_set_attrib(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i*2]);
+ stitch_draw_vbo(vbo, PRIM_LINES, col);
}
-
- glPopClientAttrib();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index d8080002818..0cb117da341 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -58,6 +58,7 @@
#include "BKE_depsgraph.h"
#include "BKE_image.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_editmesh.h"
@@ -116,7 +117,7 @@ static bool ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
if (ED_uvedit_test(obedit))
return 1;
- if (em && em->bm->totface && !CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY))
+ if (em && em->bm->totface && !CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV))
ED_mesh_uv_texture_add(obedit->data, NULL, true);
if (!ED_uvedit_test(obedit))
@@ -214,8 +215,7 @@ void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, floa
ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL);
}
else {
- MTexPoly *tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
- ima = tf->tpage;
+ ima = BKE_object_material_edit_image_get(ob, efa->mat_nr);
}
ED_image_get_uv_aspect(ima, NULL, aspx, aspy);
@@ -1443,7 +1443,7 @@ static void uv_sphere_project(float target[2], float source[3], float center[3],
target[0] -= 1.0f;
}
-static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
+static void uv_map_mirror(BMEditMesh *em, BMFace *efa)
{
BMLoop *l;
BMIter liter;
@@ -1480,7 +1480,6 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
float center[3], rotmat[4][4];
@@ -1505,8 +1504,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
uv_sphere_project(luv->uv, l->v->co, center, rotmat);
}
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
- uv_map_mirror(em, efa, tf);
+ uv_map_mirror(em, efa);
}
uv_map_clip_correct(scene, obedit, em, op);
@@ -1559,7 +1557,6 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MTexPoly *tf;
MLoopUV *luv;
float center[3], rotmat[4][4];
@@ -1584,8 +1581,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
uv_cylinder_project(luv->uv, l->v->co, center, rotmat);
}
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
- uv_map_mirror(em, efa, tf);
+ uv_map_mirror(em, efa);
}
uv_map_clip_correct(scene, obedit, em, op);
@@ -1621,7 +1617,6 @@ void ED_uvedit_unwrap_cube_project(Object *ob, BMesh *bm, float cube_size, bool
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- /* MTexPoly *tf; */ /* UNUSED */
MLoopUV *luv;
float *loc, dx, dy;
int cox, coy;
@@ -1637,8 +1632,6 @@ void ED_uvedit_unwrap_cube_project(Object *ob, BMesh *bm, float cube_size, bool
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
int first = 1;
-
- /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt
index f6b7efe978c..1ae4211aa23 100644
--- a/source/blender/freestyle/CMakeLists.txt
+++ b/source/blender/freestyle/CMakeLists.txt
@@ -557,6 +557,7 @@ set(INC
../blenkernel
../blenlib
../blentranslation
+ ../depsgraph
../imbuf
../makesdna
../makesrna
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index 1f5e2b63bfa..35ac3171987 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -105,8 +105,6 @@ NodeGroup *BlenderFileLoader::Load()
cnt++;
}
- if (!(obi->lay & _srl->lay))
- continue;
char *name = obi->ob->id.name;
//printf("%c%c:%s\n", name[0], name[1], name+2);
//print_m4("obi->mat", obi->mat);
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index f63cf771120..560d060594f 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -43,8 +43,8 @@ extern "C" {
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
+#include "BKE_collection.h"
#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h" /* free_libblock */
#include "BKE_material.h"
@@ -59,6 +59,9 @@ extern "C" {
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#include "RE_pipeline.h"
#include "render_types.h"
@@ -127,8 +130,8 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
BKE_scene_set_background(freestyle_bmain, freestyle_scene);
// Camera
- Object *object_camera = BKE_object_add(freestyle_bmain, freestyle_scene, OB_CAMERA, NULL);
- DAG_relations_tag_update(freestyle_bmain);
+ Object *object_camera = BKE_object_add(freestyle_bmain, freestyle_scene, (SceneLayer *)freestyle_scene->render_layers.first, OB_CAMERA, NULL);
+ DEG_relations_tag_update(freestyle_bmain);
Camera *camera = (Camera *)object_camera->data;
camera->type = CAM_ORTHO;
@@ -166,7 +169,7 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer()
// compositor has finished.
// release objects and data blocks
- for (Base *b = (Base *)freestyle_scene->base.first; b; b = b->next) {
+ for (Base *b = (Base *)((SceneLayer *)(freestyle_scene->render_layers.first))->object_bases.first; b; b = b->next) {
Object *ob = b->object;
void *data = ob->data;
char *name = ob->id.name;
@@ -189,7 +192,6 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer()
cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name + 2) << endl;
}
}
- BLI_freelistN(&freestyle_scene->base);
// release materials
Link *lnk = (Link *)freestyle_bmain->mat.first;
@@ -510,7 +512,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
// If still no material, create one
if (!has_mat) {
Material *ma = BKE_material_add(freestyle_bmain, "stroke_material");
- DAG_relations_tag_update(freestyle_bmain);
+ DEG_relations_tag_update(freestyle_bmain);
ma->mode |= MA_VERTEXCOLP;
ma->mode |= MA_TRANSP;
ma->mode |= MA_SHLESS;
@@ -674,7 +676,7 @@ int BlenderStrokeRenderer::get_stroke_count() const
void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
{
#if 0
- Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, OB_MESH);
+ Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, (SceneLayer *)freestyle_scene->render_layers.first, OB_MESH);
DAG_relations_tag_update(freestyle_bmain);
#else
Object *object_mesh = NewMesh();
@@ -700,17 +702,13 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
if (hasTex) {
// First UV layer
- CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, uvNames[0]);
CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, uvNames[0]);
- CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 0);
CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0);
BKE_mesh_update_customdata_pointers(mesh, true);
loopsuv[0] = mesh->mloopuv;
// Second UV layer
- CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, uvNames[1]);
CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, uvNames[1]);
- CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 1);
CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1);
BKE_mesh_update_customdata_pointers(mesh, true);
loopsuv[1] = mesh->mloopuv;
@@ -922,7 +920,6 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
Object *BlenderStrokeRenderer::NewMesh() const
{
Object *ob;
- Base *base;
char name[MAX_ID_NAME];
unsigned int mesh_id = get_stroke_mesh_id();
@@ -932,16 +929,13 @@ Object *BlenderStrokeRenderer::NewMesh() const
ob->data = BKE_mesh_add(freestyle_bmain, name);
ob->lay = 1;
- base = BKE_scene_base_add(freestyle_scene, ob);
- DAG_relations_tag_update(freestyle_bmain);
-#if 0
- BKE_scene_base_deselect_all(scene);
- BKE_scene_base_select(scene, base);
-#else
- (void)base;
-#endif
+ SceneCollection *sc_master = BKE_collection_master(freestyle_scene);
+ BKE_collection_object_add(freestyle_scene, sc_master, ob);
+
+ BKE_scene_base_add(freestyle_scene, ob);
+ DEG_relations_tag_update(freestyle_bmain);
- DAG_id_tag_update_ex(freestyle_bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update_ex(freestyle_bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
@@ -958,6 +952,8 @@ Render *BlenderStrokeRenderer::RenderScene(Render * /*re*/, bool render)
#endif
Render *freestyle_render = RE_NewRender(freestyle_scene->id.name);
+ DEG_scene_relations_update(freestyle_bmain, freestyle_scene);
+ freestyle_render->depsgraph = freestyle_scene->depsgraph;
RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene,
render && get_stroke_count() > 0);
diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
index 9c462bb6b2b..6f5491fc8ef 100644
--- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
+++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
@@ -51,7 +51,6 @@ IndexedFaceSet::IndexedFaceSet() : Rep()
_MISize = 0;
_TIndices = NULL;
_TISize = 0;
- _displayList = 0;
}
IndexedFaceSet::IndexedFaceSet(float *iVertices, unsigned iVSize, float *iNormals, unsigned iNSize,
@@ -150,8 +149,6 @@ IndexedFaceSet::IndexedFaceSet(float *iVertices, unsigned iVSize, float *iNormal
_TISize = iTISize;
_TIndices = iTIndices;
}
-
- _displayList = 0;
}
IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet& iBrother) : Rep(iBrother)
@@ -215,8 +212,6 @@ IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet& iBrother) : Rep(iBrother)
_TIndices = new unsigned[_TISize];
memcpy(_TIndices, iBrother.tindices(), _TISize * sizeof(unsigned));
}
-
- _displayList = 0;
}
IndexedFaceSet::~IndexedFaceSet()
@@ -276,10 +271,6 @@ IndexedFaceSet::~IndexedFaceSet()
delete[] _TIndices;
_TIndices = NULL;
}
-
- // should find a way to deallocates the displayList
- // glDeleteLists(GLuint list, GLSizei range)
- _displayList = 0;
}
void IndexedFaceSet::accept(SceneVisitor& v)
diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
index 8d7bf986bde..16dea6f907e 100644
--- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
+++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
@@ -150,8 +150,6 @@ public:
std::swap(_MISize, ioOther._MISize);
std::swap(_TISize, ioOther._TISize);
- std::swap(_displayList, ioOther._displayList);
-
Rep::swap(ioOther);
}
@@ -173,12 +171,6 @@ public:
/*! Compute the Bounding Box */
virtual void ComputeBBox();
- /*! modifiers */
- inline void setDisplayList(unsigned int index)
- {
- _displayList = index;
- }
-
/*! Accessors */
virtual const float *vertices() const
{
@@ -280,11 +272,6 @@ public:
return _TISize;
}
- inline unsigned int displayList() const
- {
- return _displayList;
- }
-
protected:
float *_Vertices;
float *_Normals;
@@ -311,8 +298,6 @@ protected:
unsigned _MISize;
unsigned _TISize;
- unsigned int _displayList;
-
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:IndexedFaceSet")
#endif
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 885ff2ff159..9b7cb827adb 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -31,6 +31,9 @@ set(INC
../imbuf
../makesdna
../makesrna
+ ../draw
+
+ ../editors/include
# For node muting stuff...
../nodes
@@ -39,6 +42,7 @@ set(INC
../../../intern/glew-mx
../../../intern/guardedalloc
../../../intern/smoke/extern
+ ../../../intern/gawain
)
set(INC_SYS
@@ -47,6 +51,7 @@ set(INC_SYS
set(SRC
intern/gpu_basic_shader.c
+ intern/gpu_batch.c
intern/gpu_buffers.c
intern/gpu_codegen.c
intern/gpu_compositing.c
@@ -54,13 +59,19 @@ set(SRC
intern/gpu_draw.c
intern/gpu_extensions.c
intern/gpu_framebuffer.c
+ intern/gpu_immediate.c
+ intern/gpu_immediate_util.c
intern/gpu_init_exit.c
+ intern/gpu_lamp.c
intern/gpu_material.c
+ intern/gpu_matrix.c
intern/gpu_select.c
intern/gpu_select_pick.c
intern/gpu_select_sample_query.c
intern/gpu_shader.c
intern/gpu_texture.c
+ intern/gpu_uniformbuffer.c
+ intern/gpu_viewport.c
shaders/gpu_shader_fx_lib.glsl
shaders/gpu_shader_fx_ssao_frag.glsl
@@ -69,7 +80,7 @@ set(SRC
shaders/gpu_shader_fx_dof_hq_frag.glsl
shaders/gpu_shader_fx_dof_hq_vert.glsl
shaders/gpu_shader_fx_dof_hq_geo.glsl
- shaders/gpu_shader_fx_vert.glsl
+ shaders/gpu_shader_fullscreen_vert.glsl
shaders/gpu_shader_material.glsl
shaders/gpu_shader_sep_gaussian_blur_frag.glsl
shaders/gpu_shader_sep_gaussian_blur_vert.glsl
@@ -85,6 +96,7 @@ set(SRC
shaders/gpu_shader_smoke_vert.glsl
GPU_basic_shader.h
+ GPU_batch.h
GPU_buffers.h
GPU_compositing.h
GPU_debug.h
@@ -92,16 +104,106 @@ set(SRC
GPU_extensions.h
GPU_framebuffer.h
GPU_glew.h
+ GPU_immediate.h
+ GPU_immediate_util.h
GPU_init_exit.h
+ GPU_legacy_stubs.h
GPU_material.h
+ GPU_matrix.h
GPU_select.h
GPU_shader.h
GPU_texture.h
+ GPU_uniformbuffer.h
+ GPU_viewport.h
+
intern/gpu_codegen.h
intern/gpu_private.h
+ intern/gpu_lamp_private.h
intern/gpu_select_private.h
+ intern/gpu_shader_private.h
)
+data_to_c_simple(shaders/gpu_shader_depth_only_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_uniform_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_checker_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_diag_stripes_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_lighting_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_flat_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_flat_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_line_dashed_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_line_dashed_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_line_dashed_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_image_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_alpha_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_interlace_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_normal_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_line_dashed_legacy_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_line_dashed_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_normal_smooth_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_passthrough_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl SRC)
+
+data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_screen_aligned_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_camera_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_distance_line_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl SRC)
+
+data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
+
+data_to_c_simple(shaders/gpu_shader_point_uniform_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_uniform_color_aa_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_varying_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_varying_size_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl SRC)
+
+data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_front_back_ortho_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_overlay_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_overlay_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_overlay_simple_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_edges_overlay_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_text_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_text_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_keyframe_diamond_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_keyframe_diamond_frag.glsl SRC)
+
data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fire_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_smoke_frag.glsl SRC)
@@ -116,7 +218,7 @@ data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_fx_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fullscreen_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_ssao_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_basic_shader.h b/source/blender/gpu/GPU_basic_shader.h
index d9bf3d1ced3..dc378927e79 100644
--- a/source/blender/gpu/GPU_basic_shader.h
+++ b/source/blender/gpu/GPU_basic_shader.h
@@ -64,12 +64,6 @@ typedef enum GPUBasicShaderStipple {
GPU_SHADER_STIPPLE_HEXAGON = 3,
GPU_SHADER_STIPPLE_DIAG_STRIPES = 4,
GPU_SHADER_STIPPLE_DIAG_STRIPES_SWAP = 5,
- GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW = 6,
- GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW_SWAP = 7,
- GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN = 8,
- GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN_SWAP = 9,
- GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER = 10,
- GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER_SWAP = 11
} GPUBasicShaderStipple;
void GPU_basic_shaders_init(void);
@@ -132,9 +126,6 @@ void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id);
void GPU_basic_shader_line_stipple(GLint stipple_factor, GLushort stipple_pattern);
void GPU_basic_shader_line_width(float line_width);
-bool GPU_basic_shader_use_glsl_get(void);
-void GPU_basic_shader_use_glsl_set(bool enabled);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
new file mode 100644
index 00000000000..f27153ccecf
--- /dev/null
+++ b/source/blender/gpu/GPU_batch.h
@@ -0,0 +1,51 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* Batched geometry rendering is powered by the Gawain library.
+ * This file contains any additions or modifications specific to Blender.
+ */
+
+#ifndef __GPU_BATCH_H__
+#define __GPU_BATCH_H__
+
+#include "../../../intern/gawain/gawain/batch.h"
+
+// TODO: CMake magic to do this:
+// #include "gawain/batch.h"
+
+#include "GPU_shader.h"
+
+/* Extend Batch_set_program to use Blender’s library of built-in shader programs. */
+void Batch_set_builtin_program(Batch*, GPUBuiltinShader);
+
+/* Replacement for gluSphere */
+Batch *Batch_get_sphere(int lod);
+Batch *Batch_get_sphere_wire(int lod);
+
+void gpu_batch_init(void);
+void gpu_batch_exit(void);
+
+#endif /* __GPU_BATCH_H__ */
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index e4a837d0a5f..b4d271ed3b9 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -51,6 +51,7 @@ struct GPUVertPointLink;
struct GPUDrawObject;
struct GridCommonGPUBuffer;
struct PBVH;
+struct Batch;
struct MVert;
typedef struct GPUBuffer {
@@ -260,11 +261,10 @@ void GPU_pbvh_grid_buffers_update(
void GPU_pbvh_buffers_draw(
GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
bool wireframe, bool fast);
+struct Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast);
-/* debug PBVH draw*/
-void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf);
-void GPU_pbvh_BB_draw_init(void);
-void GPU_pbvh_BB_draw_end(void);
+/* debug PBVH draw */
+void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, unsigned int pos);
bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, struct GSet *bm_faces, bool show_diffuse_color);
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
index 61b2bc591ce..c7a99d33654 100644
--- a/source/blender/gpu/GPU_debug.h
+++ b/source/blender/gpu/GPU_debug.h
@@ -41,24 +41,6 @@ extern "C" {
/* prints something if debug mode is active only */
void GPU_print_error_debug(const char *str);
-/* replacement for gluErrorString */
-const char *gpuErrorString(GLenum err);
-
-/* prints current OpenGL state */
-void GPU_state_print(void);
-
-void GPU_assert_no_gl_errors(const char *file, int line, const char *str);
-
-# define GPU_ASSERT_NO_GL_ERRORS(str) GPU_assert_no_gl_errors(__FILE__, __LINE__, (str))
-
-# define GPU_CHECK_ERRORS_AROUND(glProcCall) \
- ( \
- GPU_ASSERT_NO_GL_ERRORS("Pre: " #glProcCall), \
- (glProcCall), \
- GPU_ASSERT_NO_GL_ERRORS("Post: " #glProcCall) \
- )
-
-
/* inserts a debug marker message for the debug context messaging system */
void GPU_string_marker(const char *str);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 90b65af87c8..ad7eb0339e0 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -39,9 +39,9 @@ extern "C" {
struct ImBuf;
struct Image;
struct ImageUser;
-struct MTexPoly;
struct Object;
struct Scene;
+struct SceneLayer;
struct View3D;
struct RegionView3D;
struct SmokeModifierData;
@@ -59,6 +59,13 @@ struct DupliObject;
void GPU_state_init(void);
+/* Programmable point size
+ * - shaders set their own point size when enabled
+ * - use glPointSize when disabled */
+
+void GPU_enable_program_point_size(void);
+void GPU_disable_program_point_size(void);
+
/* Material drawing
* - first the state is initialized by a particular object and
* it's materials
@@ -66,8 +73,9 @@ void GPU_state_init(void);
* GPU_object_material_bind returns 0 if drawing should be skipped
* - after drawing, the material must be disabled again */
-void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
- struct Scene *scene, struct Object *ob, bool glsl, bool *do_alpha_after);
+void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
+ struct Scene *scene, struct SceneLayer *sl,
+ struct Object *ob, bool glsl, bool *do_alpha_after);
void GPU_end_object_materials(void);
bool GPU_object_materials_check(void);
@@ -84,29 +92,19 @@ bool GPU_material_use_matcaps_get(void);
void GPU_set_material_alpha_blend(int alphablend);
int GPU_get_material_alpha_blend(void);
-/* TexFace drawing
- * - this is mutually exclusive with material drawing, a mesh should
- * be drawn using one or the other
- * - passing NULL clears the state again */
-
-int GPU_set_tpage(struct MTexPoly *mtexpoly, int mipmap, int transp);
-void GPU_clear_tpage(bool force);
-
/* Lights
* - returns how many lights were enabled
* - this affects fixed functions materials and texface, not glsl */
int GPU_default_lights(void);
int GPU_scene_object_lights(
- struct Scene *scene, struct Object *ob,
- int lay, float viewmat[4][4], int ortho);
+ struct SceneLayer *sl, float viewmat[4][4], int ortho);
/* Text render
* - based on moving uv coordinates */
void GPU_render_text(
- struct MTexPoly *mtexpoly, int mode,
- const char *textstr, int textlen, unsigned int *col,
+ int mode, const char *textstr, int textlen, unsigned int *col,
const float *v_quad[4], const float *uv_quad[4],
int glattrib);
@@ -166,6 +164,17 @@ void GPU_select_index_get(int index, int *r_col);
int GPU_select_to_index(unsigned int col);
void GPU_select_to_index_array(unsigned int *col, const unsigned int size);
+typedef enum eGPUAttribMask {
+ GPU_DEPTH_BUFFER_BIT = (1 << 0),
+ GPU_ENABLE_BIT = (1 << 1),
+ GPU_SCISSOR_BIT = (1 << 2),
+ GPU_VIEWPORT_BIT = (1 << 3),
+ GPU_BLEND_BIT = (1 << 4),
+} eGPUAttribMask;
+
+void gpuPushAttrib(eGPUAttribMask mask);
+void gpuPopAttrib(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 31ad8243c4b..d36b0ea15be 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -38,21 +38,16 @@ extern "C" {
/* GPU extensions support */
-void GPU_extensions_disable(void);
-
-bool GPU_legacy_support(void);
bool GPU_full_non_power_of_two_support(void);
-bool GPU_display_list_support(void);
bool GPU_bicubic_bump_support(void);
-bool GPU_geometry_shader_support(void);
-bool GPU_geometry_shader_support_via_extension(void);
-bool GPU_instanced_drawing_support(void);
int GPU_max_texture_size(void);
int GPU_max_textures(void);
float GPU_max_texture_anisotropy(void);
int GPU_max_color_texture_samples(void);
int GPU_max_cube_map_size(void);
+int GPU_max_ubo_binds(void);
+int GPU_max_ubo_size(void);
int GPU_color_depth(void);
void GPU_get_dfdy_factors(float fac[2]);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 2719b8fa6a8..92f5d8a3796 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -50,8 +50,9 @@ struct GPUTexture;
void GPU_texture_bind_as_framebuffer(struct GPUTexture *tex);
GPUFrameBuffer *GPU_framebuffer_create(void);
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, char err_out[256]);
+bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, int mip);
void GPU_framebuffer_texture_detach(struct GPUTexture *tex);
+void GPU_framebuffer_bind(GPUFrameBuffer *fb);
void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot);
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, struct GPUTexture *tex);
void GPU_framebuffer_free(GPUFrameBuffer *fb);
@@ -66,6 +67,10 @@ void GPU_framebuffer_blur(
GPUFrameBuffer *fb, struct GPUTexture *tex,
GPUFrameBuffer *blurfb, struct GPUTexture *blurtex);
+void GPU_framebuffer_blit(
+ GPUFrameBuffer *fb_read, int read_slot,
+ GPUFrameBuffer *fb_write, int write_slot, bool use_depth);
+
/* GPU OffScreen
* - wrapper around framebuffer and texture for simple offscreen drawing
* - changes size if graphics card can't support it */
@@ -79,6 +84,10 @@ int GPU_offscreen_width(const GPUOffScreen *ofs);
int GPU_offscreen_height(const GPUOffScreen *ofs);
int GPU_offscreen_color_texture(const GPUOffScreen *ofs);
+void GPU_offscreen_viewport_data_get(
+ GPUOffScreen *ofs,
+ GPUFrameBuffer **r_fb, struct GPUTexture **r_color, struct GPUTexture **r_depth);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_glew.h b/source/blender/gpu/GPU_glew.h
index 94217863fd6..afe1c9763ad 100644
--- a/source/blender/gpu/GPU_glew.h
+++ b/source/blender/gpu/GPU_glew.h
@@ -34,4 +34,8 @@
#include "glew-mx.h"
+#ifndef WITH_LEGACY_OPENGL
+#include "GPU_legacy_stubs.h"
+#endif
+
#endif /* __GPU_GLEW_H__ */
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
new file mode 100644
index 00000000000..2eb4eb94f48
--- /dev/null
+++ b/source/blender/gpu/GPU_immediate.h
@@ -0,0 +1,58 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* Immediate mode rendering is powered by the Gawain library.
+ * This file contains any additions or modifications specific to Blender.
+ */
+
+#ifndef __GPU_IMMEDIATE_H__
+#define __GPU_IMMEDIATE_H__
+
+#include "../../../intern/gawain/gawain/immediate.h"
+#include "../../../intern/gawain/gawain/imm_util.h"
+
+// TODO: CMake magic to do this:
+// #include "gawain/immediate.h"
+// #include "gawain/imm_util.h"
+
+#include "GPU_shader.h"
+
+/* Extend immBindProgram to use Blender’s library of built-in shader programs.
+ * Use immUnbindProgram() when done. */
+void immBindBuiltinProgram(GPUBuiltinShader shader_id);
+
+/*
+ * Extend immUniformColor to take Blender's themes
+ */
+void immUniformThemeColor(int color_id);
+void immUniformThemeColor3(int color_id);
+void immUniformThemeColorShade(int color_id, int offset);
+void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset);
+void immUniformThemeColorBlendShade(int color_id1, int color_id2, float fac, int offset);
+void immUniformThemeColorBlend(int color_id1, int color_id2, float fac);
+void immThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset);
+
+#endif /* __GPU_IMMEDIATE_H__ */
diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h
new file mode 100644
index 00000000000..b68b353e717
--- /dev/null
+++ b/source/blender/gpu/GPU_immediate_util.h
@@ -0,0 +1,59 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_immediate_util.h
+ * \ingroup gpu
+ *
+ * Utility drawing functions (rough equivalent to OpenGL's GLU)
+ */
+
+#ifndef __GPU_IMMEDIATE_UTIL_H__
+#define __GPU_IMMEDIATE_UTIL_H__
+
+void imm_cpack(unsigned int x);
+
+void imm_draw_circle_wire(uint shdr_pos, float x, float y, float radius, int nsegments);
+void imm_draw_circle_fill(uint shdr_pos, float x, float y, float radius, int nsegments);
+
+/* use this version when VertexFormat has a vec3 position */
+void imm_draw_circle_wire_3d(unsigned pos, float x, float y, float radius, int nsegments);
+void imm_draw_circle_fill_3d(unsigned pos, float x, float y, float radius, int nsegments);
+
+void imm_draw_disk_partial_fill(
+ unsigned pos, float x, float y,
+ float radius_inner, float radius_outer, int nsegments, float start, float sweep);
+
+void imm_draw_line_box(unsigned pos, float x1, float y1, float x2, float y2);
+
+void imm_draw_line_box_3d(unsigned pos, float x1, float y1, float x2, float y2);
+
+void imm_draw_checker_box(float x1, float y1, float x2, float y2);
+
+void imm_draw_cylinder_fill_normal_3d(
+ unsigned int pos, unsigned int nor, float base, float top, float height,
+ int slices, int stacks);
+void imm_draw_cylinder_wire_3d(
+ unsigned int pos, float base, float top, float height,
+ int slices, int stacks);
+void imm_draw_cylinder_fill_3d(
+ unsigned int pos, float base, float top, float height,
+ int slices, int stacks);
+
+#endif /* __GPU_IMMEDIATE_UTIL_H__ */
diff --git a/source/blender/gpu/GPU_lamp.h b/source/blender/gpu/GPU_lamp.h
new file mode 100644
index 00000000000..e08fbede80a
--- /dev/null
+++ b/source/blender/gpu/GPU_lamp.h
@@ -0,0 +1,77 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_lamp.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_LAMP_H__
+#define __GPU_LAMP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Scene;
+struct Object;
+struct RenderEngineType;
+
+typedef struct GPULamp GPULamp;
+
+#define MAX_LAMP_DATA 2
+
+typedef struct LampEngineData {
+ void *storage[MAX_LAMP_DATA];
+} LampEngineData;
+
+LampEngineData *GPU_lamp_engine_data_get(struct Scene *scene, struct Object *ob, struct Object *par, struct RenderEngineType *re);
+
+GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
+void GPU_lamp_free(struct Object *ob);
+void GPU_lamp_engine_data_free(LampEngineData *led);
+
+bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
+bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
+void GPU_lamp_update_buffer_mats(GPULamp *lamp);
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
+void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
+int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
+int GPU_lamp_shadow_bind_code(GPULamp *lamp);
+float *GPU_lamp_dynpersmat(GPULamp *lamp);
+
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
+void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
+void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
+ float coeff_const, float coeff_lin, float coeff_quad);
+void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
+int GPU_lamp_shadow_layer(GPULamp *lamp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GPU_LAMP_H__ */
diff --git a/source/blender/gpu/GPU_legacy_stubs.h b/source/blender/gpu/GPU_legacy_stubs.h
new file mode 100644
index 00000000000..a195eac9eec
--- /dev/null
+++ b/source/blender/gpu/GPU_legacy_stubs.h
@@ -0,0 +1,457 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation, Dalai Felinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_legacy_stubs.h
+ * \ingroup gpu
+ *
+ * This is to mark the transition to OpenGL core profile
+ * The idea is to allow Blender 2.8 to be built with OpenGL 3.3 even if it means breaking things
+ *
+ * This file should be removed in the future
+ */
+
+#ifndef __GPU_LEGACY_STUBS_H__
+#define __GPU_LEGACY_STUBS_H__
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+# pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#include <stdlib.h> /* for abort(). */
+
+#include "BLI_utildefines.h"
+
+/**
+ * Empty function, use for breakpoint when a depreacated
+ * OpenGL function is called.
+ */
+static void gl_deprecated(void)
+{
+ BLI_assert(true);
+}
+
+#define _GL_BOOL BLI_INLINE GLboolean
+#define _GL_BOOL_RET { \
+ gl_deprecated(); \
+ return false; \
+}
+
+#define _GL_ENUM BLI_INLINE GLenum
+#define _GL_ENUM_RET { \
+ gl_deprecated(); \
+ return 0; \
+}
+
+#define _GL_INT BLI_INLINE GLint
+#define _GL_INT_RET { \
+ gl_deprecated(); \
+ return 0; \
+}
+
+
+#define _GL_UINT BLI_INLINE GLuint
+#define _GL_UINT_RET { \
+ gl_deprecated(); \
+ return 0; \
+}
+
+#define _GL_VOID BLI_INLINE void
+#define _GL_VOID_RET { \
+ gl_deprecated(); \
+}
+
+static bool disable_enable_check(GLenum cap)
+{
+ const bool is_deprecated = \
+ ELEM(
+ cap,
+ GL_ALPHA_TEST,
+ GL_LINE_STIPPLE,
+ GL_POINT_SPRITE,
+ GL_TEXTURE_1D,
+ GL_TEXTURE_2D,
+ GL_TEXTURE_GEN_S,
+ GL_TEXTURE_GEN_T,
+ -1
+ );
+
+ if (is_deprecated) {
+ gl_deprecated();
+ }
+
+ return is_deprecated;
+}
+
+_GL_VOID USE_CAREFULLY_glDisable (GLenum cap)
+{
+ if (!disable_enable_check(cap)) {
+ glDisable(cap);
+ }
+}
+#define glDisable USE_CAREFULLY_glDisable
+
+_GL_VOID USE_CAREFULLY_glEnable (GLenum cap)
+{
+ if (!disable_enable_check(cap)) {
+ glEnable(cap);
+ }
+}
+#define glEnable USE_CAREFULLY_glEnable
+
+/**
+ * Hand written cases
+ */
+
+_GL_VOID DO_NOT_USE_glClientActiveTexture (GLenum texture) _GL_VOID_RET
+
+
+/**
+ * List automatically generated from `gl-deprecated.h` and `glew.h`
+ */
+
+/**
+ * ENUM values
+ */
+#define DO_NOT_USE_GL_CURRENT_FOG_COORDINATE 0
+#define DO_NOT_USE_GL_FOG_COORDINATE 0
+#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY 0
+#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0
+#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_POINTER 0
+#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_STRIDE 0
+#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_TYPE 0
+#define DO_NOT_USE_GL_FOG_COORDINATE_SOURCE 0
+#define DO_NOT_USE_GL_POINT_SIZE_GRANULARITY 0
+#define DO_NOT_USE_GL_POINT_SIZE_RANGE 0
+#define DO_NOT_USE_GL_SOURCE0_ALPHA 0
+#define DO_NOT_USE_GL_SOURCE0_RGB 0
+#define DO_NOT_USE_GL_SOURCE1_ALPHA 0
+#define DO_NOT_USE_GL_SOURCE1_RGB 0
+#define DO_NOT_USE_GL_SOURCE2_ALPHA 0
+#define DO_NOT_USE_GL_SOURCE2_RGB 0
+
+/**
+ * Functions
+ */
+_GL_VOID DO_NOT_USE_glAccum (GLenum op, GLfloat value) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glAlphaFunc (GLenum func, GLclampf ref) _GL_VOID_RET
+_GL_BOOL DO_NOT_USE_glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences) _GL_BOOL_RET
+_GL_VOID DO_NOT_USE_glArrayElement (GLint i) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glBegin (GLenum mode) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glCallList (GLuint list) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glCallLists (GLsizei n, GLenum type, const void *lists) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glClearIndex (GLfloat c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glClipPlane (GLenum plane, const GLdouble *equation) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3b (GLbyte red, GLbyte green, GLbyte blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3bv (const GLbyte *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3d (GLdouble red, GLdouble green, GLdouble blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3f (GLfloat red, GLfloat green, GLfloat blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3i (GLint red, GLint green, GLint blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3s (GLshort red, GLshort green, GLshort blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3ub (GLubyte red, GLubyte green, GLubyte blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3ubv (const GLubyte *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3ui (GLuint red, GLuint green, GLuint blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3uiv (const GLuint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3us (GLushort red, GLushort green, GLushort blue) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor3usv (const GLushort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4bv (const GLbyte *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4i (GLint red, GLint green, GLint blue, GLint alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4ubv (const GLubyte *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4uiv (const GLuint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColor4usv (const GLushort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColorMaterial (GLenum face, GLenum mode) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glDeleteLists (GLuint list, GLsizei range) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glDisableClientState (GLenum array) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEdgeFlag (GLboolean flag) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEdgeFlagPointer (GLsizei stride, const void *pointer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEdgeFlagv (const GLboolean *flag) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEnableClientState (GLenum array) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEnd (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEndList (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord1d (GLdouble u) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord1dv (const GLdouble *u) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord1f (GLfloat u) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord1fv (const GLfloat *u) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord2d (GLdouble u, GLdouble v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord2dv (const GLdouble *u) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord2f (GLfloat u, GLfloat v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalCoord2fv (const GLfloat *u) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalMesh1 (GLenum mode, GLint i1, GLint i2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalPoint1 (GLint i) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glEvalPoint2 (GLint i, GLint j) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glFogf (GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glFogfv (GLenum pname, const GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glFogi (GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glFogiv (GLenum pname, const GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) _GL_VOID_RET
+_GL_UINT DO_NOT_USE_glGenLists (GLsizei range) _GL_UINT_RET
+_GL_VOID DO_NOT_USE_glGetClipPlane (GLenum plane, GLdouble *equation) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetLightfv (GLenum light, GLenum pname, GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetLightiv (GLenum light, GLenum pname, GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetMapdv (GLenum target, GLenum query, GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetMapfv (GLenum target, GLenum query, GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetMapiv (GLenum target, GLenum query, GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetMaterialiv (GLenum face, GLenum pname, GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetPixelMapfv (GLenum map, GLfloat *values) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetPixelMapuiv (GLenum map, GLuint *values) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetPixelMapusv (GLenum map, GLushort *values) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetPolygonStipple (GLubyte *mask) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetTexEnviv (GLenum target, GLenum pname, GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glGetTexGeniv (GLenum coord, GLenum pname, GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexMask (GLuint mask) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexPointer (GLenum type, GLsizei stride, const void *pointer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexd (GLdouble c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexdv (const GLdouble *c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexf (GLfloat c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexfv (const GLfloat *c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexi (GLint c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexiv (const GLint *c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexs (GLshort c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexsv (const GLshort *c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexub (GLubyte c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glIndexubv (const GLubyte *c) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glInitNames (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glInterleavedArrays (GLenum format, GLsizei stride, const void *pointer) _GL_VOID_RET
+_GL_BOOL DO_NOT_USE_glIsList (GLuint list) _GL_BOOL_RET
+_GL_VOID DO_NOT_USE_glLightModelf (GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLightModelfv (GLenum pname, const GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLightModeli (GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLightModeliv (GLenum pname, const GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLightf (GLenum light, GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLightfv (GLenum light, GLenum pname, const GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLighti (GLenum light, GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLightiv (GLenum light, GLenum pname, const GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLineStipple (GLint factor, GLushort pattern) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glListBase (GLuint base) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLoadIdentity (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLoadMatrixd (const GLdouble *m) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLoadMatrixf (const GLfloat *m) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glLoadName (GLuint name) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMapGrid1d (GLint un, GLdouble u1, GLdouble u2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMapGrid1f (GLint un, GLfloat u1, GLfloat u2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMaterialf (GLenum face, GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMaterialfv (GLenum face, GLenum pname, const GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMateriali (GLenum face, GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMaterialiv (GLenum face, GLenum pname, const GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMatrixMode (GLenum mode) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMultMatrixd (const GLdouble *m) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glMultMatrixf (const GLfloat *m) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNewList (GLuint list, GLenum mode) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3bv (const GLbyte *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3i (GLint nx, GLint ny, GLint nz) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3s (GLshort nx, GLshort ny, GLshort nz) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormal3sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glNormalPointer (GLenum type, GLsizei stride, const void *pointer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPassThrough (GLfloat token) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPixelTransferf (GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPixelTransferi (GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPixelZoom (GLfloat xfactor, GLfloat yfactor) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPolygonStipple (const GLubyte *mask) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPopAttrib (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPopClientAttrib (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPopMatrix (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPopName (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPushAttrib (GLbitfield mask) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPushClientAttrib (GLbitfield mask) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPushMatrix (void) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glPushName (GLuint name) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2d (GLdouble x, GLdouble y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2f (GLfloat x, GLfloat y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2i (GLint x, GLint y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2s (GLshort x, GLshort y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos2sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3d (GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3f (GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3i (GLint x, GLint y, GLint z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3s (GLshort x, GLshort y, GLshort z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos3sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4i (GLint x, GLint y, GLint z, GLint w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRasterPos4sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRectdv (const GLdouble *v1, const GLdouble *v2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRectfv (const GLfloat *v1, const GLfloat *v2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRecti (GLint x1, GLint y1, GLint x2, GLint y2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRectiv (const GLint *v1, const GLint *v2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRectsv (const GLshort *v1, const GLshort *v2) _GL_VOID_RET
+_GL_INT DO_NOT_USE_glRenderMode (GLenum mode) _GL_INT_RET
+_GL_VOID DO_NOT_USE_glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glScaled (GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glScalef (GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glSelectBuffer (GLsizei size, GLuint *buffer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glShadeModel (GLenum mode) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1d (GLdouble s) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1f (GLfloat s) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1i (GLint s) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1s (GLshort s) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord1sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2d (GLdouble s, GLdouble t) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2f (GLfloat s, GLfloat t) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2i (GLint s, GLint t) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2s (GLshort s, GLshort t) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord2sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3d (GLdouble s, GLdouble t, GLdouble r) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3f (GLfloat s, GLfloat t, GLfloat r) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3i (GLint s, GLint t, GLint r) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3s (GLshort s, GLshort t, GLshort r) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord3sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4i (GLint s, GLint t, GLint r, GLint q) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoord4sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexEnvf (GLenum target, GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexEnvi (GLenum target, GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexEnviv (GLenum target, GLenum pname, const GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexGend (GLenum coord, GLenum pname, GLdouble param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexGendv (GLenum coord, GLenum pname, const GLdouble *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexGenf (GLenum coord, GLenum pname, GLfloat param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexGeni (GLenum coord, GLenum pname, GLint param) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTexGeniv (GLenum coord, GLenum pname, const GLint *params) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTranslated (GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glTranslatef (GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2d (GLdouble x, GLdouble y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2f (GLfloat x, GLfloat y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2i (GLint x, GLint y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2s (GLshort x, GLshort y) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex2sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3d (GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3f (GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3i (GLint x, GLint y, GLint z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3s (GLshort x, GLshort y, GLshort z) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex3sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4dv (const GLdouble *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4fv (const GLfloat *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4i (GLint x, GLint y, GLint z, GLint w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4iv (const GLint *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertex4sv (const GLshort *v) _GL_VOID_RET
+_GL_VOID DO_NOT_USE_glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer) _GL_VOID_RET
+
+/**
+ * End of automatically generated list
+ */
+
+
+
+#undef _GL_BOOL
+#undef _GL_BOOL_RET
+#undef _GL_ENUM
+#undef _GL_ENUM_RET
+#undef _GL_INT
+#undef _GL_INT_RET
+#undef _GL_UINT
+#undef _GL_UINT_RET
+#undef _GL_VOID
+#undef _GL_VOID_RET
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
+
+#endif /* __GPU_LEGACY_STUBS_H__ */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 6db23686832..4345a31839a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -45,7 +45,6 @@ struct Image;
struct ImageUser;
struct Material;
struct Object;
-struct Image;
struct Scene;
struct SceneRenderLayer;
struct GPUVertexAttribs;
@@ -57,11 +56,12 @@ struct GPUTexture;
struct GPULamp;
struct PreviewImage;
struct World;
+struct bNodeTree;
typedef struct GPUNode GPUNode;
typedef struct GPUNodeLink GPUNodeLink;
typedef struct GPUMaterial GPUMaterial;
-typedef struct GPULamp GPULamp;
+
typedef struct GPUParticleInfo GPUParticleInfo;
/* Functions to create GPU Materials nodes */
@@ -219,14 +219,15 @@ GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo);
-
+GPUMaterial *GPU_material_from_nodetree(
+ struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, void *engine_type, int options,
+ const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines);
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
-bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
void GPU_material_bind(
GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
@@ -237,6 +238,7 @@ void GPU_material_unbind(GPUMaterial *material);
bool GPU_material_bound(GPUMaterial *material);
struct Scene *GPU_material_scene(GPUMaterial *material);
GPUMatType GPU_Material_get_type(GPUMaterial *material);
+struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
void GPU_material_vertex_attributes(GPUMaterial *material,
struct GPUVertexAttribs *attrib);
@@ -312,26 +314,8 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma);
void GPU_free_shader_export(GPUShaderExport *shader);
/* Lamps */
-
-GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
-void GPU_lamp_free(struct Object *ob);
-
-bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
-void GPU_lamp_update_buffer_mats(GPULamp *lamp);
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
-void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
-int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
-int GPU_lamp_shadow_bind_code(GPULamp *lamp);
-float *GPU_lamp_dynpersmat(GPULamp *lamp);
-
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
-void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
-void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
- float coeff_const, float coeff_lin, float coeff_quad);
-void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
-int GPU_lamp_shadow_layer(GPULamp *lamp);
GPUNodeLink *GPU_lamp_get_data(
- GPUMaterial *mat, GPULamp *lamp,
+ GPUMaterial *mat, struct GPULamp *lamp,
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy);
/* World */
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
new file mode 100644
index 00000000000..b62506c154f
--- /dev/null
+++ b/source/blender/gpu/GPU_matrix.h
@@ -0,0 +1,180 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Alexandr Kuznetsov, Jason Wilkins, Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/gpu/GPU_matrix.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_MATRIX_H__
+#define __GPU_MATRIX_H__
+
+#include "BLI_sys_types.h"
+#include "GPU_glew.h"
+#include "../../../intern/gawain/gawain/shader_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gpuMatrixReset(void); /* to Identity transform & empty stack */
+
+/* ModelView Matrix (2D or 3D) */
+
+void gpuPushMatrix(void); /* TODO: PushCopy vs PushIdentity? */
+void gpuPopMatrix(void);
+
+void gpuLoadIdentity(void);
+
+void gpuScaleUniform(float factor);
+
+
+/* 3D ModelView Matrix */
+
+void gpuLoadMatrix(const float m[4][4]);
+void gpuMultMatrix(const float m[4][4]);
+
+void gpuTranslate3f(float x, float y, float z);
+void gpuTranslate3fv(const float vec[3]);
+void gpuScale3f(float x, float y, float z);
+void gpuScale3fv(const float vec[3]);
+void gpuRotate3f(float deg, float x, float y, float z); /* axis of rotation should be a unit vector */
+void gpuRotate3fv(float deg, const float axis[3]); /* axis of rotation should be a unit vector */
+void gpuRotateAxis(float deg, char axis); /* TODO: enum for axis? */
+
+void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
+/* TODO: variant that takes eye[3], center[3], up[3] */
+
+
+/* 2D ModelView Matrix */
+
+void gpuTranslate2f(float x, float y);
+void gpuTranslate2fv(const float vec[2]);
+void gpuScale2f(float x, float y);
+void gpuScale2fv(const float vec[2]);
+void gpuRotate2D(float deg);
+
+/* Projection Matrix (2D or 3D) */
+
+void gpuPushProjectionMatrix(void);
+void gpuPopProjectionMatrix(void);
+
+/* 3D Projection Matrix */
+
+void gpuLoadIdentityProjectionMatrix(void);
+void gpuLoadProjectionMatrix(const float m[4][4]);
+
+void gpuOrtho(float left, float right, float bottom, float top, float near, float far);
+void gpuFrustum(float left, float right, float bottom, float top, float near, float far);
+void gpuPerspective(float fovy, float aspect, float near, float far);
+
+/* 3D Projection between Window and World Space */
+
+void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]);
+bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]);
+
+/* 2D Projection Matrix */
+
+void gpuOrtho2D(float left, float right, float bottom, float top);
+
+
+/* functions to get matrix values */
+const float (*gpuGetModelViewMatrix(float m[4][4]))[4];
+const float (*gpuGetProjectionMatrix(float m[4][4]))[4];
+const float (*gpuGetModelViewProjectionMatrix(float m[4][4]))[4];
+
+const float (*gpuGetNormalMatrix(float m[3][3]))[3];
+const float (*gpuGetNormalMatrixInverse(float m[3][3]))[3];
+
+
+/* set uniform values for currently bound shader */
+void gpuBindMatrices(const ShaderInterface*);
+bool gpuMatricesDirty(void); /* since last bind */
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef SUPPRESS_GENERIC_MATRIX_API
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+#define _GPU_MAT3_CONST_CAST(x) (_Generic((x), \
+ void *: (const float (*)[3])(x), \
+ float *: (const float (*)[3])(x), \
+ float [9]: (const float (*)[3])(x), \
+ float (*)[4]: (const float (*)[3])(x), \
+ float [4][4]: (const float (*)[3])(x), \
+ const void *: (const float (*)[3])(x), \
+ const float *: (const float (*)[3])(x), \
+ const float [9]: (const float (*)[3])(x), \
+ const float (*)[3]: (const float (*)[3])(x), \
+ const float [3][3]: (const float (*)[3])(x)) \
+)
+#define _GPU_MAT3_CAST(x) (_Generic((x), \
+ void *: (float (*)[3])(x), \
+ float *: (float (*)[3])(x), \
+ float [9]: (float (*)[3])(x), \
+ float (*)[3]: (float (*)[3])(x), \
+ float [3][3]: (float (*)[3])(x)) \
+)
+#define _GPU_MAT4_CONST_CAST(x) (_Generic((x), \
+ void *: (const float (*)[4])(x), \
+ float *: (const float (*)[4])(x), \
+ float [16]: (const float (*)[4])(x), \
+ float (*)[4]: (const float (*)[4])(x), \
+ float [4][4]: (const float (*)[4])(x), \
+ const void *: (const float (*)[4])(x), \
+ const float *: (const float (*)[4])(x), \
+ const float [16]: (const float (*)[4])(x), \
+ const float (*)[4]: (const float (*)[4])(x), \
+ const float [4][4]: (const float (*)[4])(x)) \
+)
+#define _GPU_MAT4_CAST(x) (_Generic((x), \
+ void *: (float (*)[4])(x), \
+ float *: (float (*)[4])(x), \
+ float [16]: (float (*)[4])(x), \
+ float (*)[4]: (float (*)[4])(x), \
+ float [4][4]: (float (*)[4])(x)) \
+)
+#else
+# define _GPU_MAT3_CONST_CAST(x) (const float (*)[3])(x)
+# define _GPU_MAT3_CAST(x) (float (*)[3])(x)
+# define _GPU_MAT4_CONST_CAST(x) (const float (*)[4])(x)
+# define _GPU_MAT4_CAST(x) (float (*)[4])(x)
+#endif /* C11 */
+
+/* make matrix inputs generic, to avoid warnings */
+# define gpuMultMatrix(x) gpuMultMatrix(_GPU_MAT4_CONST_CAST(x))
+# define gpuLoadMatrix(x) gpuLoadMatrix(_GPU_MAT4_CONST_CAST(x))
+# define gpuLoadProjectionMatrix(x) gpuLoadProjectionMatrix(_GPU_MAT4_CONST_CAST(x))
+# define gpuGetModelViewMatrix(x) gpuGetModelViewMatrix(_GPU_MAT4_CAST(x))
+# define gpuGetProjectionMatrix(x) gpuGetProjectionMatrix(_GPU_MAT4_CAST(x))
+# define gpuGetModelViewProjectionMatrix(x) gpuGetModelViewProjectionMatrix(_GPU_MAT4_CAST(x))
+# define gpuGetNormalMatrix(x) gpuGetNormalMatrix(_GPU_MAT3_CAST(x))
+# define gpuGetNormalMatrixInverse(x) gpuGetNormalMatrixInverse(_GPU_MAT3_CAST(x))
+#endif /* SUPPRESS_GENERIC_MATRIX_API */
+
+#endif /* __GPU_MATRIX_H__ */
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 5b94db6e120..05949d759a4 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -38,6 +38,7 @@ extern "C" {
typedef struct GPUShader GPUShader;
struct GPUTexture;
+struct GPUUniformBuffer;
/* GPU Shader
* - only for fragment shaders now
@@ -54,29 +55,34 @@ GPUShader *GPU_shader_create(
const char *fragcode,
const char *geocode,
const char *libcode,
- const char *defines,
- int input, int output, int number);
+ const char *defines);
GPUShader *GPU_shader_create_ex(
const char *vertexcode,
const char *fragcode,
const char *geocode,
const char *libcode,
const char *defines,
- int input, int output, int number,
const int flags);
void GPU_shader_free(GPUShader *shader);
void GPU_shader_bind(GPUShader *shader);
void GPU_shader_unbind(void);
+int GPU_shader_get_program(GPUShader *shader);
+
void *GPU_shader_get_interface(GPUShader *shader);
-void GPU_shader_set_interface(GPUShader *shader, void *interface);
+
+void *GPU_fx_shader_get_interface(GPUShader *shader);
+void GPU_fx_shader_set_interface(GPUShader *shader, void *interface);
+
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name);
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length,
int arraysize, const float *value);
void GPU_shader_uniform_vector_int(GPUShader *shader, int location, int length,
int arraysize, const int *value);
+void GPU_shader_uniform_buffer(GPUShader *shader, int location, struct GPUUniformBuffer *ubo);
void GPU_shader_uniform_texture(GPUShader *shader, int location, struct GPUTexture *tex);
void GPU_shader_uniform_int(GPUShader *shader, int location, int value);
void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number);
@@ -85,13 +91,99 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name);
/* Builtin/Non-generated shaders */
typedef enum GPUBuiltinShader {
- GPU_SHADER_VSM_STORE = 0,
- GPU_SHADER_SEP_GAUSSIAN_BLUR = 1,
- GPU_SHADER_SMOKE = 2,
- GPU_SHADER_SMOKE_FIRE = 3,
- GPU_SHADER_SMOKE_COBA = 4,
+ GPU_SHADER_VSM_STORE,
+ GPU_SHADER_SEP_GAUSSIAN_BLUR,
+ GPU_SHADER_SMOKE,
+ GPU_SHADER_SMOKE_FIRE,
+ GPU_SHADER_SMOKE_COBA,
+
+ /* specialized drawing */
+ GPU_SHADER_TEXT,
+ GPU_SHADER_EDGES_FRONT_BACK_PERSP,
+ GPU_SHADER_EDGES_FRONT_BACK_ORTHO,
+ GPU_SHADER_EDGES_OVERLAY_SIMPLE,
+ GPU_SHADER_EDGES_OVERLAY,
+ GPU_SHADER_KEYFRAME_DIAMOND,
+ GPU_SHADER_SIMPLE_LIGHTING,
+ GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR,
+ GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR,
+ GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA,
+ /* for simple 2D drawing */
+ GPU_SHADER_2D_UNIFORM_COLOR,
+ GPU_SHADER_2D_FLAT_COLOR,
+ GPU_SHADER_2D_SMOOTH_COLOR,
+ GPU_SHADER_2D_IMAGE_COLOR,
+ GPU_SHADER_2D_IMAGE_ALPHA_COLOR,
+ GPU_SHADER_2D_CHECKER,
+ GPU_SHADER_2D_DIAG_STRIPES,
+ /* for simple 3D drawing */
+ GPU_SHADER_3D_UNIFORM_COLOR,
+ GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE,
+ GPU_SHADER_3D_FLAT_COLOR,
+ GPU_SHADER_3D_FLAT_COLOR_U32, /* use for select-id's */
+ GPU_SHADER_3D_SMOOTH_COLOR,
+ GPU_SHADER_3D_DEPTH_ONLY,
+ GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
+ /* basic image drawing */
+ GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB,
+ GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
+ GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
+ GPU_SHADER_3D_IMAGE_MODULATE_ALPHA,
+ GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA,
+ GPU_SHADER_3D_IMAGE_DEPTH,
+ /* stereo 3d */
+ GPU_SHADER_2D_IMAGE_INTERLACE,
+ /* points */
+ GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR,
+ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
+ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
+ GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA,
+ GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR,
+ GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR,
+ GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR,
+ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
+ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
+ GPU_SHADER_3D_POINT_VARYING_SIZE_UNIFORM_COLOR,
+ GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR,
+ /* lines */
+ GPU_SHADER_2D_LINE_DASHED_COLOR,
+ GPU_SHADER_3D_LINE_DASHED_COLOR,
+ /* lamp drawing */
+ GPU_SHADER_3D_GROUNDPOINT,
+ GPU_SHADER_3D_GROUNDLINE,
+ GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR,
+ /* bone drawing */
+ GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR,
+ GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR,
+ /* camera drawing */
+ GPU_SHADER_CAMERA,
+ /* distance in front of objects */
+ GPU_SHADER_DISTANCE_LINES,
+ /* axis name */
+ GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS,
+ GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED,
+ /* instance */
+ GPU_SHADER_INSTANCE_UNIFORM_COLOR,
+ GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, /* Uniformly scaled */
+ GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE,
+ GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR,
+
+ GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID,
+ GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE,
+
+ GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
} GPUBuiltinShader;
+/* Keep these in sync with:
+ * gpu_shader_image_interlace_frag.glsl
+ * gpu_shader_image_rect_interlace_frag.glsl
+ **/
+typedef enum GPUInterlaceShader {
+ GPU_SHADER_INTERLACE_ROW = 0,
+ GPU_SHADER_INTERLACE_COLUMN = 1,
+ GPU_SHADER_INTERLACE_CHECKER = 2,
+} GPUInterlaceShader;
+
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);
GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 756fe79151b..01390760beb 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -55,25 +55,118 @@ typedef struct GPUTexture GPUTexture;
* - if created with from_blender, will not free the texture
*/
-typedef enum GPUHDRType {
- GPU_HDR_NONE = 0,
- GPU_HDR_HALF_FLOAT = 1,
- GPU_HDR_FULL_FLOAT = (1 << 1),
-} GPUHDRType;
+/* Wrapper to supported OpenGL/Vulkan texture internal storage
+ * If you need a type just uncomment it. Be aware that some formats
+ * are not supported by renderbuffers. All of the following formats
+ * are part of the OpenGL 3.3 core
+ * specification. */
+typedef enum GPUTextureFormat {
+ /* Formats texture & renderbuffer */
+ GPU_RGBA32F,
+ GPU_RGBA16F,
+ GPU_RGBA8,
+ GPU_RG32F,
+ GPU_RG16F,
+ GPU_R32F,
+ GPU_R16F,
+ GPU_R8,
+#if 0
+ GPU_RGBA32I,
+ GPU_RGBA32UI,
+ GPU_RGBA16,
+ GPU_RGBA16I,
+ GPU_RGBA16UI,
+ GPU_RGBA8I,
+ GPU_RGBA8UI,
+ GPU_RG32I,
+ GPU_RG32UI,
+ GPU_RG16,
+ GPU_RG16I,
+ GPU_RG16UI,
+ GPU_RG8,
+ GPU_RG8I,
+ GPU_RG8UI,
+ GPU_R32I,
+ GPU_R32UI,
+ GPU_R16I,
+ GPU_R16UI,
+ GPU_R16,
+ GPU_R8I,
+ GPU_R8UI,
+#endif
+
+ /* Special formats texture & renderbuffer */
+#if 0
+ GPU_RGB10_A2,
+ GPU_RGB10_A2UI,
+ GPU_DEPTH32F_STENCIL8,
+#endif
+ GPU_R11F_G11F_B10F,
+ GPU_DEPTH24_STENCIL8,
+
+ /* Texture only format */
+ GPU_RGB16F,
+#if 0
+ GPU_RGBA16_SNORM,
+ GPU_RGBA8_SNORM,
+ GPU_RGB32F,
+ GPU_RGB32I,
+ GPU_RGB32UI,
+ GPU_RGB16_SNORM,
+ GPU_RGB16I,
+ GPU_RGB16UI,
+ GPU_RGB16,
+ GPU_RGB8_SNORM,
+ GPU_RGB8,
+ GPU_RGB8I,
+ GPU_RGB8UI,
+ GPU_RG16_SNORM,
+ GPU_RG8_SNORM,
+ GPU_R16_SNORM,
+ GPU_R8_SNORM,
+#endif
+
+ /* Special formats texture only */
+#if 0
+ GPU_SRGB8_A8,
+ GPU_SRGB8,
+ GPU_RGB9_E5,
+ GPU_COMPRESSED_RG_RGTC2,
+ GPU_COMPRESSED_SIGNED_RG_RGTC2,
+ GPU_COMPRESSED_RED_RGTC1,
+ GPU_COMPRESSED_SIGNED_RED_RGTC1,
+#endif
+
+ /* Depth Formats */
+ GPU_DEPTH_COMPONENT32F,
+ GPU_DEPTH_COMPONENT24,
+ GPU_DEPTH_COMPONENT16,
+} GPUTextureFormat;
+
+unsigned int GPU_texture_memory_usage_get(void);
GPUTexture *GPU_texture_create_1D(int w, const float *pixels, char err_out[256]);
-GPUTexture *GPU_texture_create_2D(int w, int h, const float *pixels, GPUHDRType hdr, char err_out[256]);
-GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const float *fpixels);
+GPUTexture *GPU_texture_create_1D_custom(
+ int w, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_2D(int w, int h, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_2D_custom(
+ int w, int h, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_2D_multisample(int w, int h, const float *pixels, int samples, char err_out[256]);
+GPUTexture *GPU_texture_create_2D_array_custom(
+ int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_3D(int w, int h, int d, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_3D_custom(
+ int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_cube_custom(
+ int w, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
-GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]);
-GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, char err_out[256]);
-GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char err_out[256]);
-GPUTexture *GPU_texture_create_2D_multisample(
- int w, int h, const float *pixels, GPUHDRType hdr, int samples, char err_out[256]);
+GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256]);
+
GPUTexture *GPU_texture_from_blender(
struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time, int mipmap);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
+
void GPU_invalid_tex_init(void);
void GPU_invalid_tex_bind(int mode);
void GPU_invalid_tex_free(void);
@@ -81,12 +174,15 @@ void GPU_invalid_tex_free(void);
void GPU_texture_free(GPUTexture *tex);
void GPU_texture_ref(GPUTexture *tex);
-
void GPU_texture_bind(GPUTexture *tex, int number);
void GPU_texture_unbind(GPUTexture *tex);
int GPU_texture_bound_number(GPUTexture *tex);
-void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter);
+void GPU_texture_generate_mipmap(GPUTexture *tex);
+void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare);
+void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter);
+void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap);
+void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat);
struct GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
int GPU_texture_framebuffer_attachment(GPUTexture *tex);
@@ -95,7 +191,9 @@ void GPU_texture_framebuffer_set(GPUTexture *tex, struct GPUFrameBuffer *fb, int
int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
-int GPU_texture_depth(const GPUTexture *tex);
+int GPU_texture_format(const GPUTexture *tex);
+bool GPU_texture_depth(const GPUTexture *tex);
+bool GPU_texture_stencil(const GPUTexture *tex);
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
#ifdef __cplusplus
diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
new file mode 100644
index 00000000000..36b659e30b1
--- /dev/null
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -0,0 +1,49 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_uniformbuffer.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_UNIFORMBUFFER_H__
+#define __GPU_UNIFORMBUFFER_H__
+
+typedef struct GPUUniformBuffer GPUUniformBuffer;
+
+GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256]);
+void GPU_uniformbuffer_free(GPUUniformBuffer *ubo);
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data);
+
+void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number);
+#if 0
+void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo);
+#endif
+
+int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo);
+
+#endif /* __GPU_UNIFORMBUFFER_H__ */
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
new file mode 100644
index 00000000000..2b2a07f50b7
--- /dev/null
+++ b/source/blender/gpu/GPU_viewport.h
@@ -0,0 +1,118 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_viewport.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_VIEWPORT_H__
+#define __GPU_VIEWPORT_H__
+
+#include <stdbool.h>
+
+#include "DNA_vec_types.h"
+
+#include "GPU_framebuffer.h"
+#include "GPU_texture.h"
+
+#define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT */
+
+typedef struct GPUViewport GPUViewport;
+
+/* All FramebufferLists are just the same pointers with different names */
+typedef struct FramebufferList {
+ struct GPUFrameBuffer *framebuffers[0];
+} FramebufferList;
+
+typedef struct TextureList {
+ struct GPUTexture *textures[0];
+} TextureList;
+
+typedef struct PassList {
+ struct DRWPass *passes[0];
+} PassList;
+
+typedef struct StorageList {
+ void *storage[0]; /* custom structs from the engine */
+} StorageList;
+
+typedef struct ViewportEngineData {
+ void *engine_type;
+
+ FramebufferList *fbl;
+ TextureList *txl;
+ PassList *psl;
+ StorageList *stl;
+ char info[GPU_INFO_SIZE];
+
+ /* we may want to put this elsewhere */
+ struct DRWTextStore *text_draw_cache;
+
+ /* Profiling data */
+ double init_time;
+ double cache_time;
+ double render_time;
+ double background_time;
+} ViewportEngineData;
+
+typedef struct ViewportEngineData_Info {
+ int fbl_len;
+ int txl_len;
+ int psl_len;
+ int stl_len;
+} ViewportEngineData_Info;
+
+GPUViewport *GPU_viewport_create(void);
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
+void GPU_viewport_unbind(GPUViewport *viewport);
+void GPU_viewport_free(GPUViewport *viewport);
+
+GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs);
+void GPU_viewport_clear_from_offscreen(GPUViewport *viewport);
+
+void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type);
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type);
+void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport);
+void *GPU_viewport_texture_list_get(GPUViewport *viewport);
+void GPU_viewport_size_get(const GPUViewport *viewport, int size[2]);
+void GPU_viewport_size_set(GPUViewport *viewport, const int size[2]);
+
+/* Texture pool */
+GPUTexture *GPU_viewport_texture_pool_query(GPUViewport *viewport, void *engine, int width, int height, int channels, int format);
+
+bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash);
+
+/* debug */
+bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]);
+void GPU_viewport_debug_depth_free(GPUViewport *viewport);
+void GPU_viewport_debug_depth_store(GPUViewport *viewport, const int x, const int y);
+void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, const float zfar);
+bool GPU_viewport_debug_depth_is_valid(GPUViewport *viewport);
+int GPU_viewport_debug_depth_width(const GPUViewport *viewport);
+int GPU_viewport_debug_depth_height(const GPUViewport *viewport);
+
+#endif // __GPU_VIEWPORT_H__
diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c
index 8505bd847a0..620a06ae606 100644
--- a/source/blender/gpu/intern/gpu_basic_shader.c
+++ b/source/blender/gpu/intern/gpu_basic_shader.c
@@ -140,114 +140,6 @@ const GLubyte stipple_checker_8px[128] = {
0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
-const GLubyte stipple_interlace_row[128] = {
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};
-
-const GLubyte stipple_interlace_row_swap[128] = {
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};
-
-const GLubyte stipple_interlace_column[128] = {
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
-const GLubyte stipple_interlace_column_swap[128] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
-
-const GLubyte stipple_interlace_checker[128] = {
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa};
-
-const GLubyte stipple_interlace_checker_swap[128] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
- 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55};
-
const GLubyte stipple_hexagon[128] = {
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
@@ -267,24 +159,6 @@ const GLubyte stipple_hexagon[128] = {
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22};
/* ********************************************* */
-/* GLSL State */
-
-static bool USE_GLSL = false;
-
-/**
- * \note this isn't part of the basic shader API,
- * only set from the command line once on startup.
- */
-void GPU_basic_shader_use_glsl_set(bool enabled)
-{
- USE_GLSL = enabled;
-}
-
-bool GPU_basic_shader_use_glsl_get(void)
-{
- return USE_GLSL;
-}
-
/* Init / exit */
void GPU_basic_shaders_init(void)
@@ -316,31 +190,6 @@ static bool solid_compatible_lighting(void)
return ((directional & enabled) == enabled);
}
-#if 0
-static int detect_options()
-{
- GLint two_sided;
- int options = 0;
-
- if (glIsEnabled(GL_TEXTURE_2D))
- options |= GPU_SHADER_TEXTURE_2D;
- if (glIsEnabled(GL_TEXTURE_RECTANGLE))
- options |= GPU_SHADER_TEXTURE_RECT;
- GPU_SHADER_TEXTURE_RECT
- if (glIsEnabled(GL_COLOR_MATERIAL))
- options |= GPU_SHADER_USE_COLOR;
-
- if (glIsEnabled(GL_LIGHTING))
- options |= GPU_SHADER_LIGHTING;
-
- glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &two_sided);
- if (two_sided == GL_TRUE)
- options |= GPU_SHADER_TWO_SIDED;
-
- return options;
-}
-#endif
-
static GPUShader *gpu_basic_shader(int options)
{
/* glsl code */
@@ -388,7 +237,7 @@ static GPUShader *gpu_basic_shader(int options)
datatoc_gpu_shader_basic_frag_glsl,
geom_glsl,
NULL,
- defines, 0, 0, 0);
+ defines);
if (shader) {
/* set texture map to first texture unit */
@@ -420,102 +269,16 @@ static void gpu_basic_shader_uniform_autoset(GPUShader *shader, int options)
void GPU_basic_shader_bind(int options)
{
- if (USE_GLSL) {
- if (options) {
- const int bound_options = GPU_MATERIAL_STATE.bound_options;
-
- /* texture options need to be set for basic shader too */
- if (options & GPU_SHADER_TEXTURE_2D) {
- glEnable(GL_TEXTURE_2D);
- }
- else if (bound_options & GPU_SHADER_TEXTURE_2D) {
- glDisable(GL_TEXTURE_2D);
- }
-
- if (options & GPU_SHADER_TEXTURE_RECT) {
- glEnable(GL_TEXTURE_RECTANGLE);
- }
- else if (bound_options & GPU_SHADER_TEXTURE_RECT) {
- glDisable(GL_TEXTURE_RECTANGLE);
- }
-
- GPUShader *shader = gpu_basic_shader(options);
+ if (options) {
+ GPUShader *shader = gpu_basic_shader(options);
- if (shader) {
- GPU_shader_bind(shader);
- gpu_basic_shader_uniform_autoset(shader, options);
- }
- }
- else {
- GPU_shader_unbind();
+ if (shader) {
+ GPU_shader_bind(shader);
+ gpu_basic_shader_uniform_autoset(shader, options);
}
}
else {
- const int bound_options = GPU_MATERIAL_STATE.bound_options;
-
- if (options & GPU_SHADER_LIGHTING) {
- glEnable(GL_LIGHTING);
-
- if (options & GPU_SHADER_USE_COLOR)
- glEnable(GL_COLOR_MATERIAL);
- else
- glDisable(GL_COLOR_MATERIAL);
-
- if (options & GPU_SHADER_TWO_SIDED)
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
- else
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
- }
- else if (bound_options & GPU_SHADER_LIGHTING) {
- glDisable(GL_LIGHTING);
- glDisable(GL_COLOR_MATERIAL);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
- }
-
- if (options & GPU_SHADER_TEXTURE_2D) {
- GLint env_mode = (options & (GPU_SHADER_USE_COLOR | GPU_SHADER_LIGHTING)) ? GL_MODULATE : GL_REPLACE;
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env_mode);
- }
- else if (bound_options & GPU_SHADER_TEXTURE_2D) {
- if ((options & GPU_SHADER_TEXTURE_RECT) == 0) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- glDisable(GL_TEXTURE_2D);
- }
-
- if (options & GPU_SHADER_TEXTURE_RECT) {
- GLint env_mode = (options & (GPU_SHADER_USE_COLOR | GPU_SHADER_LIGHTING)) ? GL_MODULATE : GL_REPLACE;
- glEnable(GL_TEXTURE_RECTANGLE);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env_mode);
- }
- else if (bound_options & GPU_SHADER_TEXTURE_RECT) {
- if ((options & GPU_SHADER_TEXTURE_2D) == 0) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- glDisable(GL_TEXTURE_RECTANGLE);
- }
-
- if ((options & GPU_SHADER_LINE) && (options & GPU_SHADER_STIPPLE)) {
- glEnable(GL_LINE_STIPPLE);
- }
- else if ((bound_options & GPU_SHADER_LINE) && (bound_options & GPU_SHADER_STIPPLE)) {
- glDisable(GL_LINE_STIPPLE);
- }
-
- if (((options & GPU_SHADER_LINE) == 0) && (options & GPU_SHADER_STIPPLE)) {
- glEnable(GL_POLYGON_STIPPLE);
- }
- else if (((bound_options & GPU_SHADER_LINE) == 0) && (bound_options & GPU_SHADER_STIPPLE)) {
- glDisable(GL_POLYGON_STIPPLE);
- }
-
- if (options & GPU_SHADER_FLAT_NORMAL) {
- glShadeModel(GL_FLAT);
- }
- else if (bound_options & GPU_SHADER_FLAT_NORMAL) {
- glShadeModel(GL_SMOOTH);
- }
+ GPU_shader_unbind();
}
GPU_MATERIAL_STATE.bound_options = options;
@@ -544,175 +307,37 @@ void GPU_basic_shader_colors(
const float diffuse[3], const float specular[3],
int shininess, float alpha)
{
- float gl_diffuse[4], gl_specular[4];
-
- if (diffuse)
- copy_v3_v3(gl_diffuse, diffuse);
- else
- zero_v3(gl_diffuse);
- gl_diffuse[3] = alpha;
-
- if (specular)
- copy_v3_v3(gl_specular, specular);
- else
- zero_v3(gl_specular);
- gl_specular[3] = 1.0f;
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gl_diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gl_specular);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 128));
+ UNUSED_VARS(diffuse, specular, shininess, alpha);
+ return;
}
void GPU_basic_shader_light_set(int light_num, GPULightData *light)
{
- int light_bit = (1 << light_num);
-
- /* note that light position is affected by the current modelview matrix! */
-
- GPU_MATERIAL_STATE.lights_enabled &= ~light_bit;
- GPU_MATERIAL_STATE.lights_directional &= ~light_bit;
-
- if (light) {
- float position[4], diffuse[4], specular[4];
-
- glEnable(GL_LIGHT0 + light_num);
-
- /* position */
- if (light->type == GPU_LIGHT_SUN) {
- copy_v3_v3(position, light->direction);
- position[3] = 0.0f;
- }
- else {
- copy_v3_v3(position, light->position);
- position[3] = 1.0f;
- }
- glLightfv(GL_LIGHT0 + light_num, GL_POSITION, position);
-
- /* energy */
- copy_v3_v3(diffuse, light->diffuse);
- copy_v3_v3(specular, light->specular);
- diffuse[3] = 1.0f;
- specular[3] = 1.0f;
- glLightfv(GL_LIGHT0 + light_num, GL_DIFFUSE, diffuse);
- glLightfv(GL_LIGHT0 + light_num, GL_SPECULAR, specular);
-
- /* attenuation */
- if (light->type == GPU_LIGHT_SUN) {
- glLightf(GL_LIGHT0 + light_num, GL_CONSTANT_ATTENUATION, 1.0f);
- glLightf(GL_LIGHT0 + light_num, GL_LINEAR_ATTENUATION, 0.0f);
- glLightf(GL_LIGHT0 + light_num, GL_QUADRATIC_ATTENUATION, 0.0f);
- }
- else {
- glLightf(GL_LIGHT0 + light_num, GL_CONSTANT_ATTENUATION, light->constant_attenuation);
- glLightf(GL_LIGHT0 + light_num, GL_LINEAR_ATTENUATION, light->linear_attenuation);
- glLightf(GL_LIGHT0 + light_num, GL_QUADRATIC_ATTENUATION, light->quadratic_attenuation);
- }
-
- /* spot */
- glLightfv(GL_LIGHT0 + light_num, GL_SPOT_DIRECTION, light->direction);
- if (light->type == GPU_LIGHT_SPOT) {
- glLightf(GL_LIGHT0 + light_num, GL_SPOT_CUTOFF, light->spot_cutoff);
- glLightf(GL_LIGHT0 + light_num, GL_SPOT_EXPONENT, light->spot_exponent);
- }
- else {
- glLightf(GL_LIGHT0 + light_num, GL_SPOT_CUTOFF, 180.0f);
- glLightf(GL_LIGHT0 + light_num, GL_SPOT_EXPONENT, 0.0f);
- }
-
- GPU_MATERIAL_STATE.lights_enabled |= light_bit;
- if (position[3] == 0.0f)
- GPU_MATERIAL_STATE.lights_directional |= light_bit;
- }
- else {
- /* TODO(sergey): Needs revisit. */
- if (USE_GLSL || true) {
- /* glsl shader needs these zero to skip them */
- const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
- glLightfv(GL_LIGHT0 + light_num, GL_POSITION, zero);
- glLightfv(GL_LIGHT0 + light_num, GL_DIFFUSE, zero);
- glLightfv(GL_LIGHT0 + light_num, GL_SPECULAR, zero);
- }
-
- glDisable(GL_LIGHT0 + light_num);
- }
+ UNUSED_VARS(light_num, light);
+ return;
}
void GPU_basic_shader_light_set_viewer(bool local)
{
- glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (local) ? GL_TRUE: GL_FALSE);
+ UNUSED_VARS(local);
+ return;
}
void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id)
{
- if (USE_GLSL) {
- glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_id"), stipple_id);
- }
- else {
- switch (stipple_id) {
- case GPU_SHADER_STIPPLE_HALFTONE:
- glPolygonStipple(stipple_halftone);
- return;
- case GPU_SHADER_STIPPLE_QUARTTONE:
- glPolygonStipple(stipple_quarttone);
- return;
- case GPU_SHADER_STIPPLE_CHECKER_8PX:
- glPolygonStipple(stipple_checker_8px);
- return;
- case GPU_SHADER_STIPPLE_HEXAGON:
- glPolygonStipple(stipple_hexagon);
- return;
- case GPU_SHADER_STIPPLE_DIAG_STRIPES_SWAP:
- glPolygonStipple(stipple_diag_stripes_neg);
- return;
- case GPU_SHADER_STIPPLE_DIAG_STRIPES:
- glPolygonStipple(stipple_diag_stripes_pos);
- return;
- case GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW:
- glPolygonStipple(stipple_interlace_row);
- return;
- case GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW_SWAP:
- glPolygonStipple(stipple_interlace_row_swap);
- return;
- case GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN:
- glPolygonStipple(stipple_interlace_column);
- return;
- case GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN_SWAP:
- glPolygonStipple(stipple_interlace_column_swap);
- return;
- case GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER:
- glPolygonStipple(stipple_interlace_checker);
- return;
- case GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER_SWAP:
- glPolygonStipple(stipple_interlace_checker_swap);
- return;
- default:
- glPolygonStipple(stipple_hexagon);
- return;
- }
- }
+ glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_id"), stipple_id);
}
void GPU_basic_shader_line_width(float line_width)
{
- if (USE_GLSL) {
- GPU_MATERIAL_STATE.line_width = line_width;
- if (GPU_MATERIAL_STATE.bound_options & GPU_SHADER_LINE) {
- glUniform1f(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "line_width"), line_width);
- }
- }
- else {
- glLineWidth(line_width);
+ GPU_MATERIAL_STATE.line_width = line_width;
+ if (GPU_MATERIAL_STATE.bound_options & GPU_SHADER_LINE) {
+ glUniform1f(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "line_width"), line_width);
}
}
void GPU_basic_shader_line_stipple(GLint stipple_factor, GLushort stipple_pattern)
{
- if (USE_GLSL) {
- glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_factor"), stipple_factor);
- glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_pattern"), stipple_pattern);
- }
- else {
- glLineStipple(stipple_factor, stipple_pattern);
- }
+ glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_factor"), stipple_factor);
+ glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_pattern"), stipple_pattern);
}
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
new file mode 100644
index 00000000000..e98f07cb0e9
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -0,0 +1,171 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "GPU_batch.h"
+#include "gpu_shader_private.h"
+
+void Batch_set_builtin_program(Batch *batch, GPUBuiltinShader shader_id)
+{
+ GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
+ Batch_set_program(batch, shader->program, shader->interface);
+}
+
+static Batch *sphere_high = NULL;
+static Batch *sphere_med = NULL;
+static Batch *sphere_low = NULL;
+static Batch *sphere_wire_low = NULL;
+static Batch *sphere_wire_med = NULL;
+
+static VertexBuffer *vbo;
+static VertexFormat format = {0};
+static unsigned int pos_id, nor_id;
+static unsigned int vert;
+
+static void batch_sphere_lat_lon_vert(float lat, float lon)
+{
+ float pos[3];
+ pos[0] = sinf(lat) * cosf(lon);
+ pos[1] = cosf(lat);
+ pos[2] = sinf(lat) * sinf(lon);
+
+ VertexBuffer_set_attrib(vbo, nor_id, vert, pos);
+ VertexBuffer_set_attrib(vbo, pos_id, vert++, pos);
+}
+
+/* Replacement for gluSphere */
+static Batch *batch_sphere(int lat_res, int lon_res)
+{
+ const float lon_inc = 2 * M_PI / lon_res;
+ const float lat_inc = M_PI / lat_res;
+ float lon, lat;
+
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ nor_id = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, (lat_res - 1) * lon_res * 6);
+ vert = 0;
+
+ lon = 0.0f;
+ for (int i = 0; i < lon_res; i++, lon += lon_inc) {
+ lat = 0.0f;
+ for (int j = 0; j < lat_res; j++, lat += lat_inc) {
+ if (j != lat_res - 1) { /* Pole */
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon);
+ batch_sphere_lat_lon_vert(lat, lon);
+ }
+
+ if (j != 0) { /* Pole */
+ batch_sphere_lat_lon_vert(lat, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat, lon);
+ }
+ }
+ }
+
+ return Batch_create(PRIM_TRIANGLES, vbo, NULL);
+}
+
+static Batch *batch_sphere_wire(int lat_res, int lon_res)
+{
+ const float lon_inc = 2 * M_PI / lon_res;
+ const float lat_inc = M_PI / lat_res;
+ float lon, lat;
+
+ if (format.attrib_ct == 0) {
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ nor_id = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, (lat_res * lon_res * 2) + ((lat_res - 1) * lon_res * 2));
+ vert = 0;
+
+ lon = 0.0f;
+ for (int i = 0; i < lon_res; i++, lon += lon_inc) {
+ lat = 0.0f;
+ for (int j = 0; j < lat_res; j++, lat += lat_inc) {
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon);
+ batch_sphere_lat_lon_vert(lat, lon);
+
+ if (j != lat_res - 1) { /* Pole */
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon);
+ }
+ }
+ }
+
+ return Batch_create(PRIM_LINES, vbo, NULL);
+}
+
+Batch *Batch_get_sphere(int lod)
+{
+ BLI_assert(lod >= 0 && lod <= 2);
+
+ if (lod == 0)
+ return sphere_low;
+ else if (lod == 1)
+ return sphere_med;
+ else
+ return sphere_high;
+}
+
+Batch *Batch_get_sphere_wire(int lod)
+{
+ BLI_assert(lod >= 0 && lod <= 1);
+
+ if (lod == 0)
+ return sphere_wire_low;
+ else
+ return sphere_wire_med;
+}
+
+void gpu_batch_init(void)
+{
+ /* Hard coded resolution */
+ sphere_low = batch_sphere(8, 16);
+ sphere_med = batch_sphere(16, 10);
+ sphere_high = batch_sphere(32, 24);
+
+ sphere_wire_low = batch_sphere_wire(6, 8);
+ sphere_wire_med = batch_sphere_wire(8, 16);
+}
+
+void gpu_batch_exit(void)
+{
+ Batch_discard_all(sphere_low);
+ Batch_discard_all(sphere_med);
+ Batch_discard_all(sphere_high);
+ Batch_discard_all(sphere_wire_low);
+ Batch_discard_all(sphere_wire_med);
+}
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 9f1fe3a5a67..6281d0a3b67 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -35,8 +35,6 @@
#include <stddef.h>
#include <string.h>
-#include "GPU_glew.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_bitmap.h"
@@ -55,10 +53,14 @@
#include "GPU_buffers.h"
#include "GPU_draw.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_batch.h"
#include "bmesh.h"
+/* TODO: gawain support for baseelemarray */
+// #define USE_BASE_ELEM
+
typedef enum {
GPU_BUFFER_VERTEX_STATE = (1 << 0),
GPU_BUFFER_NORMAL_STATE = (1 << 1),
@@ -106,9 +108,8 @@ static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER;
/* multires global buffer, can be used for many grids having the same grid size */
typedef struct GridCommonGPUBuffer {
- GPUBuffer *mres_buffer;
+ ElementList *mres_buffer;
int mres_prev_gridsize;
- GLenum mres_prev_index_type;
unsigned mres_prev_totquad;
} GridCommonGPUBuffer;
@@ -943,26 +944,12 @@ void GPU_buffer_draw_elements(GPUBuffer *UNUSED(elements), unsigned int mode, in
/* XXX: the rest of the code in this file is used for optimized PBVH
* drawing and doesn't interact at all with the buffer code above */
-/* Convenience struct for building the VBO. */
-typedef struct {
- float co[3];
- short no[3];
-
- /* inserting this to align the 'color' field to a four-byte
- * boundary; drastically increases viewport performance on my
- * drivers (Gallium/Radeon) --nicholasbishop */
- char pad[2];
-
- unsigned char color[3];
-} VertexBufferFormat;
-
struct GPU_PBVH_Buffers {
- /* opengl buffer handles */
- GPUBuffer *vert_buf, *index_buf, *index_buf_fast;
- GLenum index_type;
+ ElementList *index_buf, *index_buf_fast;
+ VertexBuffer *vert_buf;
- int *baseelemarray;
- void **baseindex;
+ Batch *triangles;
+ Batch *triangles_fast;
/* mesh pointers in case buffer allocation fails */
const MPoly *mpoly;
@@ -997,6 +984,39 @@ struct GPU_PBVH_Buffers {
float diffuse_color[4];
};
+typedef struct {
+ uint pos, nor, col;
+} VertexBufferAttrID;
+
+static void gpu_pbvh_vert_format_init__gwn(VertexFormat *format, VertexBufferAttrID *vbo_id)
+{
+ vbo_id->pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ vbo_id->nor = VertexFormat_add_attrib(format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
+ vbo_id->col = VertexFormat_add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
+}
+
+static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers)
+{
+ /* force flushing to the GPU */
+ if (buffers->vert_buf->data) {
+ VertexBuffer_use(buffers->vert_buf);
+ }
+
+ BATCH_DISCARD_SAFE(buffers->triangles);
+ buffers->triangles = Batch_create(
+ PRIM_TRIANGLES, buffers->vert_buf,
+ /* can be NULL */
+ buffers->index_buf);
+
+ BATCH_DISCARD_SAFE(buffers->triangles_fast);
+ if (buffers->index_buf_fast) {
+ buffers->triangles_fast = Batch_create(
+ PRIM_TRIANGLES, buffers->vert_buf,
+ /* can be NULL */
+ buffers->index_buf_fast);
+ }
+}
+
static float gpu_color_from_mask(float mask)
{
return 1.0f - mask * 0.75f;
@@ -1035,9 +1055,6 @@ void GPU_pbvh_mesh_buffers_update(
const int *vert_indices, int totvert, const float *vmask,
const int (*face_vert_indices)[3], bool show_diffuse_color)
{
- VertexBufferFormat *vert_data;
- int i;
-
buffers->vmask = vmask;
buffers->show_diffuse_color = show_diffuse_color;
buffers->use_matcaps = GPU_material_use_matcaps_get();
@@ -1061,35 +1078,39 @@ void GPU_pbvh_mesh_buffers_update(
rgba_float_to_uchar(diffuse_color_ub, diffuse_color);
/* Build VBO */
- if (buffers->vert_buf)
- GPU_buffer_free(buffers->vert_buf);
- buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totelem);
- vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
+ VERTEXBUFFER_DISCARD_SAFE(buffers->vert_buf);
+
+ /* match 'VertexBufferFormat' */
+ VertexFormat format = {0};
+ VertexBufferAttrID vbo_id;
+ gpu_pbvh_vert_format_init__gwn(&format, &vbo_id);
- if (vert_data) {
+ buffers->vert_buf = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(buffers->vert_buf, totelem);
+
+ if (buffers->vert_buf->data) {
/* Vertex data is shared if smooth-shaded, but separate
* copies are made for flat shading because normals
* shouldn't be shared. */
if (buffers->smooth) {
- for (i = 0; i < totvert; ++i) {
+ for (uint i = 0; i < totvert; ++i) {
const MVert *v = &mvert[vert_indices[i]];
- VertexBufferFormat *out = vert_data + i;
-
- copy_v3_v3(out->co, v->co);
- memcpy(out->no, v->no, sizeof(short) * 3);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.pos, i, v->co);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.nor, i, v->no);
}
- for (i = 0; i < buffers->face_indices_len; i++) {
+ for (uint i = 0; i < buffers->face_indices_len; i++) {
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
for (uint j = 0; j < 3; j++) {
- VertexBufferFormat *out = vert_data + face_vert_indices[i][j];
-
+ int vidx = face_vert_indices[i][j];
if (vmask) {
- uint v_index = buffers->mloop[lt->tri[j]].v;
- gpu_color_from_mask_copy(vmask[v_index], diffuse_color, out->color);
+ int v_index = buffers->mloop[lt->tri[j]].v;
+ uchar color_ub[3];
+ gpu_color_from_mask_copy(vmask[v_index], diffuse_color, color_ub);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.col, vidx, color_ub);
}
else {
- copy_v3_v3_uchar(out->color, diffuse_color_ub);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.col, vidx, diffuse_color_ub);
}
}
}
@@ -1098,8 +1119,9 @@ void GPU_pbvh_mesh_buffers_update(
/* calculate normal for each polygon only once */
unsigned int mpoly_prev = UINT_MAX;
short no[3];
+ int vbo_index = 0;
- for (i = 0; i < buffers->face_indices_len; ++i) {
+ for (uint i = 0; i < buffers->face_indices_len; i++) {
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
const unsigned int vtri[3] = {
buffers->mloop[lt->tri[0]].v,
@@ -1130,22 +1152,20 @@ void GPU_pbvh_mesh_buffers_update(
for (uint j = 0; j < 3; j++) {
const MVert *v = &mvert[vtri[j]];
- VertexBufferFormat *out = vert_data;
- copy_v3_v3(out->co, v->co);
- copy_v3_v3_short(out->no, no);
- copy_v3_v3_uchar(out->color, color_ub);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.pos, vbo_index, v->co);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.nor, vbo_index, no);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.col, vbo_index, color_ub);
- vert_data++;
+ vbo_index++;
}
}
}
- GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
+ gpu_pbvh_batch_init(buffers);
}
else {
- GPU_buffer_free(buffers->vert_buf);
- buffers->vert_buf = NULL;
+ VERTEXBUFFER_DISCARD_SAFE(buffers->vert_buf);
}
}
@@ -1160,12 +1180,17 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
const int face_indices_len)
{
GPU_PBVH_Buffers *buffers;
- unsigned short *tri_data;
- int i, j, tottri;
+ int i, tottri;
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
- buffers->index_type = GL_UNSIGNED_SHORT;
+
+ /* smooth or flat for all */
+#if 0
buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
+#else
+ /* for DrawManager we dont support mixed smooth/flat */
+ buffers->smooth = (mpoly[0].flag & ME_SMOOTH) != 0;
+#endif
buffers->show_diffuse_color = false;
buffers->use_matcaps = false;
@@ -1193,35 +1218,28 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
* shading requires separate vertex normals so an index buffer is
* can't be used there. */
if (buffers->smooth) {
- buffers->index_buf = GPU_buffer_alloc(sizeof(unsigned short) * tottri * 3);
- buffers->is_index_buf_global = false;
- }
-
- if (buffers->index_buf) {
/* Fill the triangle buffer */
- tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
- if (tri_data) {
- for (i = 0; i < face_indices_len; ++i) {
- const MLoopTri *lt = &looptri[face_indices[i]];
-
- /* Skip hidden faces */
- if (paint_is_face_hidden(lt, mvert, mloop))
- continue;
-
- for (j = 0; j < 3; ++j) {
- *tri_data = face_vert_indices[i][j];
- tri_data++;
- }
- }
- GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
+ buffers->index_buf = NULL;
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, tottri, INT_MAX);
+
+ for (i = 0; i < face_indices_len; ++i) {
+ const MLoopTri *lt = &looptri[face_indices[i]];
+
+ /* Skip hidden faces */
+ if (paint_is_face_hidden(lt, mvert, mloop))
+ continue;
+
+ add_triangle_vertices(&elb, UNPACK3(face_vert_indices[i]));
}
- else {
- if (!buffers->is_index_buf_global) {
- GPU_buffer_free(buffers->index_buf);
- }
- buffers->index_buf = NULL;
- buffers->is_index_buf_global = false;
+ buffers->index_buf = ElementList_build(&elb);
+ }
+ else {
+ if (!buffers->is_index_buf_global) {
+ ELEMENTLIST_DISCARD_SAFE(buffers->index_buf);
}
+ buffers->index_buf = NULL;
+ buffers->is_index_buf_global = false;
}
buffers->tot_tri = tottri;
@@ -1241,7 +1259,6 @@ void GPU_pbvh_grid_buffers_update(
const DMFlagMat *grid_flag_mats, int *grid_indices,
int totgrid, const CCGKey *key, bool show_diffuse_color)
{
- VertexBufferFormat *vert_data;
int i, j, k, x, y;
buffers->show_diffuse_color = show_diffuse_color;
@@ -1249,12 +1266,13 @@ void GPU_pbvh_grid_buffers_update(
buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
/* Build VBO */
- if (buffers->vert_buf) {
+ if (buffers->index_buf) {
const int has_mask = key->has_mask;
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
- if (buffers->use_matcaps)
+ if (buffers->use_matcaps) {
diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
+ }
else if (show_diffuse_color) {
const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
@@ -1263,33 +1281,43 @@ void GPU_pbvh_grid_buffers_update(
copy_v4_v4(buffers->diffuse_color, diffuse_color);
- vert_data = GPU_buffer_lock_stream(buffers->vert_buf, GPU_BINDING_ARRAY);
- if (vert_data) {
+ VertexFormat format = {0};
+ VertexBufferAttrID vbo_id;
+ gpu_pbvh_vert_format_init__gwn(&format, &vbo_id);
+
+ /* Build coord/normal VBO */
+ VERTEXBUFFER_DISCARD_SAFE(buffers->vert_buf);
+ buffers->vert_buf = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(buffers->vert_buf, totgrid * key->grid_area);
+
+ uint vbo_index_offset = 0;
+ if (buffers->vert_buf->data) {
for (i = 0; i < totgrid; ++i) {
- VertexBufferFormat *vd = vert_data;
CCGElem *grid = grids[grid_indices[i]];
+ int vbo_index = vbo_index_offset;
for (y = 0; y < key->grid_size; y++) {
for (x = 0; x < key->grid_size; x++) {
CCGElem *elem = CCG_grid_elem(key, grid, x, y);
-
- copy_v3_v3(vd->co, CCG_elem_co(key, elem));
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.pos, vbo_index, CCG_elem_co(key, elem));
+
if (buffers->smooth) {
- normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
+ short no_short[3];
+ normal_float_to_short_v3(no_short, CCG_elem_no(key, elem));
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.nor, vbo_index, no_short);
if (has_mask) {
+ uchar color_ub[3];
gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
- diffuse_color, vd->color);
+ diffuse_color, color_ub);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.col, vbo_index, color_ub);
}
}
- vd++;
+ vbo_index += 1;
}
}
if (!buffers->smooth) {
- /* for flat shading, recalc normals and set the last vertex of
- * each triangle in the index buffer to have the flat normal as
- * that is what opengl will use */
for (j = 0; j < key->grid_size - 1; j++) {
for (k = 0; k < key->grid_size - 1; k++) {
CCGElem *elems[4] = {
@@ -1306,30 +1334,33 @@ void GPU_pbvh_grid_buffers_update(
CCG_elem_co(key, elems[2]),
CCG_elem_co(key, elems[3]));
- vd = vert_data + (j + 1) * key->grid_size + k;
- normal_float_to_short_v3(vd->no, fno);
+ vbo_index = vbo_index_offset + ((j + 1) * key->grid_size + k);
+ short no_short[3];
+ normal_float_to_short_v3(no_short, fno);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.nor, vbo_index, no_short);
if (has_mask) {
+ uchar color_ub[3];
gpu_color_from_mask_quad_copy(key,
elems[0],
elems[1],
elems[2],
elems[3],
diffuse_color,
- vd->color);
+ color_ub);
+ VertexBuffer_set_attrib(buffers->vert_buf, vbo_id.col, vbo_index, color_ub);
}
}
}
}
- vert_data += key->grid_area;
+ vbo_index_offset += key->grid_area;
}
- GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
+ gpu_pbvh_batch_init(buffers);
}
else {
- GPU_buffer_free(buffers->vert_buf);
- buffers->vert_buf = NULL;
+ VERTEXBUFFER_DISCARD_SAFE(buffers->vert_buf);
}
}
@@ -1344,57 +1375,54 @@ void GPU_pbvh_grid_buffers_update(
/* Build the element array buffer of grid indices using either
* unsigned shorts or unsigned ints. */
-#define FILL_QUAD_BUFFER(type_, tot_quad_, buffer_) \
+#define FILL_QUAD_BUFFER(max_vert_, tot_quad_, buffer_) \
{ \
- type_ *tri_data; \
int offset = 0; \
int i, j, k; \
- buffer_ = GPU_buffer_alloc(sizeof(type_) * (tot_quad_) * 6); \
+ \
+ ElementListBuilder elb; \
+ ElementListBuilder_init( \
+ &elb, PRIM_TRIANGLES, tot_quad_ * 2, max_vert_); \
\
/* Fill the buffer */ \
- tri_data = GPU_buffer_lock(buffer_, GPU_BINDING_INDEX); \
- if (tri_data) { \
- for (i = 0; i < totgrid; ++i) { \
- BLI_bitmap *gh = NULL; \
- if (grid_hidden) \
- gh = grid_hidden[(grid_indices)[i]]; \
+ for (i = 0; i < totgrid; ++i) { \
+ BLI_bitmap *gh = NULL; \
+ if (grid_hidden) \
+ gh = grid_hidden[(grid_indices)[i]]; \
\
- for (j = 0; j < gridsize - 1; ++j) { \
- for (k = 0; k < gridsize - 1; ++k) { \
- /* Skip hidden grid face */ \
- if (gh && \
- paint_is_grid_face_hidden(gh, \
- gridsize, k, j)) \
- continue; \
- \
- *(tri_data++) = offset + j * gridsize + k + 1; \
- *(tri_data++) = offset + j * gridsize + k; \
- *(tri_data++) = offset + (j + 1) * gridsize + k; \
- \
- *(tri_data++) = offset + (j + 1) * gridsize + k + 1; \
- *(tri_data++) = offset + j * gridsize + k + 1; \
- *(tri_data++) = offset + (j + 1) * gridsize + k; \
- } \
- } \
- \
- offset += gridsize * gridsize; \
+ for (j = 0; j < gridsize - 1; ++j) { \
+ for (k = 0; k < gridsize - 1; ++k) { \
+ /* Skip hidden grid face */ \
+ if (gh && paint_is_grid_face_hidden( \
+ gh, gridsize, k, j)) \
+ { \
+ continue; \
+ } \
+ add_generic_vertex(&elb, offset + j * gridsize + k + 1); \
+ add_generic_vertex(&elb, offset + j * gridsize + k); \
+ add_generic_vertex(&elb, offset + (j + 1) * gridsize + k); \
+ \
+ add_generic_vertex(&elb, offset + (j + 1) * gridsize + k + 1); \
+ add_generic_vertex(&elb, offset + j * gridsize + k + 1); \
+ add_generic_vertex(&elb, offset + (j + 1) * gridsize + k); \
+ } \
} \
- GPU_buffer_unlock(buffer_, GPU_BINDING_INDEX); \
- } \
- else { \
- GPU_buffer_free(buffer_); \
- (buffer_) = NULL; \
+ \
+ offset += gridsize * gridsize; \
} \
+ buffer_ = ElementList_build(&elb); \
} (void)0
/* end FILL_QUAD_BUFFER */
-static GPUBuffer *gpu_get_grid_buffer(
- int gridsize, GLenum *index_type, unsigned *totquad, GridCommonGPUBuffer **grid_common_gpu_buffer)
+static ElementList *gpu_get_grid_buffer(
+ int gridsize, unsigned *totquad, GridCommonGPUBuffer **grid_common_gpu_buffer,
+ /* remove this arg when gawain gets base-vertex support! */
+ int totgrid)
{
/* used in the FILL_QUAD_BUFFER macro */
BLI_bitmap * const *grid_hidden = NULL;
const int *grid_indices = NULL;
- int totgrid = 1;
+ // int totgrid = 1;
GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer;
@@ -1402,65 +1430,48 @@ static GPUBuffer *gpu_get_grid_buffer(
*grid_common_gpu_buffer = gridbuff = MEM_mallocN(sizeof(GridCommonGPUBuffer), __func__);
gridbuff->mres_buffer = NULL;
gridbuff->mres_prev_gridsize = -1;
- gridbuff->mres_prev_index_type = 0;
gridbuff->mres_prev_totquad = 0;
}
/* VBO is already built */
if (gridbuff->mres_buffer && gridbuff->mres_prev_gridsize == gridsize) {
- *index_type = gridbuff->mres_prev_index_type;
*totquad = gridbuff->mres_prev_totquad;
return gridbuff->mres_buffer;
}
/* we can't reuse old, delete the existing buffer */
else if (gridbuff->mres_buffer) {
- GPU_buffer_free(gridbuff->mres_buffer);
+ ElementList_discard(gridbuff->mres_buffer);
+ gridbuff->mres_buffer = NULL;
}
/* Build new VBO */
- *totquad = (gridsize - 1) * (gridsize - 1);
+ *totquad = (gridsize - 1) * (gridsize - 1) * totgrid;
+ int max_vert = gridsize * gridsize * totgrid;
- if (gridsize * gridsize < USHRT_MAX) {
- *index_type = GL_UNSIGNED_SHORT;
- FILL_QUAD_BUFFER(unsigned short, *totquad, gridbuff->mres_buffer);
- }
- else {
- *index_type = GL_UNSIGNED_INT;
- FILL_QUAD_BUFFER(unsigned int, *totquad, gridbuff->mres_buffer);
- }
+ FILL_QUAD_BUFFER(max_vert, *totquad, gridbuff->mres_buffer);
gridbuff->mres_prev_gridsize = gridsize;
- gridbuff->mres_prev_index_type = *index_type;
gridbuff->mres_prev_totquad = *totquad;
return gridbuff->mres_buffer;
}
-#define FILL_FAST_BUFFER(type_) \
+#define FILL_FAST_BUFFER() \
{ \
- type_ *buffer; \
- buffers->index_buf_fast = GPU_buffer_alloc(sizeof(type_) * 6 * totgrid); \
- buffer = GPU_buffer_lock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
- if (buffer) { \
- int i; \
- for (i = 0; i < totgrid; i++) { \
- int currentquad = i * 6; \
- buffer[currentquad] = i * gridsize * gridsize + gridsize - 1; \
- buffer[currentquad + 1] = i * gridsize * gridsize; \
- buffer[currentquad + 2] = (i + 1) * gridsize * gridsize - gridsize; \
- buffer[currentquad + 3] = (i + 1) * gridsize * gridsize - 1; \
- buffer[currentquad + 4] = i * gridsize * gridsize + gridsize - 1; \
- buffer[currentquad + 5] = (i + 1) * gridsize * gridsize - gridsize; \
- } \
- GPU_buffer_unlock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
- } \
- else { \
- GPU_buffer_free(buffers->index_buf_fast); \
- buffers->index_buf_fast = NULL; \
+ ElementListBuilder elb; \
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, 6 * totgrid, INT_MAX); \
+ for (int i = 0; i < totgrid; i++) { \
+ add_generic_vertex(&elb, i * gridsize * gridsize + gridsize - 1); \
+ add_generic_vertex(&elb, i * gridsize * gridsize); \
+ add_generic_vertex(&elb, (i + 1) * gridsize * gridsize - gridsize); \
+ add_generic_vertex(&elb, (i + 1) * gridsize * gridsize - 1); \
+ add_generic_vertex(&elb, i * gridsize * gridsize + gridsize - 1); \
+ add_generic_vertex(&elb, (i + 1) * gridsize * gridsize - gridsize); \
} \
+ buffers->index_buf_fast = ElementList_build(&elb); \
} (void)0
GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
- int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key,
+ int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *UNUSED(key),
GridCommonGPUBuffer **grid_common_gpu_buffer)
{
GPU_PBVH_Buffers *buffers;
@@ -1482,39 +1493,26 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
return buffers;
/* create and fill indices of the fast buffer too */
- if (totgrid * gridsize * gridsize < USHRT_MAX) {
- FILL_FAST_BUFFER(unsigned short);
- }
- else {
- FILL_FAST_BUFFER(unsigned int);
- }
+ FILL_FAST_BUFFER();
if (totquad == fully_visible_totquad) {
buffers->index_buf = gpu_get_grid_buffer(
- gridsize, &buffers->index_type, &buffers->tot_quad, grid_common_gpu_buffer);
+ gridsize, &buffers->tot_quad, grid_common_gpu_buffer, totgrid);
buffers->has_hidden = false;
buffers->is_index_buf_global = true;
}
else {
+ uint max_vert = totgrid * gridsize * gridsize;
buffers->tot_quad = totquad;
- if (totgrid * gridsize * gridsize < USHRT_MAX) {
- buffers->index_type = GL_UNSIGNED_SHORT;
- FILL_QUAD_BUFFER(unsigned short, totquad, buffers->index_buf);
- }
- else {
- buffers->index_type = GL_UNSIGNED_INT;
- FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
- }
+ FILL_QUAD_BUFFER(max_vert, totquad, buffers->index_buf);
- buffers->has_hidden = true;
+ buffers->has_hidden = false;
buffers->is_index_buf_global = false;
}
+#ifdef USE_BASE_ELEM
/* Build coord/normal VBO */
- if (buffers->index_buf)
- buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totgrid * key->grid_area);
-
if (GLEW_ARB_draw_elements_base_vertex /* 3.2 */) {
int i;
buffers->baseelemarray = MEM_mallocN(sizeof(int) * totgrid * 2, "GPU_PBVH_Buffers.baseelemarray");
@@ -1525,6 +1523,7 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
buffers->baseindex[i] = NULL;
}
}
+#endif
return buffers;
}
@@ -1537,26 +1536,36 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
* index '*v_index' in the 'vert_data' array and '*v_index' is
* incremented.
*/
-static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
- VertexBufferFormat *vert_data,
- int *v_index,
- const float fno[3],
- const float *fmask,
- const int cd_vert_mask_offset,
- const float diffuse_color[4])
+static void gpu_bmesh_vert_to_buffer_copy__gwn(
+ BMVert *v,
+ VertexBuffer *vert_buf,
+ const VertexBufferAttrID *vbo_id,
+ int *v_index,
+ const float fno[3],
+ const float *fmask,
+ const int cd_vert_mask_offset,
+ const float diffuse_color[4])
{
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- VertexBufferFormat *vd = &vert_data[*v_index];
/* Set coord, normal, and mask */
- copy_v3_v3(vd->co, v->co);
- normal_float_to_short_v3(vd->no, fno ? fno : v->no);
+ VertexBuffer_set_attrib(vert_buf, vbo_id->pos, *v_index, v->co);
- gpu_color_from_mask_copy(
- fmask ? *fmask :
- BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset),
- diffuse_color,
- vd->color);
+ {
+ short no_short[3];
+ normal_float_to_short_v3(no_short, fno ? fno : v->no);
+ VertexBuffer_set_attrib(vert_buf, vbo_id->nor, *v_index, no_short);
+ }
+
+ {
+ uchar color_ub[3];
+ gpu_color_from_mask_copy(
+ fmask ? *fmask :
+ BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset),
+ diffuse_color,
+ color_ub);
+ VertexBuffer_set_attrib(vert_buf, vbo_id->col, *v_index, color_ub);
+ }
/* Assign index for use in the triangle index buffer */
/* note: caller must set: bm->elem_index_dirty |= BM_VERT; */
@@ -1613,8 +1622,6 @@ void GPU_pbvh_bmesh_buffers_update(
GSet *bm_other_verts,
bool show_diffuse_color)
{
- VertexBufferFormat *vert_data;
- void *tri_data;
int tottri, totvert, maxvert = 0;
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
@@ -1653,13 +1660,17 @@ void GPU_pbvh_bmesh_buffers_update(
copy_v4_v4(buffers->diffuse_color, diffuse_color);
/* Initialize vertex buffer */
- if (buffers->vert_buf)
- GPU_buffer_free(buffers->vert_buf);
- buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totvert);
+ VERTEXBUFFER_DISCARD_SAFE(buffers->vert_buf);
+ /* match 'VertexBufferFormat' */
+ VertexFormat format = {0};
+ VertexBufferAttrID vbo_id;
+ gpu_pbvh_vert_format_init__gwn(&format, &vbo_id);
+
+ buffers->vert_buf = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(buffers->vert_buf, totvert);
/* Fill vertex buffer */
- vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
- if (vert_data) {
+ if (buffers->vert_buf->data) {
int v_index = 0;
if (buffers->smooth) {
@@ -1670,15 +1681,17 @@ void GPU_pbvh_bmesh_buffers_update(
bm->elem_index_dirty |= BM_VERT;
GSET_ITER (gs_iter, bm_unique_verts) {
- gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
- vert_data, &v_index, NULL, NULL,
- cd_vert_mask_offset, diffuse_color);
+ gpu_bmesh_vert_to_buffer_copy__gwn(
+ BLI_gsetIterator_getKey(&gs_iter),
+ buffers->vert_buf, &vbo_id, &v_index, NULL, NULL,
+ cd_vert_mask_offset, diffuse_color);
}
GSET_ITER (gs_iter, bm_other_verts) {
- gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
- vert_data, &v_index, NULL, NULL,
- cd_vert_mask_offset, diffuse_color);
+ gpu_bmesh_vert_to_buffer_copy__gwn(
+ BLI_gsetIterator_getKey(&gs_iter),
+ buffers->vert_buf, &vbo_id, &v_index, NULL, NULL,
+ cd_vert_mask_offset, diffuse_color);
}
maxvert = v_index;
@@ -1708,9 +1721,10 @@ void GPU_pbvh_bmesh_buffers_update(
fmask /= 3.0f;
for (i = 0; i < 3; i++) {
- gpu_bmesh_vert_to_buffer_copy(v[i], vert_data,
- &v_index, f->no, &fmask,
- cd_vert_mask_offset, diffuse_color);
+ gpu_bmesh_vert_to_buffer_copy__gwn(
+ v[i], buffers->vert_buf, &vbo_id,
+ &v_index, f->no, &fmask,
+ cd_vert_mask_offset, diffuse_color);
}
}
}
@@ -1718,32 +1732,30 @@ void GPU_pbvh_bmesh_buffers_update(
buffers->tot_tri = tottri;
}
- GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
-
/* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
bm->elem_index_dirty |= BM_VERT;
}
else {
+ VERTEXBUFFER_DISCARD_SAFE(buffers->vert_buf);
/* Memory map failed */
- GPU_buffer_free(buffers->vert_buf);
- buffers->vert_buf = NULL;
return;
}
if (buffers->smooth) {
- const int use_short = (maxvert < USHRT_MAX);
+ /* Fill the triangle buffer */
+ buffers->index_buf = NULL;
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, tottri, maxvert);
/* Initialize triangle index buffer */
- if (buffers->index_buf && !buffers->is_index_buf_global)
- GPU_buffer_free(buffers->index_buf);
+ if (buffers->triangles && !buffers->is_index_buf_global) {
+ BATCH_DISCARD_SAFE(buffers->triangles);
+ }
buffers->is_index_buf_global = false;
- buffers->index_buf = GPU_buffer_alloc((use_short ?
- sizeof(unsigned short) :
- sizeof(unsigned int)) * 3 * tottri);
/* Fill triangle index buffer */
- tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
- if (tri_data) {
+
+ {
GSetIterator gs_iter;
GSET_ITER (gs_iter, bm_faces) {
@@ -1755,46 +1767,25 @@ void GPU_pbvh_bmesh_buffers_update(
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BMVert *v = l_iter->v;
- if (use_short) {
- unsigned short *elem = tri_data;
- (*elem) = BM_elem_index_get(v);
- elem++;
- tri_data = elem;
- }
- else {
- unsigned int *elem = tri_data;
- (*elem) = BM_elem_index_get(v);
- elem++;
- tri_data = elem;
- }
+ add_generic_vertex(&elb, BM_elem_index_get(l_iter->v));
} while ((l_iter = l_iter->next) != l_first);
}
}
- GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
-
buffers->tot_tri = tottri;
- buffers->index_type = (use_short ?
- GL_UNSIGNED_SHORT :
- GL_UNSIGNED_INT);
- }
- else {
- /* Memory map failed */
- if (!buffers->is_index_buf_global) {
- GPU_buffer_free(buffers->index_buf);
- }
- buffers->index_buf = NULL;
- buffers->is_index_buf_global = false;
+
+ buffers->index_buf = ElementList_build(&elb);
}
}
else if (buffers->index_buf) {
if (!buffers->is_index_buf_global) {
- GPU_buffer_free(buffers->index_buf);
+ ELEMENTLIST_DISCARD_SAFE(buffers->index_buf);
}
buffers->index_buf = NULL;
buffers->is_index_buf_global = false;
}
+
+ gpu_pbvh_batch_init(buffers);
}
GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
@@ -1814,145 +1805,42 @@ void GPU_pbvh_buffers_draw(
GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
bool wireframe, bool fast)
{
- bool do_fast = fast && buffers->index_buf_fast;
- /* sets material from the first face, to solve properly face would need to
- * be sorted in buckets by materials */
- if (setMaterial) {
- if (buffers->face_indices_len) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
- const MPoly *mp = &buffers->mpoly[lt->poly];
- if (!setMaterial(mp->mat_nr + 1, NULL))
- return;
- }
- else if (buffers->totgrid) {
- const DMFlagMat *f = &buffers->grid_flag_mats[buffers->grid_indices[0]];
- if (!setMaterial(f->mat_nr + 1, NULL))
- return;
- }
- else {
- if (!setMaterial(1, NULL))
- return;
- }
- }
-
- if (buffers->vert_buf) {
- char *base = NULL;
- char *index_base = NULL;
- /* weak inspection of bound options, should not be necessary ideally */
- const int bound_options_old = GPU_basic_shader_bound_options();
- int bound_options_new = 0;
- glEnableClientState(GL_VERTEX_ARRAY);
- if (!wireframe) {
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-
- bound_options_new |= GPU_SHADER_USE_COLOR;
- }
-
- GPU_buffer_bind(buffers->vert_buf, GPU_BINDING_ARRAY);
-
- if (do_fast) {
- GPU_buffer_bind(buffers->index_buf_fast, GPU_BINDING_INDEX);
- }
- else if (buffers->index_buf) {
- GPU_buffer_bind(buffers->index_buf, GPU_BINDING_INDEX);
- }
-
- if (wireframe) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- }
- else {
- if ((buffers->smooth == false) && (buffers->face_indices_len == 0)) {
- bound_options_new |= GPU_SHADER_FLAT_NORMAL;
- }
- }
-
- if (bound_options_new & ~bound_options_old) {
- GPU_basic_shader_bind(bound_options_old | bound_options_new);
- }
-
- if (buffers->tot_quad) {
- const char *offset = base;
- const bool drawall = !(buffers->has_hidden || do_fast);
-
- if (GLEW_ARB_draw_elements_base_vertex && drawall) {
-
- glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, co));
- if (!wireframe) {
- glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, no));
- glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, color));
- }
-
- glMultiDrawElementsBaseVertex(GL_TRIANGLES, buffers->baseelemarray, buffers->index_type,
- (const void * const *)buffers->baseindex,
- buffers->totgrid, &buffers->baseelemarray[buffers->totgrid]);
- }
- else {
- int i, last = drawall ? buffers->totgrid : 1;
-
- /* we could optimize this to one draw call, but it would need more memory */
- for (i = 0; i < last; i++) {
- glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, co));
- if (!wireframe) {
- glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, no));
- glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, color));
- }
-
- if (do_fast)
- glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base);
- else
- glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base);
+ UNUSED_VARS(wireframe, fast, setMaterial);
+ bool do_fast = fast && buffers->triangles_fast;
+ Batch *triangles = do_fast ? buffers->triangles_fast : buffers->triangles;
- offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
- }
- }
- }
- else if (buffers->tot_tri) {
- int totelem = buffers->tot_tri * 3;
-
- glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
- (void *)(base + offsetof(VertexBufferFormat, co)));
-
- if (!wireframe) {
- glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
- (void *)(base + offsetof(VertexBufferFormat, no)));
- glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
- (void *)(base + offsetof(VertexBufferFormat, color)));
- }
+ if (triangles) {
- if (buffers->index_buf)
- glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, index_base);
- else
- glDrawArrays(GL_TRIANGLES, 0, totelem);
- }
+ /* Simple Shader: use when drawing without the draw-manager (old 2.7x viewport) */
+ if (triangles->interface == NULL) {
+ GPUBuiltinShader shader_id =
+ buffers->smooth ? GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR : GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR;
+ GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
- if (wireframe)
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ Batch_set_program(
+ triangles,
+ GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
- GPU_buffer_unbind(buffers->vert_buf, GPU_BINDING_ARRAY);
- if (buffers->index_buf || do_fast)
- GPU_buffer_unbind(do_fast ? buffers->index_buf_fast : buffers->index_buf, GPU_BINDING_INDEX);
+ static float light[3] = {-0.3f, 0.5f, 1.0f};
+ static float alpha = 1.0f;
+ static float world_light = 1.0f;
- glDisableClientState(GL_VERTEX_ARRAY);
- if (!wireframe) {
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- }
+ GPU_shader_uniform_vector(shader, GPU_shader_get_uniform(shader, "light"), 3, 1, light);
+ GPU_shader_uniform_vector(shader, GPU_shader_get_uniform(shader, "alpha"), 1, 1, &alpha);
+ GPU_shader_uniform_vector(shader, GPU_shader_get_uniform(shader, "global"), 1, 1, &world_light);
- if (bound_options_new & ~bound_options_old) {
- GPU_basic_shader_bind(bound_options_old);
}
+ Batch_draw(triangles);
}
}
-bool GPU_pbvh_buffers_diffuse_changed(
- GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
+Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast)
+{
+ return (fast && buffers->triangles_fast) ?
+ buffers->triangles_fast : buffers->triangles;
+}
+
+bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
{
float diffuse_color[4];
bool use_matcaps = GPU_material_use_matcaps_get();
@@ -1998,16 +1886,20 @@ bool GPU_pbvh_buffers_diffuse_changed(
void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
{
if (buffers) {
- if (buffers->vert_buf)
- GPU_buffer_free(buffers->vert_buf);
- if (buffers->index_buf && !buffers->is_index_buf_global)
- GPU_buffer_free(buffers->index_buf);
- if (buffers->index_buf_fast)
- GPU_buffer_free(buffers->index_buf_fast);
+ BATCH_DISCARD_SAFE(buffers->triangles);
+ BATCH_DISCARD_SAFE(buffers->triangles_fast);
+ if (!buffers->is_index_buf_global) {
+ ELEMENTLIST_DISCARD_SAFE(buffers->index_buf);
+ }
+ ELEMENTLIST_DISCARD_SAFE(buffers->index_buf_fast);
+ VertexBuffer_discard(buffers->vert_buf);
+
+#ifdef USE_BASE_ELEM
if (buffers->baseelemarray)
MEM_freeN(buffers->baseelemarray);
if (buffers->baseindex)
MEM_freeN(buffers->baseindex);
+#endif
MEM_freeN(buffers);
}
@@ -2020,7 +1912,7 @@ void GPU_pbvh_multires_buffers_free(GridCommonGPUBuffer **grid_common_gpu_buffer
if (gridbuff) {
if (gridbuff->mres_buffer) {
BLI_mutex_lock(&buffer_mutex);
- gpu_buffer_free_intern(gridbuff->mres_buffer);
+ ELEMENTLIST_DISCARD_SAFE(gridbuff->mres_buffer);
BLI_mutex_unlock(&buffer_mutex);
}
MEM_freeN(gridbuff);
@@ -2029,59 +1921,57 @@ void GPU_pbvh_multires_buffers_free(GridCommonGPUBuffer **grid_common_gpu_buffer
}
/* debug function, draws the pbvh BB */
-void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf)
+void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, unsigned int pos)
{
- const float quads[4][4][3] = {
- {
- {min[0], min[1], min[2]},
- {max[0], min[1], min[2]},
- {max[0], min[1], max[2]},
- {min[0], min[1], max[2]}
- },
+ if (leaf)
+ immUniformColor4f(0.0, 1.0, 0.0, 0.5);
+ else
+ immUniformColor4f(1.0, 0.0, 0.0, 0.5);
- {
- {min[0], min[1], min[2]},
- {min[0], max[1], min[2]},
- {min[0], max[1], max[2]},
- {min[0], min[1], max[2]}
- },
+ /* TODO(merwin): revisit this after we have mutable VertexBuffers
+ * could keep a static batch & index buffer, change the VBO contents per draw
+ */
- {
- {max[0], max[1], min[2]},
- {max[0], min[1], min[2]},
- {max[0], min[1], max[2]},
- {max[0], max[1], max[2]}
- },
+ immBegin(PRIM_LINES, 24);
- {
- {max[0], max[1], min[2]},
- {min[0], max[1], min[2]},
- {min[0], max[1], max[2]},
- {max[0], max[1], max[2]}
- },
- };
+ /* top */
+ immVertex3f(pos, min[0], min[1], max[2]);
+ immVertex3f(pos, min[0], max[1], max[2]);
- if (leaf)
- glColor4f(0.0, 1.0, 0.0, 0.5);
- else
- glColor4f(1.0, 0.0, 0.0, 0.5);
+ immVertex3f(pos, min[0], max[1], max[2]);
+ immVertex3f(pos, max[0], max[1], max[2]);
- glVertexPointer(3, GL_FLOAT, 0, &quads[0][0][0]);
- glDrawArrays(GL_QUADS, 0, 16);
-}
+ immVertex3f(pos, max[0], max[1], max[2]);
+ immVertex3f(pos, max[0], min[1], max[2]);
-void GPU_pbvh_BB_draw_init(void)
-{
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_CULL_FACE);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glEnable(GL_BLEND);
-}
+ immVertex3f(pos, max[0], min[1], max[2]);
+ immVertex3f(pos, min[0], min[1], max[2]);
-void GPU_pbvh_BB_draw_end(void)
-{
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glPopAttrib();
+ /* bottom */
+ immVertex3f(pos, min[0], min[1], min[2]);
+ immVertex3f(pos, min[0], max[1], min[2]);
+
+ immVertex3f(pos, min[0], max[1], min[2]);
+ immVertex3f(pos, max[0], max[1], min[2]);
+
+ immVertex3f(pos, max[0], max[1], min[2]);
+ immVertex3f(pos, max[0], min[1], min[2]);
+
+ immVertex3f(pos, max[0], min[1], min[2]);
+ immVertex3f(pos, min[0], min[1], min[2]);
+
+ /* sides */
+ immVertex3f(pos, min[0], min[1], min[2]);
+ immVertex3f(pos, min[0], min[1], max[2]);
+
+ immVertex3f(pos, min[0], max[1], min[2]);
+ immVertex3f(pos, min[0], max[1], max[2]);
+
+ immVertex3f(pos, max[0], max[1], min[2]);
+ immVertex3f(pos, max[0], max[1], max[2]);
+
+ immVertex3f(pos, max[0], min[1], min[2]);
+ immVertex3f(pos, max[0], min[1], max[2]);
+
+ immEnd();
}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index b5512aa108d..7e80021f8fc 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -622,7 +622,19 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
"tmp", input->link->output->id);
}
else if (input->source == GPU_SOURCE_BUILTIN) {
- if (input->builtin == GPU_VIEW_NORMAL)
+ if (input->builtin == GPU_INVERSE_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "viewinv");
+ else if (input->builtin == GPU_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "viewmat");
+ else if (input->builtin == GPU_CAMERA_TEXCO_FACTORS)
+ BLI_dynstr_append(ds, "camtexfac");
+ else if (input->builtin == GPU_OBJECT_MATRIX)
+ BLI_dynstr_append(ds, "objmat");
+ else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX)
+ BLI_dynstr_append(ds, "objinv");
+ else if (input->builtin == GPU_VIEW_POSITION)
+ BLI_dynstr_append(ds, "viewposition");
+ else if (input->builtin == GPU_VIEW_NORMAL)
BLI_dynstr_append(ds, "facingnormal");
else
BLI_dynstr_append(ds, GPU_builtin_name(input->builtin));
@@ -655,12 +667,12 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ");\n");
}
- BLI_dynstr_append(ds, "\n\tgl_FragColor = ");
+ BLI_dynstr_append(ds, "\n\tfragColor = ");
codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
BLI_dynstr_append(ds, ";\n");
}
-static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
+static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use_new_shading)
{
DynStr *ds = BLI_dynstr_new();
char *code;
@@ -686,8 +698,38 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
BLI_dynstr_append(ds, "void main()\n{\n");
- if (builtins & GPU_VIEW_NORMAL)
- BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? varnormal: -varnormal;\n");
+ if (use_new_shading) {
+ if (builtins & GPU_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 viewmat = ViewMatrix;\n");
+ if (builtins & GPU_CAMERA_TEXCO_FACTORS)
+ BLI_dynstr_append(ds, "\tvec4 camtexfac = CameraTexCoFactors;\n");
+ if (builtins & GPU_OBJECT_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 objmat = ModelMatrix;\n");
+ if (builtins & GPU_INVERSE_OBJECT_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 objinv = ModelMatrixInverse;\n");
+ if (builtins & GPU_INVERSE_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 viewinv = ViewMatrixInverse;\n");
+ if (builtins & GPU_VIEW_NORMAL)
+ BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? viewNormal: -viewNormal;\n");
+ if (builtins & GPU_VIEW_POSITION)
+ BLI_dynstr_append(ds, "\tvec3 viewposition = viewPosition;\n");
+ }
+ else {
+ if (builtins & GPU_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 viewmat = unfviewmat;\n");
+ if (builtins & GPU_CAMERA_TEXCO_FACTORS)
+ BLI_dynstr_append(ds, "\tvec4 camtexfac = unfcameratexfactors;\n");
+ if (builtins & GPU_OBJECT_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 objmat = unfobmat;\n");
+ if (builtins & GPU_INVERSE_OBJECT_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 objinv = unfinvobmat;\n");
+ if (builtins & GPU_INVERSE_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 viewinv = unfinvviewmat;\n");
+ if (builtins & GPU_VIEW_NORMAL)
+ BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? varnormal: -varnormal;\n");
+ if (builtins & GPU_VIEW_POSITION)
+ BLI_dynstr_append(ds, "\tvec3 viewposition = varposition;\n");
+ }
/* Calculate tangent space. */
#ifdef WITH_OPENSUBDIV
@@ -733,6 +775,95 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
return code;
}
+static const char *attrib_prefix_get(CustomDataType type)
+{
+ switch (type) {
+ case CD_ORCO: return "orco";
+ case CD_MTFACE: return "u";
+ case CD_TANGENT: return "t";
+ case CD_MCOL: return "c";
+ case CD_AUTO_FROM_NAME: return "a";
+ default: BLI_assert(false && "Attrib Prefix type not found : This should not happen!"); return "";
+ }
+}
+
+static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
+{
+ DynStr *ds = BLI_dynstr_new();
+ GPUNode *node;
+ GPUInput *input;
+ char *code;
+
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ /* XXX FIXME : see notes in mesh_render_data_create() */
+ /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
+ if (input->attribtype == CD_ORCO) {
+ /* orco is computed from local positions, see bellow */
+ BLI_dynstr_appendf(ds, "uniform vec3 OrcoTexCoFactors[2];\n");
+ }
+ else if (input->attribname[0] == '\0') {
+ BLI_dynstr_appendf(ds, "in %s %s;\n", GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype));
+ BLI_dynstr_appendf(ds, "#define att%d %s\n", input->attribid, attrib_prefix_get(input->attribtype));
+ }
+ else {
+ unsigned int hash = BLI_ghashutil_strhash_p(input->attribname);
+ BLI_dynstr_appendf(ds, "in %s %s%u;\n",
+ GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype), hash);
+ BLI_dynstr_appendf(ds, "#define att%d %s%u\n",
+ input->attribid, attrib_prefix_get(input->attribtype), hash);
+ }
+ BLI_dynstr_appendf(ds, "out %s var%d;\n",
+ GPU_DATATYPE_STR[input->type], input->attribid);
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "\n");
+
+ BLI_dynstr_append(ds, "#define ATTRIB\n");
+ BLI_dynstr_append(ds, "uniform mat3 NormalMatrix;\n");
+ BLI_dynstr_append(ds, "void pass_attrib(in vec3 position) {\n");
+
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ if (input->attribtype == CD_TANGENT) { /* silly exception */
+ BLI_dynstr_appendf(
+ ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n",
+ input->attribid, input->attribid);
+ BLI_dynstr_appendf(
+ ds, "\tvar%d.w = att%d.w;\n",
+ input->attribid, input->attribid);
+ }
+ else if (input->attribtype == CD_ORCO) {
+ BLI_dynstr_appendf(ds, "\tvar%d = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
+ input->attribid);
+ }
+ else {
+ BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n",
+ input->attribid, input->attribid);
+ }
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "}\n");
+
+ BLI_dynstr_append(ds, vert_code);
+
+ code = BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
+
+#if 0
+ if (G.debug & G_DEBUG) printf("%s\n", code);
+#endif
+
+ return code;
+}
+
static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
{
DynStr *ds = BLI_dynstr_new();
@@ -790,7 +921,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
#endif
BLI_dynstr_appendf(
- ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n",
+ ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n",
input->attribid, input->attribid);
BLI_dynstr_appendf(
ds, "\tvar%d.w = att%d.w;\n",
@@ -928,6 +1059,67 @@ GPUShader *GPU_pass_shader(GPUPass *pass)
return pass->shader;
}
+static void gpu_nodes_extract_dynamic_inputs_new(GPUPass *pass, ListBase *nodes)
+{
+ GPUShader *shader = pass->shader;
+ GPUNode *node;
+ GPUInput *next, *input;
+ ListBase *inputs = &pass->inputs;
+ int extract, z;
+
+ memset(inputs, 0, sizeof(*inputs));
+
+ if (!shader)
+ return;
+
+ GPU_shader_bind(shader);
+
+ for (node = nodes->first; node; node = node->next) {
+ z = 0;
+ for (input = node->inputs.first; input; input = next, z++) {
+ next = input->next;
+
+ /* attributes don't need to be bound, they already have
+ * an id that the drawing functions will use */
+ if (input->source == GPU_SOURCE_ATTRIB) {
+ continue;
+ }
+
+ if (input->source == GPU_SOURCE_BUILTIN ||
+ input->source == GPU_SOURCE_OPENGL_BUILTIN)
+ {
+ continue;
+ }
+
+ if (input->ima || input->tex || input->prv)
+ BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
+ else
+ BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
+
+ /* pass non-dynamic uniforms to opengl */
+ extract = 0;
+
+ if (input->ima || input->tex || input->prv) {
+ if (input->bindtex)
+ extract = 1;
+ }
+ else if (input->dynamicvec)
+ extract = 1;
+
+ if (extract)
+ input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
+
+ /* extract nodes */
+ if (extract) {
+ BLI_remlink(&node->inputs, input);
+ BLI_addtail(inputs, input);
+ }
+ }
+ }
+
+ GPU_shader_unbind();
+}
+
static void gpu_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
{
GPUShader *shader = pass->shader;
@@ -1194,7 +1386,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
#if 0
input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
#endif
- input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, GPU_HDR_NONE, NULL);
+ input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL);
input->textarget = GL_TEXTURE_2D;
MEM_freeN(link->ptr1);
@@ -1387,7 +1579,14 @@ GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
{
GPUNodeLink *link = GPU_node_link_create();
- link->attribtype = type;
+ /* Fall back to the UV layer, which matches old behavior. */
+ if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
+ link->attribtype = CD_MTFACE;
+ }
+ else {
+ link->attribtype = type;
+ }
+
link->attribname = name;
return link;
@@ -1647,6 +1846,73 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
}
}
+GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink,
+ const char *vert_code, const char *geom_code,
+ const char *frag_lib, const char *defines)
+{
+ GPUShader *shader;
+ GPUPass *pass;
+ char *vertexgen, *geometrygen, *fragmentgen, *tmp;
+ char *vertexcode, *geometrycode, *fragmentcode;
+
+ /* prune unused nodes */
+ gpu_nodes_prune(nodes, frag_outlink);
+
+ /* Hacky */
+ GPUVertexAttribs attribs;
+ gpu_nodes_get_vertex_attributes(nodes, &attribs);
+
+ /* generate code and compile with opengl */
+ fragmentgen = code_generate_fragment(nodes, frag_outlink->output, true);
+ vertexgen = code_generate_vertex_new(nodes, vert_code);
+ // geometrygen = code_generate_geometry(nodes, false);
+ UNUSED_VARS(geometrygen);
+
+ tmp = BLI_strdupcat(frag_lib, glsl_material_library);
+ fragmentcode = BLI_strdupcat(tmp, fragmentgen);
+ vertexcode = BLI_strdup(vertexgen);
+ geometrycode = (geom_code) ? BLI_strdup(geom_code) : NULL;
+
+ shader = GPU_shader_create(vertexcode,
+ fragmentcode,
+ geometrycode,
+ NULL,
+ defines);
+
+ MEM_freeN(tmp);
+
+ /* failed? */
+ if (!shader) {
+ if (fragmentcode)
+ MEM_freeN(fragmentcode);
+ if (vertexcode)
+ MEM_freeN(vertexcode);
+ if (geometrycode)
+ MEM_freeN(geometrycode);
+ MEM_freeN(fragmentgen);
+ MEM_freeN(vertexgen);
+ gpu_nodes_free(nodes);
+ return NULL;
+ }
+
+ /* create pass */
+ pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
+ pass->shader = shader;
+ pass->fragmentcode = fragmentcode;
+ pass->geometrycode = geometrycode;
+ pass->vertexcode = vertexcode;
+ pass->libcode = glsl_material_library;
+
+ /* extract dynamic inputs and throw away nodes */
+ gpu_nodes_extract_dynamic_inputs_new(pass, nodes);
+ gpu_nodes_free(nodes);
+
+ MEM_freeN(fragmentgen);
+ MEM_freeN(vertexgen);
+
+ return pass;
+}
+
GPUPass *GPU_generate_pass(
ListBase *nodes, GPUNodeLink *outlink,
GPUVertexAttribs *attribs, int *builtins,
@@ -1672,7 +1938,7 @@ GPUPass *GPU_generate_pass(
gpu_nodes_get_builtin_flag(nodes, builtins);
/* generate code and compile with opengl */
- fragmentcode = code_generate_fragment(nodes, outlink->output);
+ fragmentcode = code_generate_fragment(nodes, outlink->output, false);
vertexcode = code_generate_vertex(nodes, type);
geometrycode = code_generate_geometry(nodes, use_opensubdiv);
@@ -1688,9 +1954,6 @@ GPUPass *GPU_generate_pass(
geometrycode,
glsl_material_library,
NULL,
- 0,
- 0,
- 0,
flags);
/* failed? */
@@ -1708,7 +1971,6 @@ GPUPass *GPU_generate_pass(
/* create pass */
pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
- pass->output = outlink->output;
pass->shader = shader;
pass->fragmentcode = fragmentcode;
pass->geometrycode = geometrycode;
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 7af17f9122d..9263fe3bc3f 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -156,10 +156,7 @@ typedef struct GPUInput {
} GPUInput;
struct GPUPass {
- struct GPUPass *next, *prev;
-
ListBase inputs;
- struct GPUOutput *output;
struct GPUShader *shader;
char *fragmentcode;
char *geometrycode;
@@ -170,6 +167,9 @@ struct GPUPass {
typedef struct GPUPass GPUPass;
+GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink,
+ const char *vert_code, const char *geom_code,
+ const char *frag_lib, const char *defines);
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
struct GPUVertexAttribs *attribs, int *builtin,
const GPUMatType type, const char *name,
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index 2f2a16f9e1d..6543aacc4c1 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -42,11 +42,13 @@
#include "DNA_gpu_types.h"
#include "GPU_compositing.h"
+#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "GPU_batch.h"
#include "MEM_guardedalloc.h"
@@ -193,7 +195,8 @@ struct GPUFX {
/* we have a stencil, restore the previous state */
bool restore_stencil;
- unsigned int vbuffer;
+ Batch *quad_batch;
+ Batch *point_batch;
};
#if 0
@@ -225,7 +228,13 @@ static GPUTexture * create_concentric_sample_texture(int side)
}
}
- tex = GPU_texture_create_1D_procedural(side * side, texels, NULL);
+ tex = GPU_texture_create_1D_custom(side * side, 2, GPU_RG16F, (float *)texels, NULL);
+
+ /* Set parameters */
+ GPU_texture_bind(tex, 0);
+ GPU_texture_filter_mode(tex, false);
+ GPU_texture_unbind(tex);
+
MEM_freeN(texels);
return tex;
}
@@ -247,7 +256,13 @@ static GPUTexture *create_spiral_sample_texture(int numsaples)
texels[i][1] = r * sinf(phi);
}
- tex = GPU_texture_create_1D_procedural(numsaples, (float *)texels, NULL);
+ tex = GPU_texture_create_1D_custom(numsaples, 2, GPU_RG16F, (float *)texels, NULL);
+
+ /* Set parameters */
+ GPU_texture_bind(tex, 0);
+ GPU_texture_filter_mode(tex, false);
+ GPU_texture_unbind(tex);
+
MEM_freeN(texels);
return tex;
}
@@ -257,12 +272,32 @@ GPUFX *GPU_fx_compositor_create(void)
{
GPUFX *fx = MEM_callocN(sizeof(GPUFX), "GPUFX compositor");
- glGenBuffers(1, &fx->vbuffer);
- glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STATIC_DRAW);
- glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(float), fullscreencos);
- glBufferSubData(GL_ARRAY_BUFFER, 8 * sizeof(float), 8 * sizeof(float), fullscreenuvs);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ /* Quad buffer */
+ static VertexFormat format = {0};
+ static unsigned int pos, uvs;
+ if (format.attrib_ct == 0) {
+ pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ uvs = VertexFormat_add_attrib(&format, "uvs", COMP_F32, 2, KEEP_FLOAT);
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 4);
+ for (int i = 0; i < 4; ++i) {
+ VertexBuffer_set_attrib(vbo, pos, i, fullscreencos[i]);
+ VertexBuffer_set_attrib(vbo, uvs, i, fullscreenuvs[i]);
+ }
+ fx->quad_batch = Batch_create(PRIM_TRIANGLE_STRIP, vbo, NULL);
+
+ /* Point Buffer */
+ static VertexFormat format_point = {0};
+ static unsigned int dummy_attrib;
+ if (format_point.attrib_ct == 0) {
+ dummy_attrib = VertexFormat_add_attrib(&format_point, "pos", COMP_F32, 2, KEEP_FLOAT);
+ }
+ float dummy[2] = {0.0f, 0.0f};
+ VertexBuffer *vbo_point = VertexBuffer_create_with_format(&format_point);
+ VertexBuffer_allocate_data(vbo_point, 1);
+ VertexBuffer_set_attrib(vbo_point, dummy_attrib, 0, &dummy);
+ fx->point_batch = Batch_create(PRIM_POINTS, vbo_point, NULL);
return fx;
}
@@ -352,12 +387,14 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
void GPU_fx_compositor_destroy(GPUFX *fx)
{
cleanup_fx_gl_data(fx, true);
- glDeleteBuffers(1, &fx->vbuffer);
+ Batch_discard_all(fx->quad_batch);
+ Batch_discard_all(fx->point_batch);
MEM_freeN(fx);
}
static GPUTexture * create_jitter_texture(void)
{
+ GPUTexture *tex;
float jitter[64 * 64][2];
int i;
@@ -367,7 +404,15 @@ static GPUTexture * create_jitter_texture(void)
normalize_v2(jitter[i]);
}
- return GPU_texture_create_2D_procedural(64, 64, &jitter[0][0], true, NULL);
+ tex = GPU_texture_create_2D_custom(64, 64, 2, GPU_RG16F, &jitter[0][0], NULL);
+
+ /* Set parameters */
+ GPU_texture_bind(tex, 0);
+ GPU_texture_filter_mode(tex, false);
+ GPU_texture_wrap_mode(tex, true);
+ GPU_texture_unbind(tex);
+
+ return tex;
}
@@ -382,9 +427,6 @@ bool GPU_fx_compositor_initialize_passes(
fx->effects = 0;
- if (!GLEW_EXT_framebuffer_object)
- return false;
-
if (!fx_settings) {
cleanup_fx_gl_data(fx, true);
return false;
@@ -436,7 +478,7 @@ bool GPU_fx_compositor_initialize_passes(
if (!fx->color_buffer || !fx->depth_buffer || w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]) {
cleanup_fx_gl_data(fx, false);
- if (!(fx->color_buffer = GPU_texture_create_2D(w, h, NULL, GPU_HDR_NONE, err_out))) {
+ if (!(fx->color_buffer = GPU_texture_create_2D(w, h, NULL, err_out))) {
printf(".256%s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
@@ -472,8 +514,7 @@ bool GPU_fx_compositor_initialize_passes(
/* create textures for dof effect */
if (fx_flag & GPU_FX_FLAG_DOF) {
- bool dof_high_quality = (fx_settings->dof->high_quality != 0) &&
- GPU_geometry_shader_support() && GPU_instanced_drawing_support();
+ bool dof_high_quality = (fx_settings->dof->high_quality != 0);
/* cleanup buffers if quality setting has changed (no need to keep more buffers around than necessary ) */
if (dof_high_quality != fx->dof_high_quality)
@@ -488,38 +529,42 @@ bool GPU_fx_compositor_initialize_passes(
{
if (!(fx->dof_half_downsampled_near = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
}
if (!(fx->dof_half_downsampled_far = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
}
- if (!(fx->dof_nearfar_coc = GPU_texture_create_2D_procedural(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, false, err_out)))
+
+ if (!(fx->dof_nearfar_coc = GPU_texture_create_2D_custom(
+ fx->dof_downsampled_w, fx->dof_downsampled_h, 2, GPU_RG16F, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
}
+ GPU_texture_bind(fx->dof_nearfar_coc, 0);
+ GPU_texture_filter_mode(fx->dof_nearfar_coc, false);
+ GPU_texture_wrap_mode(fx->dof_nearfar_coc, false);
+ GPU_texture_unbind(fx->dof_nearfar_coc);
-
- if (!(fx->dof_near_blur = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_HALF_FLOAT, err_out)))
+ if (!(fx->dof_near_blur = GPU_texture_create_2D_custom(
+ fx->dof_downsampled_w, fx->dof_downsampled_h, 4, GPU_RGBA16F, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
}
- if (!(fx->dof_far_blur = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_HALF_FLOAT, err_out)))
+ if (!(fx->dof_far_blur = GPU_texture_create_2D_custom(
+ fx->dof_downsampled_w, fx->dof_downsampled_h, 4, GPU_RGBA16F, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
@@ -534,21 +579,21 @@ bool GPU_fx_compositor_initialize_passes(
if (!fx->dof_near_coc_buffer || !fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer) {
if (!(fx->dof_near_coc_buffer = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
}
if (!(fx->dof_near_coc_blurred_buffer = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
}
if (!(fx->dof_near_coc_final_buffer = GPU_texture_create_2D(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
@@ -567,7 +612,7 @@ bool GPU_fx_compositor_initialize_passes(
/* we need to pass data between shader stages, allocate an extra color buffer */
if (num_passes > 1) {
if (!fx->color_buffer_sec) {
- if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, GPU_HDR_NONE, err_out))) {
+ if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, err_out))) {
printf(".256%s\n", err_out);
cleanup_fx_gl_data(fx, true);
return false;
@@ -585,11 +630,8 @@ bool GPU_fx_compositor_initialize_passes(
/* bind the buffers */
/* first depth buffer, because system assumes read/write buffers */
- if (!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, err_out))
- printf("%.256s\n", err_out);
-
- if (!GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0, err_out))
- printf("%.256s\n", err_out);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, 0);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0, 0);
if (!GPU_framebuffer_check_valid(fx->gbuffer, err_out))
printf("%.256s\n", err_out);
@@ -600,7 +642,7 @@ bool GPU_fx_compositor_initialize_passes(
if (scissor_rect) {
int w_sc = BLI_rcti_size_x(scissor_rect) + 1;
int h_sc = BLI_rcti_size_y(scissor_rect) + 1;
- glPushAttrib(GL_SCISSOR_BIT);
+ gpuPushAttrib(GPU_SCISSOR_BIT);
glEnable(GL_SCISSOR_TEST);
glScissor(scissor_rect->xmin - rect->xmin, scissor_rect->ymin - rect->ymin,
w_sc, h_sc);
@@ -634,7 +676,7 @@ static void gpu_fx_bind_render_target(int *passes_left, GPUFX *fx, struct GPUOff
}
else {
/* bind the ping buffer to the color buffer */
- GPU_framebuffer_texture_attach(fx->gbuffer, target, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, target, 0, 0);
}
}
@@ -663,8 +705,7 @@ void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray)
GPU_framebuffer_texture_detach(fx->depth_buffer);
/* first depth buffer, because system assumes read/write buffers */
- if (!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0, err_out))
- printf("%.256s\n", err_out);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0, 0);
}
@@ -674,39 +715,35 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
/* attach regular framebuffer */
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, 0);
/* full screen quad where we will always write to depth buffer */
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_SCISSOR_BIT);
+ gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_SCISSOR_BIT);
glDepthFunc(GL_ALWAYS);
/* disable scissor from sculpt if any */
glDisable(GL_SCISSOR_TEST);
/* disable writing to color buffer, it's depth only pass */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- /* set up quad buffer */
- glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
- glVertexPointer(2, GL_FLOAT, 0, NULL);
- glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float)));
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
depth_resolve_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false);
if (depth_resolve_shader) {
- GPUDepthResolveInterface *interface = GPU_shader_get_interface(depth_resolve_shader);
+ GPUDepthResolveInterface *interface = GPU_fx_shader_get_interface(depth_resolve_shader);
- GPU_shader_bind(depth_resolve_shader);
+ /* set up quad buffer */
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(depth_resolve_shader), GPU_shader_get_interface(depth_resolve_shader));
GPU_texture_bind(fx->depth_buffer_xray, 0);
- GPU_texture_filter_mode(fx->depth_buffer_xray, false, true);
+ GPU_texture_compare_mode(fx->depth_buffer_xray, false);
+ GPU_texture_filter_mode(fx->depth_buffer_xray, true);
GPU_shader_uniform_texture(depth_resolve_shader, interface->depth_uniform, fx->depth_buffer_xray);
/* draw */
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
- GPU_texture_filter_mode(fx->depth_buffer_xray, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer_xray, true);
+ GPU_texture_filter_mode(fx->depth_buffer_xray, false);
GPU_texture_unbind(fx->depth_buffer_xray);
GPU_shader_unbind();
@@ -714,11 +751,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glPopAttrib();
+ gpuPopAttrib();
}
@@ -748,19 +781,13 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_detach(fx->color_buffer);
GPU_framebuffer_texture_detach(fx->depth_buffer);
- if (fx->restore_stencil)
- glPopAttrib();
+ if (fx->restore_stencil) {
+ gpuPopAttrib();
+ }
src = fx->color_buffer;
target = fx->color_buffer_sec;
- /* set up quad buffer */
- glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
- glVertexPointer(2, GL_FLOAT, 0, NULL);
- glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float)));
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
/* full screen FX pass */
/* invert the view matrix */
@@ -788,8 +815,6 @@ bool GPU_fx_do_composite_pass(
viewvecs[1][2] = vec_far[2] - viewvecs[0][2];
}
- /* set invalid color in case shader fails */
- glColor3f(1.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
/* ssao pass */
@@ -810,9 +835,9 @@ bool GPU_fx_do_composite_pass(
ssao_params[3] = (passes_left == 1 && !ofs) ? dfdyfac[0] : dfdyfac[1];
- GPUSSAOShaderInterface *interface = GPU_shader_get_interface(ssao_shader);
+ GPUSSAOShaderInterface *interface = GPU_fx_shader_get_interface(ssao_shader);
- GPU_shader_bind(ssao_shader);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(ssao_shader), GPU_shader_get_interface(ssao_shader));
GPU_shader_uniform_vector(ssao_shader, interface->ssao_uniform, 4, 1, ssao_params);
GPU_shader_uniform_vector(ssao_shader, interface->ssao_color_uniform, 4, 1, fx_ssao->color);
@@ -823,7 +848,8 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(ssao_shader, interface->color_uniform, src);
GPU_texture_bind(fx->depth_buffer, numslots++);
- GPU_texture_filter_mode(fx->depth_buffer, false, true);
+ GPU_texture_compare_mode(fx->depth_buffer, false);
+ GPU_texture_filter_mode(fx->depth_buffer, true);
GPU_shader_uniform_texture(ssao_shader, interface->depth_uniform, fx->depth_buffer);
GPU_texture_bind(fx->jitter_buffer, numslots++);
@@ -835,11 +861,12 @@ bool GPU_fx_do_composite_pass(
/* draw */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(src);
- GPU_texture_filter_mode(fx->depth_buffer, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer, true);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_texture_unbind(fx->depth_buffer);
GPU_texture_unbind(fx->jitter_buffer);
GPU_texture_unbind(fx->ssao_spiral_samples_tex);
@@ -892,11 +919,8 @@ bool GPU_fx_do_composite_pass(
if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3)) {
GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
GPU_framebuffer_restore();
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GPU_shader_unbind();
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
}
@@ -904,9 +928,9 @@ bool GPU_fx_do_composite_pass(
{
float invrendertargetdim[2] = {1.0f / fx->dof_downsampled_w, 1.0f / fx->dof_downsampled_h};
- GPUDOFHQPassOneInterface *interface = GPU_shader_get_interface(dof_shader_pass1);
+ GPUDOFHQPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1);
- GPU_shader_bind(dof_shader_pass1);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1), GPU_shader_get_interface(dof_shader_pass1));
GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -915,28 +939,31 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
GPU_texture_bind(fx->depth_buffer, numslots++);
- GPU_texture_filter_mode(fx->depth_buffer, false, false);
+ GPU_texture_compare_mode(fx->depth_buffer, false);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_shader_uniform_texture(dof_shader_pass1, interface->depth_uniform, fx->depth_buffer);
GPU_texture_bind(src, numslots++);
/* disable filtering for the texture so custom downsample can do the right thing */
- GPU_texture_filter_mode(src, false, false);
+ GPU_texture_filter_mode(src, false);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, src);
/* target is the downsampled coc buffer */
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_near, 0, NULL);
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_far, 1, NULL);
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_nearfar_coc, 2, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_near, 0, 0);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_far, 1, 0);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_nearfar_coc, 2, 0);
/* binding takes care of setting the viewport to the downsampled size */
GPU_framebuffer_slots_bind(fx->gbuffer, 0);
GPU_framebuffer_check_valid(fx->gbuffer, NULL);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
+
/* disable bindings */
- GPU_texture_filter_mode(src, false, true);
+ GPU_texture_filter_mode(src, true);
GPU_texture_unbind(src);
- GPU_texture_filter_mode(fx->depth_buffer, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer, true);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_texture_unbind(fx->depth_buffer);
GPU_framebuffer_texture_detach(fx->dof_half_downsampled_near);
@@ -953,24 +980,23 @@ bool GPU_fx_do_composite_pass(
int rendertargetdim[2] = {fx->dof_downsampled_w, fx->dof_downsampled_h};
float selection[2] = {0.0f, 1.0f};
- GPUDOFHQPassTwoInterface *interface = GPU_shader_get_interface(dof_shader_pass2);
+ GPUDOFHQPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2);
- GPU_shader_bind(dof_shader_pass2);
+ Batch_set_program(fx->point_batch, GPU_shader_get_program(dof_shader_pass2), GPU_shader_get_interface(dof_shader_pass2));
+
+ GPU_texture_bind(fx->dof_nearfar_coc, numslots++);
+ GPU_texture_bind(fx->dof_half_downsampled_far, numslots++);
+ GPU_texture_bind(fx->dof_half_downsampled_near, numslots++);
GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector_int(dof_shader_pass2, interface->rendertargetdim_uniform, 2, 1, rendertargetdim);
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
-
- GPU_texture_bind(fx->dof_nearfar_coc, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->coc_uniform, fx->dof_nearfar_coc);
-
- GPU_texture_bind(fx->dof_half_downsampled_far, numslots++);
- GPU_texture_bind(fx->dof_half_downsampled_near, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_far);
- GPU_texture_filter_mode(fx->dof_half_downsampled_far, false, false);
+ GPU_texture_filter_mode(fx->dof_half_downsampled_far, false);
/* target is the downsampled coc buffer */
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_far_blur, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_far_blur, 0, 0);
GPU_texture_bind_as_framebuffer(fx->dof_far_blur);
glDisable(GL_DEPTH_TEST);
@@ -981,24 +1007,24 @@ bool GPU_fx_do_composite_pass(
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
- glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h);
+ Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL);
GPU_texture_unbind(fx->dof_half_downsampled_far);
GPU_framebuffer_texture_detach(fx->dof_far_blur);
- GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near);
- GPU_texture_filter_mode(fx->dof_half_downsampled_near, false, false);
-
selection[0] = 1.0f;
selection[1] = 0.0f;
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
+ GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near);
+ GPU_texture_filter_mode(fx->dof_half_downsampled_near, false);
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0, 0);
/* have to clear the buffer unfortunately */
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
- glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h);
+ Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL);
+ Batch_done_using_program(fx->point_batch);
/* disable bindings */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -1010,15 +1036,16 @@ bool GPU_fx_do_composite_pass(
GPU_texture_unbind(fx->dof_nearfar_coc);
GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_far_blur);
+ numslots = 0;
}
/* third pass, accumulate the near/far blur fields */
{
float invrendertargetdim[2] = {1.0f / fx->dof_downsampled_w, 1.0f / fx->dof_downsampled_h};
- GPUDOFHQPassThreeInterface *interface = GPU_shader_get_interface(dof_shader_pass3);
+ GPUDOFHQPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3);
- GPU_shader_bind(dof_shader_pass3);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3), GPU_shader_get_interface(dof_shader_pass3));
GPU_shader_uniform_vector(dof_shader_pass3, interface->dof_uniform, 4, 1, dof_params);
@@ -1027,14 +1054,15 @@ bool GPU_fx_do_composite_pass(
GPU_texture_bind(fx->dof_near_blur, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->near_uniform, fx->dof_near_blur);
- GPU_texture_filter_mode(fx->dof_near_blur, false, true);
+ GPU_texture_filter_mode(fx->dof_near_blur, true);
GPU_texture_bind(fx->dof_far_blur, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->far_uniform, fx->dof_far_blur);
- GPU_texture_filter_mode(fx->dof_far_blur, false, true);
+ GPU_texture_filter_mode(fx->dof_far_blur, true);
GPU_texture_bind(fx->depth_buffer, numslots++);
- GPU_texture_filter_mode(fx->depth_buffer, false, false);
+ GPU_texture_compare_mode(fx->depth_buffer, false);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_shader_uniform_texture(dof_shader_pass3, interface->depth_uniform, fx->depth_buffer);
GPU_texture_bind(src, numslots++);
@@ -1043,13 +1071,13 @@ bool GPU_fx_do_composite_pass(
/* if this is the last pass, prepare for rendering on the frambuffer */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_blur);
GPU_texture_unbind(fx->dof_far_blur);
GPU_texture_unbind(src);
- GPU_texture_filter_mode(fx->depth_buffer, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer, true);
GPU_texture_unbind(fx->depth_buffer);
/* may not be attached, in that case this just returns */
@@ -1085,11 +1113,8 @@ bool GPU_fx_do_composite_pass(
if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3 && dof_shader_pass4 && dof_shader_pass5)) {
GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
GPU_framebuffer_restore();
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GPU_shader_unbind();
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
}
@@ -1097,9 +1122,9 @@ bool GPU_fx_do_composite_pass(
{
float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
- GPUDOFPassOneInterface *interface = GPU_shader_get_interface(dof_shader_pass1);
+ GPUDOFPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1);
- GPU_shader_bind(dof_shader_pass1);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1), GPU_shader_get_interface(dof_shader_pass1));
GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -1109,18 +1134,20 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass1, interface->color_uniform, src);
GPU_texture_bind(fx->depth_buffer, numslots++);
- GPU_texture_filter_mode(fx->depth_buffer, false, true);
+ GPU_texture_compare_mode(fx->depth_buffer, false);
+ GPU_texture_filter_mode(fx->depth_buffer, true);
GPU_shader_uniform_texture(dof_shader_pass1, interface->depth_uniform, fx->depth_buffer);
/* target is the downsampled coc buffer */
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, 0);
/* binding takes care of setting the viewport to the downsampled size */
GPU_texture_bind_as_framebuffer(fx->dof_near_coc_buffer);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(src);
- GPU_texture_filter_mode(fx->depth_buffer, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer, true);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_texture_unbind(fx->depth_buffer);
GPU_framebuffer_texture_detach(fx->dof_near_coc_buffer);
@@ -1134,32 +1161,37 @@ bool GPU_fx_do_composite_pass(
float tmp = invrendertargetdim[0];
invrendertargetdim[0] = 0.0f;
- GPUDOFPassTwoInterface *interface = GPU_shader_get_interface(dof_shader_pass2);
+ GPUDOFPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2);
dof_params[2] = GPU_texture_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor);
/* Blurring vertically */
- GPU_shader_bind(dof_shader_pass2);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2), GPU_shader_get_interface(dof_shader_pass2));
GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass2, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
GPU_shader_uniform_vector(dof_shader_pass2, interface->viewvecs_uniform, 4, 3, viewvecs[0]);
GPU_texture_bind(fx->depth_buffer, numslots++);
- GPU_texture_filter_mode(fx->depth_buffer, false, true);
+ GPU_texture_compare_mode(fx->depth_buffer, false);
+ GPU_texture_filter_mode(fx->depth_buffer, true);
GPU_shader_uniform_texture(dof_shader_pass2, interface->depth_uniform, fx->depth_buffer);
GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_buffer);
/* use final buffer as a temp here */
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, 0);
/* Drawing quad */
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
+
+ /* Rebind Shader */
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2), GPU_shader_get_interface(dof_shader_pass2));
/* *unbind/detach */
GPU_texture_unbind(fx->dof_near_coc_buffer);
+
GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer);
/* Blurring horizontally */
@@ -1170,11 +1202,13 @@ bool GPU_fx_do_composite_pass(
GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_final_buffer);
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0, NULL);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0, 0);
+
+ Batch_draw(fx->quad_batch);
/* *unbind/detach */
- GPU_texture_filter_mode(fx->depth_buffer, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer, true);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_texture_unbind(fx->depth_buffer);
GPU_texture_unbind(fx->dof_near_coc_final_buffer);
@@ -1187,9 +1221,9 @@ bool GPU_fx_do_composite_pass(
/* third pass, calculate near coc */
{
- GPUDOFPassThreeInterface *interface = GPU_shader_get_interface(dof_shader_pass3);
+ GPUDOFPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3);
- GPU_shader_bind(dof_shader_pass3);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3), GPU_shader_get_interface(dof_shader_pass3));
GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_downsampled, fx->dof_near_coc_buffer);
@@ -1197,9 +1231,9 @@ bool GPU_fx_do_composite_pass(
GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_blurred, fx->dof_near_coc_blurred_buffer);
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, 0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
@@ -1215,17 +1249,17 @@ bool GPU_fx_do_composite_pass(
float invrendertargetdim[2] = {1.0f / GPU_texture_width(fx->dof_near_coc_blurred_buffer),
1.0f / GPU_texture_height(fx->dof_near_coc_blurred_buffer)};
- GPUDOFPassFourInterface *interface = GPU_shader_get_interface(dof_shader_pass4);
+ GPUDOFPassFourInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass4);
- GPU_shader_bind(dof_shader_pass4);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass4), GPU_shader_get_interface(dof_shader_pass4));
GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass4, interface->near_coc_downsampled, fx->dof_near_coc_final_buffer);
GPU_shader_uniform_vector(dof_shader_pass4, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
- GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, NULL);
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, 0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_final_buffer);
@@ -1240,9 +1274,9 @@ bool GPU_fx_do_composite_pass(
{
float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
- GPUDOFPassFiveInterface *interface = GPU_shader_get_interface(dof_shader_pass5);
+ GPUDOFPassFiveInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass5);
- GPU_shader_bind(dof_shader_pass5);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass5), GPU_shader_get_interface(dof_shader_pass5));
GPU_shader_uniform_vector(dof_shader_pass5, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass5, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -1258,18 +1292,20 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass5, interface->medium_blurred_uniform, fx->dof_near_coc_buffer);
GPU_texture_bind(fx->depth_buffer, numslots++);
- GPU_texture_filter_mode(fx->depth_buffer, false, true);
+ GPU_texture_compare_mode(fx->depth_buffer, false);
+ GPU_texture_filter_mode(fx->depth_buffer, true);
GPU_shader_uniform_texture(dof_shader_pass5, interface->depth_uniform, fx->depth_buffer);
/* if this is the last pass, prepare for rendering on the frambuffer */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
GPU_texture_unbind(src);
- GPU_texture_filter_mode(fx->depth_buffer, true, false);
+ GPU_texture_compare_mode(fx->depth_buffer, true);
+ GPU_texture_filter_mode(fx->depth_buffer, false);
GPU_texture_unbind(fx->depth_buffer);
/* may not be attached, in that case this just returns */
@@ -1289,10 +1325,6 @@ bool GPU_fx_do_composite_pass(
}
}
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
GPU_shader_unbind();
return true;
@@ -1315,7 +1347,7 @@ void GPU_fx_compositor_init_ssao_settings(GPUSSAOSettings *fx_ssao)
fx_ssao->samples = 20;
}
-void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect effect)
+void GPU_fx_shader_init_interface(GPUShader *shader, GPUFXShaderEffect effect)
{
if (!shader)
return;
@@ -1334,7 +1366,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->ssao_concentric_tex = GPU_shader_get_uniform(shader, "ssao_concentric_tex");
interface->ssao_jitter_uniform = GPU_shader_get_uniform(shader, "jitter_tex");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1348,7 +1380,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1362,7 +1394,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->select_uniform = GPU_shader_get_uniform(shader, "layerselection");
interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1378,7 +1410,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1392,7 +1424,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
@@ -1405,7 +1437,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
@@ -1415,7 +1447,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->near_coc_downsampled = GPU_shader_get_uniform(shader, "colorbuffer");
interface->near_coc_blurred = GPU_shader_get_uniform(shader, "blurredcolorbuffer");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
@@ -1425,7 +1457,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->near_coc_downsampled = GPU_shader_get_uniform(shader, "colorbuffer");
interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
@@ -1440,7 +1472,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1450,7 +1482,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.c
index 7a0562617d6..8aea87ef659 100644
--- a/source/blender/gpu/intern/gpu_debug.c
+++ b/source/blender/gpu/intern/gpu_debug.c
@@ -20,7 +20,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): Brecht Van Lommel, Jason Wilkins.
+ * Contributor(s): Brecht Van Lommel, Jason Wilkins, Mike Erwin.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -44,122 +44,18 @@
#include <stdlib.h>
#include <string.h>
-#define CASE_CODE_RETURN_STR(code) case code: return #code;
+#ifndef __APPLE__ /* only non-Apple systems implement OpenGL debug callbacks */
-static const char *gpu_gl_error_symbol(GLenum err)
-{
- switch (err) {
- CASE_CODE_RETURN_STR(GL_NO_ERROR)
- CASE_CODE_RETURN_STR(GL_INVALID_ENUM)
- CASE_CODE_RETURN_STR(GL_INVALID_VALUE)
- CASE_CODE_RETURN_STR(GL_INVALID_OPERATION)
- CASE_CODE_RETURN_STR(GL_STACK_OVERFLOW)
- CASE_CODE_RETURN_STR(GL_STACK_UNDERFLOW)
- CASE_CODE_RETURN_STR(GL_OUT_OF_MEMORY)
-
-#if GL_ARB_imaging
- CASE_CODE_RETURN_STR(GL_TABLE_TOO_LARGE)
-#endif
-
-#if defined(WITH_GLU)
- CASE_CODE_RETURN_STR(GLU_INVALID_ENUM)
- CASE_CODE_RETURN_STR(GLU_INVALID_VALUE)
- CASE_CODE_RETURN_STR(GLU_OUT_OF_MEMORY)
-#endif
-
- default:
- return "<unknown error>";
- }
-}
-
-#undef CASE_CODE_RETURN_STR
-
-
-static bool gpu_report_gl_errors(const char *file, int line, const char *str)
-{
- GLenum gl_error = glGetError();
-
- if (gl_error == GL_NO_ERROR) {
- return true;
- }
- else {
- /* glGetError should have cleared the error flag, so if we get the
- * same flag twice that means glGetError itself probably triggered
- * the error. This happens on Windows if the GL context is invalid.
- */
- {
- GLenum new_error = glGetError();
- if (gl_error == new_error) {
- fprintf(stderr, "GL: Possible context invalidation issue\n");
- return false;
- }
- }
-
- fprintf(stderr,
- "%s:%d: ``%s'' -> GL Error (0x%04X - %s): %s\n",
- file, line, str, gl_error,
- gpu_gl_error_symbol(gl_error),
- gpuErrorString(gl_error));
-
- return false;
- }
-}
-
-
-const char *gpuErrorString(GLenum err)
-{
- switch (err) {
- case GL_NO_ERROR:
- return "No Error";
-
- case GL_INVALID_ENUM:
- return "Invalid Enumeration";
-
- case GL_INVALID_VALUE:
- return "Invalid Value";
-
- case GL_INVALID_OPERATION:
- return "Invalid Operation";
-
- case GL_STACK_OVERFLOW:
- return "Stack Overflow";
-
- case GL_STACK_UNDERFLOW:
- return "Stack Underflow";
-
- case GL_OUT_OF_MEMORY:
- return "Out of Memory";
-
-#if GL_ARB_imaging
- case GL_TABLE_TOO_LARGE:
- return "Table Too Large";
-#endif
-
-#if defined(WITH_GLU)
- case GLU_INVALID_ENUM:
- return "Invalid Enum (GLU)";
-
- case GLU_INVALID_VALUE:
- return "Invalid Value (GLU)";
-
- case GLU_OUT_OF_MEMORY:
- return "Out of Memory (GLU)";
-#endif
-
- default:
- return "<unknown error>";
- }
-}
+/* control whether we use older AMD_debug_output extension
+ * some supported GPU + OS combos do not have the newer extensions */
+# define LEGACY_DEBUG 1
-
-/* Debug callbacks need the same calling convention as OpenGL functions.
- */
-#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
- /* Win32 but not WinCE */
-# define APIENTRY __stdcall
-#else
-# define APIENTRY
-#endif
+/* Debug callbacks need the same calling convention as OpenGL functions. */
+# if defined(_WIN32)
+# define APIENTRY __stdcall
+# else
+# define APIENTRY
+# endif
static const char *source_name(GLenum source)
@@ -189,32 +85,11 @@ static const char *message_type_name(GLenum message)
}
}
-static const char *category_name_amd(GLenum category)
-{
- switch (category) {
- case GL_DEBUG_CATEGORY_API_ERROR_AMD: return "API error";
- case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: return "window system";
- case GL_DEBUG_CATEGORY_DEPRECATION_AMD: return "deprecated behavior";
- case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: return "undefined behavior";
- case GL_DEBUG_CATEGORY_PERFORMANCE_AMD: return "performance";
- case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: return "shader compiler";
- case GL_DEBUG_CATEGORY_APPLICATION_AMD: return "application";
- case GL_DEBUG_CATEGORY_OTHER_AMD: return "other";
- default: return "???";
- }
-}
-
-
static void APIENTRY gpu_debug_proc(
GLenum source, GLenum type, GLuint UNUSED(id),
GLenum severity, GLsizei UNUSED(length),
const GLchar *message, const GLvoid *UNUSED(userParm))
{
- if (type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR) {
- /* Blender 2.7x uses OpenGL 2.1, we don't care if features are deprecated */
- return;
- }
-
bool backtrace = false;
switch (severity) {
@@ -233,18 +108,28 @@ static void APIENTRY gpu_debug_proc(
}
}
+# if LEGACY_DEBUG
+
+static const char *category_name_amd(GLenum category)
+{
+ switch (category) {
+ case GL_DEBUG_CATEGORY_API_ERROR_AMD: return "API error";
+ case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: return "window system";
+ case GL_DEBUG_CATEGORY_DEPRECATION_AMD: return "deprecated behavior";
+ case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: return "undefined behavior";
+ case GL_DEBUG_CATEGORY_PERFORMANCE_AMD: return "performance";
+ case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: return "shader compiler";
+ case GL_DEBUG_CATEGORY_APPLICATION_AMD: return "application";
+ case GL_DEBUG_CATEGORY_OTHER_AMD: return "other";
+ default: return "???";
+ }
+}
-#ifndef GLEW_ES_ONLY
static void APIENTRY gpu_debug_proc_amd(
GLuint UNUSED(id), GLenum category,
GLenum severity, GLsizei UNUSED(length),
const GLchar *message, GLvoid *UNUSED(userParm))
{
- if (category == GL_DEBUG_CATEGORY_DEPRECATION_AMD) {
- /* Blender 2.7x uses OpenGL 2.1, we don't care if features are deprecated */
- return;
- }
-
bool backtrace = false;
switch (severity) {
@@ -261,148 +146,88 @@ static void APIENTRY gpu_debug_proc_amd(
fflush(stderr);
}
}
-#endif
-
+# endif /* LEGACY_DEBUG */
-#undef APIENTRY
+# undef APIENTRY
+#endif /* not Apple */
void gpu_debug_init(void)
{
+#ifdef __APPLE__
+ fprintf(stderr, "OpenGL debug callback is not available on Apple.\n");
+#else /* not Apple */
const char success[] = "Successfully hooked OpenGL debug callback.";
-#if !defined(WITH_GLEW_ES) && !defined(GLEW_ES_ONLY)
- if (GLEW_VERSION_4_3) {
- fprintf(stderr, "Using OpenGL 4.3 debug facilities\n");
- glEnable(GL_DEBUG_OUTPUT);
- glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- glDebugMessageCallback((GLDEBUGPROC)gpu_debug_proc, mxGetCurrentContext());
- glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
- GPU_string_marker(success);
- return;
- }
-#endif
-
- if (GLEW_KHR_debug) {
-#ifndef GLEW_ES_ONLY
- fprintf(stderr, "Using KHR_debug extension\n");
+ if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
+ fprintf(stderr, "Using %s\n", GLEW_VERSION_4_3 ? "OpenGL 4.3 debug facilities" : "KHR_debug extension");
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- glDebugMessageCallback((GLDEBUGPROC)gpu_debug_proc, mxGetCurrentContext());
+ glDebugMessageCallback((GLDEBUGPROC)gpu_debug_proc, NULL);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
GPU_string_marker(success);
-#endif
- return;
}
-
-#ifndef GLEW_ES_ONLY
- if (GLEW_ARB_debug_output) {
+ else if (GLEW_ARB_debug_output) {
fprintf(stderr, "Using ARB_debug_output extension\n");
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- glDebugMessageCallbackARB((GLDEBUGPROCARB)gpu_debug_proc, mxGetCurrentContext());
+ glDebugMessageCallbackARB((GLDEBUGPROCARB)gpu_debug_proc, NULL);
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
GPU_string_marker(success);
-
- return;
}
-
- if (GLEW_AMD_debug_output) {
+# if LEGACY_DEBUG
+ else if (GLEW_AMD_debug_output) {
fprintf(stderr, "Using AMD_debug_output extension\n");
- glDebugMessageCallbackAMD(gpu_debug_proc_amd, mxGetCurrentContext());
+ glDebugMessageCallbackAMD(gpu_debug_proc_amd, NULL);
glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
GPU_string_marker(success);
-
- return;
}
-#endif
-
- fprintf(stderr, "Failed to hook OpenGL debug callback.\n");
-
- return;
+# endif
+ else {
+ fprintf(stderr, "Failed to hook OpenGL debug callback.\n");
+ }
+#endif /* not Apple */
}
void gpu_debug_exit(void)
{
-#ifndef WITH_GLEW_ES
-#ifndef GLEW_ES_ONLY
- if (GLEW_VERSION_4_3) {
- glDebugMessageCallback(NULL, NULL);
-
- return;
- }
-#endif
-#endif
-
- if (GLEW_KHR_debug) {
-#ifndef GLEW_ES_ONLY
+#ifndef __APPLE__
+ if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
glDebugMessageCallback(NULL, NULL);
-#endif
- return;
}
-
-#ifndef GLEW_ES_ONLY
- if (GLEW_ARB_debug_output) {
+ else if (GLEW_ARB_debug_output) {
glDebugMessageCallbackARB(NULL, NULL);
-
- return;
}
-
- if (GLEW_AMD_debug_output) {
+# if LEGACY_DEBUG
+ else if (GLEW_AMD_debug_output) {
glDebugMessageCallbackAMD(NULL, NULL);
-
- return;
}
+# endif
#endif
-
- return;
}
void GPU_string_marker(const char *buf)
{
-#ifndef WITH_GLEW_ES
-#ifndef GLEW_ES_ONLY
- if (GLEW_VERSION_4_3) {
+#ifdef __APPLE__
+ UNUSED_VARS(buf);
+#else /* not Apple */
+ if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
glDebugMessageInsert(
GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
GL_DEBUG_SEVERITY_NOTIFICATION, -1, buf);
-
- return;
}
-#endif
-#endif
-
- if (GLEW_KHR_debug) {
-#ifndef GLEW_ES_ONLY
- glDebugMessageInsert(
- GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
- GL_DEBUG_SEVERITY_NOTIFICATION, -1, buf);
-#endif
- return;
- }
-
-#ifndef GLEW_ES_ONLY
- if (GLEW_ARB_debug_output) {
+ else if (GLEW_ARB_debug_output) {
glDebugMessageInsertARB(
GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0,
GL_DEBUG_SEVERITY_LOW_ARB, -1, buf);
-
- return;
}
-
- if (GLEW_AMD_debug_output) {
+# if LEGACY_DEBUG
+ else if (GLEW_AMD_debug_output) {
glDebugMessageInsertAMD(
GL_DEBUG_CATEGORY_APPLICATION_AMD, GL_DEBUG_SEVERITY_LOW_AMD, 0,
0, buf);
-
- return;
- }
-
- if (GLEW_GREMEDY_string_marker) {
- glStringMarkerGREMEDY(0, buf);
-
- return;
}
-#endif
+# endif
+#endif /* not Apple */
}
void GPU_print_error_debug(const char *str)
@@ -410,401 +235,3 @@ void GPU_print_error_debug(const char *str)
if (G.debug & G_DEBUG)
fprintf(stderr, "GPU: %s\n", str);
}
-
-
-void GPU_assert_no_gl_errors(const char *file, int line, const char *str)
-{
- if (G.debug) {
- GLboolean gl_ok = gpu_report_gl_errors(file, line, str);
-
- BLI_assert(gl_ok);
- (void) gl_ok;
- }
-}
-
-
-static void gpu_state_print_fl_ex(const char *name, GLenum type)
-{
- const unsigned char err_mark[4] = {0xff, 0xff, 0xff, 0xff};
-
- float value[32];
- int a;
-
- memset(value, 0xff, sizeof(value));
- glGetFloatv(type, value);
-
- if (glGetError() == GL_NO_ERROR) {
- printf("%s: ", name);
- for (a = 0; a < 32; a++) {
- if (memcmp(&value[a], err_mark, sizeof(value[a])) == 0) {
- break;
- }
- printf("%.2f ", value[a]);
- }
- printf("\n");
- }
-}
-
-#define gpu_state_print_fl(val) gpu_state_print_fl_ex(#val, val)
-
-void GPU_state_print(void)
-{
- GPU_ASSERT_NO_GL_ERRORS("GPU_state_print"); /* clear any errors */
-
- gpu_state_print_fl(GL_ACCUM_ALPHA_BITS);
- gpu_state_print_fl(GL_ACCUM_BLUE_BITS);
- gpu_state_print_fl(GL_ACCUM_CLEAR_VALUE);
- gpu_state_print_fl(GL_ACCUM_GREEN_BITS);
- gpu_state_print_fl(GL_ACCUM_RED_BITS);
- gpu_state_print_fl(GL_ACTIVE_TEXTURE);
- gpu_state_print_fl(GL_ALIASED_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_ALIASED_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_ALPHA_BIAS);
- gpu_state_print_fl(GL_ALPHA_BITS);
- gpu_state_print_fl(GL_ALPHA_SCALE);
- gpu_state_print_fl(GL_ALPHA_TEST);
- gpu_state_print_fl(GL_ALPHA_TEST_FUNC);
- gpu_state_print_fl(GL_ALPHA_TEST_REF);
- gpu_state_print_fl(GL_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_AUTO_NORMAL);
- gpu_state_print_fl(GL_AUX_BUFFERS);
- gpu_state_print_fl(GL_BLEND);
- gpu_state_print_fl(GL_BLEND_COLOR);
- gpu_state_print_fl(GL_BLEND_DST_ALPHA);
- gpu_state_print_fl(GL_BLEND_DST_RGB);
- gpu_state_print_fl(GL_BLEND_EQUATION_ALPHA);
- gpu_state_print_fl(GL_BLEND_EQUATION_RGB);
- gpu_state_print_fl(GL_BLEND_SRC_ALPHA);
- gpu_state_print_fl(GL_BLEND_SRC_RGB);
- gpu_state_print_fl(GL_BLUE_BIAS);
- gpu_state_print_fl(GL_BLUE_BITS);
- gpu_state_print_fl(GL_BLUE_SCALE);
- gpu_state_print_fl(GL_CLIENT_ACTIVE_TEXTURE);
- gpu_state_print_fl(GL_CLIENT_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_CLIP_PLANE0);
- gpu_state_print_fl(GL_COLOR_ARRAY);
- gpu_state_print_fl(GL_COLOR_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_COLOR_ARRAY_SIZE);
- gpu_state_print_fl(GL_COLOR_ARRAY_STRIDE);
- gpu_state_print_fl(GL_COLOR_ARRAY_TYPE);
- gpu_state_print_fl(GL_COLOR_CLEAR_VALUE);
- gpu_state_print_fl(GL_COLOR_LOGIC_OP);
- gpu_state_print_fl(GL_COLOR_MATERIAL);
- gpu_state_print_fl(GL_COLOR_MATERIAL_FACE);
- gpu_state_print_fl(GL_COLOR_MATERIAL_PARAMETER);
- gpu_state_print_fl(GL_COLOR_MATRIX);
- gpu_state_print_fl(GL_COLOR_MATRIX_STACK_DEPTH);
- gpu_state_print_fl(GL_COLOR_SUM);
- gpu_state_print_fl(GL_COLOR_TABLE);
- gpu_state_print_fl(GL_COLOR_WRITEMASK);
- gpu_state_print_fl(GL_COMPRESSED_TEXTURE_FORMATS);
- gpu_state_print_fl(GL_CONVOLUTION_1D);
- gpu_state_print_fl(GL_CONVOLUTION_2D);
- gpu_state_print_fl(GL_CULL_FACE);
- gpu_state_print_fl(GL_CULL_FACE_MODE);
- gpu_state_print_fl(GL_CURRENT_COLOR);
- gpu_state_print_fl(GL_CURRENT_FOG_COORD);
- gpu_state_print_fl(GL_CURRENT_INDEX);
- gpu_state_print_fl(GL_CURRENT_NORMAL);
- gpu_state_print_fl(GL_CURRENT_PROGRAM);
- gpu_state_print_fl(GL_CURRENT_RASTER_COLOR);
- gpu_state_print_fl(GL_CURRENT_RASTER_DISTANCE);
- gpu_state_print_fl(GL_CURRENT_RASTER_INDEX);
- gpu_state_print_fl(GL_CURRENT_RASTER_POSITION);
- gpu_state_print_fl(GL_CURRENT_RASTER_POSITION_VALID);
- gpu_state_print_fl(GL_CURRENT_RASTER_SECONDARY_COLOR);
- gpu_state_print_fl(GL_CURRENT_RASTER_TEXTURE_COORDS);
- gpu_state_print_fl(GL_CURRENT_SECONDARY_COLOR);
- gpu_state_print_fl(GL_CURRENT_TEXTURE_COORDS);
- gpu_state_print_fl(GL_DEPTH_BIAS);
- gpu_state_print_fl(GL_DEPTH_BITS);
- gpu_state_print_fl(GL_DEPTH_CLEAR_VALUE);
- gpu_state_print_fl(GL_DEPTH_FUNC);
- gpu_state_print_fl(GL_DEPTH_RANGE);
- gpu_state_print_fl(GL_DEPTH_SCALE);
- gpu_state_print_fl(GL_DEPTH_TEST);
- gpu_state_print_fl(GL_DEPTH_WRITEMASK);
- gpu_state_print_fl(GL_DITHER);
- gpu_state_print_fl(GL_DOUBLEBUFFER);
- gpu_state_print_fl(GL_DRAW_BUFFER);
- gpu_state_print_fl(GL_DRAW_BUFFER0);
- gpu_state_print_fl(GL_EDGE_FLAG);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_STRIDE);
- gpu_state_print_fl(GL_ELEMENT_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_FEEDBACK_BUFFER_SIZE);
- gpu_state_print_fl(GL_FEEDBACK_BUFFER_TYPE);
- gpu_state_print_fl(GL_FOG);
- gpu_state_print_fl(GL_FOG_COLOR);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_STRIDE);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_TYPE);
- gpu_state_print_fl(GL_FOG_COORD_SRC);
- gpu_state_print_fl(GL_FOG_DENSITY);
- gpu_state_print_fl(GL_FOG_END);
- gpu_state_print_fl(GL_FOG_HINT);
- gpu_state_print_fl(GL_FOG_INDEX);
- gpu_state_print_fl(GL_FOG_MODE);
- gpu_state_print_fl(GL_FOG_START);
- gpu_state_print_fl(GL_FRAGMENT_PROGRAM_ARB); /* TODO: remove ARB program support */
- gpu_state_print_fl(GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
- gpu_state_print_fl(GL_FRONT_FACE);
- gpu_state_print_fl(GL_GENERATE_MIPMAP_HINT);
- gpu_state_print_fl(GL_GREEN_BIAS);
- gpu_state_print_fl(GL_GREEN_BITS);
- gpu_state_print_fl(GL_GREEN_SCALE);
- gpu_state_print_fl(GL_HISTOGRAM);
- gpu_state_print_fl(GL_INDEX_ARRAY);
- gpu_state_print_fl(GL_INDEX_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_INDEX_ARRAY_STRIDE);
- gpu_state_print_fl(GL_INDEX_ARRAY_TYPE);
- gpu_state_print_fl(GL_INDEX_BITS);
- gpu_state_print_fl(GL_INDEX_CLEAR_VALUE);
- gpu_state_print_fl(GL_INDEX_LOGIC_OP);
- gpu_state_print_fl(GL_INDEX_MODE);
- gpu_state_print_fl(GL_INDEX_OFFSET);
- gpu_state_print_fl(GL_INDEX_SHIFT);
- gpu_state_print_fl(GL_INDEX_WRITEMASK);
- gpu_state_print_fl(GL_LIGHT0);
- gpu_state_print_fl(GL_LIGHT1);
- gpu_state_print_fl(GL_LIGHT2);
- gpu_state_print_fl(GL_LIGHT3);
- gpu_state_print_fl(GL_LIGHT4);
- gpu_state_print_fl(GL_LIGHT5);
- gpu_state_print_fl(GL_LIGHT6);
- gpu_state_print_fl(GL_LIGHT7);
- gpu_state_print_fl(GL_LIGHTING);
- gpu_state_print_fl(GL_LIGHT_MODEL_AMBIENT);
- gpu_state_print_fl(GL_LIGHT_MODEL_COLOR_CONTROL);
- gpu_state_print_fl(GL_LIGHT_MODEL_LOCAL_VIEWER);
- gpu_state_print_fl(GL_LIGHT_MODEL_TWO_SIDE);
- gpu_state_print_fl(GL_LINE_SMOOTH);
- gpu_state_print_fl(GL_LINE_SMOOTH_HINT);
- gpu_state_print_fl(GL_LINE_STIPPLE);
- gpu_state_print_fl(GL_LINE_STIPPLE_PATTERN);
- gpu_state_print_fl(GL_LINE_STIPPLE_REPEAT);
- gpu_state_print_fl(GL_LINE_WIDTH);
- gpu_state_print_fl(GL_LINE_WIDTH_GRANULARITY);
- gpu_state_print_fl(GL_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_LIST_BASE);
- gpu_state_print_fl(GL_LIST_INDEX);
- gpu_state_print_fl(GL_LIST_MODE);
- gpu_state_print_fl(GL_LOGIC_OP);
- gpu_state_print_fl(GL_LOGIC_OP_MODE);
- gpu_state_print_fl(GL_MAP1_COLOR_4);
- gpu_state_print_fl(GL_MAP1_GRID_DOMAIN);
- gpu_state_print_fl(GL_MAP1_GRID_SEGMENTS);
- gpu_state_print_fl(GL_MAP1_INDEX);
- gpu_state_print_fl(GL_MAP1_NORMAL);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_1);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_2);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_3);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_4);
- gpu_state_print_fl(GL_MAP1_VERTEX_3);
- gpu_state_print_fl(GL_MAP1_VERTEX_4);
- gpu_state_print_fl(GL_MAP2_COLOR_4);
- gpu_state_print_fl(GL_MAP2_GRID_DOMAIN);
- gpu_state_print_fl(GL_MAP2_GRID_SEGMENTS);
- gpu_state_print_fl(GL_MAP2_INDEX);
- gpu_state_print_fl(GL_MAP2_NORMAL);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_1);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_2);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_3);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_4);
- gpu_state_print_fl(GL_MAP2_VERTEX_3);
- gpu_state_print_fl(GL_MAP2_VERTEX_4);
- gpu_state_print_fl(GL_MAP_COLOR);
- gpu_state_print_fl(GL_MAP_STENCIL);
- gpu_state_print_fl(GL_MATRIX_MODE);
- gpu_state_print_fl(GL_MAX_3D_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_CLIP_PLANES);
- gpu_state_print_fl(GL_MAX_COLOR_MATRIX_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_DRAW_BUFFERS);
- gpu_state_print_fl(GL_MAX_ELEMENTS_INDICES);
- gpu_state_print_fl(GL_MAX_ELEMENTS_VERTICES);
- gpu_state_print_fl(GL_MAX_EVAL_ORDER);
- gpu_state_print_fl(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
- gpu_state_print_fl(GL_MAX_LIGHTS);
- gpu_state_print_fl(GL_MAX_LIST_NESTING);
- gpu_state_print_fl(GL_MAX_MODELVIEW_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_NAME_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_PIXEL_MAP_TABLE);
- gpu_state_print_fl(GL_MAX_PROJECTION_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_TEXTURE_COORDS);
- gpu_state_print_fl(GL_MAX_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_TEXTURE_LOD_BIAS);
- gpu_state_print_fl(GL_MAX_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_TEXTURE_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_TEXTURE_UNITS);
- gpu_state_print_fl(GL_MAX_VARYING_FLOATS);
- gpu_state_print_fl(GL_MAX_VERTEX_ATTRIBS);
- gpu_state_print_fl(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
- gpu_state_print_fl(GL_MAX_VIEWPORT_DIMS);
- gpu_state_print_fl(GL_MINMAX);
- gpu_state_print_fl(GL_MODELVIEW_MATRIX);
- gpu_state_print_fl(GL_MODELVIEW_STACK_DEPTH);
- gpu_state_print_fl(GL_MULTISAMPLE);
- gpu_state_print_fl(GL_NAME_STACK_DEPTH);
- gpu_state_print_fl(GL_NORMALIZE);
- gpu_state_print_fl(GL_NORMAL_ARRAY);
- gpu_state_print_fl(GL_NORMAL_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_NORMAL_ARRAY_STRIDE);
- gpu_state_print_fl(GL_NORMAL_ARRAY_TYPE);
- gpu_state_print_fl(GL_NUM_COMPRESSED_TEXTURE_FORMATS);
- gpu_state_print_fl(GL_PACK_ALIGNMENT);
- gpu_state_print_fl(GL_PACK_IMAGE_HEIGHT);
- gpu_state_print_fl(GL_PACK_LSB_FIRST);
- gpu_state_print_fl(GL_PACK_ROW_LENGTH);
- gpu_state_print_fl(GL_PACK_SKIP_IMAGES);
- gpu_state_print_fl(GL_PACK_SKIP_PIXELS);
- gpu_state_print_fl(GL_PACK_SKIP_ROWS);
- gpu_state_print_fl(GL_PACK_SWAP_BYTES);
- gpu_state_print_fl(GL_PERSPECTIVE_CORRECTION_HINT);
- gpu_state_print_fl(GL_PIXEL_MAP_A_TO_A_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_B_TO_B_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_G_TO_G_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_A_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_B_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_G_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_I_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_R_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_R_TO_R_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_S_TO_S_SIZE);
- gpu_state_print_fl(GL_PIXEL_PACK_BUFFER_BINDING);
- gpu_state_print_fl(GL_PIXEL_UNPACK_BUFFER_BINDING);
- gpu_state_print_fl(GL_POINT_DISTANCE_ATTENUATION);
- gpu_state_print_fl(GL_POINT_FADE_THRESHOLD_SIZE);
- gpu_state_print_fl(GL_POINT_SIZE);
- gpu_state_print_fl(GL_POINT_SIZE_GRANULARITY);
- gpu_state_print_fl(GL_POINT_SIZE_MAX);
- gpu_state_print_fl(GL_POINT_SIZE_MIN);
- gpu_state_print_fl(GL_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_POINT_SMOOTH);
- gpu_state_print_fl(GL_POINT_SMOOTH_HINT);
- gpu_state_print_fl(GL_POINT_SPRITE);
- gpu_state_print_fl(GL_POLYGON_MODE);
- gpu_state_print_fl(GL_POLYGON_OFFSET_FACTOR);
- gpu_state_print_fl(GL_POLYGON_OFFSET_FILL);
- gpu_state_print_fl(GL_POLYGON_OFFSET_LINE);
- gpu_state_print_fl(GL_POLYGON_OFFSET_POINT);
- gpu_state_print_fl(GL_POLYGON_OFFSET_UNITS);
- gpu_state_print_fl(GL_POLYGON_SMOOTH);
- gpu_state_print_fl(GL_POLYGON_SMOOTH_HINT);
- gpu_state_print_fl(GL_POLYGON_STIPPLE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_COLOR_TABLE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_COLOR_TABLE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_RED_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_RED_SCALE);
- gpu_state_print_fl(GL_PROJECTION_MATRIX);
- gpu_state_print_fl(GL_PROJECTION_STACK_DEPTH);
- gpu_state_print_fl(GL_READ_BUFFER);
- gpu_state_print_fl(GL_RED_BIAS);
- gpu_state_print_fl(GL_RED_BITS);
- gpu_state_print_fl(GL_RED_SCALE);
- gpu_state_print_fl(GL_RENDER_MODE);
- gpu_state_print_fl(GL_RESCALE_NORMAL);
- gpu_state_print_fl(GL_RGBA_MODE);
- gpu_state_print_fl(GL_SAMPLES);
- gpu_state_print_fl(GL_SAMPLE_BUFFERS);
- gpu_state_print_fl(GL_SAMPLE_COVERAGE_INVERT);
- gpu_state_print_fl(GL_SAMPLE_COVERAGE_VALUE);
- gpu_state_print_fl(GL_SCISSOR_BOX);
- gpu_state_print_fl(GL_SCISSOR_TEST);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_SIZE);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_STRIDE);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_TYPE);
- gpu_state_print_fl(GL_SELECTION_BUFFER_SIZE);
- gpu_state_print_fl(GL_SEPARABLE_2D);
- gpu_state_print_fl(GL_SHADE_MODEL);
- gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_GRANULARITY);
- gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_GRANULARITY);
- gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_STENCIL_BACK_FAIL);
- gpu_state_print_fl(GL_STENCIL_BACK_FUNC);
- gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_FAIL);
- gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_PASS);
- gpu_state_print_fl(GL_STENCIL_BACK_REF);
- gpu_state_print_fl(GL_STENCIL_BACK_VALUE_MASK);
- gpu_state_print_fl(GL_STENCIL_BACK_WRITEMASK);
- gpu_state_print_fl(GL_STENCIL_BITS);
- gpu_state_print_fl(GL_STENCIL_CLEAR_VALUE);
- gpu_state_print_fl(GL_STENCIL_FAIL);
- gpu_state_print_fl(GL_STENCIL_FUNC);
- gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_FAIL);
- gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_PASS);
- gpu_state_print_fl(GL_STENCIL_REF);
- gpu_state_print_fl(GL_STENCIL_TEST);
- gpu_state_print_fl(GL_STENCIL_VALUE_MASK);
- gpu_state_print_fl(GL_STENCIL_WRITEMASK);
- gpu_state_print_fl(GL_STEREO);
- gpu_state_print_fl(GL_SUBPIXEL_BITS);
- gpu_state_print_fl(GL_TEXTURE_1D);
- gpu_state_print_fl(GL_TEXTURE_2D);
- gpu_state_print_fl(GL_TEXTURE_3D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_1D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_2D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_3D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_CUBE_MAP);
- gpu_state_print_fl(GL_TEXTURE_COMPRESSION_HINT);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_SIZE);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_STRIDE);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_TYPE);
- gpu_state_print_fl(GL_TEXTURE_CUBE_MAP);
- gpu_state_print_fl(GL_TEXTURE_GEN_Q);
- gpu_state_print_fl(GL_TEXTURE_GEN_R);
- gpu_state_print_fl(GL_TEXTURE_GEN_S);
- gpu_state_print_fl(GL_TEXTURE_GEN_T);
- gpu_state_print_fl(GL_TEXTURE_MATRIX);
- gpu_state_print_fl(GL_TEXTURE_STACK_DEPTH);
- gpu_state_print_fl(GL_TRANSPOSE_COLOR_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_MODELVIEW_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_PROJECTION_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_TEXTURE_MATRIX);
- gpu_state_print_fl(GL_UNPACK_ALIGNMENT);
- gpu_state_print_fl(GL_UNPACK_IMAGE_HEIGHT);
- gpu_state_print_fl(GL_UNPACK_LSB_FIRST);
- gpu_state_print_fl(GL_UNPACK_ROW_LENGTH);
- gpu_state_print_fl(GL_UNPACK_SKIP_IMAGES);
- gpu_state_print_fl(GL_UNPACK_SKIP_PIXELS);
- gpu_state_print_fl(GL_UNPACK_SKIP_ROWS);
- gpu_state_print_fl(GL_UNPACK_SWAP_BYTES);
- gpu_state_print_fl(GL_VERTEX_ARRAY);
- gpu_state_print_fl(GL_VERTEX_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_VERTEX_ARRAY_SIZE);
- gpu_state_print_fl(GL_VERTEX_ARRAY_STRIDE);
- gpu_state_print_fl(GL_VERTEX_ARRAY_TYPE);
- gpu_state_print_fl(GL_VERTEX_PROGRAM_POINT_SIZE);
- gpu_state_print_fl(GL_VERTEX_PROGRAM_TWO_SIDE);
- gpu_state_print_fl(GL_VIEWPORT);
- gpu_state_print_fl(GL_ZOOM_X);
- gpu_state_print_fl(GL_ZOOM_Y);
-}
-
-#undef gpu_state_print_fl
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 1583d16ca27..529727b5e17 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -38,8 +38,6 @@
#include <string.h>
-#include "GPU_glew.h"
-
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
@@ -81,6 +79,7 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -109,23 +108,27 @@ static void gpu_mcol(unsigned int ucol)
}
void GPU_render_text(
- MTexPoly *mtexpoly, int mode,
- const char *textstr, int textlen, unsigned int *col,
+ int mode, const char *textstr, int textlen, unsigned int *col,
const float *v_quad[4], const float *uv_quad[4],
int glattrib)
{
- if ((mode & GEMAT_TEXT) && (textlen > 0) && mtexpoly->tpage) {
+ /* XXX, 2.8 removes texface */
+#if 0
+ Image *ima = mtexpoly->tpage;
+#else
+ Image *ima = NULL;
+#endif
+ if ((mode & GEMAT_TEXT) && (textlen > 0) && ima) {
const float *v1 = v_quad[0];
const float *v2 = v_quad[1];
const float *v3 = v_quad[2];
const float *v4 = v_quad[3];
- Image *ima = (Image *)mtexpoly->tpage;
const size_t textlen_st = textlen;
float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
-
+
/* multiline */
float line_start = 0.0f, line_height;
-
+
if (v4)
line_height = max_ffff(v1[1], v2[1], v3[1], v4[2]) - min_ffff(v1[1], v2[1], v3[1], v4[2]);
else
@@ -133,50 +136,48 @@ void GPU_render_text(
line_height *= 1.2f; /* could be an option? */
/* end multiline */
-
+
/* color has been set */
- if (mtexpoly->mode & TF_OBCOL)
- col = NULL;
- else if (!col)
+ if (!col)
glColor3f(1.0f, 1.0f, 1.0f);
- glPushMatrix();
-
+ gpuPushMatrix();
+
/* get the tab width */
ImBuf *first_ibuf = BKE_image_get_first_ibuf(ima);
matrixGlyph(first_ibuf, ' ', &centerx, &centery,
- &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
-
+ &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+
float advance_tab = advance * 4; /* tab width could also be an option */
-
-
+
+
for (size_t index = 0; index < textlen_st; ) {
unsigned int character;
float uv[4][2];
/* lets calculate offset stuff */
character = BLI_str_utf8_as_unicode_and_size_safe(textstr + index, &index);
-
+
if (character == '\n') {
- glTranslatef(line_start, -line_height, 0.0f);
+ gpuTranslate2f(line_start, -line_height);
line_start = 0.0f;
continue;
}
else if (character == '\t') {
- glTranslatef(advance_tab, 0.0f, 0.0f);
+ gpuTranslate2f(advance_tab, 0.0f);
line_start -= advance_tab; /* so we can go back to the start of the line */
continue;
-
+
}
else if (character > USHRT_MAX) {
/* not much we can do here bmfonts take ushort */
character = '?';
}
-
+
/* space starts at offset 1 */
/* character = character - ' ' + 1; */
matrixGlyph(first_ibuf, character, & centerx, &centery,
- &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+ &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
uv[0][0] = (uv_quad[0][0] - centerx) * sizex + transx;
uv[0][1] = (uv_quad[0][1] - centery) * sizey + transy;
@@ -184,13 +185,13 @@ void GPU_render_text(
uv[1][1] = (uv_quad[1][1] - centery) * sizey + transy;
uv[2][0] = (uv_quad[2][0] - centerx) * sizex + transx;
uv[2][1] = (uv_quad[2][1] - centery) * sizey + transy;
-
+
glBegin(GL_POLYGON);
if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[0]);
else glTexCoord2fv(uv[0]);
if (col) gpu_mcol(col[0]);
glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
-
+
if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[1]);
else glTexCoord2fv(uv[1]);
if (col) gpu_mcol(col[1]);
@@ -212,28 +213,29 @@ void GPU_render_text(
}
glEnd();
- glTranslatef(advance, 0.0f, 0.0f);
+ gpuTranslate2f(advance, 0.0f);
line_start -= advance; /* so we can go back to the start of the line */
}
- glPopMatrix();
+ gpuPopMatrix();
BKE_image_release_ibuf(ima, first_ibuf, NULL);
}
}
/* Checking powers of two for images since OpenGL ES requires it */
-
+#ifdef WITH_DDS
static bool is_power_of_2_resolution(int w, int h)
{
return is_power_of_2_i(w) && is_power_of_2_i(h);
}
+#endif
static bool is_over_resolution_limit(GLenum textarget, int w, int h)
{
int size = (textarget == GL_TEXTURE_2D) ?
GPU_max_texture_size() : GPU_max_cube_map_size();
int reslimit = (U.glreslimit != 0) ?
- min_ii(U.glreslimit, size) : size;
+ min_ii(U.glreslimit, size) : size;
return (w > reslimit || h > reslimit);
}
@@ -269,8 +271,7 @@ static struct GPUTextureState {
int alphablend;
float anisotropic;
int gpu_mipmap;
- MTexPoly *lasttface;
-} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.0f, 0, NULL};
+} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.0f, 0};
/* Mipmap settings */
@@ -279,36 +280,13 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap)
int old_value = GTS.gpu_mipmap;
/* only actually enable if it's supported */
- GTS.gpu_mipmap = gpu_mipmap && GLEW_EXT_framebuffer_object;
+ GTS.gpu_mipmap = gpu_mipmap;
if (old_value != GTS.gpu_mipmap) {
GPU_free_images();
}
}
-static void gpu_generate_mipmap(GLenum target)
-{
- const bool is_ati = GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY);
- int target_enabled = 0;
-
- /* work around bug in ATI driver, need to have GL_TEXTURE_2D enabled
- * http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation */
- if (is_ati) {
- target_enabled = glIsEnabled(target);
- if (!target_enabled)
- glEnable(target);
- }
-
- /* TODO: simplify when we transition to GL >= 3 */
- if (GLEW_VERSION_3_0 || GLEW_ARB_framebuffer_object)
- glGenerateMipmap(target);
- else if (GLEW_EXT_framebuffer_object)
- glGenerateMipmapEXT(target);
-
- if (is_ati && !target_enabled)
- glDisable(target);
-}
-
void GPU_set_mipmap(bool mipmap)
{
if (GTS.domipmap != mipmap) {
@@ -415,43 +393,16 @@ static unsigned int *gpu_get_image_bindcode(Image *ima, GLenum textarget)
return bind;
}
-void GPU_clear_tpage(bool force)
-{
- if (GTS.lasttface == NULL && !force)
- return;
-
- GTS.lasttface = NULL;
- GTS.curtile = 0;
- GTS.curima = NULL;
- if (GTS.curtilemode != 0) {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- }
- GTS.curtilemode = 0;
- GTS.curtileXRep = 0;
- GTS.curtileYRep = 0;
- GTS.alphablend = -1;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_ALPHA_TEST);
-}
-
static void gpu_set_alpha_blend(GPUBlendMode alphablend)
{
if (alphablend == GPU_BLEND_SOLID) {
glDisable(GL_BLEND);
- glDisable(GL_ALPHA_TEST);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (alphablend == GPU_BLEND_ADD) {
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
- glDisable(GL_ALPHA_TEST);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}
else if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_SORT)) {
@@ -460,59 +411,20 @@ static void gpu_set_alpha_blend(GPUBlendMode alphablend)
/* for OpenGL render we use the alpha channel, this makes alpha blend correct */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
+
/* if U.glalphaclip == 1.0, some cards go bonkers...
* turn off alpha test in this case */
- /* added after 2.45 to clip alpha */
- if (U.glalphaclip == 1.0f) {
- glDisable(GL_ALPHA_TEST);
- }
- else {
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, U.glalphaclip);
- }
}
else if (alphablend == GPU_BLEND_CLIP) {
glDisable(GL_BLEND);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, 0.5f);
}
else if (alphablend == GPU_BLEND_ALPHA_TO_COVERAGE) {
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, U.glalphaclip);
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}
}
-static void gpu_verify_alpha_blend(int alphablend)
-{
- /* verify alpha blending modes */
- if (GTS.alphablend == alphablend)
- return;
-
- gpu_set_alpha_blend(alphablend);
- GTS.alphablend = alphablend;
-}
-
-static void gpu_verify_reflection(Image *ima)
-{
- if (ima && (ima->flag & IMA_REFLECT)) {
- /* enable reflection mapping */
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- }
- else {
- /* disable reflection mapping */
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- }
-}
-
typedef struct VerifyThreadData {
ImBuf *ibuf;
float *srgb_frect;
@@ -604,19 +516,6 @@ int GPU_verify_image(
return (ima != NULL);
}
- /* if tiling mode or repeat changed, change texture matrix to fit */
- if (GTS.tilemode != GTS.curtilemode || GTS.curtileXRep != GTS.tileXRep ||
- GTS.curtileYRep != GTS.tileYRep)
- {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
-
- if (ima && (ima->tpageflag & IMA_TILES))
- glScalef(ima->xrep, ima->yrep, 1.0f);
-
- glMatrixMode(GL_MODELVIEW);
- }
-
/* check if we have a valid image */
if (ima == NULL || ima->ok == 0)
return 0;
@@ -652,29 +551,29 @@ int GPU_verify_image(
GPU_free_image(ima);
ima->tpageflag &= ~IMA_TPAGE_REFRESH;
}
-
+
if (GTS.tilemode) {
/* tiled mode */
if (ima->repbind == NULL) gpu_make_repbind(ima);
if (GTS.tile >= ima->totbind) GTS.tile = 0;
-
+
/* this happens when you change repeat buttons */
if (ima->repbind && textarget == GL_TEXTURE_2D) bind = &ima->repbind[GTS.tile];
else bind = gpu_get_image_bindcode(ima, textarget);
-
+
if (*bind == 0) {
short texwindx = ibuf->x / ima->xrep;
short texwindy = ibuf->y / ima->yrep;
-
+
if (GTS.tile >= ima->xrep * ima->yrep)
GTS.tile = ima->xrep * ima->yrep - 1;
-
+
short texwinsy = GTS.tile / ima->xrep;
short texwinsx = GTS.tile - texwinsy * ima->xrep;
-
+
texwinsx *= texwindx;
texwinsy *= texwindy;
-
+
tpx = texwindx;
tpy = texwindy;
@@ -748,7 +647,7 @@ int GPU_verify_image(
memcpy(tilerectrow, rectrow, tpx * sizeof(*rectrow));
}
-
+
rect = tilerect;
}
}
@@ -759,13 +658,13 @@ int GPU_verify_image(
else
#endif
GPU_create_gl_tex(bind, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima);
-
+
/* mark as non-color data texture */
if (*bind) {
if (is_data)
- ima->tpageflag |= IMA_GLBIND_IS_DATA;
+ ima->tpageflag |= IMA_GLBIND_IS_DATA;
else
- ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
+ ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
}
/* clean up */
@@ -858,30 +757,6 @@ void GPU_create_gl_tex(
int tpx = rectw;
int tpy = recth;
- /* scale if not a power of two. this is not strictly necessary for newer
- * GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures
- * Then don't bother scaling for hardware that supports NPOT textures! */
- if (textarget == GL_TEXTURE_2D &&
- ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
- is_over_resolution_limit(textarget, rectw, recth)))
- {
- rectw = smaller_power_of_2_limit(rectw);
- recth = smaller_power_of_2_limit(recth);
-
- if (use_high_bit_depth) {
- ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
- IMB_scaleImBuf(ibuf, rectw, recth);
-
- frect = ibuf->rect_float;
- }
- else {
- ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
- IMB_scaleImBuf(ibuf, rectw, recth);
-
- rect = ibuf->rect;
- }
- }
-
/* create image */
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
@@ -900,7 +775,7 @@ void GPU_create_gl_tex(
if (GPU_get_mipmap() && mipmap) {
if (GTS.gpu_mipmap) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ glGenerateMipmap(GL_TEXTURE_2D);
}
else {
int i;
@@ -951,7 +826,7 @@ void GPU_create_gl_tex(
if (GPU_get_mipmap() && mipmap) {
if (GTS.gpu_mipmap) {
- gpu_generate_mipmap(GL_TEXTURE_CUBE_MAP);
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
}
else {
if (!ibuf) {
@@ -975,7 +850,7 @@ void GPU_create_gl_tex(
if (mip_cube_map) {
for (int j = 0; j < 6; j++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i,
- informat, mipw, miph, 0, GL_RGBA, type, mip_cube_map[j]);
+ informat, mipw, miph, 0, GL_RGBA, type, mip_cube_map[j]);
}
}
gpu_del_cube_map(mip_cube_map);
@@ -1056,7 +931,7 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf)
size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize;
glCompressedTexImage2D(GL_TEXTURE_2D, i, format, width, height,
- 0, size, ibuf->dds_data.data + offset);
+ 0, size, ibuf->dds_data.data + offset);
offset += size;
width >>= 1;
@@ -1091,62 +966,6 @@ void GPU_create_gl_tex_compressed(
}
#endif
}
-static void gpu_verify_repeat(Image *ima)
-{
- /* set either clamp or repeat in X/Y */
- if (ima->tpageflag & IMA_CLAMP_U)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- else
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-
- if (ima->tpageflag & IMA_CLAMP_V)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- else
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-}
-
-int GPU_set_tpage(MTexPoly *mtexpoly, int mipmap, int alphablend)
-{
- /* check if we need to clear the state */
- if (mtexpoly == NULL) {
- GPU_clear_tpage(false);
- return 0;
- }
-
- Image *ima = mtexpoly->tpage;
- GTS.lasttface = mtexpoly;
-
- gpu_verify_alpha_blend(alphablend);
- gpu_verify_reflection(ima);
-
- if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, mtexpoly->tile, 1, mipmap, false)) {
- GTS.curtile = GTS.tile;
- GTS.curima = GTS.ima;
- GTS.curtilemode = GTS.tilemode;
- GTS.curtileXRep = GTS.tileXRep;
- GTS.curtileYRep = GTS.tileYRep;
-
- glEnable(GL_TEXTURE_2D);
- }
- else {
- glDisable(GL_TEXTURE_2D);
-
- GTS.curtile = 0;
- GTS.curima = NULL;
- GTS.curtilemode = 0;
- GTS.curtileXRep = 0;
- GTS.curtileYRep = 0;
-
- return 0;
- }
-
- gpu_verify_repeat(ima);
-
- /* Did this get lost in the image recode? */
- /* BKE_image_tag_time(ima);*/
-
- return 1;
-}
/* these two functions are called on entering and exiting texture paint mode,
* temporary disabling/enabling mipmapping on all images for quick texture
@@ -1206,9 +1025,7 @@ void GPU_paint_set_mipmap(bool mipmap)
/* check if image has been downscaled and do scaled partial update */
static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
{
- if ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(ibuf->x, ibuf->y)) ||
- is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y))
- {
+ if (is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y)) {
int x_limit = smaller_power_of_2_limit(ibuf->x);
int y_limit = smaller_power_of_2_limit(ibuf->y);
@@ -1261,7 +1078,7 @@ static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x,
}
if (GPU_get_mipmap()) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ glGenerateMipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1296,7 +1113,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
float *buffer = MEM_mallocN(w * h * sizeof(float) * 4, "temp_texpaint_float_buf");
bool is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA) != 0;
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
-
+
if (gpu_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
MEM_freeN(buffer);
BKE_image_release_ibuf(ima, ibuf, NULL);
@@ -1311,7 +1128,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
/* we have already accounted for the case where GTS.gpu_mipmap is false
* so we will be using GPU mipmap generation here */
if (GPU_get_mipmap()) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ glGenerateMipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1337,7 +1154,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
- GL_UNSIGNED_BYTE, ibuf->rect);
+ GL_UNSIGNED_BYTE, ibuf->rect);
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
@@ -1345,7 +1162,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
/* see comment above as to why we are using gpu mipmap generation here */
if (GPU_get_mipmap()) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ glGenerateMipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1361,9 +1178,9 @@ void GPU_update_images_framechange(void)
if (ima->tpageflag & IMA_TWINANIM) {
if (ima->twend >= ima->xrep * ima->yrep)
ima->twend = ima->xrep * ima->yrep - 1;
-
+
/* check: is bindcode not in the array? free. (to do) */
-
+
ima->lastframe++;
if (ima->lastframe > ima->twend)
ima->lastframe = ima->twsta;
@@ -1386,9 +1203,9 @@ int GPU_update_image_time(Image *ima, double time)
if (ima->tpageflag & IMA_TWINANIM) {
if (ima->twend >= ima->xrep * ima->yrep) ima->twend = ima->xrep * ima->yrep - 1;
-
+
/* check: is the bindcode not in the array? Then free. (still to do) */
-
+
float diff = (float)((float)time - ima->lastupdate);
inc = (int)(diff * (float)ima->animspeed);
@@ -1437,31 +1254,40 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres)
if (smoke_has_colors(sds->fluid)) {
float *data = MEM_callocN(sizeof(float) * sds->total_cells * 4, "smokeColorTexture");
smoke_get_rgba(sds->fluid, data, 0);
- sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 4, data);
+ sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], data, NULL);
MEM_freeN(data);
}
/* density only */
else {
- sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_density(sds->fluid));
+ sds->tex = GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
+ GPU_R8, smoke_get_density(sds->fluid), NULL);
}
- sds->tex_flame = (smoke_has_fuel(sds->fluid)) ? GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_flame(sds->fluid)) : NULL;
+ sds->tex_flame = (smoke_has_fuel(sds->fluid)) ?
+ GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
+ GPU_R8, smoke_get_flame(sds->fluid), NULL) :
+ NULL;
}
else if (!sds->tex && highres) {
/* rgba texture for color + density */
if (smoke_turbulence_has_colors(sds->wt)) {
float *data = MEM_callocN(sizeof(float) * smoke_turbulence_get_cells(sds->wt) * 4, "smokeColorTexture");
smoke_turbulence_get_rgba(sds->wt, data, 0);
- sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 4, data);
+ sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], data, NULL);
MEM_freeN(data);
}
/* density only */
else {
- sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_density(sds->wt));
+ sds->tex = GPU_texture_create_3D_custom(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1,
+ GPU_R8, smoke_turbulence_get_density(sds->wt), NULL);
}
- sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ? GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_flame(sds->wt)) : NULL;
+ sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ?
+ GPU_texture_create_3D_custom(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1,
+ GPU_R8, smoke_turbulence_get_flame(sds->wt), NULL):
+ NULL;
}
- sds->tex_shadow = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, sds->shadow);
+ sds->tex_shadow = GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
+ GPU_R8, sds->shadow, NULL);
}
#else // WITH_SMOKE
(void)highres;
@@ -1528,7 +1354,7 @@ void GPU_free_image(Image *ima)
/* free repeated image binding */
if (ima->repbind) {
glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
-
+
MEM_freeN(ima->repbind);
ima->repbind = NULL;
}
@@ -1601,7 +1427,7 @@ typedef struct GPUMaterialFixed {
float spec[3];
int hard;
float alpha;
-} GPUMaterialFixed;
+} GPUMaterialFixed;
static struct GPUMaterialState {
GPUMaterialFixed (*matbuf);
@@ -1657,12 +1483,12 @@ static void gpu_material_to_fixed(
copy_v3_v3(smat->spec, &bmat->specr);
smat->alpha = 1.0f;
smat->hard = CLAMPIS(bmat->har, 0, 128);
-
+
if (dimdown) {
mul_v3_fl(smat->diff, 0.8f);
mul_v3_fl(smat->spec, 0.5f);
}
-
+
if (gamma) {
linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
linearrgb_to_srgb_v3_v3(smat->spec, smat->spec);
@@ -1673,7 +1499,7 @@ static void gpu_material_to_fixed(
if (bmat->shade_flag & MA_OBCOLOR)
mul_v3_v3(smat->diff, ob->col);
-
+
mul_v3_v3fl(smat->spec, &bmat->specr, bmat->spec);
smat->hard = CLAMPIS(bmat->har, 1, 128);
smat->alpha = 1.0f;
@@ -1710,7 +1536,7 @@ void GPU_end_dupli_object(void)
}
void GPU_begin_object_materials(
- View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob,
+ View3D *v3d, RegionView3D *rv3d, Scene *scene, SceneLayer *sl, Object *ob,
bool glsl, bool *do_alpha_after)
{
Material *ma;
@@ -1749,8 +1575,10 @@ void GPU_begin_object_materials(
#ifdef WITH_GAMEENGINE
if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- ob = BKE_object_lod_matob_get(ob, scene);
+ ob = BKE_object_lod_matob_get(ob, sl);
}
+#else
+ UNUSED_VARS(sl);
#endif
/* initialize state */
@@ -1789,7 +1617,7 @@ void GPU_begin_object_materials(
GMS.is_alpha_pass = (v3d->transp != false);
if (GMS.use_alpha_pass)
*do_alpha_after = false;
-
+
if (GMS.totmat > FIXEDMAT) {
GMS.matbuf = MEM_callocN(sizeof(GPUMaterialFixed) * GMS.totmat, "GMS.matbuf");
GMS.gmatbuf = MEM_callocN(sizeof(*GMS.gmatbuf) * GMS.totmat, "GMS.matbuf");
@@ -1808,11 +1636,11 @@ void GPU_begin_object_materials(
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
-
+
GMS.alphablend[0] = GPU_BLEND_SOLID;
}
else {
-
+
/* no materials assigned? */
if (ob->totcol == 0) {
gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes, true);
@@ -1827,7 +1655,7 @@ void GPU_begin_object_materials(
GMS.alphablend[0] = GPU_BLEND_SOLID;
}
-
+
/* setup materials */
for (a = 1; a <= ob->totcol; a++) {
/* find a suitable material */
@@ -1985,7 +1813,7 @@ int GPU_object_material_bind(int nr, void *attribs)
gpu_get_particle_info(&partile_info);
}
- if (GPU_get_material_builtins(gpumat) & GPU_OBJECT_INFO) {
+ if ((GPU_get_material_builtins(gpumat) & GPU_OBJECT_INFO) != 0) {
GPU_get_object_info(object_info, mat);
}
@@ -2062,7 +1890,7 @@ void GPU_set_material_alpha_blend(int alphablend)
{
if (GMS.lastalphablend == alphablend)
return;
-
+
gpu_set_alpha_blend(alphablend);
GMS.lastalphablend = alphablend;
}
@@ -2133,13 +1961,6 @@ void GPU_end_object_materials(void)
GMS.gmatbuf = NULL;
GMS.alphablend = NULL;
GMS.two_sided_lighting = false;
-
- /* resetting the texture matrix after the scaling needed for tiled textures */
- if (GTS.tilemode) {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- }
}
/* Lights */
@@ -2153,13 +1974,13 @@ int GPU_default_lights(void)
U.light[0].col[0] = 0.8; U.light[0].col[1] = 0.8; U.light[0].col[2] = 0.8;
U.light[0].spec[0] = 0.5; U.light[0].spec[1] = 0.5; U.light[0].spec[2] = 0.5;
U.light[0].spec[3] = 1.0;
-
+
U.light[1].flag = 0;
U.light[1].vec[0] = 0.5; U.light[1].vec[1] = 0.5; U.light[1].vec[2] = 0.1;
U.light[1].col[0] = 0.4; U.light[1].col[1] = 0.4; U.light[1].col[2] = 0.8;
U.light[1].spec[0] = 0.3; U.light[1].spec[1] = 0.3; U.light[1].spec[2] = 0.5;
U.light[1].spec[3] = 1.0;
-
+
U.light[2].flag = 0;
U.light[2].vec[0] = 0.3; U.light[2].vec[1] = -0.3; U.light[2].vec[2] = -0.2;
U.light[2].col[0] = 0.8; U.light[2].col[1] = 0.5; U.light[2].col[2] = 0.4;
@@ -2192,31 +2013,28 @@ int GPU_default_lights(void)
return count;
}
-int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][4], int ortho)
+int GPU_scene_object_lights(SceneLayer *sl, float viewmat[4][4], int ortho)
{
/* disable all lights */
for (int count = 0; count < 8; count++)
GPU_basic_shader_light_set(count, NULL);
-
+
/* view direction for specular is not computed correct by default in
* opengl, so we set the settings ourselfs */
GPU_basic_shader_light_set_viewer(!ortho);
int count = 0;
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
if (base->object->type != OB_LAMP)
continue;
- if (!(base->lay & lay) || !(base->lay & ob->lay))
- continue;
-
Lamp *la = base->object->data;
-
+
/* setup lamp transform */
- glPushMatrix();
- glLoadMatrixf((float *)viewmat);
-
+ gpuPushMatrix();
+ gpuLoadMatrix(viewmat);
+
/* setup light */
GPULightData light = {0};
@@ -2235,7 +2053,7 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][
light.constant_attenuation = 1.0f;
light.linear_attenuation = la->att1 / la->dist;
light.quadratic_attenuation = la->att2 / (la->dist * la->dist);
-
+
if (la->type == LA_SPOT) {
light.type = GPU_LIGHT_SPOT;
negate_v3_v3(light.direction, base->object->obmat[2]);
@@ -2246,11 +2064,11 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][
else
light.type = GPU_LIGHT_POINT;
}
-
+
GPU_basic_shader_light_set(count, &light);
-
- glPopMatrix();
-
+
+ gpuPopMatrix();
+
count++;
if (count == 8)
break;
@@ -2297,64 +2115,36 @@ static void gpu_multisample(bool enable)
void GPU_state_init(void)
{
- float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
- float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 35);
- glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-
GPU_default_lights();
-
+
+ GPU_disable_program_point_size();
+
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+
glDepthFunc(GL_LEQUAL);
- /* scaling matrices */
- glEnable(GL_NORMALIZE);
- glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
- glDisable(GL_FOG);
- glDisable(GL_LIGHTING);
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_LOGIC_OP);
+ glDisable(GL_COLOR_LOGIC_OP);
glDisable(GL_STENCIL_TEST);
- glDisable(GL_TEXTURE_1D);
- glDisable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- /* default disabled, enable should be local per function */
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
- glPixelTransferi(GL_RED_SCALE, 1);
- glPixelTransferi(GL_RED_BIAS, 0);
- glPixelTransferi(GL_GREEN_SCALE, 1);
- glPixelTransferi(GL_GREEN_BIAS, 0);
- glPixelTransferi(GL_BLUE_SCALE, 1);
- glPixelTransferi(GL_BLUE_BIAS, 0);
- glPixelTransferi(GL_ALPHA_SCALE, 1);
- glPixelTransferi(GL_ALPHA_BIAS, 0);
-
- glPixelTransferi(GL_DEPTH_BIAS, 0);
- glPixelTransferi(GL_DEPTH_SCALE, 1);
- glDepthRange(0.0, 1.0);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
+ glDepthRange(0.0, 1.0);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
gpu_multisample(false);
+}
+
+void GPU_enable_program_point_size(void)
+{
+ glEnable(GL_PROGRAM_POINT_SIZE);
+}
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+void GPU_disable_program_point_size(void)
+{
+ glDisable(GL_PROGRAM_POINT_SIZE);
}
#ifdef WITH_OPENSUBDIV
@@ -2500,10 +2290,10 @@ void GPU_select_to_index_array(unsigned int *col, const unsigned int size)
{
#define INDEX_BUF_ARRAY(INDEX_FROM_BUF_BITS) \
for (i = size; i--; col++) { \
- if ((c = *col)) { \
- *col = INDEX_FROM_BUF_BITS(c); \
- } \
- } ((void)0)
+ if ((c = *col)) { \
+ *col = INDEX_FROM_BUF_BITS(c); \
+ } \
+ } ((void)0)
if (size > 0) {
unsigned int i, c;
@@ -2531,4 +2321,172 @@ void GPU_select_to_index_array(unsigned int *col, const unsigned int size)
#undef INDEX_BUF_ARRAY
}
+#define STATE_STACK_DEPTH 16
+
+typedef struct {
+ eGPUAttribMask mask;
+
+ /* GL_ENABLE_BIT */
+ unsigned int is_blend : 1;
+ unsigned int is_cull_face : 1;
+ unsigned int is_depth_test : 1;
+ unsigned int is_dither : 1;
+ unsigned int is_lighting : 1;
+ unsigned int is_line_smooth : 1;
+ unsigned int is_color_logic_op : 1;
+ unsigned int is_multisample : 1;
+ unsigned int is_polygon_offset_line : 1;
+ unsigned int is_polygon_offset_fill : 1;
+ unsigned int is_polygon_smooth : 1;
+ unsigned int is_sample_alpha_to_coverage : 1;
+ unsigned int is_scissor_test : 1;
+ unsigned int is_stencil_test : 1;
+
+ bool is_clip_plane[6];
+
+ /* GL_DEPTH_BUFFER_BIT */
+ /* unsigned int is_depth_test : 1; */
+ int depth_func;
+ double depth_clear_value;
+ bool depth_write_mask;
+
+ /* GL_SCISSOR_BIT */
+ int scissor_box[4];
+ /* unsigned int is_scissor_test : 1; */
+
+ /* GL_VIEWPORT_BIT */
+ int viewport[4];
+ double near_far[2];
+} GPUAttribValues;
+
+typedef struct {
+ GPUAttribValues attrib_stack[STATE_STACK_DEPTH];
+ unsigned int top;
+} GPUAttribStack;
+
+static GPUAttribStack state = {
+ .top = 0
+};
+
+#define AttribStack state
+#define Attrib state.attrib_stack[state.top]
+
+/**
+ * Replacement for glPush/PopAttributes
+ *
+ * We don't need to cover all the options of legacy OpenGL
+ * but simply the ones used by Blender.
+ */
+void gpuPushAttrib(eGPUAttribMask mask)
+{
+ Attrib.mask = mask;
+
+ if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) {
+ Attrib.is_depth_test = glIsEnabled(GL_DEPTH_TEST);
+ glGetIntegerv(GL_DEPTH_FUNC, &Attrib.depth_func);
+ glGetDoublev(GL_DEPTH_CLEAR_VALUE, &Attrib.depth_clear_value);
+ glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attrib.depth_write_mask);
+ }
+
+ if ((mask & GPU_ENABLE_BIT) != 0) {
+ Attrib.is_blend = glIsEnabled(GL_BLEND);
+
+ for (int i = 0; i < 6; i++) {
+ Attrib.is_clip_plane[i] = glIsEnabled(GL_CLIP_PLANE0 + i);
+ }
+
+ Attrib.is_cull_face = glIsEnabled(GL_CULL_FACE);
+ Attrib.is_depth_test = glIsEnabled(GL_DEPTH_TEST);
+ Attrib.is_dither = glIsEnabled(GL_DITHER);
+ Attrib.is_line_smooth = glIsEnabled(GL_LINE_SMOOTH);
+ Attrib.is_color_logic_op = glIsEnabled(GL_COLOR_LOGIC_OP);
+ Attrib.is_multisample = glIsEnabled(GL_MULTISAMPLE);
+ Attrib.is_polygon_offset_line = glIsEnabled(GL_POLYGON_OFFSET_LINE);
+ Attrib.is_polygon_offset_fill = glIsEnabled(GL_POLYGON_OFFSET_FILL);
+ Attrib.is_polygon_smooth = glIsEnabled(GL_POLYGON_SMOOTH);
+ Attrib.is_sample_alpha_to_coverage = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE);
+ Attrib.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
+ Attrib.is_stencil_test = glIsEnabled(GL_STENCIL_TEST);
+ }
+
+ if ((mask & GPU_SCISSOR_BIT) != 0) {
+ Attrib.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
+ glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attrib.scissor_box);
+ }
+
+ if ((mask & GPU_VIEWPORT_BIT) != 0) {
+ glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attrib.near_far);
+ glGetIntegerv(GL_VIEWPORT, (GLint *)&Attrib.viewport);
+ }
+
+ if ((mask & GPU_BLEND_BIT) != 0) {
+ Attrib.is_blend = glIsEnabled(GL_BLEND);
+ }
+
+ BLI_assert(AttribStack.top < STATE_STACK_DEPTH);
+ AttribStack.top++;
+}
+
+static void restore_mask(GLenum cap, const bool value) {
+ if (value) {
+ glEnable(cap);
+ }
+ else {
+ glDisable(cap);
+ }
+}
+
+void gpuPopAttrib(void)
+{
+ BLI_assert(AttribStack.top > 0);
+ AttribStack.top--;
+
+ GLint mask = Attrib.mask;
+
+ if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) {
+ restore_mask(GL_DEPTH_TEST, Attrib.is_depth_test);
+ glDepthFunc(Attrib.depth_func);
+ glClearDepth(Attrib.depth_clear_value);
+ glDepthMask(Attrib.depth_write_mask);
+ }
+
+ if ((mask & GPU_ENABLE_BIT) != 0) {
+ restore_mask(GL_BLEND, Attrib.is_blend);
+
+ for (int i = 0; i < 6; i++) {
+ restore_mask(GL_CLIP_PLANE0 + i, Attrib.is_clip_plane[i]);
+ }
+
+ restore_mask(GL_CULL_FACE, Attrib.is_cull_face);
+ restore_mask(GL_DEPTH_TEST, Attrib.is_depth_test);
+ restore_mask(GL_DITHER, Attrib.is_dither);
+ restore_mask(GL_LINE_SMOOTH, Attrib.is_line_smooth);
+ restore_mask(GL_COLOR_LOGIC_OP, Attrib.is_color_logic_op);
+ restore_mask(GL_MULTISAMPLE, Attrib.is_multisample);
+ restore_mask(GL_POLYGON_OFFSET_LINE, Attrib.is_polygon_offset_line);
+ restore_mask(GL_POLYGON_OFFSET_FILL, Attrib.is_polygon_offset_fill);
+ restore_mask(GL_POLYGON_SMOOTH, Attrib.is_polygon_smooth);
+ restore_mask(GL_SAMPLE_ALPHA_TO_COVERAGE, Attrib.is_sample_alpha_to_coverage);
+ restore_mask(GL_SCISSOR_TEST, Attrib.is_scissor_test);
+ restore_mask(GL_STENCIL_TEST, Attrib.is_stencil_test);
+ }
+
+ if ((mask & GPU_VIEWPORT_BIT) != 0) {
+ glViewport(Attrib.viewport[0], Attrib.viewport[1], Attrib.viewport[2], Attrib.viewport[3]);
+ glDepthRange(Attrib.near_far[0], Attrib.near_far[1]);
+ }
+
+ if ((mask & GPU_SCISSOR_BIT) != 0) {
+ restore_mask(GL_SCISSOR_TEST, Attrib.is_scissor_test);
+ glScissor(Attrib.scissor_box[0], Attrib.scissor_box[1], Attrib.scissor_box[2], Attrib.scissor_box[3]);
+ }
+
+ if ((mask & GPU_BLEND_BIT) != 0) {
+ restore_mask(GL_BLEND, Attrib.is_blend);
+ }
+}
+
+#undef Attrib
+#undef AttribStack
+
/** \} */
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index e0ce87d0e68..6bf330179d3 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -56,14 +56,11 @@
/* Extensions support */
/* -- extension: version of GL that absorbs it
+ * EXT_gpu_shader4: 3.0
* ARB_framebuffer object: 3.0
- * EXT_framebuffer_object: 3.0
- * EXT_framebuffer_blit: 3.0
- * EXT_framebuffer_multisample: 3.0
* EXT_framebuffer_multisample_blit_scaled: ???
* ARB_draw_instanced: 3.1
* ARB_texture_multisample: 3.2
- * EXT_geometry_shader4: 3.2
* ARB_texture_query_lod: 4.0
*/
@@ -71,7 +68,8 @@ static struct GPUGlobal {
GLint maxtexsize;
GLint maxcubemapsize;
GLint maxtextures;
- bool extdisabled;
+ GLint maxubosize;
+ GLint maxubobinds;
int colordepth;
int samples_color_texture_max;
GPUDeviceType device;
@@ -93,11 +91,6 @@ bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
/* GPU Extensions */
-void GPU_extensions_disable(void)
-{
- GG.extdisabled = true;
-}
-
int GPU_max_texture_size(void)
{
return GG.maxtexsize;
@@ -123,6 +116,16 @@ int GPU_max_cube_map_size(void)
return GG.maxcubemapsize;
}
+int GPU_max_ubo_binds(void)
+{
+ return GG.maxubobinds;
+}
+
+int GPU_max_ubo_size(void)
+{
+ return GG.maxubosize;
+}
+
void GPU_get_dfdy_factors(float fac[2])
{
copy_v2_v2(fac, GG.dfdyfactors);
@@ -130,8 +133,11 @@ void GPU_get_dfdy_factors(float fac[2])
void gpu_extensions_init(void)
{
- /* BLI_assert(GLEW_VERSION_2_1); */
- /* ^-- maybe a bit extreme? */
+ /* during 2.8 development each platform has its own OpenGL minimum requirements
+ * final 2.8 release will be unified on OpenGL 3.3 core profile, no required extensions
+ * see developer.blender.org/T49012 for details
+ */
+ BLI_assert(GLEW_VERSION_3_3);
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GG.maxtextures);
@@ -143,11 +149,22 @@ void gpu_extensions_init(void)
else
GG.max_anisotropy = 1.0f;
+ glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &GG.maxubobinds);
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GG.maxubosize);
+
+#ifndef NDEBUG
+ GLint ret;
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &ret);
+ /* We expect FRONT_LEFT to be the default buffer. */
+ BLI_assert(ret == GL_FRAMEBUFFER_DEFAULT);
+#endif
+
GLint r, g, b;
- glGetIntegerv(GL_RED_BITS, &r);
- glGetIntegerv(GL_GREEN_BITS, &g);
- glGetIntegerv(GL_BLUE_BITS, &b);
- GG.colordepth = r + g + b; /* assumes same depth for RGB */
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &r);
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, &g);
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, &b);
+ GG.colordepth = r + g + b; /* Assumes same depth for RGB. */
if (GLEW_VERSION_3_2 || GLEW_ARB_texture_multisample) {
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &GG.samples_color_texture_max);
@@ -201,10 +218,6 @@ void gpu_extensions_init(void)
GG.driver = GPU_DRIVER_ANY;
}
- /* make sure double side isn't used by default and only getting enabled in places where it's
- * really needed to prevent different unexpected behaviors like with intel gme965 card (sergey) */
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-
#ifdef _WIN32
GG.os = GPU_OS_WIN;
#elif defined(__APPLE__)
@@ -246,43 +259,6 @@ void gpu_extensions_exit(void)
GPU_invalid_tex_free();
}
-bool GPU_legacy_support(void)
-{
- /* return whether or not current GL context is compatible with legacy OpenGL */
- static bool checked = false;
- static bool support = true;
-
- if (!checked) {
- if (GLEW_VERSION_3_2) {
- GLint profile;
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
-
- if (G.debug & G_DEBUG_GPU) {
- printf("GL_CONTEXT_PROFILE_MASK = %#x (%s profile)\n", (unsigned int)profile,
- (profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) ? "compatibility" :
- (profile & GL_CONTEXT_CORE_PROFILE_BIT) ? "core" : "unknown");
- }
-
- if (profile == 0) {
- /* workaround for nVidia's Linux driver */
- support = GLEW_ARB_compatibility;
- }
- else {
- support = profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
- }
- }
- else if (GLEW_VERSION_3_1) {
- support = GLEW_ARB_compatibility;
- }
-
- /* any OpenGL version <= 3.0 is legacy, so support remains true */
-
- checked = true;
- }
-
- return support;
-}
-
bool GPU_full_non_power_of_two_support(void)
{
/* always supported on full GL but still relevant for OpenGL ES 2.0 where
@@ -290,39 +266,11 @@ bool GPU_full_non_power_of_two_support(void)
return true;
}
-bool GPU_display_list_support(void)
-{
- /* deprecated in GL 3
- * supported on older GL and compatibility profile
- * still queried by game engine
- */
- return true;
-}
-
bool GPU_bicubic_bump_support(void)
{
return GLEW_VERSION_4_0 || (GLEW_ARB_texture_query_lod && GLEW_VERSION_3_0);
}
-bool GPU_geometry_shader_support(void)
-{
- /* in GL 3.2 geometry shaders are fully supported
- * core profile clashes with our other shaders so accept compatibility only
- * other GL versions can use EXT_geometry_shader4 if available
- */
- return (GLEW_VERSION_3_2 && GPU_legacy_support()) || GLEW_EXT_geometry_shader4;
-}
-
-bool GPU_geometry_shader_support_via_extension(void)
-{
- return GLEW_EXT_geometry_shader4 && !(GLEW_VERSION_3_2 && GPU_legacy_support());
-}
-
-bool GPU_instanced_drawing_support(void)
-{
- return GLEW_VERSION_3_1 || GLEW_ARB_draw_instanced;
-}
-
int GPU_color_depth(void)
{
return GG.colordepth;
@@ -330,12 +278,14 @@ int GPU_color_depth(void)
bool GPU_mem_stats_supported(void)
{
- return (GLEW_NVX_gpu_memory_info || (GLEW_ATI_meminfo)) && (G.debug & G_DEBUG_GPU_MEM);
+ return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo) && (G.debug & G_DEBUG_GPU_MEM);
}
void GPU_mem_stats_get(int *totalmem, int *freemem)
{
+ /* TODO(merwin): use Apple's platform API to get this info */
+
if (GLEW_NVX_gpu_memory_info) {
/* returned value in Kb */
glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index e7a8beae5cc..dd23eaceaff 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -32,9 +32,10 @@
#include "BKE_global.h"
-#include "GPU_debug.h"
-#include "GPU_glew.h"
+#include "GPU_batch.h"
+#include "GPU_draw.h"
#include "GPU_framebuffer.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -54,44 +55,37 @@ struct GPUFrameBuffer {
static void gpu_print_framebuffer_error(GLenum status, char err_out[256])
{
+ const char *format = "GPUFrameBuffer: framebuffer status %s\n";
const char *err = "unknown";
+#define format_status(X) \
+ case GL_FRAMEBUFFER_##X: err = "GL_FRAMEBUFFER_"#X; \
+ break;
+
switch (status) {
- case GL_FRAMEBUFFER_COMPLETE_EXT:
- break;
- case GL_INVALID_OPERATION:
- err = "Invalid operation";
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
- err = "Incomplete attachment";
- break;
- case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
- err = "Unsupported framebuffer format";
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
- err = "Missing attachment";
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
- err = "Attached images must have same dimensions";
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
- err = "Attached images must have same format";
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
- err = "Missing draw buffer";
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
- err = "Missing read buffer";
- break;
+ /* success */
+ format_status(COMPLETE)
+ /* errors shared by OpenGL desktop & ES */
+ format_status(INCOMPLETE_ATTACHMENT)
+ format_status(INCOMPLETE_MISSING_ATTACHMENT)
+ format_status(UNSUPPORTED)
+#if 0 /* for OpenGL ES only */
+ format_status(INCOMPLETE_DIMENSIONS)
+#else /* for desktop GL only */
+ format_status(INCOMPLETE_DRAW_BUFFER)
+ format_status(INCOMPLETE_READ_BUFFER)
+ format_status(INCOMPLETE_MULTISAMPLE)
+ format_status(UNDEFINED)
+#endif
}
+#undef format_status
+
if (err_out) {
- BLI_snprintf(err_out, 256, "GPUFrameBuffer: framebuffer incomplete error %d '%s'",
- (int)status, err);
+ BLI_snprintf(err_out, 256, format, err);
}
else {
- fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d '%s'\n",
- (int)status, err);
+ fprintf(stderr, format, err);
}
}
@@ -101,41 +95,33 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
{
GPUFrameBuffer *fb;
- if (!(GLEW_VERSION_3_0 || GLEW_ARB_framebuffer_object ||
- (GLEW_EXT_framebuffer_object && GLEW_EXT_framebuffer_blit)))
- {
- return NULL;
- }
-
fb = MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
- glGenFramebuffersEXT(1, &fb->object);
+ glGenFramebuffers(1, &fb->object);
if (!fb->object) {
- fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
- (int)glGetError());
+ fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed.\n");
GPU_framebuffer_free(fb);
return NULL;
}
/* make sure no read buffer is enabled, so completeness check will not fail. We set those at binding time */
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
glReadBuffer(GL_NONE);
glDrawBuffer(GL_NONE);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
return fb;
}
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
+bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
{
GLenum attachment;
- GLenum error;
if (slot >= GPU_FB_MAX_SLOTS) {
fprintf(stderr,
"Attaching to index %d framebuffer slot unsupported. "
"Use at most %d\n", slot, GPU_FB_MAX_SLOTS);
- return 0;
+ return false;
}
if ((G.debug & G_DEBUG)) {
@@ -146,27 +132,26 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
}
}
- if (GPU_texture_depth(tex))
- attachment = GL_DEPTH_ATTACHMENT_EXT;
- else
- attachment = GL_COLOR_ATTACHMENT0_EXT + slot;
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
- /* Clean glError buffer. */
- while (glGetError() != GL_NO_ERROR) {}
-
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
- GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
-
- error = glGetError();
+ if (GPU_texture_stencil(tex) && GPU_texture_depth(tex))
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ else if (GPU_texture_depth(tex))
+ attachment = GL_DEPTH_ATTACHMENT;
+ else
+ attachment = GL_COLOR_ATTACHMENT0 + slot;
- if (error == GL_INVALID_OPERATION) {
- GPU_framebuffer_restore();
- gpu_print_framebuffer_error(error, err_out);
- return 0;
- }
+#if defined(WITH_GL_PROFILE_COMPAT)
+ /* Workaround for Mac & Mesa compatibility profile, remove after we switch to core profile */
+ /* glFramebufferTexture was introduced in 3.2. It is *not* available in the ARB FBO extension */
+ if (GLEW_VERSION_3_2)
+ glFramebufferTexture(GL_FRAMEBUFFER, attachment, GPU_texture_opengl_bindcode(tex), mip); /* normal core call, same as below */
+ else
+ glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), mip);
+#else
+ glFramebufferTexture(GL_FRAMEBUFFER, attachment, GPU_texture_opengl_bindcode(tex), mip);
+#endif
if (GPU_texture_depth(tex))
fb->depthtex = tex;
@@ -175,7 +160,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
GPU_texture_framebuffer_set(tex, fb, slot);
- return 1;
+ return true;
}
void GPU_framebuffer_texture_detach(GPUTexture *tex)
@@ -188,21 +173,34 @@ void GPU_framebuffer_texture_detach(GPUTexture *tex)
return;
if (GG.currentfb != fb->object) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
}
- if (GPU_texture_depth(tex)) {
+ if (GPU_texture_stencil(tex) && GPU_texture_depth(tex)) {
+ fb->depthtex = NULL;
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ }
+ else if (GPU_texture_depth(tex)) {
fb->depthtex = NULL;
- attachment = GL_DEPTH_ATTACHMENT_EXT;
+ attachment = GL_DEPTH_ATTACHMENT;
}
else {
BLI_assert(fb->colortex[fb_attachment] == tex);
fb->colortex[fb_attachment] = NULL;
- attachment = GL_COLOR_ATTACHMENT0_EXT + fb_attachment;
+ attachment = GL_COLOR_ATTACHMENT0 + fb_attachment;
}
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, GPU_texture_target(tex), 0, 0);
+#if defined(WITH_GL_PROFILE_COMPAT)
+ /* Workaround for Mac & Mesa compatibility profile, remove after we switch to core profile */
+ /* glFramebufferTexture was introduced in 3.2. It is *not* available in the ARB FBO extension */
+ if (GLEW_VERSION_3_2)
+ glFramebufferTexture(GL_FRAMEBUFFER, attachment, 0, 0); /* normal core call, same as below */
+ else
+ glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GPU_texture_target(tex), 0, 0);
+#else
+ glFramebufferTexture(GL_FRAMEBUFFER, attachment, 0, 0);
+#endif
GPU_texture_framebuffer_set(tex, NULL, -1);
}
@@ -218,11 +216,11 @@ void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
}
/* push attributes */
- glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
+ gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT);
glDisable(GL_SCISSOR_TEST);
/* bind framebuffer */
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
if (GPU_texture_depth(tex)) {
glDrawBuffer(GL_NONE);
@@ -230,22 +228,17 @@ void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
}
else {
/* last bound prevails here, better allow explicit control here too */
- glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + fb_attachment);
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + fb_attachment);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0 + fb_attachment);
+ glReadBuffer(GL_COLOR_ATTACHMENT0 + fb_attachment);
}
if (GPU_texture_target(tex) == GL_TEXTURE_2D_MULTISAMPLE) {
glEnable(GL_MULTISAMPLE);
}
- /* push matrices and set default viewport and matrix */
+ /* set default viewport */
glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
GG.currentfb = fb->object;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
}
void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
@@ -260,56 +253,80 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
for (i = 0; i < 4; i++) {
if (fb->colortex[i]) {
- attachments[numslots] = GL_COLOR_ATTACHMENT0_EXT + i;
+ attachments[numslots] = GL_COLOR_ATTACHMENT0 + i;
numslots++;
}
}
/* push attributes */
- glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
+ gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT);
glDisable(GL_SCISSOR_TEST);
/* bind framebuffer */
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
/* last bound prevails here, better allow explicit control here too */
glDrawBuffers(numslots, attachments);
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
+ glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
- /* push matrices and set default viewport and matrix */
+ /* set default viewport */
glViewport(0, 0, GPU_texture_width(fb->colortex[slot]), GPU_texture_height(fb->colortex[slot]));
GG.currentfb = fb->object;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
}
+void GPU_framebuffer_bind(GPUFrameBuffer *fb)
+{
+ int numslots = 0, i;
+ GLenum attachments[4];
+ GLenum readattachement = 0;
+ GPUTexture *tex;
+
+ for (i = 0; i < 4; i++) {
+ if (fb->colortex[i]) {
+ attachments[numslots] = GL_COLOR_ATTACHMENT0 + i;
+ tex = fb->colortex[i];
+
+ if (!readattachement)
+ readattachement = GL_COLOR_ATTACHMENT0 + i;
+
+ numslots++;
+ }
+ }
+
+ /* bind framebuffer */
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
+
+ if (numslots == 0) {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ tex = fb->depthtex;
+ }
+ else {
+ /* last bound prevails here, better allow explicit control here too */
+ glDrawBuffers(numslots, attachments);
+ glReadBuffer(readattachement);
+ }
+
+ glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
+ GG.currentfb = fb->object;
+}
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
{
- /* restore matrix */
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- /* restore attributes */
- glPopAttrib();
+ /* Restore attributes. */
+ gpuPopAttrib();
}
void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
{
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
/* last bound prevails here, better allow explicit control here too */
- glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0 + slot);
+ glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
/* push matrices and set default viewport and matrix */
glViewport(0, 0, GPU_texture_width(fb->colortex[slot]), GPU_texture_height(fb->colortex[slot]));
GG.currentfb = fb->object;
- GG.currentfb = fb->object;
}
bool GPU_framebuffer_bound(GPUFrameBuffer *fb)
@@ -319,22 +336,17 @@ bool GPU_framebuffer_bound(GPUFrameBuffer *fb)
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
{
- GLenum status;
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
-
- /* Clean glError buffer. */
- while (glGetError() != GL_NO_ERROR) {}
-
- status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
GPU_framebuffer_restore();
gpu_print_framebuffer_error(status, err_out);
return false;
}
-
+
return true;
}
@@ -351,10 +363,10 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb)
}
if (fb->object) {
- glDeleteFramebuffersEXT(1, &fb->object);
+ glDeleteFramebuffers(1, &fb->object);
if (GG.currentfb == fb->object) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
GG.currentfb = 0;
}
}
@@ -365,7 +377,7 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb)
void GPU_framebuffer_restore(void)
{
if (GG.currentfb != 0) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
GG.currentfb = 0;
}
}
@@ -374,73 +386,113 @@ void GPU_framebuffer_blur(
GPUFrameBuffer *fb, GPUTexture *tex,
GPUFrameBuffer *blurfb, GPUTexture *blurtex)
{
+ const float fullscreencos[4][2] = {{-1.0f, -1.0f}, {1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}};
+ const float fullscreenuvs[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}};
+
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static Batch batch = {{0}};
+
const float scaleh[2] = {1.0f / GPU_texture_width(blurtex), 0.0f};
const float scalev[2] = {0.0f, 1.0f / GPU_texture_height(tex)};
GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
- int scale_uniform, texture_source_uniform;
if (!blur_shader)
return;
- scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU");
- texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource");
+ /* Preparing to draw quad */
+ if (format.attrib_ct == 0) {
+ unsigned int i = 0;
+ /* Vertex format */
+ unsigned int pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int uvs = VertexFormat_add_attrib(&format, "uvs", COMP_F32, 2, KEEP_FLOAT);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 36);
+
+ for (int j = 0; j < 3; ++j) {
+ VertexBuffer_set_attrib(&vbo, uvs, i, fullscreenuvs[j]);
+ VertexBuffer_set_attrib(&vbo, pos, i++, fullscreencos[j]);
+ }
+ for (int j = 1; j < 4; ++j) {
+ VertexBuffer_set_attrib(&vbo, uvs, i, fullscreenuvs[j]);
+ VertexBuffer_set_attrib(&vbo, pos, i++, fullscreencos[j]);
+ }
+
+ Batch_init(&batch, GL_TRIANGLES, &vbo, NULL);
+ }
+ glDisable(GL_DEPTH_TEST);
+
/* Blurring horizontally */
-
/* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid
* pushing unnecessary matrices onto the OpenGL stack. */
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object);
- glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glBindFramebuffer(GL_FRAMEBUFFER, blurfb->object);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
/* avoid warnings from texture binding */
GG.currentfb = blurfb->object;
- GPU_shader_bind(blur_shader);
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh);
- GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
glViewport(0, 0, GPU_texture_width(blurtex), GPU_texture_height(blurtex));
- /* Preparing to draw quad */
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glDisable(GL_DEPTH_TEST);
-
GPU_texture_bind(tex, 0);
- /* Drawing quad */
- glBegin(GL_QUADS);
- glTexCoord2d(0, 0); glVertex2f(1, 1);
- glTexCoord2d(1, 0); glVertex2f(-1, 1);
- glTexCoord2d(1, 1); glVertex2f(-1, -1);
- glTexCoord2d(0, 1); glVertex2f(1, -1);
- glEnd();
+ Batch_set_builtin_program(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
+ Batch_Uniform2f(&batch, "ScaleU", scaleh[0], scaleh[1]);
+ Batch_Uniform1i(&batch, "textureSource", GL_TEXTURE0);
+ Batch_draw(&batch);
/* Blurring vertically */
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
- glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
GG.currentfb = fb->object;
glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev);
- GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
+
GPU_texture_bind(blurtex, 0);
- glBegin(GL_QUADS);
- glTexCoord2d(0, 0); glVertex2f(1, 1);
- glTexCoord2d(1, 0); glVertex2f(-1, 1);
- glTexCoord2d(1, 1); glVertex2f(-1, -1);
- glTexCoord2d(0, 1); glVertex2f(1, -1);
- glEnd();
+ /* Hack to make the following uniform stick */
+ Batch_set_builtin_program(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
+ Batch_Uniform2f(&batch, "ScaleU", scalev[0], scalev[1]);
+ Batch_Uniform1i(&batch, "textureSource", GL_TEXTURE0);
+ Batch_draw(&batch);
+}
- GPU_shader_unbind();
+void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, int read_slot, GPUFrameBuffer *fb_write, int write_slot, bool use_depth)
+{
+ GPUTexture *read_tex = (use_depth) ? fb_read->depthtex : fb_read->colortex[read_slot];
+ GPUTexture *write_tex = (use_depth) ? fb_write->depthtex : fb_write->colortex[write_slot];
+ int read_attach = (use_depth) ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + GPU_texture_framebuffer_attachment(read_tex);
+ int write_attach = (use_depth) ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + GPU_texture_framebuffer_attachment(write_tex);
+ int read_bind = GPU_texture_opengl_bindcode(read_tex);
+ int write_bind = GPU_texture_opengl_bindcode(write_tex);
+ const int read_w = GPU_texture_width(read_tex);
+ const int read_h = GPU_texture_height(read_tex);
+ const int write_w = GPU_texture_width(write_tex);
+ const int write_h = GPU_texture_height(write_tex);
+
+ /* read from multi-sample buffer */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb_read->object);
+ glFramebufferTexture2D(
+ GL_READ_FRAMEBUFFER, read_attach,
+ GL_TEXTURE_2D, read_bind, 0);
+ BLI_assert(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+ /* write into new single-sample buffer */
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_write->object);
+ glFramebufferTexture2D(
+ GL_DRAW_FRAMEBUFFER, write_attach,
+ GL_TEXTURE_2D, write_bind, 0);
+ BLI_assert(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+ glBlitFramebuffer(0, 0, read_w, read_h, 0, 0, write_w, write_h, (use_depth) ? GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ /* Restore previous framebuffer */
+ glBindFramebuffer(GL_FRAMEBUFFER, GG.currentfb);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
/* GPUOffScreen */
@@ -464,12 +516,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, char err_
}
if (samples) {
- if (!GLEW_EXT_framebuffer_multisample ||
- !GLEW_ARB_texture_multisample ||
- /* Only needed for GPU_offscreen_read_pixels.
- * We could add an arg if we intend to use multi-sample
- * offscreen buffers w/o reading their pixels */
- !GLEW_EXT_framebuffer_blit ||
+ if (!GLEW_ARB_texture_multisample ||
/* This is required when blitting from a multi-sampled buffers,
* even though we're not scaling. */
!GLEW_EXT_framebuffer_multisample_blit_scaled)
@@ -484,18 +531,18 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, char err_
return NULL;
}
- if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) {
+ if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) {
GPU_offscreen_free(ofs);
return NULL;
}
- ofs->color = GPU_texture_create_2D_multisample(width, height, NULL, GPU_HDR_NONE, samples, err_out);
+ ofs->color = GPU_texture_create_2D_multisample(width, height, NULL, samples, err_out);
if (!ofs->color) {
GPU_offscreen_free(ofs);
return NULL;
}
- if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) {
+ if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, 0)) {
GPU_offscreen_free(ofs);
return NULL;
}
@@ -569,37 +616,37 @@ void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
#ifdef USE_FBO_CTX_SWITCH
/* read from multi-sample buffer */
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, ofs->color->fb->object);
- glFramebufferTexture2DEXT(
- GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + ofs->color->fb_attachment,
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs->color->fb->object);
+ glFramebufferTexture2D(
+ GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + ofs->color->fb_attachment,
GL_TEXTURE_2D_MULTISAMPLE, ofs->color->bindcode, 0);
- status = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
goto finally;
}
#endif
/* write into new single-sample buffer */
- glGenFramebuffersEXT(1, &fbo_blit);
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo_blit);
- glFramebufferTexture2DEXT(
- GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ glGenFramebuffers(1, &fbo_blit);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_blit);
+ glFramebufferTexture2D(
+ GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, tex_blit, 0);
- status = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
goto finally;
}
/* perform the copy */
- glBlitFramebufferEXT(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
/* read the results */
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fbo_blit);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_blit);
glReadPixels(0, 0, w, h, GL_RGBA, type, pixels);
#ifdef USE_FBO_CTX_SWITCH
/* restore the original frame-bufer */
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ofs->color->fb->object);
+ glBindFramebuffer(GL_FRAMEBUFFER, ofs->color->fb->object);
#undef USE_FBO_CTX_SWITCH
#endif
@@ -610,10 +657,8 @@ finally:
glDeleteTextures(1, &tex_blit);
}
if (fbo_blit) {
- glDeleteFramebuffersEXT(1, &fbo_blit);
+ glDeleteFramebuffers(1, &fbo_blit);
}
-
- GPU_ASSERT_NO_GL_ERRORS("Read Multi-Sample Pixels");
}
else {
glReadPixels(0, 0, w, h, GL_RGBA, type, pixels);
@@ -635,3 +680,12 @@ int GPU_offscreen_color_texture(const GPUOffScreen *ofs)
return GPU_texture_opengl_bindcode(ofs->color);
}
+/* only to be used by viewport code! */
+void GPU_offscreen_viewport_data_get(
+ GPUOffScreen *ofs,
+ GPUFrameBuffer **r_fb, GPUTexture **r_color, GPUTexture **r_depth)
+{
+ *r_fb = ofs->fb;
+ *r_color = ofs->color;
+ *r_depth = ofs->depth;
+}
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c
new file mode 100644
index 00000000000..5f22b7f9279
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_immediate.c
@@ -0,0 +1,88 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "UI_resources.h"
+#include "BLI_utildefines.h"
+
+#include "gpu_shader_private.h"
+
+void immBindBuiltinProgram(GPUBuiltinShader shader_id)
+{
+ GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
+ immBindProgram(shader->program, shader->interface);
+}
+
+void immUniformThemeColor(int color_id)
+{
+ float color[4];
+ UI_GetThemeColor4fv(color_id, color);
+ immUniformColor4fv(color);
+}
+
+void immUniformThemeColor3(int color_id)
+{
+ float color[3];
+ UI_GetThemeColor3fv(color_id, color);
+ immUniformColor3fv(color);
+}
+
+void immUniformThemeColorShade(int color_id, int offset)
+{
+ float color[4];
+ UI_GetThemeColorShade4fv(color_id, offset, color);
+ immUniformColor4fv(color);
+}
+
+void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset)
+{
+ float color[4];
+ UI_GetThemeColorShadeAlpha4fv(color_id, color_offset, alpha_offset, color);
+ immUniformColor4fv(color);
+}
+
+void immUniformThemeColorBlendShade(int color_id1, int color_id2, float fac, int offset)
+{
+ float color[4];
+ UI_GetThemeColorBlendShade4fv(color_id1, color_id2, fac, offset, color);
+ immUniformColor4fv(color);
+}
+
+void immUniformThemeColorBlend(int color_id1, int color_id2, float fac)
+{
+ uint8_t color[3];
+ UI_GetThemeColorBlend3ubv(color_id1, color_id2, fac, color);
+ immUniformColor3ubv(color);
+}
+
+void immThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
+{
+ unsigned char col[4];
+ UI_GetThemeColorShadeAlpha4ubv(colorid, coloffset, alphaoffset, col);
+ immUniformColor4ub(col[0], col[1], col[2], col[3]);
+}
diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c
new file mode 100644
index 00000000000..40da4cf091b
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_immediate_util.c
@@ -0,0 +1,344 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/gpu/intern/gpu_immediate_util.c
+ * \ingroup gpu
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
+/**
+ * Pack color into 3 bytes
+ *
+ * This define converts a numerical value to the equivalent 24-bit
+ * color, while not being endian-sensitive. On little-endians, this
+ * is the same as doing a 'naive' indexing, on big-endian, it is not!
+ *
+ * \note BGR format (i.e. 0xBBGGRR)...
+ *
+ * \param x color.
+ */
+void imm_cpack(unsigned int x)
+{
+ immUniformColor3ub(((x) & 0xFF),
+ (((x) >> 8) & 0xFF),
+ (((x) >> 16) & 0xFF));
+}
+
+static void imm_draw_circle(PrimitiveType prim_type, const uint shdr_pos, float x, float y, float rad, int nsegments)
+{
+ immBegin(prim_type, nsegments);
+ for (int i = 0; i < nsegments; ++i) {
+ const float angle = 2 * M_PI * ((float)i / (float)nsegments);
+ immVertex2f(shdr_pos, x + rad * cosf(angle), y + rad * sinf(angle));
+ }
+ immEnd();
+}
+
+/**
+ * Draw a circle outline with the given \a radius.
+ * The circle is centered at \a x, \a y and drawn in the XY plane.
+ *
+ * \param shdr_pos The vertex attribute number for position.
+ * \param x Horizontal center.
+ * \param y Vertical center.
+ * \param radius The circle's radius.
+ * \param nsegments The number of segments to use in drawing (more = smoother).
+ */
+void imm_draw_circle_wire(uint shdr_pos, float x, float y, float rad, int nsegments)
+{
+ imm_draw_circle(PRIM_LINE_LOOP, shdr_pos, x, y, rad, nsegments);
+}
+
+/**
+ * Draw a filled circle with the given \a radius.
+ * The circle is centered at \a x, \a y and drawn in the XY plane.
+ *
+ * \param shdr_pos The vertex attribute number for position.
+ * \param x Horizontal center.
+ * \param y Vertical center.
+ * \param radius The circle's radius.
+ * \param nsegments The number of segments to use in drawing (more = smoother).
+ */
+void imm_draw_circle_fill(uint shdr_pos, float x, float y, float rad, int nsegments)
+{
+ imm_draw_circle(PRIM_TRIANGLE_FAN, shdr_pos, x, y, rad, nsegments);
+}
+
+/**
+ * \note We could have `imm_draw_lined_disk_partial` but currently there is no need.
+ */
+static void imm_draw_disk_partial(
+ PrimitiveType prim_type, unsigned pos, float x, float y,
+ float rad_inner, float rad_outer, int nsegments, float start, float sweep)
+{
+ /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
+ const float angle_start = -(DEG2RADF(start)) + (M_PI / 2);
+ const float angle_end = -(DEG2RADF(sweep) - angle_start);
+ nsegments += 1;
+ immBegin(prim_type, nsegments * 2);
+ for (int i = 0; i < nsegments; ++i) {
+ const float angle = interpf(angle_start, angle_end, ((float)i / (float)(nsegments - 1)));
+ const float angle_sin = sinf(angle);
+ const float angle_cos = cosf(angle);
+ immVertex2f(pos, x + rad_inner * angle_cos, y + rad_inner * angle_sin);
+ immVertex2f(pos, x + rad_outer * angle_cos, y + rad_outer * angle_sin);
+ }
+ immEnd();
+}
+
+/**
+ * Draw a filled arc with the given inner and outer radius.
+ * The circle is centered at \a x, \a y and drawn in the XY plane.
+ *
+ * \note Arguments are `gluPartialDisk` compatible.
+ *
+ * \param pos: The vertex attribute number for position.
+ * \param x: Horizontal center.
+ * \param y: Vertical center.
+ * \param radius_inner: The inner circle's radius.
+ * \param radius_outer: The outer circle's radius (can be zero).
+ * \param nsegments: The number of segments to use in drawing (more = smoother).
+ * \param start: Specifies the starting angle, in degrees, of the disk portion.
+ * \param sweep: Specifies the sweep angle, in degrees, of the disk portion.
+ */
+void imm_draw_disk_partial_fill(
+ unsigned pos, float x, float y,
+ float rad_inner, float rad_outer, int nsegments, float start, float sweep)
+{
+ imm_draw_disk_partial(PRIM_TRIANGLE_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep);
+}
+
+static void imm_draw_circle_3D(
+ PrimitiveType prim_type, unsigned pos, float x, float y,
+ float rad, int nsegments)
+{
+ immBegin(prim_type, nsegments);
+ for (int i = 0; i < nsegments; ++i) {
+ float angle = 2 * M_PI * ((float)i / (float)nsegments);
+ immVertex3f(pos, x + rad * cosf(angle), y + rad * sinf(angle), 0.0f);
+ }
+ immEnd();
+}
+
+void imm_draw_circle_wire_3d(unsigned pos, float x, float y, float rad, int nsegments)
+{
+ imm_draw_circle_3D(PRIM_LINE_LOOP, pos, x, y, rad, nsegments);
+}
+
+void imm_draw_circle_fill_3d(unsigned pos, float x, float y, float rad, int nsegments)
+{
+ imm_draw_circle_3D(PRIM_TRIANGLE_FAN, pos, x, y, rad, nsegments);
+}
+
+/**
+* Draw a lined box.
+*
+* \param pos The vertex attribute number for position.
+* \param x1 left.
+* \param y1 bottom.
+* \param x2 right.
+* \param y2 top.
+*/
+void imm_draw_line_box(unsigned pos, float x1, float y1, float x2, float y2)
+{
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2, y1);
+ immEnd();
+}
+
+void imm_draw_line_box_3d(unsigned pos, float x1, float y1, float x2, float y2)
+{
+ /* use this version when VertexFormat has a vec3 position */
+ immBegin(PRIM_LINE_LOOP, 4);
+ immVertex3f(pos, x1, y1, 0.0f);
+ immVertex3f(pos, x1, y2, 0.0f);
+ immVertex3f(pos, x2, y2, 0.0f);
+ immVertex3f(pos, x2, y1, 0.0f);
+ immEnd();
+}
+
+/**
+ * Draw a standard checkerboard to indicate transparent backgrounds.
+ */
+void imm_draw_checker_box(float x1, float y1, float x2, float y2)
+{
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
+
+ immUniform4f("color1", 0.15f, 0.15f, 0.15f, 1.0f);
+ immUniform4f("color2", 0.2f, 0.2f, 0.2f, 1.0f);
+ immUniform1i("size", 8);
+
+ immRectf(pos, x1, y1, x2, y2);
+
+ immUnbindProgram();
+}
+
+/**
+* Draw a cylinder. Replacement for gluCylinder.
+* _warning_ : Slow, better use it only if you no other choices.
+*
+* \param pos The vertex attribute number for position.
+* \param nor The vertex attribute number for normal.
+* \param base Specifies the radius of the cylinder at z = 0.
+* \param top Specifies the radius of the cylinder at z = height.
+* \param height Specifies the height of the cylinder.
+* \param slices Specifies the number of subdivisions around the z axis.
+* \param stacks Specifies the number of subdivisions along the z axis.
+*/
+void imm_draw_cylinder_fill_normal_3d(
+ unsigned int pos, unsigned int nor, float base, float top, float height, int slices, int stacks)
+{
+ immBegin(PRIM_TRIANGLES, 6 * slices * stacks);
+ for (int i = 0; i < slices; ++i) {
+ const float angle1 = 2 * M_PI * ((float)i / (float)slices);
+ const float angle2 = 2 * M_PI * ((float)(i + 1) / (float)slices);
+ const float cos1 = cosf(angle1);
+ const float sin1 = sinf(angle1);
+ const float cos2 = cosf(angle2);
+ const float sin2 = sinf(angle2);
+
+ for (int j = 0; j < stacks; ++j) {
+ float fac1 = (float)j / (float)stacks;
+ float fac2 = (float)(j + 1) / (float)stacks;
+ float r1 = base * (1.f - fac1) + top * fac1;
+ float r2 = base * (1.f - fac2) + top * fac2;
+ float h1 = height * ((float)j / (float)stacks);
+ float h2 = height * ((float)(j + 1) / (float)stacks);
+
+ float v1[3] = {r1 *cos2, r1 * sin2, h1};
+ float v2[3] = {r2 *cos2, r2 * sin2, h2};
+ float v3[3] = {r2 *cos1, r2 * sin1, h2};
+ float v4[3] = {r1 *cos1, r1 * sin1, h1};
+ float n1[3], n2[3];
+
+ /* calc normals */
+ sub_v3_v3v3(n1, v2, v1);
+ normalize_v3(n1);
+ n1[0] = cos1; n1[1] = sin1; n1[2] = 1 - n1[2];
+
+ sub_v3_v3v3(n2, v3, v4);
+ normalize_v3(n2);
+ n2[0] = cos2; n2[1] = sin2; n2[2] = 1 - n2[2];
+
+ /* first tri */
+ immAttrib3fv(nor, n2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immAttrib3fv(nor, n1);
+ immVertex3fv(pos, v3);
+
+ /* second tri */
+ immVertex3fv(pos, v3);
+ immVertex3fv(pos, v4);
+ immAttrib3fv(nor, n2);
+ immVertex3fv(pos, v1);
+ }
+ }
+ immEnd();
+}
+
+void imm_draw_cylinder_wire_3d(unsigned int pos, float base, float top, float height, int slices, int stacks)
+{
+ immBegin(PRIM_LINES, 6 * slices * stacks);
+ for (int i = 0; i < slices; ++i) {
+ const float angle1 = 2 * M_PI * ((float)i / (float)slices);
+ const float angle2 = 2 * M_PI * ((float)(i + 1) / (float)slices);
+ const float cos1 = cosf(angle1);
+ const float sin1 = sinf(angle1);
+ const float cos2 = cosf(angle2);
+ const float sin2 = sinf(angle2);
+
+ for (int j = 0; j < stacks; ++j) {
+ float fac1 = (float)j / (float)stacks;
+ float fac2 = (float)(j + 1) / (float)stacks;
+ float r1 = base * (1.f - fac1) + top * fac1;
+ float r2 = base * (1.f - fac2) + top * fac2;
+ float h1 = height * ((float)j / (float)stacks);
+ float h2 = height * ((float)(j + 1) / (float)stacks);
+
+ float v1[3] = {r1 * cos2, r1 * sin2, h1};
+ float v2[3] = {r2 * cos2, r2 * sin2, h2};
+ float v3[3] = {r2 * cos1, r2 * sin1, h2};
+ float v4[3] = {r1 * cos1, r1 * sin1, h1};
+
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+
+ immVertex3fv(pos, v2);
+ immVertex3fv(pos, v3);
+
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v4);
+ }
+ }
+ immEnd();
+}
+
+void imm_draw_cylinder_fill_3d(unsigned int pos, float base, float top, float height, int slices, int stacks)
+{
+ immBegin(PRIM_TRIANGLES, 6 * slices * stacks);
+ for (int i = 0; i < slices; ++i) {
+ const float angle1 = 2 * M_PI * ((float)i / (float)slices);
+ const float angle2 = 2 * M_PI * ((float)(i + 1) / (float)slices);
+ const float cos1 = cosf(angle1);
+ const float sin1 = sinf(angle1);
+ const float cos2 = cosf(angle2);
+ const float sin2 = sinf(angle2);
+
+ for (int j = 0; j < stacks; ++j) {
+ float fac1 = (float)j / (float)stacks;
+ float fac2 = (float)(j + 1) / (float)stacks;
+ float r1 = base * (1.f - fac1) + top * fac1;
+ float r2 = base * (1.f - fac2) + top * fac2;
+ float h1 = height * ((float)j / (float)stacks);
+ float h2 = height * ((float)(j + 1) / (float)stacks);
+
+ float v1[3] = {r1 * cos2, r1 * sin2, h1};
+ float v2[3] = {r2 * cos2, r2 * sin2, h2};
+ float v3[3] = {r2 * cos1, r2 * sin1, h2};
+ float v4[3] = {r1 * cos1, r1 * sin1, h1};
+
+ /* first tri */
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immVertex3fv(pos, v3);
+
+ /* second tri */
+ immVertex3fv(pos, v3);
+ immVertex3fv(pos, v4);
+ immVertex3fv(pos, v1);
+ }
+ }
+ immEnd();
+}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index c72c83b6b07..7a6b1ff6c70 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -31,7 +31,8 @@
#include "BLI_sys_types.h"
#include "GPU_init_exit.h" /* interface */
-
+#include "GPU_immediate.h"
+#include "GPU_batch.h"
#include "BKE_global.h"
#include "intern/gpu_codegen.h"
@@ -59,14 +60,22 @@ void GPU_init(void)
if (G.debug & G_DEBUG_GPU)
gpu_debug_init();
+ gpu_batch_init();
+
+ immInit();
}
void GPU_exit(void)
{
+ immDestroy();
+
+ gpu_batch_exit();
+
if (G.debug & G_DEBUG_GPU)
gpu_debug_exit();
+
gpu_codegen_exit();
gpu_extensions_exit(); /* must come last */
diff --git a/source/blender/gpu/intern/gpu_lamp.c b/source/blender/gpu/intern/gpu_lamp.c
new file mode 100644
index 00000000000..86c40baf5cc
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_lamp.c
@@ -0,0 +1,486 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_lamp.c
+ * \ingroup gpu
+ *
+ * Manages Opengl lights.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_lamp_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_group.h"
+
+#include "GPU_framebuffer.h"
+#include "GPU_glew.h"
+#include "GPU_lamp.h"
+#include "GPU_material.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "gpu_lamp_private.h"
+
+bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
+{
+ if (srl && srl->light_override)
+ return BKE_group_object_exists(srl->light_override, lamp->ob);
+ else if (ma && ma->group)
+ return BKE_group_object_exists(ma->group, lamp->ob);
+ else
+ return true;
+}
+
+static void gpu_lamp_calc_winmat(GPULamp *lamp)
+{
+ float temp, angle, pixsize, wsize;
+
+ if (lamp->type == LA_SUN) {
+ wsize = lamp->la->shadow_frustum_size;
+ orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
+ }
+ else if (lamp->type == LA_SPOT) {
+ angle = saacos(lamp->spotsi);
+ temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
+ pixsize = lamp->d / temp;
+ wsize = pixsize * 0.5f * lamp->size;
+ /* compute shadows according to X and Y scaling factors */
+ perspective_m4(
+ lamp->winmat,
+ -wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
+ -wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
+ lamp->d, lamp->clipend);
+ }
+}
+
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
+{
+ float mat[4][4];
+ float obmat_scale[3];
+
+ lamp->lay = lay;
+ lamp->hide = hide;
+
+ normalize_m4_m4_ex(mat, obmat, obmat_scale);
+
+ copy_v3_v3(lamp->vec, mat[2]);
+ copy_v3_v3(lamp->co, mat[3]);
+ copy_m4_m4(lamp->obmat, mat);
+ invert_m4_m4(lamp->imat, mat);
+
+ if (lamp->type == LA_SPOT) {
+ /* update spotlamp scale on X and Y axis */
+ lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
+ lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
+ }
+
+ if (GPU_lamp_has_shadow_buffer(lamp)) {
+ /* makeshadowbuf */
+ gpu_lamp_calc_winmat(lamp);
+ }
+}
+
+void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
+{
+ lamp->energy = energy;
+ if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
+
+ lamp->col[0] = r;
+ lamp->col[1] = g;
+ lamp->col[2] = b;
+}
+
+void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
+ float coeff_const, float coeff_lin, float coeff_quad)
+{
+ lamp->dist = distance;
+ lamp->att1 = att1;
+ lamp->att2 = att2;
+ lamp->coeff_const = coeff_const;
+ lamp->coeff_lin = coeff_lin;
+ lamp->coeff_quad = coeff_quad;
+}
+
+void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
+{
+ lamp->spotsi = cosf(spotsize * 0.5f);
+ lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
+}
+
+static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
+{
+ lamp->scene = scene;
+ lamp->ob = ob;
+ lamp->par = par;
+ lamp->la = la;
+
+ /* add_render_lamp */
+ lamp->mode = la->mode;
+ lamp->type = la->type;
+
+ lamp->energy = la->energy;
+ if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
+
+ lamp->col[0] = la->r;
+ lamp->col[1] = la->g;
+ lamp->col[2] = la->b;
+
+ GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
+
+ lamp->spotsi = la->spotsize;
+ if (lamp->mode & LA_HALO)
+ if (lamp->spotsi > DEG2RADF(170.0f))
+ lamp->spotsi = DEG2RADF(170.0f);
+ lamp->spotsi = cosf(lamp->spotsi * 0.5f);
+ lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
+ lamp->k = la->k;
+
+ lamp->dist = la->dist;
+ lamp->falloff_type = la->falloff_type;
+ lamp->att1 = la->att1;
+ lamp->att2 = la->att2;
+ lamp->coeff_const = la->coeff_const;
+ lamp->coeff_lin = la->coeff_lin;
+ lamp->coeff_quad = la->coeff_quad;
+ lamp->curfalloff = la->curfalloff;
+
+ /* initshadowbuf */
+ lamp->bias = 0.02f * la->bias;
+ lamp->size = la->bufsize;
+ lamp->d = la->clipsta;
+ lamp->clipend = la->clipend;
+
+ /* arbitrary correction for the fact we do no soft transition */
+ lamp->bias *= 0.25f;
+}
+
+static void gpu_lamp_shadow_free(GPULamp *lamp)
+{
+ if (lamp->tex) {
+ GPU_texture_free(lamp->tex);
+ lamp->tex = NULL;
+ }
+ if (lamp->depthtex) {
+ GPU_texture_free(lamp->depthtex);
+ lamp->depthtex = NULL;
+ }
+ if (lamp->fb) {
+ GPU_framebuffer_free(lamp->fb);
+ lamp->fb = NULL;
+ }
+ if (lamp->blurtex) {
+ GPU_texture_free(lamp->blurtex);
+ lamp->blurtex = NULL;
+ }
+ if (lamp->blurfb) {
+ GPU_framebuffer_free(lamp->blurfb);
+ lamp->blurfb = NULL;
+ }
+}
+
+static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size)
+{
+ return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
+}
+
+LampEngineData *GPU_lamp_engine_data_get(Scene *scene, Object *ob, Object *par, struct RenderEngineType *re)
+{
+ GPULamp *lamp;
+ LinkData *link;
+
+ for (link = ob->gpulamp.first; link; link = link->next) {
+ lamp = (GPULamp *)link->data;
+
+ if ((lamp->par == par) && (lamp->scene == scene) && (lamp->re == re))
+ return &lamp->data;
+ }
+
+ lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
+
+ link = MEM_callocN(sizeof(LinkData), "GPULampLink");
+ link->data = lamp;
+ BLI_addtail(&ob->gpulamp, link);
+
+ lamp->scene = scene;
+ lamp->ob = ob;
+ lamp->par = par;
+ lamp->la = ob->data;
+ lamp->re = re;
+
+ return &lamp->data;
+}
+
+GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
+{
+ Lamp *la;
+ GPULamp *lamp;
+ LinkData *link;
+
+ for (link = ob->gpulamp.first; link; link = link->next) {
+ lamp = (GPULamp *)link->data;
+
+ if (lamp->par == par && lamp->scene == scene)
+ return link->data;
+ }
+
+ lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
+
+ link = MEM_callocN(sizeof(LinkData), "GPULampLink");
+ link->data = lamp;
+ BLI_addtail(&ob->gpulamp, link);
+
+ la = ob->data;
+ gpu_lamp_from_blender(scene, ob, par, la, lamp);
+
+ if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
+ (la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
+ {
+ /* opengl */
+ lamp->fb = GPU_framebuffer_create();
+ if (!lamp->fb) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
+ /* Shadow depth map */
+ lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
+ if (!lamp->depthtex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ /* Shadow color map */
+ lamp->tex = gpu_lamp_create_vsm_shadow_map(lamp->size);
+ if (!lamp->tex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ /* FBO and texture for blurring */
+ lamp->blurfb = GPU_framebuffer_create();
+ if (!lamp->blurfb) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ lamp->blurtex = gpu_lamp_create_vsm_shadow_map(lamp->size * 0.5);
+ if (!lamp->blurtex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ /* we need to properly bind to test for completeness */
+ GPU_texture_bind_as_framebuffer(lamp->blurtex);
+
+ if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
+ }
+ else {
+ lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
+ if (!lamp->tex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+ }
+
+ GPU_framebuffer_restore();
+
+ lamp->shadow_color[0] = la->shdwr;
+ lamp->shadow_color[1] = la->shdwg;
+ lamp->shadow_color[2] = la->shdwb;
+ }
+ else {
+ lamp->shadow_color[0] = 1.0;
+ lamp->shadow_color[1] = 1.0;
+ lamp->shadow_color[2] = 1.0;
+ }
+
+ return lamp;
+}
+
+void GPU_lamp_engine_data_free(LampEngineData *led)
+{
+ for (int i = 0; i < MAX_LAMP_DATA; ++i) {
+ if (led->storage[i]) {
+ MEM_freeN(led->storage[i]);
+ led->storage[i] = NULL;
+ }
+ }
+}
+
+void GPU_lamp_free(Object *ob)
+{
+ GPULamp *lamp;
+ LinkData *link;
+ LinkData *nlink;
+ Material *ma;
+
+ for (link = ob->gpulamp.first; link; link = link->next) {
+ lamp = link->data;
+
+ while (lamp->materials.first) {
+ nlink = lamp->materials.first;
+ ma = nlink->data;
+ BLI_freelinkN(&lamp->materials, nlink);
+
+ if (ma->gpumaterial.first)
+ GPU_material_free(&ma->gpumaterial);
+ }
+
+ gpu_lamp_shadow_free(lamp);
+ GPU_lamp_engine_data_free(&lamp->data);
+
+ MEM_freeN(lamp);
+ }
+
+ BLI_freelistN(&ob->gpulamp);
+}
+
+bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
+{
+ return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
+ !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
+ lamp->tex && lamp->fb);
+}
+
+void GPU_lamp_update_buffer_mats(GPULamp *lamp)
+{
+ float rangemat[4][4], persmat[4][4];
+
+ /* initshadowbuf */
+ invert_m4_m4(lamp->viewmat, lamp->obmat);
+ normalize_v3(lamp->viewmat[0]);
+ normalize_v3(lamp->viewmat[1]);
+ normalize_v3(lamp->viewmat[2]);
+
+ /* makeshadowbuf */
+ mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
+
+ /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
+ unit_m4(rangemat);
+ rangemat[0][0] = 0.5f;
+ rangemat[1][1] = 0.5f;
+ rangemat[2][2] = 0.5f;
+ rangemat[3][0] = 0.5f;
+ rangemat[3][1] = 0.5f;
+ rangemat[3][2] = 0.5f;
+
+ mul_m4_m4m4(lamp->persmat, rangemat, persmat);
+}
+
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
+{
+ GPU_lamp_update_buffer_mats(lamp);
+
+ /* opengl */
+ glDisable(GL_SCISSOR_TEST);
+ GPU_texture_bind_as_framebuffer(lamp->tex);
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
+ GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
+
+ /* set matrices */
+ copy_m4_m4(viewmat, lamp->viewmat);
+ copy_m4_m4(winmat, lamp->winmat);
+ *winsize = lamp->size;
+}
+
+void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
+{
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
+ GPU_shader_unbind();
+ GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
+ }
+
+ GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
+ GPU_framebuffer_restore();
+ glEnable(GL_SCISSOR_TEST);
+}
+
+int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
+{
+ return lamp->la->shadowmap_type;
+}
+
+int GPU_lamp_shadow_bind_code(GPULamp *lamp)
+{
+ return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
+}
+
+float *GPU_lamp_dynpersmat(GPULamp *lamp)
+{
+ return &lamp->dynpersmat[0][0];
+}
+
+int GPU_lamp_shadow_layer(GPULamp *lamp)
+{
+ if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
+ return lamp->lay;
+ else
+ return -1;
+}
diff --git a/source/blender/gpu/intern/gpu_lamp_private.h b/source/blender/gpu/intern/gpu_lamp_private.h
new file mode 100644
index 00000000000..ef71385e66d
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_lamp_private.h
@@ -0,0 +1,86 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_lamp_private.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_LAMP_PRIVATE_H__
+#define __GPU_LAMP_PRIVATE_H__
+
+#include "BLI_sys_types.h" /* for bool */
+
+struct GPULamp {
+ Scene *scene;
+ Object *ob;
+ Object *par;
+ Lamp *la;
+ struct RenderEngineType *re;
+
+ /* Old Viewport (pre-2.8) */
+ int type, mode, lay, hide;
+
+ float dynenergy, dyncol[3];
+ float energy, col[3];
+
+ float co[3], vec[3];
+ float dynco[3], dynvec[3];
+ float obmat[4][4];
+ float imat[4][4];
+ float dynimat[4][4];
+
+ float spotsi, spotbl, k;
+ float spotvec[2];
+ float dyndist, dynatt1, dynatt2;
+ float dist, att1, att2;
+ float coeff_const, coeff_lin, coeff_quad;
+ float shadow_color[3];
+
+ float bias, d, clipend;
+ int size;
+
+ int falloff_type;
+ struct CurveMapping *curfalloff;
+
+ float winmat[4][4];
+ float viewmat[4][4];
+ float persmat[4][4];
+ float dynpersmat[4][4];
+
+ GPUFrameBuffer *fb;
+ GPUFrameBuffer *blurfb;
+ GPUTexture *tex;
+ GPUTexture *depthtex;
+ GPUTexture *blurtex;
+
+ ListBase materials;
+
+ /* New viewport */
+ struct LampEngineData data;
+};
+
+#endif /* __GPU_LAMP_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 1f3ae7f708a..c00baef2856 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -60,11 +60,13 @@
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
+#include "GPU_lamp.h"
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "gpu_codegen.h"
+#include "gpu_lamp_private.h"
#ifdef WITH_OPENSUBDIV
# include "BKE_DerivedMesh.h"
@@ -92,12 +94,15 @@ static struct GPUWorld {
} GPUWorld;
struct GPUMaterial {
- Scene *scene;
+ Scene *scene; /* DEPRECATED was only usefull for lamps */
Material *ma;
/* material for mesh surface, worlds or something else.
* some code generation is done differently depending on the use case */
- int type;
+ int type; /* DEPRECATED */
+
+ void *engine; /* attached engine type */
+ int options; /* to identify shader variations (shadow, probe, world background...) */
/* for creating the material */
ListBase nodes;
@@ -130,50 +135,6 @@ struct GPUMaterial {
bool is_opensubdiv;
};
-struct GPULamp {
- Scene *scene;
- Object *ob;
- Object *par;
- Lamp *la;
-
- int type, mode, lay, hide;
-
- float dynenergy, dyncol[3];
- float energy, col[3];
-
- float co[3], vec[3];
- float dynco[3], dynvec[3];
- float obmat[4][4];
- float imat[4][4];
- float dynimat[4][4];
-
- float spotsi, spotbl, k;
- float spotvec[2];
- float dyndist, dynatt1, dynatt2;
- float dist, att1, att2;
- float coeff_const, coeff_lin, coeff_quad;
- float shadow_color[3];
-
- float bias, d, clipend;
- int size;
-
- int falloff_type;
- struct CurveMapping *curfalloff;
-
- float winmat[4][4];
- float viewmat[4][4];
- float persmat[4][4];
- float dynpersmat[4][4];
-
- GPUFrameBuffer *fb;
- GPUFrameBuffer *blurfb;
- GPUTexture *tex;
- GPUTexture *depthtex;
- GPUTexture *blurtex;
-
- ListBase materials;
-};
-
/* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
static void texture_rgb_blend(
GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
@@ -312,16 +273,6 @@ void GPU_material_free(ListBase *gpumaterial)
BLI_freelistN(gpumaterial);
}
-bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
-{
- if (srl && srl->light_override)
- return BKE_group_object_exists(srl->light_override, lamp->ob);
- else if (ma && ma->group)
- return BKE_group_object_exists(ma->group, lamp->ob);
- else
- return true;
-}
-
void GPU_material_bind(
GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
@@ -488,6 +439,10 @@ GPUMatType GPU_Material_get_type(GPUMaterial *material)
return material->type;
}
+GPUPass *GPU_material_get_pass(GPUMaterial *material)
+{
+ return material->pass;
+}
void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
{
@@ -2148,6 +2103,48 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
return mat;
}
+/* TODO : This is supposed to replace GPU_material_from_blender/_world in the future */
+GPUMaterial *GPU_material_from_nodetree(
+ Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options,
+ const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
+{
+ GPUMaterial *mat;
+ GPUNodeLink *outlink;
+ LinkData *link;
+
+ for (link = gpumaterials->first; link; link = link->next) {
+ GPUMaterial *current_material = (GPUMaterial *)link->data;
+ if (current_material->engine == engine_type &&
+ current_material->options == options)
+ {
+ return current_material;
+ }
+ }
+
+ /* allocate material */
+ mat = GPU_material_construct_begin(NULL); /* TODO remove GPU_material_construct_begin */
+ mat->scene = scene;
+ mat->engine = engine_type;
+ mat->options = options;
+
+ ntreeGPUMaterialNodes(ntree, mat, NODE_NEWER_SHADING);
+
+ /* Let Draw manager finish the construction. */
+ if (mat->outlink) {
+ outlink = mat->outlink;
+ mat->pass = GPU_generate_pass_new(&mat->nodes, outlink, vert_code, geom_code, frag_lib, defines);
+ }
+
+ /* note that even if building the shader fails in some way, we still keep
+ * it to avoid trying to compile again and again, and simple do not use
+ * the actual shader on drawing */
+
+ link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
+ link->data = mat;
+ BLI_addtail(gpumaterials, link);
+
+ return mat;
+}
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv)
{
@@ -2235,386 +2232,6 @@ void GPU_materials_free(void)
/* Lamps and shadow buffers */
-static void gpu_lamp_calc_winmat(GPULamp *lamp)
-{
- float temp, angle, pixsize, wsize;
-
- if (lamp->type == LA_SUN) {
- wsize = lamp->la->shadow_frustum_size;
- orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
- }
- else if (lamp->type == LA_SPOT) {
- angle = saacos(lamp->spotsi);
- temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
- pixsize = lamp->d / temp;
- wsize = pixsize * 0.5f * lamp->size;
- /* compute shadows according to X and Y scaling factors */
- perspective_m4(
- lamp->winmat,
- -wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
- -wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
- lamp->d, lamp->clipend);
- }
-}
-
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
-{
- float mat[4][4];
- float obmat_scale[3];
-
- lamp->lay = lay;
- lamp->hide = hide;
-
- normalize_m4_m4_ex(mat, obmat, obmat_scale);
-
- copy_v3_v3(lamp->vec, mat[2]);
- copy_v3_v3(lamp->co, mat[3]);
- copy_m4_m4(lamp->obmat, mat);
- invert_m4_m4(lamp->imat, mat);
-
- if (lamp->type == LA_SPOT) {
- /* update spotlamp scale on X and Y axis */
- lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
- lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
- }
-
- if (GPU_lamp_has_shadow_buffer(lamp)) {
- /* makeshadowbuf */
- gpu_lamp_calc_winmat(lamp);
- }
-}
-
-void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
-{
- lamp->energy = energy;
- if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
-
- lamp->col[0] = r;
- lamp->col[1] = g;
- lamp->col[2] = b;
-}
-
-void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
- float coeff_const, float coeff_lin, float coeff_quad)
-{
- lamp->dist = distance;
- lamp->att1 = att1;
- lamp->att2 = att2;
- lamp->coeff_const = coeff_const;
- lamp->coeff_lin = coeff_lin;
- lamp->coeff_quad = coeff_quad;
-}
-
-void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
-{
- lamp->spotsi = cosf(spotsize * 0.5f);
- lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
-}
-
-static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
-{
- lamp->scene = scene;
- lamp->ob = ob;
- lamp->par = par;
- lamp->la = la;
-
- /* add_render_lamp */
- lamp->mode = la->mode;
- lamp->type = la->type;
-
- lamp->energy = la->energy;
- if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
-
- lamp->col[0] = la->r;
- lamp->col[1] = la->g;
- lamp->col[2] = la->b;
-
- GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
-
- lamp->spotsi = la->spotsize;
- if (lamp->mode & LA_HALO)
- if (lamp->spotsi > DEG2RADF(170.0f))
- lamp->spotsi = DEG2RADF(170.0f);
- lamp->spotsi = cosf(lamp->spotsi * 0.5f);
- lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
- lamp->k = la->k;
-
- lamp->dist = la->dist;
- lamp->falloff_type = la->falloff_type;
- lamp->att1 = la->att1;
- lamp->att2 = la->att2;
- lamp->coeff_const = la->coeff_const;
- lamp->coeff_lin = la->coeff_lin;
- lamp->coeff_quad = la->coeff_quad;
- lamp->curfalloff = la->curfalloff;
-
- /* initshadowbuf */
- lamp->bias = 0.02f * la->bias;
- lamp->size = la->bufsize;
- lamp->d = la->clipsta;
- lamp->clipend = la->clipend;
-
- /* arbitrary correction for the fact we do no soft transition */
- lamp->bias *= 0.25f;
-}
-
-static void gpu_lamp_shadow_free(GPULamp *lamp)
-{
- if (lamp->tex) {
- GPU_texture_free(lamp->tex);
- lamp->tex = NULL;
- }
- if (lamp->depthtex) {
- GPU_texture_free(lamp->depthtex);
- lamp->depthtex = NULL;
- }
- if (lamp->fb) {
- GPU_framebuffer_free(lamp->fb);
- lamp->fb = NULL;
- }
- if (lamp->blurtex) {
- GPU_texture_free(lamp->blurtex);
- lamp->blurtex = NULL;
- }
- if (lamp->blurfb) {
- GPU_framebuffer_free(lamp->blurfb);
- lamp->blurfb = NULL;
- }
-}
-
-GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
-{
- Lamp *la;
- GPULamp *lamp;
- LinkData *link;
-
- for (link = ob->gpulamp.first; link; link = link->next) {
- lamp = (GPULamp *)link->data;
-
- if (lamp->par == par && lamp->scene == scene)
- return link->data;
- }
-
- lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
-
- link = MEM_callocN(sizeof(LinkData), "GPULampLink");
- link->data = lamp;
- BLI_addtail(&ob->gpulamp, link);
-
- la = ob->data;
- gpu_lamp_from_blender(scene, ob, par, la, lamp);
-
- if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
- (la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
- {
- /* opengl */
- lamp->fb = GPU_framebuffer_create();
- if (!lamp->fb) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
- /* Shadow depth map */
- lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
- if (!lamp->depthtex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- /* Shadow color map */
- lamp->tex = GPU_texture_create_vsm_shadow_map(lamp->size, NULL);
- if (!lamp->tex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- /* FBO and texture for blurring */
- lamp->blurfb = GPU_framebuffer_create();
- if (!lamp->blurfb) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- lamp->blurtex = GPU_texture_create_vsm_shadow_map(lamp->size * 0.5, NULL);
- if (!lamp->blurtex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- /* we need to properly bind to test for completeness */
- GPU_texture_bind_as_framebuffer(lamp->blurtex);
-
- if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
- }
- else {
- lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
- if (!lamp->tex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
- }
-
- GPU_framebuffer_restore();
-
- lamp->shadow_color[0] = la->shdwr;
- lamp->shadow_color[1] = la->shdwg;
- lamp->shadow_color[2] = la->shdwb;
- }
- else {
- lamp->shadow_color[0] = 1.0;
- lamp->shadow_color[1] = 1.0;
- lamp->shadow_color[2] = 1.0;
- }
-
- return lamp;
-}
-
-void GPU_lamp_free(Object *ob)
-{
- GPULamp *lamp;
- LinkData *link;
- LinkData *nlink;
- Material *ma;
-
- for (link = ob->gpulamp.first; link; link = link->next) {
- lamp = link->data;
-
- while (lamp->materials.first) {
- nlink = lamp->materials.first;
- ma = nlink->data;
- BLI_freelinkN(&lamp->materials, nlink);
-
- if (ma->gpumaterial.first)
- GPU_material_free(&ma->gpumaterial);
- }
-
- gpu_lamp_shadow_free(lamp);
-
- MEM_freeN(lamp);
- }
-
- BLI_freelistN(&ob->gpulamp);
-}
-
-bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
-{
- return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
- !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
- lamp->tex && lamp->fb);
-}
-
-void GPU_lamp_update_buffer_mats(GPULamp *lamp)
-{
- float rangemat[4][4], persmat[4][4];
-
- /* initshadowbuf */
- invert_m4_m4(lamp->viewmat, lamp->obmat);
- normalize_v3(lamp->viewmat[0]);
- normalize_v3(lamp->viewmat[1]);
- normalize_v3(lamp->viewmat[2]);
-
- /* makeshadowbuf */
- mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
-
- /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
- unit_m4(rangemat);
- rangemat[0][0] = 0.5f;
- rangemat[1][1] = 0.5f;
- rangemat[2][2] = 0.5f;
- rangemat[3][0] = 0.5f;
- rangemat[3][1] = 0.5f;
- rangemat[3][2] = 0.5f;
-
- mul_m4_m4m4(lamp->persmat, rangemat, persmat);
-}
-
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
-{
- GPU_lamp_update_buffer_mats(lamp);
-
- /* opengl */
- glDisable(GL_SCISSOR_TEST);
- GPU_texture_bind_as_framebuffer(lamp->tex);
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
- GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
-
- /* set matrices */
- copy_m4_m4(viewmat, lamp->viewmat);
- copy_m4_m4(winmat, lamp->winmat);
- *winsize = lamp->size;
-}
-
-void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
-{
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
- GPU_shader_unbind();
- GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
- }
-
- GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
- GPU_framebuffer_restore();
- glEnable(GL_SCISSOR_TEST);
-}
-
-int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
-{
- return lamp->la->shadowmap_type;
-}
-
-int GPU_lamp_shadow_bind_code(GPULamp *lamp)
-{
- return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
-}
-
-float *GPU_lamp_dynpersmat(GPULamp *lamp)
-{
- return &lamp->dynpersmat[0][0];
-}
-
-int GPU_lamp_shadow_layer(GPULamp *lamp)
-{
- if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
- return lamp->lay;
- else
- return -1;
-}
-
GPUNodeLink *GPU_lamp_get_data(
GPUMaterial *mat, GPULamp *lamp,
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy)
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
new file mode 100644
index 00000000000..775d1cd87b2
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -0,0 +1,624 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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 ipmlied 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) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Alexandr Kuznetsov, Jason Wilkins, Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/gpu/intern/gpu_matrix.c
+ * \ingroup gpu
+ */
+
+#define SUPPRESS_GENERIC_MATRIX_API
+#include "GPU_matrix.h"
+
+#include "BLI_math_matrix.h"
+#include "BLI_math_rotation.h"
+#include "BLI_math_vector.h"
+
+
+#define DEBUG_MATRIX_BIND 0
+
+#define MATRIX_STACK_DEPTH 32
+
+typedef float Mat4[4][4];
+typedef float Mat3[3][3];
+
+typedef struct MatrixStack {
+ Mat4 stack[MATRIX_STACK_DEPTH];
+ unsigned int top;
+} MatrixStack;
+
+typedef struct {
+ MatrixStack model_view_stack;
+ MatrixStack projection_stack;
+
+ bool dirty;
+
+ /* TODO: cache of derived matrices (Normal, MVP, inverse MVP, etc)
+ * generate as needed for shaders, invalidate when original matrices change
+ *
+ * TODO: separate Model from View transform? Batches/objects have model,
+ * camera/eye has view & projection
+ */
+} MatrixState;
+
+#define MATRIX_4X4_IDENTITY {{1.0f, 0.0f, 0.0f, 0.0f}, \
+ {0.0f, 1.0f, 0.0f, 0.0f}, \
+ {0.0f, 0.0f, 1.0f, 0.0f}, \
+ {0.0f, 0.0f, 0.0f, 1.0f}}
+
+static MatrixState state = {
+ .model_view_stack = {{MATRIX_4X4_IDENTITY}, 0},
+ .projection_stack = {{MATRIX_4X4_IDENTITY}, 0},
+ .dirty = true
+};
+
+#undef MATRIX_4X4_IDENTITY
+
+#define ModelViewStack state.model_view_stack
+#define ModelView ModelViewStack.stack[ModelViewStack.top]
+
+#define ProjectionStack state.projection_stack
+#define Projection ProjectionStack.stack[ProjectionStack.top]
+
+void gpuMatrixReset(void)
+{
+ state.model_view_stack.top = 0;
+ state.projection_stack.top = 0;
+ unit_m4(ModelView);
+ unit_m4(Projection);
+ state.dirty = true;
+}
+
+#ifdef WITH_GPU_SAFETY
+
+/* Check if matrix is numerically good */
+static void checkmat(cosnt float *m)
+{
+ const int n = 16;
+ for (int i = 0; i < n; i++) {
+#if _MSC_VER
+ BLI_assert(_finite(m[i]));
+#else
+ BLI_assert(!isinf(m[i]));
+#endif
+ }
+}
+
+#define CHECKMAT(m) checkmat((const float*)m)
+
+#else
+
+#define CHECKMAT(m)
+
+#endif
+
+
+void gpuPushMatrix(void)
+{
+ BLI_assert(ModelViewStack.top < MATRIX_STACK_DEPTH);
+ ModelViewStack.top++;
+ copy_m4_m4(ModelView, ModelViewStack.stack[ModelViewStack.top - 1]);
+}
+
+void gpuPopMatrix(void)
+{
+ BLI_assert(ModelViewStack.top > 0);
+ ModelViewStack.top--;
+ state.dirty = true;
+}
+
+void gpuPushProjectionMatrix(void)
+{
+ BLI_assert(ProjectionStack.top < MATRIX_STACK_DEPTH);
+ ProjectionStack.top++;
+ copy_m4_m4(Projection, ProjectionStack.stack[ProjectionStack.top - 1]);
+}
+
+void gpuPopProjectionMatrix(void)
+{
+ BLI_assert(ProjectionStack.top > 0);
+ ProjectionStack.top--;
+ state.dirty = true;
+}
+
+void gpuLoadMatrix(const float m[4][4])
+{
+ copy_m4_m4(ModelView, m);
+ CHECKMAT(ModelView3D);
+ state.dirty = true;
+}
+
+void gpuLoadIdentityProjectionMatrix(void)
+{
+ unit_m4(Projection);
+ CHECKMAT(Projection3D);
+ state.dirty = true;
+}
+
+void gpuLoadProjectionMatrix(const float m[4][4])
+{
+ copy_m4_m4(Projection, m);
+ CHECKMAT(Projection3D);
+ state.dirty = true;
+}
+
+void gpuLoadIdentity(void)
+{
+ unit_m4(ModelView);
+ state.dirty = true;
+}
+
+void gpuTranslate2f(float x, float y)
+{
+ Mat4 m;
+ unit_m4(m);
+ m[3][0] = x;
+ m[3][1] = y;
+ gpuMultMatrix(m);
+}
+
+void gpuTranslate2fv(const float vec[2])
+{
+ gpuTranslate2f(vec[0], vec[1]);
+}
+
+void gpuTranslate3f(float x, float y, float z)
+{
+#if 1
+ translate_m4(ModelView, x, y, z);
+ CHECKMAT(ModelView);
+#else /* above works well in early testing, below is generic version */
+ Mat4 m;
+ unit_m4(m);
+ m[3][0] = x;
+ m[3][1] = y;
+ m[3][2] = z;
+ gpuMultMatrix(m);
+#endif
+ state.dirty = true;
+}
+
+void gpuTranslate3fv(const float vec[3])
+{
+ gpuTranslate3f(vec[0], vec[1], vec[2]);
+}
+
+void gpuScaleUniform(float factor)
+{
+ Mat4 m;
+ scale_m4_fl(m, factor);
+ gpuMultMatrix(m);
+}
+
+void gpuScale2f(float x, float y)
+{
+ Mat4 m = {{0.0f}};
+ m[0][0] = x;
+ m[1][1] = y;
+ m[2][2] = 1.0f;
+ m[3][3] = 1.0f;
+ gpuMultMatrix(m);
+}
+
+void gpuScale2fv(const float vec[2])
+{
+ gpuScale2f(vec[0], vec[1]);
+}
+
+void gpuScale3f(float x, float y, float z)
+{
+ Mat4 m = {{0.0f}};
+ m[0][0] = x;
+ m[1][1] = y;
+ m[2][2] = z;
+ m[3][3] = 1.0f;
+ gpuMultMatrix(m);
+}
+
+void gpuScale3fv(const float vec[3])
+{
+ gpuScale3f(vec[0], vec[1], vec[2]);
+}
+
+void gpuMultMatrix(const float m[4][4])
+{
+ mul_m4_m4_post(ModelView, m);
+ CHECKMAT(ModelView);
+ state.dirty = true;
+}
+
+void gpuRotate2D(float deg)
+{
+ /* essentially RotateAxis('Z')
+ * TODO: simpler math for 2D case
+ */
+ rotate_m4(ModelView, 'Z', DEG2RADF(deg));
+}
+
+void gpuRotate3f(float deg, float x, float y, float z)
+{
+ const float axis[3] = {x, y, z};
+ gpuRotate3fv(deg, axis);
+}
+
+void gpuRotate3fv(float deg, const float axis[3])
+{
+ Mat4 m;
+ axis_angle_to_mat4(m, axis, DEG2RADF(deg));
+ gpuMultMatrix(m);
+}
+
+void gpuRotateAxis(float deg, char axis)
+{
+ /* rotate_m4 works in place */
+ rotate_m4(ModelView, axis, DEG2RADF(deg));
+ CHECKMAT(ModelView);
+ state.dirty = true;
+}
+
+static void mat4_ortho_set(float m[4][4], float left, float right, float bottom, float top, float near, float far)
+{
+ m[0][0] = 2.0f / (right - left);
+ m[1][0] = 0.0f;
+ m[2][0] = 0.0f;
+ m[3][0] = -(right + left) / (right - left);
+
+ m[0][1] = 0.0f;
+ m[1][1] = 2.0f / (top - bottom);
+ m[2][1] = 0.0f;
+ m[3][1] = -(top + bottom) / (top - bottom);
+
+ m[0][2] = 0.0f;
+ m[1][2] = 0.0f;
+ m[2][2] = -2.0f / (far - near);
+ m[3][2] = -(far + near) / (far - near);
+
+ m[0][3] = 0.0f;
+ m[1][3] = 0.0f;
+ m[2][3] = 0.0f;
+ m[3][3] = 1.0f;
+
+ state.dirty = true;
+}
+
+static void mat4_frustum_set(float m[4][4], float left, float right, float bottom, float top, float near, float far)
+{
+ m[0][0] = 2.0f * near / (right - left);
+ m[1][0] = 0.0f;
+ m[2][0] = (right + left) / (right - left);
+ m[3][0] = 0.0f;
+
+ m[0][1] = 0.0f;
+ m[1][1] = 2.0f * near / (top - bottom);
+ m[2][1] = (top + bottom) / (top - bottom);
+ m[3][1] = 0.0f;
+
+ m[0][2] = 0.0f;
+ m[1][2] = 0.0f;
+ m[2][2] = -(far + near) / (far - near);
+ m[3][2] = -2.0f * far * near / (far - near);
+
+ m[0][3] = 0.0f;
+ m[1][3] = 0.0f;
+ m[2][3] = -1.0f;
+ m[3][3] = 0.0f;
+
+ state.dirty = true;
+}
+
+static void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3])
+{
+/* This function is loosely based on Mesa implementation.
+ *
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+ float side[3];
+
+ normalize_v3(lookdir);
+
+ cross_v3_v3v3(side, lookdir, camup);
+
+ normalize_v3(side);
+
+ cross_v3_v3v3(camup, side, lookdir);
+
+ m[0][0] = side[0];
+ m[1][0] = side[1];
+ m[2][0] = side[2];
+ m[3][0] = 0.0f;
+
+ m[0][1] = camup[0];
+ m[1][1] = camup[1];
+ m[2][1] = camup[2];
+ m[3][1] = 0.0f;
+
+ m[0][2] = -lookdir[0];
+ m[1][2] = -lookdir[1];
+ m[2][2] = -lookdir[2];
+ m[3][2] = 0.0f;
+
+ m[0][3] = 0.0f;
+ m[1][3] = 0.0f;
+ m[2][3] = 0.0f;
+ m[3][3] = 1.0f;
+
+ state.dirty = true;
+}
+
+void gpuOrtho(float left, float right, float bottom, float top, float near, float far)
+{
+ mat4_ortho_set(Projection, left, right, bottom, top, near, far);
+ CHECKMAT(Projection);
+ state.dirty = true;
+}
+
+void gpuOrtho2D(float left, float right, float bottom, float top)
+{
+ Mat4 m;
+ mat4_ortho_set(m, left, right, bottom, top, -1.0f, 1.0f);
+ CHECKMAT(Projection2D);
+ state.dirty = true;
+}
+
+void gpuFrustum(float left, float right, float bottom, float top, float near, float far)
+{
+ mat4_frustum_set(Projection, left, right, bottom, top, near, far);
+ CHECKMAT(Projection);
+ state.dirty = true;
+}
+
+void gpuPerspective(float fovy, float aspect, float near, float far)
+{
+ float half_height = tanf(fovy * (float)(M_PI / 360.0)) * near;
+ float half_width = half_height * aspect;
+ gpuFrustum(-half_width, +half_width, -half_height, +half_height, near, far);
+}
+
+void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
+{
+ Mat4 cm;
+ float lookdir[3];
+ float camup[3] = {upX, upY, upZ};
+
+ lookdir[0] = centerX - eyeX;
+ lookdir[1] = centerY - eyeY;
+ lookdir[2] = centerZ - eyeZ;
+
+ mat4_look_from_origin(cm, lookdir, camup);
+
+ gpuMultMatrix(cm);
+ gpuTranslate3f(-eyeX, -eyeY, -eyeZ);
+}
+
+void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3])
+{
+ float v[4];
+
+ mul_v4_m4v3(v, model, world);
+ mul_m4_v4(proj, v);
+
+ if (v[3] != 0.0f) {
+ mul_v3_fl(v, 1.0f / v[3]);
+ }
+
+ win[0] = view[0] + (view[2] * (v[0] + 1)) * 0.5f;
+ win[1] = view[1] + (view[3] * (v[1] + 1)) * 0.5f;
+ win[2] = (v[2] + 1) * 0.5f;
+}
+
+bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3])
+{
+ float pm[4][4];
+ float in[4];
+ float out[4];
+
+ mul_m4_m4m4(pm, proj, model);
+
+ if (!invert_m4(pm)) {
+ zero_v3(world);
+ return false;
+ }
+
+ in[0] = win[0];
+ in[1] = win[1];
+ in[2] = win[2];
+ in[3] = 1;
+
+ /* Map x and y from window coordinates */
+ in[0] = (in[0] - view[0]) / view[2];
+ in[1] = (in[1] - view[1]) / view[3];
+
+ /* Map to range -1 to +1 */
+ in[0] = 2 * in[0] - 1;
+ in[1] = 2 * in[1] - 1;
+ in[2] = 2 * in[2] - 1;
+
+ mul_v4_m4v3(out, pm, in);
+
+ if (out[3] == 0.0f) {
+ copy_v3_v3(world, out);
+ return false;
+ }
+
+ mul_v3_v3fl(world, out, 1.0f / out[3]);
+ return true;
+}
+
+const float (*gpuGetModelViewMatrix(float m[4][4]))[4]
+{
+ if (m) {
+ copy_m4_m4(m, ModelView);
+ return m;
+ }
+ else {
+ return ModelView;
+ }
+}
+
+const float (*gpuGetProjectionMatrix(float m[4][4]))[4]
+{
+ if (m) {
+ copy_m4_m4(m, Projection);
+ return m;
+ }
+ else {
+ return Projection;
+ }
+}
+
+const float (*gpuGetModelViewProjectionMatrix(float m[4][4]))[4]
+{
+ if (m == NULL) {
+ static Mat4 temp;
+ m = temp;
+ }
+
+ mul_m4_m4m4(m, Projection, ModelView);
+ return m;
+}
+
+const float (*gpuGetNormalMatrix(float m[3][3]))[3]
+{
+ if (m == NULL) {
+ static Mat3 temp3;
+ m = temp3;
+ }
+
+ copy_m3_m4(m, (const float (*)[4])gpuGetModelViewMatrix(NULL));
+
+ invert_m3(m);
+ transpose_m3(m);
+
+ return m;
+}
+
+const float (*gpuGetNormalMatrixInverse(float m[3][3]))[3]
+{
+ if (m == NULL) {
+ static Mat3 temp3;
+ m = temp3;
+ }
+
+ gpuGetNormalMatrix(m);
+ invert_m3(m);
+
+ return m;
+}
+
+void gpuBindMatrices(const ShaderInterface* shaderface)
+{
+ /* set uniform values to matrix stack values
+ * call this before a draw call if desired matrices are dirty
+ * call glUseProgram before this, as glUniform expects program to be bound
+ */
+
+ const ShaderInput *MV = ShaderInterface_builtin_uniform(shaderface, UNIFORM_MODELVIEW);
+ const ShaderInput *P = ShaderInterface_builtin_uniform(shaderface, UNIFORM_PROJECTION);
+ const ShaderInput *MVP = ShaderInterface_builtin_uniform(shaderface, UNIFORM_MVP);
+
+ const ShaderInput *N = ShaderInterface_builtin_uniform(shaderface, UNIFORM_NORMAL);
+ const ShaderInput *MV_inv = ShaderInterface_builtin_uniform(shaderface, UNIFORM_MODELVIEW_INV);
+ const ShaderInput *P_inv = ShaderInterface_builtin_uniform(shaderface, UNIFORM_PROJECTION_INV);
+
+ if (MV) {
+ #if DEBUG_MATRIX_BIND
+ puts("setting MV matrix");
+ #endif
+
+ glUniformMatrix4fv(MV->location, 1, GL_FALSE, (const float *)gpuGetModelViewMatrix(NULL));
+ }
+
+ if (P) {
+ #if DEBUG_MATRIX_BIND
+ puts("setting P matrix");
+ #endif
+
+ glUniformMatrix4fv(P->location, 1, GL_FALSE, (const float *)gpuGetProjectionMatrix(NULL));
+ }
+
+ if (MVP) {
+ #if DEBUG_MATRIX_BIND
+ puts("setting MVP matrix");
+ #endif
+
+ glUniformMatrix4fv(MVP->location, 1, GL_FALSE, (const float *)gpuGetModelViewProjectionMatrix(NULL));
+ }
+
+ if (N) {
+ #if DEBUG_MATRIX_BIND
+ puts("setting normal matrix");
+ #endif
+
+ glUniformMatrix3fv(N->location, 1, GL_FALSE, (const float *)gpuGetNormalMatrix(NULL));
+ }
+
+ if (MV_inv) {
+ Mat4 m;
+ gpuGetModelViewMatrix(m);
+ invert_m4(m);
+ glUniformMatrix4fv(MV_inv->location, 1, GL_FALSE, (const float*) m);
+ }
+
+ if (P_inv) {
+ Mat4 m;
+ gpuGetProjectionMatrix(m);
+ invert_m4(m);
+ glUniformMatrix4fv(P_inv->location, 1, GL_FALSE, (const float*) m);
+ }
+
+ state.dirty = false;
+}
+
+bool gpuMatricesDirty(void)
+{
+ return state.dirty;
+}
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 9496ff137dc..c384fa01fc6 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -181,12 +181,7 @@ unsigned int GPU_select_end(void)
*/
bool GPU_select_query_check_active(void)
{
- return ((U.gpu_select_method == USER_SELECT_USE_OCCLUSION_QUERY) ||
- ((U.gpu_select_method == USER_SELECT_AUTO) &&
- (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) ||
- /* unsupported by nouveau, gallium 0.4, see: T47940 */
- GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE))));
-
+ return ELEM(U.gpu_select_method, USER_SELECT_USE_OCCLUSION_QUERY, USER_SELECT_AUTO);
}
/* ----------------------------------------------------------------------------
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 0a77420fa25..f1d311890e6 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -31,6 +31,8 @@
#include <stdlib.h>
#include <float.h>
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
#include "GPU_select.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
@@ -316,8 +318,8 @@ void gpu_select_pick_begin(
/* Restrict OpenGL operations for when we don't have cache */
if (ps->is_cached == false) {
+ gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT);
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
/* disable writing to the framebuffer */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -331,10 +333,6 @@ void gpu_select_pick_begin(
glDepthFunc(GL_LEQUAL);
}
- /* set just in case */
- glPixelTransferf(GL_DEPTH_BIAS, 0.0);
- glPixelTransferf(GL_DEPTH_SCALE, 1.0);
-
float viewport[4];
glGetFloatv(GL_SCISSOR_BOX, viewport);
@@ -540,7 +538,7 @@ unsigned int gpu_select_pick_end(void)
gpu_select_pick_load_id(ps->gl.prev_id);
}
- glPopAttrib();
+ gpuPopAttrib();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index ba5fefc5227..a7374604379 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -32,6 +32,8 @@
#include <stdlib.h>
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
#include "GPU_select.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
@@ -94,7 +96,7 @@ void gpu_select_query_begin(
g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids");
glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
+ gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT);
/* disable writing to the framebuffer */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -202,7 +204,7 @@ unsigned int gpu_select_query_end(void)
glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries);
MEM_freeN(g_query_state.queries);
MEM_freeN(g_query_state.id);
- glPopAttrib();
+ gpuPopAttrib();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
return hits;
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index b579f87698c..24eb88d0114 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -34,18 +34,104 @@
#include "BKE_global.h"
#include "GPU_compositing.h"
-#include "GPU_debug.h"
#include "GPU_extensions.h"
-#include "GPU_glew.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
-#include "GPU_material.h"
+#include "GPU_uniformbuffer.h"
-/* TODO(sergey): Find better default values for this constants. */
-#define MAX_DEFINE_LENGTH 1024
-#define MAX_EXT_DEFINE_LENGTH 1024
+#include "gpu_shader_private.h"
+
+/* Adjust these constants as needed. */
+#define MAX_DEFINE_LENGTH 256
+#define MAX_EXT_DEFINE_LENGTH 256
/* Non-generated shaders */
+extern char datatoc_gpu_shader_depth_only_frag_glsl[];
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_checker_frag_glsl[];
+extern char datatoc_gpu_shader_diag_stripes_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_flat_color_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl[];
+extern char datatoc_gpu_shader_flat_color_frag_glsl[];
+extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[];
+extern char datatoc_gpu_shader_2D_vert_glsl[];
+extern char datatoc_gpu_shader_2D_flat_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_2D_image_vert_glsl[];
+
+extern char datatoc_gpu_shader_3D_image_vert_glsl[];
+extern char datatoc_gpu_shader_image_linear_frag_glsl[];
+extern char datatoc_gpu_shader_image_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_interlace_frag_glsl[];
+extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
+extern char datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl[];
+extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[];
+extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_3D_normal_vert_glsl[];
+extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_normal_flat_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
+extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
+
+extern char datatoc_gpu_shader_instance_vert_glsl[];
+extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_screen_aligned_vert_glsl[];
+extern char datatoc_gpu_shader_instance_camera_vert_glsl[];
+extern char datatoc_gpu_shader_instance_distance_line_vert_glsl[];
+extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
+extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl[];
+extern char datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl[];
+
+extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
+extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
+
+extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
+extern char datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_varying_size_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_uniform_size_outline_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_varying_size_varying_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl[];
+
+extern char datatoc_gpu_shader_2D_line_dashed_vert_glsl[];
+extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[];
+extern char datatoc_gpu_shader_2D_line_dashed_geom_glsl[];
+extern char datatoc_gpu_shader_3D_line_dashed_legacy_vert_glsl[];
+extern char datatoc_gpu_shader_3D_line_dashed_vert_glsl[];
+
+extern char datatoc_gpu_shader_edges_front_back_persp_vert_glsl[];
+extern char datatoc_gpu_shader_edges_front_back_persp_geom_glsl[];
+extern char datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl[];
+extern char datatoc_gpu_shader_edges_front_back_ortho_vert_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_vert_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_geom_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_simple_geom_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_frag_glsl[];
+extern char datatoc_gpu_shader_text_vert_glsl[];
+extern char datatoc_gpu_shader_text_frag_glsl[];
+extern char datatoc_gpu_shader_keyframe_diamond_vert_glsl[];
+extern char datatoc_gpu_shader_keyframe_diamond_frag_glsl[];
+
extern char datatoc_gpu_shader_fire_frag_glsl[];
extern char datatoc_gpu_shader_smoke_vert_glsl[];
extern char datatoc_gpu_shader_smoke_frag_glsl[];
@@ -53,7 +139,7 @@ extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
-extern char datatoc_gpu_shader_fx_vert_glsl[];
+extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
@@ -63,41 +149,25 @@ extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[];
extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
extern char datatoc_gpu_shader_fx_lib_glsl[];
-static struct GPUShadersGlobal {
- struct {
- GPUShader *vsm_store;
- GPUShader *sep_gaussian_blur;
- GPUShader *smoke;
- GPUShader *smoke_fire;
- GPUShader *smoke_coba;
- /* cache for shader fx. Those can exist in combinations so store them here */
- GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
- } shaders;
-} GG = {{NULL}};
-
-/* GPUShader */
+/* cache of built-in shaders (each is created on first use) */
+static GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS] = { NULL };
-struct GPUShader {
- GLuint program; /* handle for full program (links shader stages below) */
+/* cache for shader fx. Those can exist in combinations so store them here */
+static GPUShader *fx_shaders[MAX_FX_SHADERS * 2] = { NULL };
- GLuint vertex; /* handle for vertex shader */
- GLuint geometry; /* handle for geometry shader */
- GLuint fragment; /* handle for fragment shader */
-
- int totattrib; /* total number of attributes */
- int uniforms; /* required uniforms */
-
- void *uniform_interface; /* cached uniform interface for shader. Data depends on shader */
-};
+typedef struct {
+ const char *vert;
+ const char *frag;
+ const char *geom; /* geometry stage runs between vert & frag, but is less common, so it goes last */
+} GPUShaderStages;
static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
{
- int i;
int line = 1;
fprintf(stderr, "GPUShader: %s error:\n", task);
- for (i = 0; i < totcode; i++) {
+ for (int i = 0; i < totcode; i++) {
const char *c, *pos, *end = code[i] + strlen(code[i]);
if (G.debug & G_DEBUG) {
@@ -120,71 +190,19 @@ static void shader_print_errors(const char *task, const char *log, const char **
static const char *gpu_shader_version(void)
{
- if (GLEW_VERSION_3_2) {
- if (GLEW_ARB_compatibility) {
- return "#version 150 compatibility\n";
- /* highest version that is widely supported
- * gives us native geometry shaders!
- * use compatibility profile so we can continue using builtin shader input/output names
- */
- }
- else {
- return "#version 130\n";
- /* latest version that is compatible with existing shaders */
- }
- }
- else if (GLEW_VERSION_3_1) {
- if (GLEW_ARB_compatibility) {
- return "#version 140\n";
- /* also need the ARB_compatibility extension, handled below */
- }
- else {
- return "#version 130\n";
- /* latest version that is compatible with existing shaders */
- }
- }
- else if (GLEW_VERSION_3_0) {
- return "#version 130\n";
- /* GLSL 1.3 has modern syntax/keywords/datatypes so use if available
- * older features are deprecated but still available without compatibility extension or profile
- */
- }
- else {
- return "#version 120\n";
- /* minimum supported */
- }
+ return "#version 330\n";
}
-
-static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH], bool use_geometry_shader)
+static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
{
/* enable extensions for features that are not part of our base GLSL version
* don't use an extension for something already available!
*/
if (GLEW_ARB_texture_query_lod) {
- /* a #version 400 feature, but we use #version 150 maximum so use extension */
+ /* a #version 400 feature, but we use #version 330 maximum so use extension */
strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
}
-
- if (use_geometry_shader && GPU_geometry_shader_support_via_extension()) {
- strcat(defines, "#extension GL_EXT_geometry_shader4: enable\n");
- }
-
- if (GLEW_VERSION_3_1 && !GLEW_VERSION_3_2 && GLEW_ARB_compatibility) {
- strcat(defines, "#extension GL_ARB_compatibility: enable\n");
- }
-
- if (!GLEW_VERSION_3_1) {
- if (GLEW_ARB_draw_instanced) {
- strcat(defines, "#extension GL_ARB_draw_instanced: enable\n");
- }
-
- if (!GLEW_VERSION_3_0 && GLEW_EXT_gpu_shader4) {
- strcat(defines, "#extension GL_EXT_gpu_shader4: enable\n");
- /* TODO: maybe require this? shaders become so much nicer */
- }
- }
}
static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
@@ -207,10 +225,6 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
if (GPU_bicubic_bump_support())
strcat(defines, "#define BUMP_BICUBIC\n");
- if (GLEW_VERSION_3_0) {
- strcat(defines, "#define BIT_OPERATIONS\n");
- }
-
#ifdef WITH_OPENSUBDIV
/* TODO(sergey): Check whether we actually compiling shader for
* the OpenSubdiv mesh.
@@ -243,19 +257,13 @@ GPUShader *GPU_shader_create(const char *vertexcode,
const char *fragcode,
const char *geocode,
const char *libcode,
- const char *defines,
- int input,
- int output,
- int number)
+ const char *defines)
{
return GPU_shader_create_ex(vertexcode,
fragcode,
geocode,
libcode,
defines,
- input,
- output,
- number,
GPU_SHADER_FLAGS_NONE);
}
@@ -264,16 +272,9 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
const char *geocode,
const char *libcode,
const char *defines,
- int input,
- int output,
- int number,
const int flags)
{
#ifdef WITH_OPENSUBDIV
- /* TODO(sergey): used to add #version 150 to the geometry shader.
- * Could safely be renamed to "use_geometry_code" since it's very
- * likely any of geometry code will want to use GLSL 1.5.
- */
bool use_opensubdiv = (flags & GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV) != 0;
#else
UNUSED_VARS(flags);
@@ -286,9 +287,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
char standard_defines[MAX_DEFINE_LENGTH] = "";
char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
- if (geocode && !GPU_geometry_shader_support())
- return NULL;
-
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
if (vertexcode)
@@ -313,7 +311,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
gpu_shader_standard_defines(standard_defines,
use_opensubdiv,
(flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0);
- gpu_shader_standard_extensions(standard_extensions, geocode != NULL);
+ gpu_shader_standard_extensions(standard_extensions);
if (vertexcode) {
const char *source[5];
@@ -405,20 +403,12 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
GPU_shader_free(shader);
return NULL;
}
-
- if (!use_opensubdiv) {
- GPU_shader_geometry_stage_primitive_io(shader, input, output, number);
- }
}
#ifdef WITH_OPENSUBDIV
if (use_opensubdiv) {
glBindAttribLocation(shader->program, 0, "position");
glBindAttribLocation(shader->program, 1, "normal");
- GPU_shader_geometry_stage_primitive_io(shader,
- GL_LINES_ADJACENCY_EXT,
- GL_TRIANGLE_STRIP,
- 4);
}
#endif
@@ -436,16 +426,26 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
return NULL;
}
+ shader->interface = ShaderInterface_create(shader->program);
+
#ifdef WITH_OPENSUBDIV
/* TODO(sergey): Find a better place for this. */
- if (use_opensubdiv && GLEW_VERSION_4_1) {
- glProgramUniform1i(shader->program,
- glGetUniformLocation(shader->program, "FVarDataOffsetBuffer"),
- 30); /* GL_TEXTURE30 */
-
- glProgramUniform1i(shader->program,
- glGetUniformLocation(shader->program, "FVarDataBuffer"),
- 31); /* GL_TEXTURE31 */
+ if (use_opensubdiv) {
+ if (GLEW_VERSION_4_1) {
+ glProgramUniform1i(shader->program,
+ ShaderInterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location,
+ 30); /* GL_TEXTURE30 */
+
+ glProgramUniform1i(shader->program,
+ ShaderInterface_uniform(shader->interface, "FVarDataBuffer")->location,
+ 31); /* GL_TEXTURE31 */
+ }
+ else {
+ glUseProgram(shader->program);
+ glUniform1i(ShaderInterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, 30);
+ glUniform1i(ShaderInterface_uniform(shader->interface, "FVarDataBuffer")->location, 31);
+ glUseProgram(0);
+ }
}
#endif
@@ -454,20 +454,21 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
void GPU_shader_bind(GPUShader *shader)
{
- GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
+ BLI_assert(shader && shader->program);
+
glUseProgram(shader->program);
- GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
+ gpuBindMatrices(shader->interface);
}
void GPU_shader_unbind(void)
{
- GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
glUseProgram(0);
- GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
}
void GPU_shader_free(GPUShader *shader)
{
+ BLI_assert(shader);
+
if (shader->vertex)
glDeleteShader(shader->vertex);
if (shader->geometry)
@@ -480,20 +481,43 @@ void GPU_shader_free(GPUShader *shader)
if (shader->uniform_interface)
MEM_freeN(shader->uniform_interface);
+ if (shader->interface)
+ ShaderInterface_discard(shader->interface);
+
MEM_freeN(shader);
}
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
{
- return glGetUniformLocation(shader->program, name);
+ BLI_assert(shader && shader->program);
+ const ShaderInput *uniform = ShaderInterface_uniform(shader->interface, name);
+ return uniform ? uniform->location : -1;
}
-void *GPU_shader_get_interface(GPUShader *shader)
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+
+ return glGetUniformBlockIndex(shader->program, name);
+}
+
+void *GPU_fx_shader_get_interface(GPUShader *shader)
{
return shader->uniform_interface;
}
-void GPU_shader_set_interface(GPUShader *shader, void *interface)
+void *GPU_shader_get_interface(GPUShader *shader)
+{
+ return shader->interface;
+}
+
+/* Clement : Temp */
+int GPU_shader_get_program(GPUShader *shader)
+{
+ return (int)shader->program;
+}
+
+void GPU_fx_shader_set_interface(GPUShader *shader, void *interface)
{
shader->uniform_interface = interface;
}
@@ -503,16 +527,12 @@ void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int leng
if (location == -1 || value == NULL)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
-
if (length == 1) glUniform1fv(location, arraysize, value);
else if (length == 2) glUniform2fv(location, arraysize, value);
else if (length == 3) glUniform3fv(location, arraysize, value);
else if (length == 4) glUniform4fv(location, arraysize, value);
else if (length == 9) glUniformMatrix3fv(location, arraysize, 0, value);
else if (length == 16) glUniformMatrix4fv(location, arraysize, 0, value);
-
- GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
@@ -520,14 +540,10 @@ void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int
if (location == -1)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
-
if (length == 1) glUniform1iv(location, arraysize, value);
else if (length == 2) glUniform2iv(location, arraysize, value);
else if (length == 3) glUniform3iv(location, arraysize, value);
else if (length == 4) glUniform4iv(location, arraysize, value);
-
- GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
@@ -535,22 +551,22 @@ void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
if (location == -1)
return;
- GPU_CHECK_ERRORS_AROUND(glUniform1i(location, value));
+ glUniform1i(location, value);
}
-void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number)
+void GPU_shader_uniform_buffer(GPUShader *shader, int location, GPUUniformBuffer *ubo)
{
- if (GPU_geometry_shader_support_via_extension()) {
- /* geometry shaders must provide this info themselves for #version 150 and up */
- glProgramParameteriEXT(shader->program, GL_GEOMETRY_INPUT_TYPE_EXT, input);
- glProgramParameteriEXT(shader->program, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
- glProgramParameteriEXT(shader->program, GL_GEOMETRY_VERTICES_OUT_EXT, number);
+ int bindpoint = GPU_uniformbuffer_bindpoint(ubo);
+
+ if (location == -1) {
+ return;
}
+
+ glUniformBlockBinding(shader->program, location, bindpoint);
}
void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
{
- GLenum arbnumber;
int number = GPU_texture_bound_number(tex);
int bindcode = GPU_texture_opengl_bindcode(tex);
int target = GPU_texture_target(tex);
@@ -566,78 +582,223 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
if (location == -1)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
-
- arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + number);
+ if (number != 0)
+ glActiveTexture(GL_TEXTURE0 + number);
- if (number != 0) glActiveTexture(arbnumber);
if (bindcode != 0)
glBindTexture(target, bindcode);
else
GPU_invalid_tex_bind(target);
+
glUniform1i(location, number);
- glEnable(target);
- if (number != 0) glActiveTexture(GL_TEXTURE0);
- GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
+ if (number != 0)
+ glActiveTexture(GL_TEXTURE0);
}
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
- int index;
-
- GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocation(shader->program, name));
-
- return index;
+ BLI_assert(shader && shader->program);
+ const ShaderInput *attrib = ShaderInterface_attrib(shader->interface, name);
+ return attrib ? attrib->location : -1;
}
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
{
- GPUShader *retval = NULL;
-
- switch (shader) {
- case GPU_SHADER_VSM_STORE:
- if (!GG.shaders.vsm_store)
- GG.shaders.vsm_store = GPU_shader_create(
- datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.vsm_store;
- break;
- case GPU_SHADER_SEP_GAUSSIAN_BLUR:
- if (!GG.shaders.sep_gaussian_blur)
- GG.shaders.sep_gaussian_blur = GPU_shader_create(
- datatoc_gpu_shader_sep_gaussian_blur_vert_glsl,
- datatoc_gpu_shader_sep_gaussian_blur_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.sep_gaussian_blur;
- break;
- case GPU_SHADER_SMOKE:
- if (!GG.shaders.smoke)
- GG.shaders.smoke = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.smoke;
- break;
- case GPU_SHADER_SMOKE_FIRE:
- if (!GG.shaders.smoke_fire)
- GG.shaders.smoke_fire = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_fire_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.smoke_fire;
- break;
- case GPU_SHADER_SMOKE_COBA:
- if (!GG.shaders.smoke_coba)
- GG.shaders.smoke_coba = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
- NULL, NULL, "#define USE_COBA;\n", 0, 0, 0);
- retval = GG.shaders.smoke_coba;
- break;
- }
+ BLI_assert(shader != GPU_NUM_BUILTIN_SHADERS); /* don't be a troll */
+
+ static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = {
+ [GPU_SHADER_VSM_STORE] = { datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl },
+ [GPU_SHADER_SEP_GAUSSIAN_BLUR] = { datatoc_gpu_shader_sep_gaussian_blur_vert_glsl,
+ datatoc_gpu_shader_sep_gaussian_blur_frag_glsl },
+ [GPU_SHADER_SMOKE] = { datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl },
+ [GPU_SHADER_SMOKE_FIRE] = { datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl },
+ [GPU_SHADER_SMOKE_COBA] = { datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl },
+
+ [GPU_SHADER_TEXT] = { datatoc_gpu_shader_text_vert_glsl, datatoc_gpu_shader_text_frag_glsl },
+ [GPU_SHADER_KEYFRAME_DIAMOND] = { datatoc_gpu_shader_keyframe_diamond_vert_glsl,
+ datatoc_gpu_shader_keyframe_diamond_frag_glsl },
+ [GPU_SHADER_EDGES_FRONT_BACK_PERSP] = { datatoc_gpu_shader_edges_front_back_persp_vert_glsl,
+ /* this version is */ datatoc_gpu_shader_flat_color_frag_glsl,
+ /* magical but slooow */ datatoc_gpu_shader_edges_front_back_persp_geom_glsl },
+ [GPU_SHADER_EDGES_FRONT_BACK_ORTHO] = { datatoc_gpu_shader_edges_front_back_ortho_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_EDGES_OVERLAY_SIMPLE] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_edges_overlay_frag_glsl,
+ datatoc_gpu_shader_edges_overlay_simple_geom_glsl },
+ [GPU_SHADER_EDGES_OVERLAY] = { datatoc_gpu_shader_edges_overlay_vert_glsl,
+ datatoc_gpu_shader_edges_overlay_frag_glsl,
+ datatoc_gpu_shader_edges_overlay_geom_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING] = { datatoc_gpu_shader_3D_normal_vert_glsl, datatoc_gpu_shader_simple_lighting_frag_glsl },
+ /* Use 'USE_FLAT_NORMAL' to make flat shader from smooth */
+ [GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR] = { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA] = { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl },
+
+ [GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_mask_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_IMAGE_MODULATE_ALPHA] = { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_modulate_alpha_frag_glsl },
+ [GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA] = { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl },
+ [GPU_SHADER_3D_IMAGE_DEPTH] = { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_depth_linear_frag_glsl },
+
+ [GPU_SHADER_2D_IMAGE_INTERLACE] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_interlace_frag_glsl },
+ [GPU_SHADER_2D_CHECKER] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_checker_frag_glsl },
+
+ [GPU_SHADER_2D_DIAG_STRIPES] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_diag_stripes_frag_glsl },
+
+ [GPU_SHADER_2D_UNIFORM_COLOR] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_2D_FLAT_COLOR] = { datatoc_gpu_shader_2D_flat_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_2D_SMOOTH_COLOR] = { datatoc_gpu_shader_2D_smooth_color_vert_glsl,
+ datatoc_gpu_shader_2D_smooth_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_linear_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_ALPHA_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_alpha_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_shuffle_color_frag_glsl },
+ [GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_3D_FLAT_COLOR_U32] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_3D_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl,
+ datatoc_gpu_shader_3D_smooth_color_frag_glsl },
+ [GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl },
+ [GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl },
+
+ [GPU_SHADER_3D_GROUNDPOINT] = { datatoc_gpu_shader_3D_groundpoint_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_passthrough_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ datatoc_gpu_shader_3D_groundline_geom_glsl },
+
+ [GPU_SHADER_2D_LINE_DASHED_COLOR] = { datatoc_gpu_shader_2D_line_dashed_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl,
+ datatoc_gpu_shader_2D_line_dashed_geom_glsl },
+ [GPU_SHADER_3D_LINE_DASHED_COLOR] = { datatoc_gpu_shader_3D_line_dashed_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl,
+ datatoc_gpu_shader_2D_line_dashed_geom_glsl },
+
+ [GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR] =
+ { datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_frag_glsl},
+ [GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR] = { datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR] = { datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] = { datatoc_gpu_shader_instance_screen_aligned_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED] = { datatoc_gpu_shader_instance_screen_aligned_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+
+ [GPU_SHADER_CAMERA] = { datatoc_gpu_shader_instance_camera_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_DISTANCE_LINES] = { datatoc_gpu_shader_instance_distance_line_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+
+ [GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR] =
+ { datatoc_gpu_shader_2D_point_varying_size_varying_color_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_aa_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl },
+ [GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR] = { datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_VARYING_SIZE_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_point_varying_size_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR] =
+ { datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
+ { datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_aa_frag_glsl },
+ [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_3D_point_uniform_size_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
+
+ [GPU_SHADER_INSTANCE_UNIFORM_COLOR] = { datatoc_gpu_shader_instance_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE] =
+ { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE] =
+ { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR] = { datatoc_gpu_shader_instance_edges_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_gpu_shader_instance_edges_variying_color_geom_glsl},
+
+ [GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID] = { datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_frag_glsl },
+ [GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE] = { datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ };
+
+ if (builtin_shaders[shader] == NULL) {
+ /* just a few special cases */
+ const char *defines = NULL;
+ switch (shader) {
+ case GPU_SHADER_SMOKE_COBA:
+ defines = "#define USE_COBA;\n";
+ break;
+ case GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE:
+ defines = "#define UNIFORM_SCALE;\n";
+ break;
+ case GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS:
+ defines = "#define AXIS_NAME;\n";
+ break;
+ case GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR:
+ case GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID:
+ defines = "#define USE_INSTANCE_COLOR;\n";
+ break;
+ case GPU_SHADER_3D_FLAT_COLOR_U32:
+ defines = "#define USE_COLOR_U32;\n";
+ break;
+ case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR:
+ defines = "#define USE_FLAT_NORMAL;\n";
+ break;
+ default:
+ break;
+ }
+
+ const GPUShaderStages *stages = builtin_shader_stages + shader;
- if (retval == NULL)
- printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
+ if (shader == GPU_SHADER_EDGES_FRONT_BACK_PERSP && !GLEW_VERSION_3_2) {
+ /* TODO: remove after switch to core profile (maybe) */
+ static const GPUShaderStages legacy_fancy_edges =
+ { datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl,
+ datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl };
+ stages = &legacy_fancy_edges;
+ }
- return retval;
+ if (shader == GPU_SHADER_3D_LINE_DASHED_COLOR && !GLEW_VERSION_3_2) {
+ /* Dashed need geometry shader, which are not supported by legacy OpenGL, fallback to solid lines. */
+ /* TODO: remove after switch to core profile (maybe) */
+ static const GPUShaderStages legacy_dashed_lines = { datatoc_gpu_shader_3D_line_dashed_legacy_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl };
+ stages = &legacy_dashed_lines;
+ }
+
+ /* common case */
+ builtin_shaders[shader] = GPU_shader_create(stages->vert, stages->frag, stages->geom, NULL, defines);
+ }
+
+ return builtin_shaders[shader];
}
#define MAX_DEFINES 100
@@ -657,103 +818,80 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effect, bool persp)
strcat(defines, "#define PERSP_MATRIX\n");
}
- if (!GG.shaders.fx_shaders[offset]) {
+ if (!fx_shaders[offset]) {
GPUShader *shader = NULL;
switch (effect) {
case GPU_SHADER_FX_SSAO:
- shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
strcat(defines, "#define FIRST_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
strcat(defines, "#define SECOND_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
strcat(defines, "#define THIRD_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
strcat(defines, "#define FOURTH_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
strcat(defines, "#define FIFTH_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE:
strcat(defines, "#define FIRST_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO:
strcat(defines, "#define SECOND_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl,
- defines, GL_POINTS, GL_TRIANGLE_STRIP, 4);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE:
strcat(defines, "#define THIRD_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
case GPU_SHADER_FX_DEPTH_RESOLVE:
- shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines);
break;
}
- GG.shaders.fx_shaders[offset] = shader;
+ fx_shaders[offset] = shader;
GPU_fx_shader_init_interface(shader, effect);
}
- return GG.shaders.fx_shaders[offset];
+ return fx_shaders[offset];
}
void GPU_shader_free_builtin_shaders(void)
{
- int i;
-
- if (GG.shaders.vsm_store) {
- GPU_shader_free(GG.shaders.vsm_store);
- GG.shaders.vsm_store = NULL;
- }
-
- if (GG.shaders.sep_gaussian_blur) {
- GPU_shader_free(GG.shaders.sep_gaussian_blur);
- GG.shaders.sep_gaussian_blur = NULL;
- }
-
- if (GG.shaders.smoke) {
- GPU_shader_free(GG.shaders.smoke);
- GG.shaders.smoke = NULL;
- }
-
- if (GG.shaders.smoke_fire) {
- GPU_shader_free(GG.shaders.smoke_fire);
- GG.shaders.smoke_fire = NULL;
- }
-
- if (GG.shaders.smoke_coba) {
- GPU_shader_free(GG.shaders.smoke_coba);
- GG.shaders.smoke_coba = NULL;
+ for (int i = 0; i < GPU_NUM_BUILTIN_SHADERS; ++i) {
+ if (builtin_shaders[i]) {
+ GPU_shader_free(builtin_shaders[i]);
+ builtin_shaders[i] = NULL;
+ }
}
- for (i = 0; i < 2 * MAX_FX_SHADERS; ++i) {
- if (GG.shaders.fx_shaders[i]) {
- GPU_shader_free(GG.shaders.fx_shaders[i]);
- GG.shaders.fx_shaders[i] = NULL;
+ for (int i = 0; i < 2 * MAX_FX_SHADERS; ++i) {
+ if (fx_shaders[i]) {
+ GPU_shader_free(fx_shaders[i]);
+ fx_shaders[i] = NULL;
}
}
}
-
-
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h
new file mode 100644
index 00000000000..c0c24187da5
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_private.h
@@ -0,0 +1,45 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_shader_private.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_SHADER_PRIVATE_H__
+#define __GPU_SHADER_PRIVATE_H__
+
+#include "GPU_glew.h"
+#include "gawain/shader_interface.h"
+
+struct GPUShader {
+ GLuint program; /* handle for full program (links shader stages below) */
+
+ GLuint vertex; /* handle for vertex shader */
+ GLuint geometry; /* handle for geometry shader */
+ GLuint fragment; /* handle for fragment shader */
+
+ void *uniform_interface; /* cached uniform interface for shader. Data depends on shader */
+ /* NOTE: ^-- only FX compositing shaders use this */
+
+ ShaderInterface *interface; /* cached uniform & attrib interface for shader */
+};
+
+#endif /* __GPU_SHADER_PRIVATE_H__ */
+
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 1c97c2ce811..3ac1571bf82 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -49,9 +49,8 @@ static struct GPUTextureGlobal {
} GG = {NULL, NULL, NULL};
/* GPUTexture */
-
struct GPUTexture {
- int w, h; /* width/height */
+ int w, h, d; /* width/height/depth */
int number; /* number for multitexture binding */
int refcount; /* reference count */
GLenum target; /* GL_TEXTURE_* */
@@ -62,43 +61,257 @@ struct GPUTexture {
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
int fb_attachment; /* slot the texture is attached to */
- int depth; /* is a depth texture? if 3D how deep? */
+ bool depth; /* is a depth texture? */
+ bool stencil; /* is a stencil texture? */
+
+ unsigned int bytesize; /* number of byte for one pixel */
+ int format; /* GPUTextureFormat */
};
-static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixels)
+/* ------ Memory Management ------- */
+/* Records every texture allocation / free
+ * to estimate the Texture Pool Memory consumption */
+static unsigned int memory_usage;
+
+static unsigned int gpu_texture_memory_footprint_compute(GPUTexture *tex)
{
- unsigned char *pixels, *p;
- const float *fp = fpixels;
- const int len = 4 * length;
+ switch (tex->target) {
+ case GL_TEXTURE_1D:
+ return tex->bytesize * tex->w;
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_2D:
+ return tex->bytesize * tex->w * tex->h;
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_3D:
+ return tex->bytesize * tex->w * tex->h * tex->d;
+ case GL_TEXTURE_CUBE_MAP:
+ return tex->bytesize * 6 * tex->w * tex->h;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ return tex->bytesize * 6 * tex->w * tex->h * tex->d;
+ default:
+ return 0;
+ }
+}
- p = pixels = MEM_callocN(sizeof(unsigned char) * len, "GPUTexturePixels");
+static void gpu_texture_memory_footprint_add(GPUTexture *tex)
+{
+ memory_usage += gpu_texture_memory_footprint_compute(tex);
+}
- for (int a = 0; a < len; a++, p++, fp++)
- *p = FTOCHAR((*fp));
+static void gpu_texture_memory_footprint_remove(GPUTexture *tex)
+{
+ memory_usage -= gpu_texture_memory_footprint_compute(tex);
+}
- return pixels;
+unsigned int GPU_texture_memory_usage_get(void)
+{
+ return memory_usage;
}
-static void gpu_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
+/* -------------------------------- */
+
+static GLenum gpu_texture_get_format(
+ int components, GPUTextureFormat data_type,
+ GLenum *format, GLenum *data_format, bool *is_depth, bool *is_stencil, unsigned int *bytesize)
{
- void *pixels = MEM_callocN(sizeof(char) * 4 * w * h, "GPUTextureEmptyPixels");
+ if (data_type == GPU_DEPTH_COMPONENT24 ||
+ data_type == GPU_DEPTH_COMPONENT16 ||
+ data_type == GPU_DEPTH_COMPONENT32F)
+ {
+ *is_depth = true;
+ *is_stencil = false;
+ *data_format = GL_FLOAT;
+ *format = GL_DEPTH_COMPONENT;
+ }
+ else if (data_type == GPU_DEPTH24_STENCIL8) {
+ *is_depth = true;
+ *is_stencil = true;
+ *data_format = GL_UNSIGNED_INT_24_8;
+ *format = GL_DEPTH_STENCIL;
+ }
+ else {
+ *is_depth = false;
+ *is_stencil = false;
+ *data_format = GL_FLOAT;
+
+ switch (components) {
+ case 1: *format = GL_RED; break;
+ case 2: *format = GL_RG; break;
+ case 3: *format = GL_RGB; break;
+ case 4: *format = GL_RGBA; break;
+ default: break;
+ }
+ }
- if (target == GL_TEXTURE_1D)
- glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
- else
- glTexSubImage2D(target, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
-
- MEM_freeN(pixels);
+ switch (data_type) {
+ case GPU_RGBA32F:
+ *bytesize = 32;
+ break;
+ case GPU_RG32F:
+ case GPU_RGBA16F:
+ *bytesize = 16;
+ break;
+ case GPU_RGB16F:
+ *bytesize = 12;
+ break;
+ case GPU_RG16F:
+ case GPU_DEPTH24_STENCIL8:
+ case GPU_DEPTH_COMPONENT32F:
+ case GPU_RGBA8:
+ case GPU_R11F_G11F_B10F:
+ case GPU_R32F:
+ *bytesize = 4;
+ break;
+ case GPU_DEPTH_COMPONENT24:
+ *bytesize = 3;
+ break;
+ case GPU_DEPTH_COMPONENT16:
+ case GPU_R16F:
+ *bytesize = 2;
+ break;
+ case GPU_R8:
+ *bytesize = 1;
+ break;
+ default:
+ *bytesize = 0;
+ break;
+ }
+
+ /* You can add any of the available type to this list
+ * For available types see GPU_texture.h */
+ switch (data_type) {
+ /* Formats texture & renderbuffer */
+ case GPU_RGBA32F: return GL_RGBA32F;
+ case GPU_RGBA16F: return GL_RGBA16F;
+ case GPU_RG32F: return GL_RG32F;
+ case GPU_RGB16F: return GL_RGB16F;
+ case GPU_RG16F: return GL_RG16F;
+ case GPU_RGBA8: return GL_RGBA8;
+ case GPU_R32F: return GL_R32F;
+ case GPU_R16F: return GL_R16F;
+ case GPU_R8: return GL_R8;
+ /* Special formats texture & renderbuffer */
+ case GPU_R11F_G11F_B10F: return GL_R11F_G11F_B10F;
+ case GPU_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
+ /* Texture only format */
+ /* ** Add Format here **/
+ /* Special formats texture only */
+ /* ** Add Format here **/
+ /* Depth Formats */
+ case GPU_DEPTH_COMPONENT32F: return GL_DEPTH_COMPONENT32F;
+ case GPU_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24;
+ case GPU_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16;
+ default:
+ fprintf(stderr, "Texture format incorrect or unsupported\n");
+ return 0;
+ }
}
-static GPUTexture *GPU_texture_create_nD(
- int w, int h, int n, const float *fpixels, int depth,
- GPUHDRType hdr_type, int components, int samples,
- char err_out[256])
+static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int channels, const float *fpixels)
+{
+ const unsigned int xf = w / tex->w, yf = h / tex->h, zf = d / tex->d;
+ float *nfpixels = MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d, "GPUTexture Rescaled 3Dtex");
+
+ if (nfpixels) {
+ GPU_print_error_debug("You need to scale a 3D texture, feel the pain!");
+
+ for (unsigned k = 0; k < tex->d; k++) {
+ for (unsigned j = 0; j < tex->h; j++) {
+ for (unsigned i = 0; i < tex->w; i++) {
+ /* obviously doing nearest filtering here,
+ * it's going to be slow in any case, let's not make it worse */
+ float xb = i * xf;
+ float yb = j * yf;
+ float zb = k * zf;
+ unsigned int offset = k * (tex->w * tex->h) + i * tex->h + j;
+ unsigned int offset_orig = (zb) * (w * h) + (xb) * h + (yb);
+
+ if (channels == 4) {
+ nfpixels[offset * 4] = fpixels[offset_orig * 4];
+ nfpixels[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
+ nfpixels[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
+ nfpixels[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
+ }
+ else
+ nfpixels[offset] = fpixels[offset_orig];
+ }
+ }
+ }
+ }
+
+ return nfpixels;
+}
+
+/* This tries to allocate video memory for a given texture
+ * If alloc fails, lower the resolution until it fits. */
+static bool gpu_texture_try_alloc(
+ GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, GLenum data_format,
+ int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
{
- GLenum type, format, internalformat;
- void *pixels = NULL;
+ int r_width;
+
+ switch (proxy) {
+ case GL_PROXY_TEXTURE_1D:
+ glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
+ break;
+ case GL_PROXY_TEXTURE_1D_ARRAY:
+ case GL_PROXY_TEXTURE_2D:
+ glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
+ break;
+ case GL_PROXY_TEXTURE_2D_ARRAY:
+ case GL_PROXY_TEXTURE_3D:
+ glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
+ break;
+ }
+
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &r_width);
+
+ if (r_width == 0 && try_rescale) {
+ const int w = tex->w, h = tex->h, d = tex->d;
+
+ /* Find largest texture possible */
+ while (r_width == 0) {
+ tex->w /= 2;
+ tex->h /= 2;
+ tex->d /= 2;
+
+ /* really unlikely to happen but keep this just in case */
+ if (tex->w == 0) break;
+ if (tex->h == 0 && proxy != GL_PROXY_TEXTURE_1D) break;
+ if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
+
+ if (proxy == GL_PROXY_TEXTURE_1D)
+ glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
+ else if (proxy == GL_PROXY_TEXTURE_2D)
+ glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
+ else if (proxy == GL_PROXY_TEXTURE_3D)
+ glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
+
+ glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
+ }
+
+ /* Rescale */
+ if (r_width > 0) {
+ switch (proxy) {
+ case GL_PROXY_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_2D:
+ /* Do nothing for now */
+ return false;
+ case GL_PROXY_TEXTURE_3D:
+ *rescaled_fpixels = GPU_texture_3D_rescale(tex, w, h, d, channels, fpixels);
+ return (bool)*rescaled_fpixels;
+ }
+ }
+ }
+
+ return (r_width > 0);
+}
+static GPUTexture *GPU_texture_create_nD(
+ int w, int h, int d, int n, const float *fpixels,
+ GPUTextureFormat data_type, int components, int samples,
+ const bool can_rescale, char err_out[256])
+{
if (samples) {
CLAMP_MAX(samples, GPU_max_color_texture_samples());
}
@@ -106,264 +319,204 @@ static GPUTexture *GPU_texture_create_nD(
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = w;
tex->h = h;
+ tex->d = d;
tex->number = -1;
tex->refcount = 1;
- tex->target = (n == 1) ? GL_TEXTURE_1D : (samples ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D);
- tex->target_base = (n == 1) ? GL_TEXTURE_1D : GL_TEXTURE_2D;
- tex->depth = depth;
tex->fb_attachment = -1;
+ tex->format = data_type;
+ if (n == 2) {
+ if (d == 0)
+ tex->target_base = tex->target = GL_TEXTURE_2D;
+ else
+ tex->target_base = tex->target = GL_TEXTURE_2D_ARRAY;
+ }
+ else if (n == 1) {
+ if (h == 0)
+ tex->target_base = tex->target = GL_TEXTURE_1D;
+ else
+ tex->target_base = tex->target = GL_TEXTURE_1D_ARRAY;
+ }
+ else if (n == 3) {
+ tex->target_base = tex->target = GL_TEXTURE_3D;
+ }
+ else {
+ /* should never happen */
+ MEM_freeN(tex);
+ return NULL;
+ }
+
+ if (samples && n == 2 && d == 0)
+ tex->target = GL_TEXTURE_2D_MULTISAMPLE;
+
+ GLenum format, internalformat, data_format;
+ internalformat = gpu_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil, &tex->bytesize);
+
+ gpu_texture_memory_footprint_add(tex);
+
+ /* Generate Texture object */
glGenTextures(1, &tex->bindcode);
if (!tex->bindcode) {
- if (err_out) {
- BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d",
- (int)glGetError());
- }
- else {
- fprintf(stderr, "GPUTexture: texture create failed: %d\n",
- (int)glGetError());
- }
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUTexture: texture create failed");
+ else
+ fprintf(stderr, "GPUTexture: texture create failed");
GPU_texture_free(tex);
return NULL;
}
- if (!GPU_full_non_power_of_two_support()) {
- tex->w = power_of_2_max_i(tex->w);
- tex->h = power_of_2_max_i(tex->h);
- }
-
tex->number = 0;
glBindTexture(tex->target, tex->bindcode);
- if (depth) {
- type = GL_UNSIGNED_BYTE;
- format = GL_DEPTH_COMPONENT;
- internalformat = GL_DEPTH_COMPONENT;
- }
- else {
- type = GL_FLOAT;
-
- if (components == 4) {
- format = GL_RGBA;
- switch (hdr_type) {
- case GPU_HDR_NONE:
- internalformat = GL_RGBA8;
- break;
- /* the following formats rely on ARB_texture_float or OpenGL 3.0 */
- case GPU_HDR_HALF_FLOAT:
- internalformat = GL_RGBA16F_ARB;
- break;
- case GPU_HDR_FULL_FLOAT:
- internalformat = GL_RGBA32F_ARB;
- break;
- default:
- break;
- }
- }
- else if (components == 2) {
- /* these formats rely on ARB_texture_rg or OpenGL 3.0 */
- format = GL_RG;
- switch (hdr_type) {
- case GPU_HDR_NONE:
- internalformat = GL_RG8;
- break;
- case GPU_HDR_HALF_FLOAT:
- internalformat = GL_RG16F;
- break;
- case GPU_HDR_FULL_FLOAT:
- internalformat = GL_RG32F;
- break;
- default:
- break;
- }
- }
+ /* Check if texture fit in VRAM */
+ GLenum proxy = GL_PROXY_TEXTURE_2D;
- if (fpixels && hdr_type == GPU_HDR_NONE) {
- type = GL_UNSIGNED_BYTE;
- pixels = GPU_texture_convert_pixels(w * h, fpixels);
- }
+ if (n == 2) {
+ if (d > 0)
+ proxy = GL_PROXY_TEXTURE_2D_ARRAY;
+ }
+ else if (n == 1) {
+ if (h == 0)
+ proxy = GL_PROXY_TEXTURE_1D;
+ else
+ proxy = GL_PROXY_TEXTURE_1D_ARRAY;
+ }
+ else if (n == 3) {
+ proxy = GL_PROXY_TEXTURE_3D;
}
- if (tex->target == GL_TEXTURE_1D) {
- glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, NULL);
+ float *rescaled_fpixels = NULL;
+ bool valid = gpu_texture_try_alloc(tex, proxy, internalformat, format, data_format, components, can_rescale,
+ fpixels, &rescaled_fpixels);
+ if (!valid) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUTexture: texture alloc failed");
+ else
+ fprintf(stderr, "GPUTexture: texture alloc failed. Not enough Video Memory.");
+ GPU_texture_free(tex);
+ return NULL;
+ }
- if (fpixels) {
- glTexSubImage1D(tex->target, 0, 0, w, format, type,
- pixels ? pixels : fpixels);
+ /* Upload Texture */
+ const float *pix = (rescaled_fpixels) ? rescaled_fpixels : fpixels;
- if (tex->w > w) {
- gpu_glTexSubImageEmpty(tex->target, format, w, 0, tex->w - w, 1);
- }
- }
- }
- else {
+ if (tex->target == GL_TEXTURE_2D ||
+ tex->target == GL_TEXTURE_2D_MULTISAMPLE ||
+ tex->target == GL_TEXTURE_1D_ARRAY)
+ {
if (samples) {
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
+ if (pix)
+ glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pix);
}
else {
- glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0,
- format, type, NULL);
- }
-
- if (fpixels) {
- glTexSubImage2D(tex->target, 0, 0, 0, w, h,
- format, type, pixels ? pixels : fpixels);
-
- if (tex->w > w) {
- gpu_glTexSubImageEmpty(tex->target, format, w, 0, tex->w - w, tex->h);
- }
- if (tex->h > h) {
- gpu_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h - h);
- }
+ glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, data_format, pix);
}
}
+ else if (tex->target == GL_TEXTURE_1D) {
+ glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, data_format, pix);
+ }
+ else {
+ glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, pix);
+ }
- if (pixels)
- MEM_freeN(pixels);
+ if (rescaled_fpixels)
+ MEM_freeN(rescaled_fpixels);
- if (depth) {
+ /* Texture Parameters */
+ if (tex->depth) {
glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(tex->target_base, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(tex->target_base, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
- glTexParameteri(tex->target_base, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
}
else {
glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
- if (tex->target_base != GL_TEXTURE_1D) {
- glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ if (n > 1) {
glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
- else
- glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ if (n > 2) {
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ }
+
+ GPU_texture_unbind(tex);
return tex;
}
-
-GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const float *fpixels)
+static GPUTexture *GPU_texture_cube_create(
+ int w, int d,
+ const float *fpixels_px, const float *fpixels_py, const float *fpixels_pz,
+ const float *fpixels_nx, const float *fpixels_ny, const float *fpixels_nz,
+ GPUTextureFormat data_type, int components,
+ char err_out[256])
{
- GLenum type, format, internalformat;
- void *pixels = NULL;
+ GLenum format, internalformat, data_format;
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = w;
- tex->h = h;
- tex->depth = depth;
+ tex->h = w;
+ tex->d = d;
tex->number = -1;
tex->refcount = 1;
- tex->target = GL_TEXTURE_3D;
- tex->target_base = GL_TEXTURE_3D;
-
- glGenTextures(1, &tex->bindcode);
-
- if (!tex->bindcode) {
- fprintf(stderr, "GPUTexture: texture create failed: %d\n",
- (int)glGetError());
- GPU_texture_free(tex);
- return NULL;
- }
-
- tex->number = 0;
- glBindTexture(tex->target, tex->bindcode);
-
- GPU_ASSERT_NO_GL_ERRORS("3D glBindTexture");
+ tex->fb_attachment = -1;
+ tex->format = data_type;
- type = GL_FLOAT;
- if (channels == 4) {
- format = GL_RGBA;
- internalformat = GL_RGBA8;
+ if (d == 0) {
+ tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP;
}
else {
- format = GL_RED;
- internalformat = GL_INTENSITY8;
+ BLI_assert(false && "Cubemap array Not implemented yet");
+ // tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY;
}
- /* 3D textures are quite heavy, test if it's possible to create them first */
- glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
+ internalformat = gpu_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil, &tex->bytesize);
- bool rescale = false;
- int r_width;
+ gpu_texture_memory_footprint_add(tex);
- glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
+ /* Generate Texture object */
+ glGenTextures(1, &tex->bindcode);
- while (r_width == 0) {
- rescale = true;
- tex->w /= 2;
- tex->h /= 2;
- tex->depth /= 2;
- glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
- glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
+ if (!tex->bindcode) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUTexture: texture create failed");
+ else
+ fprintf(stderr, "GPUTexture: texture create failed");
+ GPU_texture_free(tex);
+ return NULL;
}
- /* really unlikely to happen but keep this just in case */
- tex->w = max_ii(tex->w, 1);
- tex->h = max_ii(tex->h, 1);
- tex->depth = max_ii(tex->depth, 1);
-
-#if 0
- if (fpixels)
- pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
-#endif
-
- GPU_ASSERT_NO_GL_ERRORS("3D glTexImage3D");
-
- /* hardcore stuff, 3D texture rescaling - warning, this is gonna hurt your performance a lot, but we need it
- * for gooseberry */
- if (rescale && fpixels) {
- /* FIXME: should these be floating point? */
- const unsigned int xf = w / tex->w, yf = h / tex->h, zf = depth / tex->depth;
- float *tex3d = MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->depth, "tex3d");
-
- GPU_print_error_debug("You need to scale a 3D texture, feel the pain!");
-
- for (unsigned k = 0; k < tex->depth; k++) {
- for (unsigned j = 0; j < tex->h; j++) {
- for (unsigned i = 0; i < tex->w; i++) {
- /* obviously doing nearest filtering here,
- * it's going to be slow in any case, let's not make it worse */
- float xb = i * xf;
- float yb = j * yf;
- float zb = k * zf;
- unsigned int offset = k * (tex->w * tex->h) + i * tex->h + j;
- unsigned int offset_orig = (zb) * (w * h) + (xb) * h + (yb);
-
- if (channels == 4) {
- tex3d[offset * 4] = fpixels[offset_orig * 4];
- tex3d[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
- tex3d[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
- tex3d[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
- }
- else
- tex3d[offset] = fpixels[offset_orig];
- }
- }
- }
+ tex->number = 0;
+ glBindTexture(tex->target, tex->bindcode);
- glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, tex3d);
+ /* Upload Texture */
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_px);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_py);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_pz);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_nx);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_ny);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_nz);
- MEM_freeN(tex3d);
+ /* Texture Parameters */
+ if (tex->depth) {
+ glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(tex->target_base, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(tex->target_base, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
}
else {
- if (fpixels) {
- glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
- GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
- }
+ glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
-
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-
- if (pixels)
- MEM_freeN(pixels);
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
GPU_texture_unbind(tex);
@@ -380,6 +533,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
/* see GPUInput::textarget: it can take two values - GL_TEXTURE_2D and GL_TEXTURE_CUBE_MAP
* these values are correct for glDisable, so textarget can be safely used in
* GPU_texture_bind/GPU_texture_unbind through tex->target_base */
+ /* (is any of this obsolete now that we don't glEnable/Disable textures?) */
if (textarget == GL_TEXTURE_2D)
gputt = TEXTARGET_TEXTURE_2D;
else
@@ -398,14 +552,15 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
tex->target = textarget;
tex->target_base = textarget;
tex->fromblender = 1;
+ tex->format = -1;
ima->gputexture[gputt] = tex;
if (!glIsTexture(tex->bindcode)) {
- GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
+ GPU_print_error_debug("Blender Texture Not Loaded");
}
else {
- GLint w, h, border;
+ GLint w, h;
GLenum gettarget;
@@ -417,10 +572,8 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
glBindTexture(textarget, tex->bindcode);
glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_BORDER, &border);
-
- tex->w = w - border;
- tex->h = h - border;
+ tex->w = w;
+ tex->h = h;
}
glBindTexture(textarget, 0);
@@ -452,11 +605,12 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
tex->refcount = 1;
tex->target = GL_TEXTURE_2D;
tex->target_base = GL_TEXTURE_2D;
+ tex->format = -1;
prv->gputexture[0] = tex;
if (!glIsTexture(tex->bindcode)) {
- GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
+ GPU_print_error_debug("Blender Texture Not Loaded");
}
else {
GLint w, h;
@@ -475,114 +629,88 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
}
-GPUTexture *GPU_texture_create_1D(int w, const float *fpixels, char err_out[256])
+GPUTexture *GPU_texture_create_1D(int w, const float *pixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, GPU_HDR_NONE, 4, 0, err_out);
-
- if (tex)
- GPU_texture_unbind(tex);
-
- return tex;
+ return GPU_texture_create_nD(w, 0, 0, 1, pixels, GPU_RGBA8, 4, 0, false, err_out);
}
-GPUTexture *GPU_texture_create_2D(int w, int h, const float *fpixels, GPUHDRType hdr, char err_out[256])
+GPUTexture *GPU_texture_create_1D_custom(
+ int w, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, hdr, 4, 0, err_out);
-
- if (tex)
- GPU_texture_unbind(tex);
-
- return tex;
+ return GPU_texture_create_nD(w, 0, 0, 1, pixels, data_type, channels, 0, false, err_out);
}
-GPUTexture *GPU_texture_create_2D_multisample(
- int w, int h, const float *fpixels, GPUHDRType hdr, int samples, char err_out[256])
-{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, hdr, 4, samples, err_out);
- if (tex)
- GPU_texture_unbind(tex);
-
- return tex;
+GPUTexture *GPU_texture_create_2D(int w, int h, const float *pixels, char err_out[256])
+{
+ return GPU_texture_create_nD(w, h, 0, 2, pixels, GPU_RGBA8, 4, 0, false, err_out);
}
-GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
+GPUTexture *GPU_texture_create_2D_custom(
+ int w, int h, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, 0, err_out);
-
- if (tex)
- GPU_texture_unbind(tex);
-
- return tex;
+ return GPU_texture_create_nD(w, h, 0, 2, pixels, data_type, channels, 0, false, err_out);
}
-GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256])
-{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, samples, err_out);
- if (tex)
- GPU_texture_unbind(tex);
-
- return tex;
+GPUTexture *GPU_texture_create_2D_multisample(int w, int h, const float *pixels, int samples, char err_out[256])
+{
+ return GPU_texture_create_nD(w, h, 0, 2, pixels, GPU_RGBA8, 4, samples, false, err_out);
}
-/**
- * A shadow map for VSM needs two components (depth and depth^2)
- */
-GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256])
+GPUTexture *GPU_texture_create_2D_array_custom(int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, GPU_HDR_FULL_FLOAT, 2, 0, err_out);
-
- if (tex) {
- /* Now we tweak some of the settings */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- GPU_texture_unbind(tex);
- }
-
- return tex;
+ return GPU_texture_create_nD(w, h, d, 2, pixels, data_type, channels, 0, false, err_out);
}
-GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, char err_out[256])
+GPUTexture *GPU_texture_create_3D(int w, int h, int d, const float *pixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, pixels, 0, GPU_HDR_HALF_FLOAT, 2, 0, err_out);
+ return GPU_texture_create_nD(w, h, d, 3, pixels, GPU_RGBA8, 4, 0, true, err_out);
+}
- if (tex) {
- /* Now we tweak some of the settings */
- if (repeat) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+GPUTexture *GPU_texture_create_3D_custom(int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256])
+{
+ return GPU_texture_create_nD(w, h, d, 3, pixels, data_type, channels, 0, true, err_out);
+}
+GPUTexture *GPU_texture_create_cube_custom(int w, int channels, GPUTextureFormat data_type, const float *fpixels, char err_out[256])
+{
+ const float *fpixels_px, *fpixels_py, *fpixels_pz, *fpixels_nx, *fpixels_ny, *fpixels_nz;
- GPU_texture_unbind(tex);
+ if (fpixels) {
+ fpixels_px = fpixels + 0 * w * w * channels;
+ fpixels_nx = fpixels + 1 * w * w * channels;
+ fpixels_py = fpixels + 2 * w * w * channels;
+ fpixels_ny = fpixels + 3 * w * w * channels;
+ fpixels_pz = fpixels + 4 * w * w * channels;
+ fpixels_nz = fpixels + 5 * w * w * channels;
+ }
+ else {
+ fpixels_px = fpixels_py = fpixels_pz = fpixels_nx = fpixels_ny = fpixels_nz = NULL;
}
- return tex;
+ return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz, data_type, channels, err_out);
}
-GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char err_out[256])
+GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, 0, 1, pixels, 0, GPU_HDR_HALF_FLOAT, 2, 0, err_out);
-
- if (tex) {
- /* Now we tweak some of the settings */
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, 0, false, err_out);
+}
- GPU_texture_unbind(tex);
- }
+GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256])
+{
+ return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH24_STENCIL8, 1, 0, false, err_out);
+}
- return tex;
+GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256])
+{
+ return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, samples, false, err_out);
}
void GPU_invalid_tex_init(void)
{
+ memory_usage = 0;
const float color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
GG.invalid_tex_1D = GPU_texture_create_1D(1, color, NULL);
- GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, GPU_HDR_NONE, NULL);
- GG.invalid_tex_3D = GPU_texture_create_3D(1, 1, 1, 4, color);
+ GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, NULL);
+ GG.invalid_tex_3D = GPU_texture_create_3D(1, 1, 1, color, NULL);
}
void GPU_invalid_tex_bind(int mode)
@@ -627,21 +755,18 @@ void GPU_texture_bind(GPUTexture *tex, int number)
if (number < 0)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Texture Bind");
+ if (number != 0)
+ glActiveTexture(GL_TEXTURE0 + number);
- GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + number);
- if (number != 0) glActiveTexture(arbnumber);
- if (tex->bindcode != 0) {
+ if (tex->bindcode != 0)
glBindTexture(tex->target_base, tex->bindcode);
- }
else
GPU_invalid_tex_bind(tex->target_base);
- glEnable(tex->target_base);
- if (number != 0) glActiveTexture(GL_TEXTURE0);
- tex->number = number;
+ if (number != 0)
+ glActiveTexture(GL_TEXTURE0);
- GPU_ASSERT_NO_GL_ERRORS("Post Texture Bind");
+ tex->number = number;
}
void GPU_texture_unbind(GPUTexture *tex)
@@ -653,18 +778,16 @@ void GPU_texture_unbind(GPUTexture *tex)
if (tex->number == -1)
return;
-
- GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
- GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + tex->number);
- if (tex->number != 0) glActiveTexture(arbnumber);
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+
glBindTexture(tex->target_base, 0);
- glDisable(tex->target_base);
- if (tex->number != 0) glActiveTexture(GL_TEXTURE0);
- tex->number = -1;
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0);
- GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
+ tex->number = -1;
}
int GPU_texture_bound_number(GPUTexture *tex)
@@ -672,7 +795,7 @@ int GPU_texture_bound_number(GPUTexture *tex)
return tex->number;
}
-void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter)
+void GPU_texture_generate_mipmap(GPUTexture *tex)
{
if (tex->number >= GPU_max_textures()) {
fprintf(stderr, "Not enough texture slots.\n");
@@ -682,29 +805,99 @@ void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter)
if (tex->number == -1)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0 + tex->number);
- GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + tex->number);
- if (tex->number != 0) glActiveTexture(arbnumber);
+ glGenerateMipmap(tex->target_base);
- if (tex->depth) {
- if (compare)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
- else
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0);
+}
+
+void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare)
+{
+ if (tex->number >= GPU_max_textures()) {
+ fprintf(stderr, "Not enough texture slots.\n");
+ return;
}
- if (use_filter) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (tex->number == -1)
+ return;
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+
+ /* TODO viewport: use GL_COMPARE_REF_TO_TEXTURE after we switch to core profile */
+ if (tex->depth)
+ glTexParameteri(tex->target_base, GL_TEXTURE_COMPARE_MODE, use_compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE);
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0);
+}
+
+void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
+{
+ if (tex->number >= GPU_max_textures()) {
+ fprintf(stderr, "Not enough texture slots.\n");
+ return;
}
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ if (tex->number == -1)
+ return;
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+
+ GLenum filter = use_filter ? GL_LINEAR : GL_NEAREST;
+ glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, filter);
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0);
+}
+
+void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap)
+{
+ if (tex->number >= GPU_max_textures()) {
+ fprintf(stderr, "Not enough texture slots.\n");
+ return;
}
- if (tex->number != 0) glActiveTexture(GL_TEXTURE0);
- GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
+ if (tex->number == -1)
+ return;
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+
+ GLenum mipmap = use_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
+ glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, mipmap);
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0);
+}
+
+void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat)
+{
+ if (tex->number >= GPU_max_textures()) {
+ fprintf(stderr, "Not enough texture slots.\n");
+ return;
+ }
+
+ if (tex->number == -1)
+ return;
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+
+ GLenum repeat = use_repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE;
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_S, repeat);
+ if (tex->target_base != GL_TEXTURE_1D)
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_T, repeat);
+ if (tex->target_base == GL_TEXTURE_3D)
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, repeat);
+
+ if (tex->number != 0)
+ glActiveTexture(GL_TEXTURE0);
}
void GPU_texture_free(GPUTexture *tex)
@@ -720,6 +913,8 @@ void GPU_texture_free(GPUTexture *tex)
if (tex->bindcode && !tex->fromblender)
glDeleteTextures(1, &tex->bindcode);
+ gpu_texture_memory_footprint_remove(tex);
+
MEM_freeN(tex);
}
}
@@ -744,11 +939,21 @@ int GPU_texture_height(const GPUTexture *tex)
return tex->h;
}
-int GPU_texture_depth(const GPUTexture *tex)
+int GPU_texture_format(const GPUTexture *tex)
+{
+ return tex->format;
+}
+
+bool GPU_texture_depth(const GPUTexture *tex)
{
return tex->depth;
}
+bool GPU_texture_stencil(const GPUTexture *tex)
+{
+ return tex->stencil;
+}
+
int GPU_texture_opengl_bindcode(const GPUTexture *tex)
{
return tex->bindcode;
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
new file mode 100644
index 00000000000..76aa1a8226f
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -0,0 +1,105 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_uniformbuffer.c
+ * \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
+#include "GPU_extensions.h"
+#include "GPU_glew.h"
+#include "GPU_uniformbuffer.h"
+
+struct GPUUniformBuffer {
+ int size; /* in bytes */
+ GLuint bindcode; /* opengl identifier for UBO */
+ int bindpoint; /* current binding point */
+};
+
+GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256])
+{
+ GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBuffer), "GPUUniformBuffer");
+ ubo->size = size;
+
+ /* Generate Buffer object */
+ glGenBuffers(1, &ubo->bindcode);
+
+ if (!ubo->bindcode) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUUniformBuffer: UBO create failed");
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ if (ubo->size > GPU_max_ubo_size()) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUUniformBuffer: UBO too big");
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+ return ubo;
+}
+
+void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
+{
+ glDeleteBuffers(1, &ubo->bindcode);
+ MEM_freeN(ubo);
+}
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
+{
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+}
+
+void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
+{
+ if (number >= GPU_max_ubo_binds()) {
+ fprintf(stderr, "Not enough UBO slots.\n");
+ return;
+ }
+
+ if (ubo->bindcode != 0) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
+ }
+
+ ubo->bindpoint = number;
+}
+
+int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
+{
+ return ubo->bindpoint;
+} \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
new file mode 100644
index 00000000000..49c8d37f6f1
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -0,0 +1,584 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_viewport.c
+ * \ingroup gpu
+ *
+ * System that manages viewport drawing.
+ */
+
+#include <string.h>
+
+#include "BLI_listbase.h"
+#include "BLI_rect.h"
+#include "BLI_string.h"
+
+#include "DNA_vec_types.h"
+
+#include "BKE_global.h"
+
+#include "GPU_framebuffer.h"
+#include "GPU_glew.h"
+#include "GPU_immediate.h"
+#include "GPU_texture.h"
+#include "GPU_viewport.h"
+
+#include "DRW_engine.h"
+
+#include "MEM_guardedalloc.h"
+
+static const int default_fbl_len = (sizeof(DefaultFramebufferList)) / sizeof(void *);
+static const int default_txl_len = (sizeof(DefaultTextureList)) / sizeof(void *);
+
+/* Maximum number of simultaneous engine enabled at the same time.
+ * Setting it lower than the real number will do lead to
+ * higher VRAM usage due to sub-efficient buffer reuse. */
+#define MAX_ENGINE_BUFFER_SHARING 5
+
+typedef struct ViewportTempTexture {
+ struct ViewportTempTexture *next, *prev;
+ void *user[MAX_ENGINE_BUFFER_SHARING];
+ GPUTexture *texture;
+} ViewportTempTexture;
+
+struct GPUViewport {
+ float pad[4];
+
+ /* debug */
+ GPUTexture *debug_depth;
+ int size[2];
+
+ ListBase data; /* ViewportEngineData wrapped in LinkData */
+ unsigned int data_hash; /* If hash mismatch we free all ViewportEngineData in this viewport */
+
+ DefaultFramebufferList *fbl;
+ DefaultTextureList *txl;
+
+ ListBase tex_pool; /* ViewportTempTexture list : Temporary textures shared across draw engines */
+};
+
+static void gpu_viewport_buffers_free(FramebufferList *fbl, int fbl_len, TextureList *txl, int txl_len);
+static void gpu_viewport_storage_free(StorageList *stl, int stl_len);
+static void gpu_viewport_passes_free(PassList *psl, int psl_len);
+static void gpu_viewport_texture_pool_free(GPUViewport *viewport);
+
+GPUViewport *GPU_viewport_create(void)
+{
+ GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport");
+ viewport->fbl = MEM_callocN(sizeof(DefaultFramebufferList), "FramebufferList");
+ viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList");
+
+ viewport->size[0] = viewport->size[1] = -1;
+
+ return viewport;
+}
+
+GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs)
+{
+ GPUViewport *viewport = GPU_viewport_create();
+ GPU_offscreen_viewport_data_get(ofs, &viewport->fbl->default_fb, &viewport->txl->color, &viewport->txl->depth);
+ viewport->size[0] = GPU_offscreen_width(ofs);
+ viewport->size[1] = GPU_offscreen_height(ofs);
+ return viewport;
+}
+/**
+ * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
+ */
+void GPU_viewport_clear_from_offscreen(GPUViewport *viewport)
+{
+ viewport->fbl->default_fb = NULL;
+ viewport->txl->color = NULL;
+ viewport->txl->depth = NULL;
+}
+
+void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
+{
+ LinkData *ld = MEM_callocN(sizeof(LinkData), "LinkData");
+ ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
+ int fbl_len, txl_len, psl_len, stl_len;
+
+ DRW_engine_viewport_data_size_get(engine_type, &fbl_len, &txl_len, &psl_len, &stl_len);
+
+ data->engine_type = engine_type;
+
+ data->fbl = MEM_callocN((sizeof(void *) * fbl_len) + sizeof(FramebufferList), "FramebufferList");
+ data->txl = MEM_callocN((sizeof(void *) * txl_len) + sizeof(TextureList), "TextureList");
+ data->psl = MEM_callocN((sizeof(void *) * psl_len) + sizeof(PassList), "PassList");
+ data->stl = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), "StorageList");
+
+ ld->data = data;
+ BLI_addtail(&viewport->data, ld);
+
+ return data;
+}
+
+static void gpu_viewport_engines_data_free(GPUViewport *viewport)
+{
+ int fbl_len, txl_len, psl_len, stl_len;
+
+ LinkData *next;
+ for (LinkData *link = viewport->data.first; link; link = next) {
+ next = link->next;
+ ViewportEngineData *data = link->data;
+ DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, &psl_len, &stl_len);
+
+ gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len);
+ gpu_viewport_passes_free(data->psl, psl_len);
+ gpu_viewport_storage_free(data->stl, stl_len);
+
+ MEM_freeN(data->fbl);
+ MEM_freeN(data->txl);
+ MEM_freeN(data->psl);
+ MEM_freeN(data->stl);
+
+ /* We could handle this in the DRW module */
+ if (data->text_draw_cache) {
+ extern void DRW_text_cache_destroy(struct DRWTextStore *dt);
+ DRW_text_cache_destroy(data->text_draw_cache);
+ data->text_draw_cache = NULL;
+ }
+
+ MEM_freeN(data);
+
+ BLI_remlink(&viewport->data, link);
+ MEM_freeN(link);
+ }
+
+ gpu_viewport_texture_pool_free(viewport);
+}
+
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type)
+{
+ for (LinkData *link = viewport->data.first; link; link = link->next) {
+ ViewportEngineData *vdata = link->data;
+ if (vdata->engine_type == engine_type) {
+ return vdata;
+ }
+ }
+ return NULL;
+}
+
+void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport)
+{
+ return viewport->fbl;
+}
+
+void *GPU_viewport_texture_list_get(GPUViewport *viewport)
+{
+ return viewport->txl;
+}
+
+void GPU_viewport_size_get(const GPUViewport *viewport, int size[2])
+{
+ size[0] = viewport->size[0];
+ size[1] = viewport->size[1];
+}
+
+/**
+ * Special case, this is needed for when we have a viewport without a frame-buffer output
+ * (occlusion queries for eg) but still need to set the size since it may be used for other calculations.
+ */
+void GPU_viewport_size_set(GPUViewport *viewport, const int size[2])
+{
+ viewport->size[0] = size[0];
+ viewport->size[1] = size[1];
+}
+
+/**
+ * Try to find a texture coresponding to params into the texture pool.
+ * If no texture was found, create one and add it to the pool.
+ */
+GPUTexture *GPU_viewport_texture_pool_query(GPUViewport *viewport, void *engine, int width, int height, int channels, int format)
+{
+ GPUTexture *tex;
+
+ for (ViewportTempTexture *tmp_tex = viewport->tex_pool.first; tmp_tex; tmp_tex = tmp_tex->next) {
+ if ((GPU_texture_width(tmp_tex->texture) == width) &&
+ (GPU_texture_height(tmp_tex->texture) == height) &&
+ (GPU_texture_format(tmp_tex->texture) == format))
+ {
+ /* Search if the engine is not already using this texture */
+ for (int i = 0; i < MAX_ENGINE_BUFFER_SHARING; ++i) {
+ if (tmp_tex->user[i] == engine) {
+ break;
+ }
+
+ if (tmp_tex->user[i] == NULL) {
+ tmp_tex->user[i] = engine;
+ return tmp_tex->texture;
+ }
+ }
+ }
+ }
+
+ tex = GPU_texture_create_2D_custom(width, height, channels, format, NULL, NULL);
+
+ ViewportTempTexture *tmp_tex = MEM_callocN(sizeof(ViewportTempTexture), "ViewportTempTexture");
+ tmp_tex->texture = tex;
+ tmp_tex->user[0] = engine;
+
+ BLI_addtail(&viewport->tex_pool, tmp_tex);
+
+ return tex;
+}
+
+static void gpu_viewport_texture_pool_clear_users(GPUViewport *viewport)
+{
+ ViewportTempTexture *tmp_tex_next;
+
+ for (ViewportTempTexture *tmp_tex = viewport->tex_pool.first; tmp_tex; tmp_tex = tmp_tex_next) {
+ tmp_tex_next = tmp_tex->next;
+ bool no_user = true;
+ for (int i = 0; i < MAX_ENGINE_BUFFER_SHARING; ++i) {
+ if (tmp_tex->user[i] != NULL) {
+ tmp_tex->user[i] = NULL;
+ no_user = false;
+ }
+ }
+
+ if (no_user) {
+ GPU_texture_free(tmp_tex->texture);
+ BLI_freelinkN(&viewport->tex_pool, tmp_tex);
+ }
+ }
+}
+
+static void gpu_viewport_texture_pool_free(GPUViewport *viewport)
+{
+ for (ViewportTempTexture *tmp_tex = viewport->tex_pool.first; tmp_tex; tmp_tex = tmp_tex->next) {
+ GPU_texture_free(tmp_tex->texture);
+ }
+
+ BLI_freelistN(&viewport->tex_pool);
+}
+
+bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash)
+{
+ bool dirty = false;
+
+ /* TODO for testing only, we need proper cache invalidation */
+ if (G.debug_value != 666 && G.debug_value != 667) {
+ for (LinkData *link = viewport->data.first; link; link = link->next) {
+ ViewportEngineData *data = link->data;
+ int psl_len;
+ DRW_engine_viewport_data_size_get(data->engine_type, NULL, NULL, &psl_len, NULL);
+ gpu_viewport_passes_free(data->psl, psl_len);
+ }
+ dirty = true;
+ }
+
+ if (viewport->data_hash != hash) {
+ gpu_viewport_engines_data_free(viewport);
+ dirty = true;
+ }
+
+ viewport->data_hash = hash;
+
+ return dirty;
+}
+
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
+{
+ DefaultFramebufferList *dfbl = viewport->fbl;
+ DefaultTextureList *dtxl = viewport->txl;
+ int fbl_len, txl_len;
+
+ /* add one pixel because of scissor test */
+ int rect_w = BLI_rcti_size_x(rect) + 1;
+ int rect_h = BLI_rcti_size_y(rect) + 1;
+
+ if (dfbl->default_fb) {
+ if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
+ gpu_viewport_buffers_free(
+ (FramebufferList *)viewport->fbl, default_fbl_len,
+ (TextureList *)viewport->txl, default_txl_len);
+
+ for (LinkData *link = viewport->data.first; link; link = link->next) {
+ ViewportEngineData *data = link->data;
+ DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, NULL, NULL);
+ gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len);
+ }
+
+ gpu_viewport_texture_pool_free(viewport);
+ }
+ }
+
+ gpu_viewport_texture_pool_clear_users(viewport);
+
+ if (!dfbl->default_fb) {
+ bool ok = true;
+ viewport->size[0] = rect_w;
+ viewport->size[1] = rect_h;
+
+ dfbl->default_fb = GPU_framebuffer_create();
+ if (!dfbl->default_fb) {
+ ok = false;
+ goto cleanup;
+ }
+
+ /* Color */
+ /* No multi samples for now */
+ dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
+ if (!dtxl->color) {
+ ok = false;
+ goto cleanup;
+ }
+
+ if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->color, 0, 0)) {
+ ok = false;
+ goto cleanup;
+ }
+
+ /* Depth */
+ dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
+
+ if (dtxl->depth) {
+ /* Define texture parameters */
+ GPU_texture_bind(dtxl->depth, 0);
+ GPU_texture_compare_mode(dtxl->depth, false);
+ GPU_texture_filter_mode(dtxl->depth, true);
+ GPU_texture_unbind(dtxl->depth);
+ }
+ else {
+ ok = false;
+ goto cleanup;
+ }
+
+ if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0)) {
+ ok = false;
+ goto cleanup;
+ }
+ else if (!GPU_framebuffer_check_valid(dfbl->default_fb, NULL)) {
+ ok = false;
+ goto cleanup;
+ }
+
+cleanup:
+ if (!ok) {
+ GPU_viewport_free(viewport);
+ MEM_freeN(viewport);
+ return;
+ }
+
+ GPU_framebuffer_restore();
+ }
+
+ GPU_framebuffer_slots_bind(dfbl->default_fb, 0);
+}
+
+static void draw_ofs_to_screen(GPUViewport *viewport)
+{
+ DefaultTextureList *dtxl = viewport->txl;
+
+ GPUTexture *color = dtxl->color;
+
+ const float w = (float)GPU_texture_width(color);
+ const float h = (float)GPU_texture_height(color);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+ GPU_texture_bind(color, 0);
+
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+
+ immBegin(PRIM_TRIANGLE_STRIP, 4);
+
+ immAttrib2f(texcoord, 0.0f, 0.0f);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ immAttrib2f(texcoord, 1.0f, 0.0f);
+ immVertex2f(pos, w, 0.0f);
+
+ immAttrib2f(texcoord, 0.0f, 1.0f);
+ immVertex2f(pos, 0.0f, h);
+
+ immAttrib2f(texcoord, 1.0f, 1.0f);
+ immVertex2f(pos, w, h);
+
+ immEnd();
+
+ GPU_texture_unbind(color);
+
+ immUnbindProgram();
+}
+
+void GPU_viewport_unbind(GPUViewport *viewport)
+{
+ DefaultFramebufferList *dfbl = viewport->fbl;
+
+ if (dfbl->default_fb) {
+ GPU_framebuffer_texture_unbind(NULL, NULL);
+ GPU_framebuffer_restore();
+
+ glEnable(GL_SCISSOR_TEST);
+ glDisable(GL_DEPTH_TEST);
+
+ /* This might be bandwidth limiting */
+ draw_ofs_to_screen(viewport);
+ }
+}
+
+static void gpu_viewport_buffers_free(
+ FramebufferList *fbl, int fbl_len,
+ TextureList *txl, int txl_len)
+{
+ for (int i = 0; i < fbl_len; i++) {
+ GPUFrameBuffer *fb = fbl->framebuffers[i];
+ if (fb) {
+ GPU_framebuffer_free(fb);
+ fbl->framebuffers[i] = NULL;
+ }
+ }
+ for (int i = 0; i < txl_len; i++) {
+ GPUTexture *tex = txl->textures[i];
+ if (tex) {
+ GPU_texture_free(tex);
+ txl->textures[i] = NULL;
+ }
+ }
+}
+
+static void gpu_viewport_storage_free(StorageList *stl, int stl_len)
+{
+ for (int i = 0; i < stl_len; i++) {
+ void *storage = stl->storage[i];
+ if (storage) {
+ MEM_freeN(storage);
+ stl->storage[i] = NULL;
+ }
+ }
+}
+
+static void gpu_viewport_passes_free(PassList *psl, int psl_len)
+{
+ for (int i = 0; i < psl_len; i++) {
+ struct DRWPass *pass = psl->passes[i];
+ if (pass) {
+ DRW_pass_free(pass);
+ MEM_freeN(pass);
+ psl->passes[i] = NULL;
+ }
+ }
+}
+
+void GPU_viewport_free(GPUViewport *viewport)
+{
+ gpu_viewport_engines_data_free(viewport);
+
+ gpu_viewport_buffers_free(
+ (FramebufferList *)viewport->fbl, default_fbl_len,
+ (TextureList *)viewport->txl, default_txl_len);
+
+ gpu_viewport_texture_pool_free(viewport);
+
+ MEM_freeN(viewport->fbl);
+ MEM_freeN(viewport->txl);
+
+ GPU_viewport_debug_depth_free(viewport);
+}
+
+/****************** debug ********************/
+
+bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256])
+{
+ viewport->debug_depth = GPU_texture_create_2D_custom(width, height, 4, GPU_RGBA16F, NULL, err_out);
+ return (viewport->debug_depth != NULL);
+}
+
+void GPU_viewport_debug_depth_free(GPUViewport *viewport)
+{
+ if (viewport->debug_depth != NULL) {
+ MEM_freeN(viewport->debug_depth);
+ viewport->debug_depth = NULL;
+ }
+}
+
+void GPU_viewport_debug_depth_store(GPUViewport *viewport, const int x, const int y)
+{
+ const int w = GPU_texture_width(viewport->debug_depth);
+ const int h = GPU_texture_height(viewport->debug_depth);
+
+ GPU_texture_bind(viewport->debug_depth, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, x, y, w, h, 0);
+ GPU_texture_unbind(viewport->debug_depth);
+}
+
+void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, const float zfar)
+{
+ const float w = (float)GPU_texture_width(viewport->debug_depth);
+ const float h = (float)GPU_texture_height(viewport->debug_depth);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH);
+
+ GPU_texture_bind(viewport->debug_depth, 0);
+
+ immUniform1f("znear", znear);
+ immUniform1f("zfar", zfar);
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+
+ immBegin(PRIM_TRIANGLE_STRIP, 4);
+
+ immAttrib2f(texcoord, 0.0f, 0.0f);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ immAttrib2f(texcoord, 1.0f, 0.0f);
+ immVertex2f(pos, w, 0.0f);
+
+ immAttrib2f(texcoord, 0.0f, 1.0f);
+ immVertex2f(pos, 0.0f, h);
+
+ immAttrib2f(texcoord, 1.0f, 1.0f);
+ immVertex2f(pos, w, h);
+
+ immEnd();
+
+ GPU_texture_unbind(viewport->debug_depth);
+
+ immUnbindProgram();
+}
+
+int GPU_viewport_debug_depth_width(const GPUViewport *viewport)
+{
+ return GPU_texture_width(viewport->debug_depth);
+}
+
+int GPU_viewport_debug_depth_height(const GPUViewport *viewport)
+{
+ return GPU_texture_height(viewport->debug_depth);
+}
+
+bool GPU_viewport_debug_depth_is_valid(GPUViewport *viewport)
+{
+ return viewport->debug_depth != NULL;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl
new file mode 100644
index 00000000000..769e2b0e37c
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+in vec4 color;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl
new file mode 100644
index 00000000000..228f3f1da19
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+/* Keep in sync with intern/opencolorio/gpu_shader_display_transform_vertex.glsl */
+in vec2 texCoord;
+in vec2 pos;
+out vec2 texCoord_interp;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f);
+ texCoord_interp = texCoord;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl
new file mode 100644
index 00000000000..346d3b3c6d9
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl
@@ -0,0 +1,42 @@
+
+// Draw dashed lines, perforated in screen space.
+
+noperspective in float distance_along_line;
+out vec4 fragColor;
+
+uniform float dash_width;
+
+/* Simple mode, discarding non-dash parts (so no need for blending at all). */
+uniform float dash_factor; /* if > 1.0, solid line. */
+uniform vec4 color;
+
+/* More advanced mode, allowing for complex, multi-colored patterns. Enabled when num_colors > 0. */
+/* Note: max number of steps/colors in pattern is 32! */
+uniform int num_colors; /* Enabled if > 0, 1 for solid line. */
+uniform vec4 colors[32];
+
+void main()
+{
+ /* Solid line cases, simple. */
+ if (num_colors == 1) {
+ fragColor = colors[0];
+ }
+ else if (dash_factor >= 1.0f) {
+ fragColor = color;
+ }
+ else {
+ /* Actually dashed line... */
+ float normalized_distance = fract(distance_along_line / dash_width);
+ if (num_colors > 0) {
+ fragColor = colors[int(normalized_distance * num_colors)];
+ }
+ else {
+ if (normalized_distance <= dash_factor) {
+ fragColor = color;
+ }
+ else {
+ discard;
+ }
+ }
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl
new file mode 100644
index 00000000000..e0b618e0b1a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl
@@ -0,0 +1,46 @@
+
+// Draw dashed lines, perforated in screen space.
+
+/* Make to be used with dynamic batching so no Model Matrix needed */
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 viewport_size;
+
+/* Uniforms from fragment shader, used here to optimize out useless computation in case of solid line. */
+uniform float dash_factor; /* if > 1.0, solid line. */
+uniform int num_colors; /* Enabled if > 0, 1 for solid line. */
+
+layout(lines) in;
+
+layout(line_strip, max_vertices = 2) out;
+noperspective out float distance_along_line;
+
+void main()
+{
+ vec4 v1 = gl_in[0].gl_Position;
+ vec4 v2 = gl_in[1].gl_Position;
+
+ gl_Position = v1;
+ distance_along_line = 0.0f;
+ EmitVertex();
+
+ gl_Position = v2;
+ if ((num_colors == 1) || (dash_factor >= 1.0f)) {
+ /* Solid line, optimise out distance computation! */
+ distance_along_line = 0.0f;
+ }
+ else {
+ vec2 p1 = (v1.xy / v1.w) * 0.5 + 0.5; // <- device coordinates in [0..1] range.
+ p1 = p1 * viewport_size; // <- 'virtual' screen coordinates.
+
+ vec2 p2 = (v2.xy / v2.w) * 0.5 + 0.5; // <- device coordinates in [0..1] range.
+ p2 = p2 * viewport_size; // <- 'virtual' screen coordinates.
+
+ distance_along_line = distance(p1, p2);
+ }
+ EmitVertex();
+
+ EndPrimitive();
+
+ /* Note: we could also use similar approach as diag_stripes_frag, but this would give us dashed 'anchored'
+ * to the screen, and not to one end of the line... */
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl
new file mode 100644
index 00000000000..14f56d7e0dd
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl
@@ -0,0 +1,11 @@
+
+// Draw dashed lines, perforated in screen space.
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl
new file mode 100644
index 00000000000..1f833cfb7be
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl
@@ -0,0 +1,21 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform float size;
+
+in vec2 pos;
+out vec2 radii;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_PointSize = size;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * size;
+
+ // start at the outside and progress toward the center
+ radii[0] = radius;
+ radii[1] = radius - 1.0;
+
+ // convert to PointCoord units
+ radii /= size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl
new file mode 100644
index 00000000000..99bdeb22904
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl
@@ -0,0 +1,24 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform float size;
+uniform float outlineWidth;
+
+in vec2 pos;
+out vec4 radii;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_PointSize = size;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * size;
+
+ // 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 /= size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl
new file mode 100644
index 00000000000..5fad95236df
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl
@@ -0,0 +1,27 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform float size;
+uniform float outlineWidth;
+
+in vec2 pos;
+in vec4 color;
+out vec4 radii;
+out vec4 fillColor;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_PointSize = size;
+ fillColor = color;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * size;
+
+ // 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 /= size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl
new file mode 100644
index 00000000000..d6aacf0cdc5
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl
@@ -0,0 +1,14 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+in float size;
+in vec4 color;
+out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_PointSize = size;
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl
new file mode 100644
index 00000000000..4a4bfb6a616
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl
@@ -0,0 +1,8 @@
+
+noperspective in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl
new file mode 100644
index 00000000000..fe91f4d0902
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+in vec4 color;
+
+noperspective out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_vert.glsl
new file mode 100644
index 00000000000..89e3c52f9f8
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_vert.glsl
@@ -0,0 +1,9 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl
new file mode 100644
index 00000000000..84e44837264
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl
@@ -0,0 +1,12 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
+uniform vec4 ClipPlane;
+
+in vec3 pos;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_ClipDistance[0] = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl
new file mode 100644
index 00000000000..7db7e28d8e6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl
@@ -0,0 +1,26 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+#if defined(USE_COLOR_U32)
+in uint color;
+#else
+in vec4 color;
+#endif
+
+flat out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+#if defined(USE_COLOR_U32)
+ finalColor = vec4(
+ ((color ) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 8) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 16) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 24) ) * (1.0f / 255.0f));
+#else
+ finalColor = color;
+#endif
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl
new file mode 100644
index 00000000000..f16fa21b342
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl
@@ -0,0 +1,16 @@
+
+/* Make to be used with dynamic batching so no Model Matrix needed */
+uniform mat4 ViewProjectionMatrix;
+
+layout(points) in;
+layout(line_strip, max_vertices = 2) out;
+
+void main()
+{
+ vec3 vert = gl_in[0].gl_Position.xyz;
+ gl_Position = ViewProjectionMatrix * vec4(vert.xyz, 1.0);
+ EmitVertex();
+ gl_Position = ViewProjectionMatrix * vec4(vert.xy, 0.0, 1.0);
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl
new file mode 100644
index 00000000000..55f410eb25d
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl
@@ -0,0 +1,11 @@
+
+/* Made to be used with dynamic batching so no Model Matrix needed */
+uniform mat4 ViewProjectionMatrix;
+
+in vec3 pos;
+
+void main()
+{
+ gl_Position = ViewProjectionMatrix * vec4(pos.xy, 0.0, 1.0);
+ gl_PointSize = 2.0;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl
new file mode 100644
index 00000000000..eb877ab20b6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl
@@ -0,0 +1,12 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 texCoord;
+in vec3 pos;
+out vec2 texCoord_interp;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos.xyz, 1.0f);
+ texCoord_interp = texCoord;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_legacy_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_legacy_vert.glsl
new file mode 100644
index 00000000000..eab4c1b4543
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_legacy_vert.glsl
@@ -0,0 +1,16 @@
+
+/* Note: nearly the same code as for 2D version... Maybe we could deduplicate? */
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 viewport_size;
+
+in vec3 pos;
+noperspective out float distance_along_line;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ /* Hack - prevent stupid GLSL compiler to optimize out unused viewport_size uniform, which gives crash! */
+ distance_along_line = viewport_size.x * 0.000001f - viewport_size.x * 0.0000009f;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_vert.glsl
new file mode 100644
index 00000000000..a02b0d219fb
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_vert.glsl
@@ -0,0 +1,11 @@
+
+// Draw dashed lines, perforated in screen space.
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl
new file mode 100644
index 00000000000..e6b8fed7265
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl
@@ -0,0 +1,22 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+
+in vec3 pos;
+in vec3 nor;
+in vec4 color;
+
+#ifdef USE_FLAT_NORMAL
+flat out vec3 normal;
+flat out vec4 finalColor;
+#else
+out vec3 normal;
+out vec4 finalColor;
+#endif
+
+void main()
+{
+ normal = normalize(NormalMatrix * nor);
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl
new file mode 100644
index 00000000000..a3f447a85f9
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+
+in vec3 pos;
+in vec3 nor;
+out vec3 normal;
+
+void main()
+{
+ normal = normalize(NormalMatrix * nor);
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl
new file mode 100644
index 00000000000..60793bf56b6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl
@@ -0,0 +1,8 @@
+
+/* Does Nothing */
+in vec3 pos;
+
+void main()
+{
+ gl_Position = vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl
new file mode 100644
index 00000000000..2fe9c0623fa
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl
@@ -0,0 +1,12 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in vec4 color;
+out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl
new file mode 100644
index 00000000000..ebc945fcf35
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl
@@ -0,0 +1,21 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform float size;
+
+in vec3 pos;
+out vec2 radii;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = size;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * size;
+
+ // start at the outside and progress toward the center
+ radii[0] = radius;
+ radii[1] = radius - 1.0;
+
+ // convert to PointCoord units
+ radii /= size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl
new file mode 100644
index 00000000000..0d6b90cfba4
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl
@@ -0,0 +1,24 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform float size;
+uniform float outlineWidth;
+
+in vec3 pos;
+out vec4 radii;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = size;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * size;
+
+ // 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 /= size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl
new file mode 100644
index 00000000000..e14b9535c89
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl
@@ -0,0 +1,14 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in float size;
+in vec4 color;
+out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = size;
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl
new file mode 100644
index 00000000000..e4f173ab617
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl
@@ -0,0 +1,11 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in float size;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl
new file mode 100644
index 00000000000..41fdefd22e8
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl
@@ -0,0 +1,8 @@
+
+in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl
new file mode 100644
index 00000000000..a1feb2f75b7
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in vec4 color;
+
+out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_vert.glsl
new file mode 100644
index 00000000000..059473ebb74
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_vert.glsl
@@ -0,0 +1,9 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
index 01a335af048..5f7455582cd 100644
--- a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
@@ -20,12 +20,10 @@
#define STIPPLE_HEXAGON 3
#define STIPPLE_DIAG_STRIPES 4
#define STIPPLE_DIAG_STRIPES_SWAP 5
-#define STIPPLE_S3D_INTERLACE_ROW 6
-#define STIPPLE_S3D_INTERLACE_ROW_SWAP 7
-#define STIPPLE_S3D_INTERLACE_COLUMN 8
-#define STIPPLE_S3D_INTERLACE_COLUMN_SWAP 9
-#define STIPPLE_S3D_INTERLACE_CHECKERBOARD 10
-#define STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP 11
+
+#ifndef NO_SPECULAR
+uniform mat4 ProjectionMatrix;
+#endif
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
#if defined(USE_FLAT_NORMAL)
@@ -58,7 +56,7 @@ uniform sampler2D_default texture_map;
#ifdef USE_STIPPLE
uniform int stipple_id;
#if defined(DRAW_LINE)
-varying in float t;
+varying float t;
uniform int stipple_pattern;
#endif
#endif
@@ -74,14 +72,9 @@ void main()
/* We have to use mod function and integer casting.
* This can be optimized further with the bitwise operations
* when GLSL 1.3 is supported. */
- if (stipple_id == STIPPLE_HALFTONE ||
- stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD ||
- stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP)
- {
+ if (stipple_id == STIPPLE_HALFTONE) {
int result = int(mod(gl_FragCoord.x + gl_FragCoord.y, 2));
bool dis = result == 0;
- if (stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP)
- dis = !dis;
if (dis)
discard;
}
@@ -116,22 +109,6 @@ void main()
if (!((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx))
discard;
}
- else if (stipple_id == STIPPLE_S3D_INTERLACE_ROW || stipple_id == STIPPLE_S3D_INTERLACE_ROW_SWAP) {
- int result = int(mod(gl_FragCoord.y, 2));
- bool dis = result == 0;
- if (stipple_id == STIPPLE_S3D_INTERLACE_ROW_SWAP)
- dis = !dis;
- if (dis)
- discard;
- }
- else if (stipple_id == STIPPLE_S3D_INTERLACE_COLUMN || stipple_id == STIPPLE_S3D_INTERLACE_COLUMN_SWAP) {
- int result = int(mod(gl_FragCoord.x, 2));
- bool dis = result != 0;
- if (stipple_id == STIPPLE_S3D_INTERLACE_COLUMN_SWAP)
- dis = !dis;
- if (dis)
- discard;
- }
else if (stipple_id == STIPPLE_HEXAGON) {
int mody = int(mod(gl_FragCoord.y, 2));
int modx = int(mod(gl_FragCoord.x, 4));
@@ -190,7 +167,7 @@ void main()
#ifndef NO_SPECULAR
/* view vector computation, depends on orthographics or perspective */
- vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
+ vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
#endif
for (int i = 0; i < NUM_SCENE_LIGHTS; i++) {
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl b/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl
index a88681a5fd3..13f05b340bf 100644
--- a/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl
@@ -14,9 +14,9 @@ layout(line_strip, max_vertices = 10) out;
layout(triangle_strip, max_vertices = 6) out;
#endif
-varying out float t;
-varying in vec4 varying_vertex_color_line[];
-varying out vec4 varying_vertex_color;
+out float t;
+in vec4 varying_vertex_color_line[];
+out vec4 varying_vertex_color;
uniform ivec4 viewport;
uniform float line_width;
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
index 42fbdadf1d1..dbf6c267f14 100644
--- a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
@@ -1,4 +1,8 @@
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat3 NormalMatrix;
+
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
#if defined(USE_FLAT_NORMAL)
varying vec3 eyespace_vert_pos;
@@ -29,15 +33,15 @@ varying float gl_ClipDistance[6];
void main()
{
- vec4 co = gl_ModelViewMatrix * gl_Vertex;
+ vec4 co = ModelViewMatrix * gl_Vertex;
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
#if !defined(USE_FLAT_NORMAL)
- varying_normal = normalize(gl_NormalMatrix * gl_Normal);
+ varying_normal = normalize(NormalMatrix * gl_Normal);
#endif
#if defined(USE_FLAT_NORMAL)
/* transform vertex into eyespace */
- eyespace_vert_pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
+ eyespace_vert_pos = (ModelViewMatrix * gl_Vertex).xyz;
#endif
#ifndef USE_SOLID_LIGHTING
@@ -45,7 +49,7 @@ void main()
#endif
#endif
- gl_Position = gl_ProjectionMatrix * co;
+ gl_Position = ProjectionMatrix * co;
#ifdef CLIP_WORKAROUND
int i;
diff --git a/source/blender/gpu/shaders/gpu_shader_checker_frag.glsl b/source/blender/gpu/shaders/gpu_shader_checker_frag.glsl
new file mode 100644
index 00000000000..545f6d19e21
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_checker_frag.glsl
@@ -0,0 +1,20 @@
+
+uniform vec4 color1;
+uniform vec4 color2;
+uniform int size;
+
+out vec4 fragColor;
+
+void main()
+{
+ vec2 phase = mod(gl_FragCoord.xy, (size*2));
+
+ if ((phase.x > size && phase.y < size) ||
+ (phase.x < size && phase.y > size))
+ {
+ fragColor = color1;
+ }
+ else {
+ fragColor = color2;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl b/source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl
new file mode 100644
index 00000000000..60e71e19004
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl
@@ -0,0 +1,6 @@
+
+void main()
+{
+ // no color output, only depth (line below is implicit)
+ // gl_FragDepth = gl_FragCoord.z;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl b/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl
new file mode 100644
index 00000000000..beb71c58100
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl
@@ -0,0 +1,20 @@
+
+uniform vec4 color1;
+uniform vec4 color2;
+uniform int size1;
+uniform int size2;
+
+out vec4 fragColor;
+
+void main()
+{
+ float phase = mod((gl_FragCoord.x + gl_FragCoord.y), (size1 + size2));
+
+ if (phase < size1)
+ {
+ fragColor = color1;
+ }
+ else {
+ fragColor = color2;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl
new file mode 100644
index 00000000000..4ed7ed56c11
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl
@@ -0,0 +1,54 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+uniform bool drawFront = true;
+uniform bool drawBack = true;
+uniform bool drawSilhouette = true;
+
+uniform vec4 frontColor;
+uniform vec4 backColor;
+uniform vec4 silhouetteColor;
+
+uniform vec3 eye; // direction we are looking
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+
+// normals of faces this edge joins (object coords)
+in vec3 N1;
+in vec3 N2;
+
+flat out vec4 finalColor;
+
+// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
+
+// to discard an entire line, set both endpoints to nowhere
+// and it won't produce any fragments
+const vec4 nowhere = vec4(vec3(0.0), 1.0);
+
+void main()
+{
+ bool face_1_front = dot(N1, eye) > 0.0;
+ bool face_2_front = dot(N2, eye) > 0.0;
+
+ vec4 position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ if (face_1_front && face_2_front) {
+ // front-facing edge
+ gl_Position = drawFront ? position : nowhere;
+ finalColor = frontColor;
+ }
+ else if (face_1_front || face_2_front) {
+ // exactly one face is front-facing, silhouette edge
+ gl_Position = drawSilhouette ? position : nowhere;
+ finalColor = silhouetteColor;
+ }
+ else {
+ // back-facing edge
+ gl_Position = drawBack ? position : nowhere;
+ finalColor = backColor;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl
new file mode 100644
index 00000000000..10b5fad7972
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl
@@ -0,0 +1,60 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. This geometry shader
+// decides which edge type to use if endpoints disagree.
+
+uniform mat4 ProjectionMatrix;
+
+uniform bool drawFront = true;
+uniform bool drawBack = true;
+uniform bool drawSilhouette = true;
+
+uniform vec4 frontColor;
+uniform vec4 backColor;
+uniform vec4 silhouetteColor;
+
+layout(lines) in;
+layout(line_strip, max_vertices = 2) out;
+
+in vec4 MV_pos[];
+in float edgeClass[];
+
+flat out vec4 finalColor;
+
+void emitLine(vec4 color)
+{
+ gl_Position = ProjectionMatrix * MV_pos[0];
+ EmitVertex();
+ gl_Position = ProjectionMatrix * MV_pos[1];
+ finalColor = color;
+ EmitVertex();
+ EndPrimitive();
+}
+
+void main()
+{
+ float finalEdgeClass = max(edgeClass[0], edgeClass[1]);
+
+ if (finalEdgeClass > 0.0f) {
+ // front-facing edge
+ if (drawFront)
+ emitLine(frontColor);
+ }
+ else if (finalEdgeClass < 0.0f) {
+ // back-facing edge
+ if (drawBack)
+ emitLine(backColor);
+ }
+ else {
+ // exactly one face is front-facing, silhouette edge
+ if (drawSilhouette)
+ emitLine(silhouetteColor);
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl
new file mode 100644
index 00000000000..30b3bdb890d
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl
@@ -0,0 +1,68 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// This shader is an imperfect stepping stone until all platforms are
+// ready for geometry shaders.
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. Need to use a geometry
+// shader or pass in an extra position attribute (the other endpoint)
+// to do this properly.
+
+uniform bool drawFront = true;
+uniform bool drawBack = true;
+uniform bool drawSilhouette = true;
+
+uniform vec4 frontColor;
+uniform vec4 backColor;
+uniform vec4 silhouetteColor;
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+
+in vec3 pos;
+
+// normals of faces this edge joins (object coords)
+in vec3 N1;
+in vec3 N2;
+
+flat out vec4 finalColor;
+
+// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
+
+// to discard an entire line, set its color to invisible
+// (must have GL_BLEND enabled, or discard in fragment shader)
+const vec4 invisible = vec4(0.0);
+
+bool front(vec3 N)
+{
+ vec4 xformed = ModelViewMatrix * vec4(pos, 1.0);
+ return dot(NormalMatrix * N, normalize(-xformed.xyz)) > 0.0;
+}
+
+void main()
+{
+ bool face_1_front = front(N1);
+ bool face_2_front = front(N2);
+
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ if (face_1_front && face_2_front) {
+ // front-facing edge
+ finalColor = drawFront ? frontColor : invisible;
+ }
+ else if (face_1_front || face_2_front) {
+ // exactly one face is front-facing, silhouette edge
+ finalColor = drawSilhouette ? silhouetteColor : invisible;
+ }
+ else {
+ // back-facing edge
+ finalColor = drawBack ? backColor : invisible;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl
new file mode 100644
index 00000000000..e1fb78dd1a9
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl
@@ -0,0 +1,44 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. We use a geometry
+// shader to resolve this properly.
+
+uniform mat4 ModelViewMatrix;
+uniform mat3 NormalMatrix;
+
+in vec3 pos;
+in vec3 N1, N2; // normals of faces this edge joins (object coords)
+
+out vec4 MV_pos;
+out float edgeClass;
+
+// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
+
+bool front(vec3 N, vec3 eye)
+{
+ return dot(NormalMatrix * N, eye) > 0.0;
+}
+
+void main()
+{
+ MV_pos = ModelViewMatrix * vec4(pos, 1.0);
+
+ vec3 eye = normalize(-MV_pos.xyz);
+
+ bool face_1_front = front(N1, eye);
+ bool face_2_front = front(N2, eye);
+
+ if (face_1_front && face_2_front)
+ edgeClass = 1.0; // front-facing edge
+ else if (face_1_front || face_2_front)
+ edgeClass = 0.0; // exactly one face is front-facing, silhouette edge
+ else
+ edgeClass = -1.0; // back-facing edge
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl
new file mode 100644
index 00000000000..0538c037dcf
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl
@@ -0,0 +1,20 @@
+
+#define SMOOTH 1
+
+const float transitionWidth = 1.0;
+
+uniform vec4 fillColor = vec4(0);
+uniform vec4 outlineColor = vec4(0,0,0,1);
+
+noperspective in vec3 distanceToOutline;
+
+out vec4 FragColor;
+
+void main() {
+ float edgeness = min(min(distanceToOutline.x, distanceToOutline.y), distanceToOutline.z);
+#if SMOOTH
+ FragColor = mix(outlineColor, fillColor, smoothstep(0, transitionWidth, edgeness));
+#else
+ FragColor = (edgeness <= 0) ? outlineColor : fillColor;
+#endif
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl
new file mode 100644
index 00000000000..ad0dccb6c81
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl
@@ -0,0 +1,67 @@
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+uniform float outlineWidth = 1.0;
+uniform vec2 viewportSize;
+
+in vec4 pos_xformed[];
+in float widthModulator[];
+
+noperspective out vec3 distanceToOutline;
+
+// project to screen space
+vec2 proj(int axis) {
+ vec4 pos = pos_xformed[axis];
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+float dist(vec2 pos[3], int v) {
+ // current vertex position
+ vec2 vpos = pos[v];
+ // endpoints of opposite edge
+ vec2 e1 = pos[(v + 1) % 3];
+ vec2 e2 = pos[(v + 2) % 3];
+
+ float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify
+ return abs_det / distance(e2, e1);
+}
+
+vec3 distance[3];
+
+void clearEdge(int v) {
+ float distant = 10 * outlineWidth;
+ for (int i = 0; i < 3; ++i)
+ distance[i][v] += distant;
+}
+
+void modulateEdge(int v) {
+ float offset = min(widthModulator[v],1) * outlineWidth;
+ for (int i = 0; i < 3; ++i)
+ distance[i][v] -= offset;
+}
+
+void main() {
+ vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2));
+
+ for (int v = 0; v < 3; ++v)
+ distance[v] = vec3(0);
+
+ for (int v = 0; v < 3; ++v) {
+ if (widthModulator[v] > 0) {
+ distance[v][v] = dist(pos, v);
+ modulateEdge(v);
+ }
+ }
+
+ for (int v = 0; v < 3; ++v)
+ if (widthModulator[v] <= 0)
+ clearEdge(v);
+
+ for (int v = 0; v < 3; ++v) {
+ gl_Position = pos_xformed[v];
+ distanceToOutline = distance[v];
+ EmitVertex();
+ }
+
+ EndPrimitive();
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl
new file mode 100644
index 00000000000..ec692e210c2
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl
@@ -0,0 +1,52 @@
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+uniform float outlineWidth = 1.0;
+uniform vec2 viewportSize;
+
+noperspective out vec3 distanceToOutline;
+
+// project to screen space
+vec2 proj(int axis) {
+ vec4 pos = gl_in[axis].gl_Position;
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+float dist(vec2 pos[3], int v) {
+ // current vertex position
+ vec2 vpos = pos[v];
+ // endpoints of opposite edge
+ vec2 e1 = pos[(v + 1) % 3];
+ vec2 e2 = pos[(v + 2) % 3];
+
+ float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify
+ return abs_det / distance(e2, e1);
+}
+
+vec3 distance[3];
+
+void modulateEdge(int v) {
+ float offset = 0.5 * outlineWidth;
+ for (int i = 0; i < 3; ++i)
+ distance[i][v] -= offset;
+}
+
+void main() {
+ vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2));
+
+ for (int v = 0; v < 3; ++v)
+ distance[v] = vec3(0);
+
+ for (int v = 0; v < 3; ++v) {
+ distance[v][v] = dist(pos, v);
+ modulateEdge(v);
+ }
+
+ for (int v = 0; v < 3; ++v) {
+ gl_Position = gl_in[v].gl_Position;
+ distanceToOutline = distance[v];
+ EmitVertex();
+ }
+
+ EndPrimitive();
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
new file mode 100644
index 00000000000..fb1d0aafe05
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in float edgeWidthModulator;
+
+out vec4 pos_xformed;
+out float widthModulator;
+
+void main() {
+ pos_xformed = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ widthModulator = edgeWidthModulator;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
index 3819203bcd9..fc9cafb6b02 100644
--- a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
@@ -1,17 +1,15 @@
-varying vec3 coords;
+in vec3 coords;
+out vec4 fragColor;
uniform sampler3D flame_texture;
uniform sampler1D spectrum_texture;
void main()
{
- float flame = texture3D(flame_texture, coords).r;
- vec4 emission = texture1D(spectrum_texture, flame);
+ float flame = texture(flame_texture, coords).r;
+ vec4 emission = texture(spectrum_texture, flame);
- vec4 color;
- color.rgb = emission.a * emission.rgb;
- color.a = emission.a;
-
- gl_FragColor = color;
+ fragColor.rgb = emission.a * emission.rgb;
+ fragColor.a = emission.a;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl b/source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl
new file mode 100644
index 00000000000..cefae1021d2
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl
@@ -0,0 +1,11 @@
+
+flat in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ if (finalColor.a > 0.0)
+ fragColor = finalColor;
+ else
+ discard;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl
new file mode 100644
index 00000000000..d738ed5ddb2
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl
@@ -0,0 +1,8 @@
+
+flat in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl
new file mode 100644
index 00000000000..fc5cc1cdcc3
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl
@@ -0,0 +1,10 @@
+
+in vec2 pos;
+in vec2 uvs;
+out vec4 uvcoordsvar;
+
+void main()
+{
+ uvcoordsvar = vec4(uvs, 0.0, 0.0);
+ gl_Position = vec4(pos, 0.0, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
index e04cd7d3306..c4e7cff2b0b 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
@@ -1,9 +1,10 @@
uniform sampler2D depthbuffer;
-varying vec4 uvcoordsvar;
+
+in vec4 uvcoordsvar;
void main(void)
{
- float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+ float depth = texture(depthbuffer, uvcoordsvar.xy).r;
/* XRay background, discard */
if (depth >= 1.0) {
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
index 338ef6d51a7..15d30e75969 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -17,17 +17,18 @@ uniform vec4 dof_params;
uniform vec4 viewvecs[3];
// coordinates on framebuffer in normalized (0.0-1.0) uv space
-varying vec4 uvcoordsvar;
+in vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
-varying vec2 color_uv1;
-varying vec2 color_uv2;
+in vec2 color_uv1;
+in vec2 color_uv2;
-varying vec2 depth_uv1;
-varying vec2 depth_uv2;
-varying vec2 depth_uv3;
-varying vec2 depth_uv4;
+in vec2 depth_uv1;
+in vec2 depth_uv2;
+in vec2 depth_uv3;
+in vec2 depth_uv4;
+out vec4 FragColor;
float calculate_far_coc(in float zdepth)
{
@@ -63,85 +64,85 @@ void first_pass()
offset_row[2] = 3.0 * offset_row[0];
/* heavily blur the image */
- vec4 color = texture2D(colorbuffer, color_uv1);
- color += texture2D(colorbuffer, color_uv1 + offset_row[1]);
- color += texture2D(colorbuffer, color_uv2);
- color += texture2D(colorbuffer, color_uv2 + offset_row[1]);
+ vec4 color = texture(colorbuffer, color_uv1);
+ color += texture(colorbuffer, color_uv1 + offset_row[1]);
+ color += texture(colorbuffer, color_uv2);
+ color += texture(colorbuffer, color_uv2 + offset_row[1]);
color /= 4.0;
- depth.r = texture2D(depthbuffer, depth_uv1).r;
- depth.g = texture2D(depthbuffer, depth_uv2).r;
- depth.b = texture2D(depthbuffer, depth_uv3).r;
- depth.a = texture2D(depthbuffer, depth_uv4).r;
+ depth.r = texture(depthbuffer, depth_uv1).r;
+ depth.g = texture(depthbuffer, depth_uv2).r;
+ depth.b = texture(depthbuffer, depth_uv3).r;
+ depth.a = texture(depthbuffer, depth_uv4).r;
zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
coc = calculate_near_coc(zdepth);
- depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[0]).r;
- depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[0]).r;
- depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[0]).r;
- depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[0]).r;
+ depth.r = texture(depthbuffer, depth_uv1 + offset_row[0]).r;
+ depth.g = texture(depthbuffer, depth_uv2 + offset_row[0]).r;
+ depth.b = texture(depthbuffer, depth_uv3 + offset_row[0]).r;
+ depth.a = texture(depthbuffer, depth_uv4 + offset_row[0]).r;
zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
coc = max(calculate_near_coc(zdepth), coc);
- depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[1]).r;
- depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[1]).r;
- depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[1]).r;
- depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[1]).r;
+ depth.r = texture(depthbuffer, depth_uv1 + offset_row[1]).r;
+ depth.g = texture(depthbuffer, depth_uv2 + offset_row[1]).r;
+ depth.b = texture(depthbuffer, depth_uv3 + offset_row[1]).r;
+ depth.a = texture(depthbuffer, depth_uv4 + offset_row[1]).r;
zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
coc = max(calculate_near_coc(zdepth), coc);
- depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[2]).r;
- depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[2]).r;
- depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[2]).r;
- depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[2]).r;
+ depth.r = texture(depthbuffer, depth_uv1 + offset_row[2]).r;
+ depth.g = texture(depthbuffer, depth_uv2 + offset_row[2]).r;
+ depth.b = texture(depthbuffer, depth_uv3 + offset_row[2]).r;
+ depth.a = texture(depthbuffer, depth_uv4 + offset_row[2]).r;
zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
coc = max(calculate_near_coc(zdepth), coc);
final_coc = max(max(coc.x, coc.y), max(coc.z, coc.w));
- gl_FragColor = vec4(color.rgb, final_coc);
+ FragColor = vec4(color.rgb, final_coc);
}
/* second pass, gaussian blur the downsampled image */
void second_pass()
{
- vec4 depth = vec4(texture2D(depthbuffer, uvcoordsvar.xy).r);
+ vec4 depth = vec4(texture(depthbuffer, uvcoordsvar.xy).r);
/* clever sampling to sample 2 pixels at once. Of course it's not real gaussian sampling this way */
- vec4 color = texture2D(colorbuffer, uvcoordsvar.xy) * 0.3125;
- color += texture2D(colorbuffer, uvcoordsvar.xy + invrendertargetdim) * 0.234375;
- color += texture2D(colorbuffer, uvcoordsvar.xy + 2.5 * invrendertargetdim) * 0.09375;
- color += texture2D(colorbuffer, uvcoordsvar.xy + 4.5 * invrendertargetdim) * 0.015625;
- color += texture2D(colorbuffer, uvcoordsvar.xy - invrendertargetdim) * 0.234375;
- color += texture2D(colorbuffer, uvcoordsvar.xy - 2.5 * invrendertargetdim) * 0.09375;
- color += texture2D(colorbuffer, uvcoordsvar.xy - 4.5 * invrendertargetdim) * 0.015625;
-
- gl_FragColor = color;
+ vec4 color = texture(colorbuffer, uvcoordsvar.xy) * 0.3125;
+ color += texture(colorbuffer, uvcoordsvar.xy + invrendertargetdim) * 0.234375;
+ color += texture(colorbuffer, uvcoordsvar.xy + 2.5 * invrendertargetdim) * 0.09375;
+ color += texture(colorbuffer, uvcoordsvar.xy + 4.5 * invrendertargetdim) * 0.015625;
+ color += texture(colorbuffer, uvcoordsvar.xy - invrendertargetdim) * 0.234375;
+ color += texture(colorbuffer, uvcoordsvar.xy - 2.5 * invrendertargetdim) * 0.09375;
+ color += texture(colorbuffer, uvcoordsvar.xy - 4.5 * invrendertargetdim) * 0.015625;
+
+ FragColor = color;
}
/* third pass, calculate the final coc from blurred and unblurred images */
void third_pass()
{
- vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
- vec4 color_blurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy);
+ vec4 color = texture(colorbuffer, uvcoordsvar.xy);
+ vec4 color_blurred = texture(blurredcolorbuffer, uvcoordsvar.xy);
float coc = 2.0 * max(color_blurred.a, color.a); -color.a;
- gl_FragColor = vec4(color.rgb, coc);
+ FragColor = vec4(color.rgb, coc);
}
/* fourth pass, blur the final coc once to get rid of discontinuities */
void fourth_pass()
{
- vec4 color = texture2D(colorbuffer, uvcoordsvar.xz);
- color += texture2D(colorbuffer, uvcoordsvar.yz);
- color += texture2D(colorbuffer, uvcoordsvar.xw);
- color += texture2D(colorbuffer, uvcoordsvar.yw);
+ vec4 color = texture(colorbuffer, uvcoordsvar.xz);
+ color += texture(colorbuffer, uvcoordsvar.yz);
+ color += texture(colorbuffer, uvcoordsvar.xw);
+ color += texture(colorbuffer, uvcoordsvar.yw);
- gl_FragColor = color / 4.0;
+ FragColor = color / 4.0;
}
vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
@@ -150,10 +151,10 @@ vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
vec4 result = weight * color;
weight *= 4.0;
- result += weight * texture2D(colorbuffer, uv + color_uv1.xy);
- result += weight * texture2D(colorbuffer, uv - color_uv1.xy);
- result += weight * texture2D(colorbuffer, uv + color_uv1.yx);
- result += weight * texture2D(colorbuffer, uv - color_uv1.yx);
+ result += weight * texture(colorbuffer, uv + color_uv1.xy);
+ result += weight * texture(colorbuffer, uv - color_uv1.xy);
+ result += weight * texture(colorbuffer, uv + color_uv1.yx);
+ result += weight * texture(colorbuffer, uv - color_uv1.yx);
return result;
}
@@ -163,11 +164,11 @@ vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
void fifth_pass()
{
vec4 factors;
- vec4 color_orig = texture2D(colorbuffer, uvcoordsvar.xy);
- vec4 highblurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy);
- vec4 mediumblurred = texture2D(mblurredcolorbuffer, uvcoordsvar.xy);
+ vec4 color_orig = texture(colorbuffer, uvcoordsvar.xy);
+ vec4 highblurred = texture(blurredcolorbuffer, uvcoordsvar.xy);
+ vec4 mediumblurred = texture(mblurredcolorbuffer, uvcoordsvar.xy);
vec4 smallblurred = small_sample_blur(colorbuffer, uvcoordsvar.xy, color_orig);
- float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+ float depth = texture(depthbuffer, uvcoordsvar.xy).r;
float zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), vec4(depth)).r;
float coc_far = clamp(calculate_far_coc(zdepth), 0.0, 1.0);
@@ -188,7 +189,7 @@ void fifth_pass()
color /= dot(factors, vec4(1.0));
/* using original color is not correct, but use that for now because alpha of
* blurred buffers uses CoC instead */
- gl_FragColor = vec4(color.rgb, color_orig.a);
+ FragColor = vec4(color.rgb, color_orig.a);
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
index 182113367d3..c41c1d0820b 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
@@ -14,24 +14,28 @@ uniform sampler2D depthbuffer;
uniform sampler2D cocbuffer;
-/* this includes focal distance in x and aperture size in y */
+/* this includes aperture size in x and focal distance in y */
uniform vec4 dof_params;
/* viewvectors for reconstruction of world space */
uniform vec4 viewvecs[3];
/* initial uv coordinate */
-varying vec2 uvcoord;
+in vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
-varying vec2 particlecoord;
-varying vec4 color;
+in vec2 particlecoord;
+flat in vec4 color;
/* downsampling coordinates */
-varying vec2 downsample1;
-varying vec2 downsample2;
-varying vec2 downsample3;
-varying vec2 downsample4;
+in vec2 downsample1;
+in vec2 downsample2;
+in vec2 downsample3;
+in vec2 downsample4;
+
+layout(location = 0) out vec4 fragData0;
+layout(location = 1) out vec4 fragData1;
+layout(location = 2) out vec4 fragData2;
#define M_PI 3.1415926535897932384626433832795
@@ -55,15 +59,15 @@ void downsample_pass()
float far_coc, near_coc;
/* custom downsampling. We need to be careful to sample nearest here to avoid leaks */
- vec4 color1 = texture2D(colorbuffer, downsample1);
- vec4 color2 = texture2D(colorbuffer, downsample2);
- vec4 color3 = texture2D(colorbuffer, downsample3);
- vec4 color4 = texture2D(colorbuffer, downsample4);
+ vec4 color1 = texture(colorbuffer, downsample1);
+ vec4 color2 = texture(colorbuffer, downsample2);
+ vec4 color3 = texture(colorbuffer, downsample3);
+ vec4 color4 = texture(colorbuffer, downsample4);
- depth.r = texture2D(depthbuffer, downsample1).r;
- depth.g = texture2D(depthbuffer, downsample2).r;
- depth.b = texture2D(depthbuffer, downsample3).r;
- depth.a = texture2D(depthbuffer, downsample4).r;
+ depth.r = texture(depthbuffer, downsample1).r;
+ depth.g = texture(depthbuffer, downsample2).r;
+ depth.b = texture(depthbuffer, downsample3).r;
+ depth.a = texture(depthbuffer, downsample4).r;
zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
coc = calculate_coc(zdepth);
@@ -82,16 +86,16 @@ void downsample_pass()
float norm_far = dot(far_weights, vec4(1.0));
/* now write output to weighted buffers. */
- gl_FragData[0] = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z +
+ fragData0 = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z +
color4 * near_weights.w;
- gl_FragData[1] = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z +
+ fragData1 = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z +
color4 * far_weights.w;
if (norm_near > 0.0)
- gl_FragData[0] /= norm_near;
+ fragData0 /= norm_near;
if (norm_far > 0.0)
- gl_FragData[1] /= norm_far;
- gl_FragData[2] = vec4(near_coc, far_coc, 0.0, 1.0);
+ fragData1 /= norm_far;
+ fragData2 = vec4(near_coc, far_coc, 0.0, 1.0);
}
/* accumulate color in the near/far blur buffers */
@@ -102,36 +106,36 @@ void accumulate_pass(void) {
if (dof_params.w == 0.0)
r = 1.0;
else
- r = cos(M_PI / dof_params.w) /
- (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI))));
+ r = cos(M_PI / dof_params.w) /
+ (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI))));
if (dot(particlecoord, particlecoord) > r * r)
discard;
- gl_FragData[0] = color;
+ fragData0 = color;
}
-#define MERGE_THRESHOLD 4.0
+#define MERGE_THRESHOLD 4.0
/* combine the passes, */
void final_pass(void) {
vec4 finalcolor;
float totalweight;
- float depth = texture2D(depthbuffer, uvcoord).r;
+ float depth = texture(depthbuffer, uvcoord).r;
vec4 zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), vec4(depth));
float coc_near = calculate_coc(zdepth).r;
float coc_far = max(-coc_near, 0.0);
coc_near = max(coc_near, 0.0);
- vec4 farcolor = texture2D(farbuffer, uvcoord);
+ vec4 farcolor = texture(farbuffer, uvcoord);
float farweight = farcolor.a;
if (farweight > 0.0)
farcolor /= farweight;
- vec4 nearcolor = texture2D(nearbuffer, uvcoord);
+ vec4 nearcolor = texture(nearbuffer, uvcoord);
- vec4 srccolor = texture2D(colorbuffer, uvcoord);
+ vec4 srccolor = texture(colorbuffer, uvcoord);
- vec4 coc = texture2D(cocbuffer, uvcoord);
+ vec4 coc = texture(cocbuffer, uvcoord);
float mixfac = smoothstep(1.0, MERGE_THRESHOLD, coc_far);
finalcolor = mix(srccolor, farcolor, mixfac);
@@ -152,7 +156,9 @@ void final_pass(void) {
finalcolor = mix(finalcolor, nearcolor, nearweight / totalweight);
}
- gl_FragData[0] = finalcolor;
+ fragData0 = finalcolor;
+ // fragData0 = vec4(nearweight, farweight, 0.0, 1.0);
+ // fragData0 = vec4(nearcolor.rgb, 1.0);
}
void main()
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
index 4c650e7695f..52d0a9be499 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
@@ -5,27 +5,14 @@ uniform vec2 layerselection;
uniform sampler2D cocbuffer;
-#if __VERSION__ >= 150
- layout(points) in;
- layout(triangle_strip, max_vertices = 4) out;
-
- #define POS gl_in[0].gl_Position
-#else
- /* use the EXT_geometry_shader4 way */
- #define POS gl_PositionIn[0]
-#endif
-
-/* initial uv coordinate */
-#if __VERSION__ < 130
- varying in vec2 uvcoord[];
- varying out vec2 particlecoord;
- varying out vec4 color;
- #define textureLod texture2DLod
-#else
- in vec2 uvcoord[];
- out vec2 particlecoord;
- out vec4 color;
-#endif
+layout(points) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+#define POS gl_in[0].gl_Position
+
+in vec2 uvcoord[];
+out vec2 particlecoord;
+flat out vec4 color;
#define M_PI 3.1415926535897932384626433832795
@@ -46,21 +33,23 @@ void main()
vec2 offset_far = vec2(offset_val * 0.5) / vec2(rendertargetdim.x, rendertargetdim.y);
- gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
color = colortex;
+
+ gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
particlecoord = vec2(-1.0, -1.0);
EmitVertex();
+
gl_Position = POS + vec4(-offset_far.x, offset_far.y, 0.0, 0.0);
particlecoord = vec2(-1.0, 1.0);
- color = colortex;
EmitVertex();
+
gl_Position = POS + vec4(offset_far.x, -offset_far.y, 0.0, 0.0);
particlecoord = vec2(1.0, -1.0);
- color = colortex;
EmitVertex();
+
gl_Position = POS + vec4(offset_far.x, offset_far.y, 0.0, 0.0);
particlecoord = vec2(1.0, 1.0);
- color = colortex;
EmitVertex();
+
EndPrimitive();
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
index 09a0c75facc..1dd5bf42b25 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
@@ -1,27 +1,31 @@
-uniform vec2 invrendertargetdim;
-uniform ivec2 rendertargetdim;
+
+in vec2 pos;
+in vec2 uvs;
/* initial uv coordinate */
-varying vec2 uvcoord;
+out vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
-varying vec2 particlecoord;
+out vec2 particlecoord;
/* downsampling coordinates */
-varying vec2 downsample1;
-varying vec2 downsample2;
-varying vec2 downsample3;
-varying vec2 downsample4;
+out vec2 downsample1;
+out vec2 downsample2;
+out vec2 downsample3;
+out vec2 downsample4;
+
+uniform vec2 invrendertargetdim;
+uniform ivec2 rendertargetdim;
void vert_dof_downsample()
{
/* gather pixels from neighbors. half dimensions means we offset half a pixel to
* get this right though it's possible we may lose a pixel at some point */
- downsample1 = gl_MultiTexCoord0.xy + vec2(-0.5, -0.5) * invrendertargetdim;
- downsample2 = gl_MultiTexCoord0.xy + vec2(-0.5, 0.5) * invrendertargetdim;
- downsample3 = gl_MultiTexCoord0.xy + vec2(0.5, 0.5) * invrendertargetdim;
- downsample4 = gl_MultiTexCoord0.xy + vec2(0.5, -0.5) * invrendertargetdim;
+ downsample1 = uvs.xy + vec2(-0.5, -0.5) * invrendertargetdim;
+ downsample2 = uvs.xy + vec2(-0.5, 0.5) * invrendertargetdim;
+ downsample3 = uvs.xy + vec2(0.5, 0.5) * invrendertargetdim;
+ downsample4 = uvs.xy + vec2(0.5, -0.5) * invrendertargetdim;
- gl_Position = gl_Vertex;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
/* geometry shading pass, calculate a texture coordinate based on the indexed id */
@@ -42,8 +46,8 @@ void vert_dof_coc_scatter_pass()
void vert_dof_final()
{
- uvcoord = gl_MultiTexCoord0.xy;
- gl_Position = gl_Vertex;
+ uvcoord = uvs;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void main()
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
index 63b57d5775c..0fcab6302e4 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
@@ -1,51 +1,54 @@
uniform vec2 invrendertargetdim;
-//texture coordinates for framebuffer read
-varying vec4 uvcoordsvar;
+in vec2 pos;
+in vec2 uvs;
+
+/* texture coordinates for framebuffer read */
+out vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
-varying vec2 color_uv1;
-varying vec2 color_uv2;
+out vec2 color_uv1;
+out vec2 color_uv2;
-varying vec2 depth_uv1;
-varying vec2 depth_uv2;
-varying vec2 depth_uv3;
-varying vec2 depth_uv4;
+out vec2 depth_uv1;
+out vec2 depth_uv2;
+out vec2 depth_uv3;
+out vec2 depth_uv4;
//very simple shader for gull screen FX, just pass values on
void vert_generic()
{
- uvcoordsvar = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
+ uvcoordsvar = vec4(uvs, 0.0, 0.0);
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_first_pass()
{
/* we offset the texture coordinates by 1.5 pixel,
* then we reuse that to sample the surrounding pixels */
- color_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
- color_uv2 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
+ color_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim;
+ color_uv2 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim;
- depth_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
- depth_uv2 = gl_MultiTexCoord0.xy + vec2(-0.5, -1.5) * invrendertargetdim;
- depth_uv3 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
- depth_uv4 = gl_MultiTexCoord0.xy + vec2(1.5, -1.5) * invrendertargetdim;
+ depth_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim;
+ depth_uv2 = uvs.xy + vec2(-0.5, -1.5) * invrendertargetdim;
+ depth_uv3 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim;
+ depth_uv4 = uvs.xy + vec2(1.5, -1.5) * invrendertargetdim;
- gl_Position = gl_Vertex;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_fourth_pass()
{
vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
- uvcoordsvar = gl_MultiTexCoord0.xxyy +
+ uvcoordsvar = uvs.xxyy +
halfpixel *
vec4(invrendertargetdim.x,
invrendertargetdim.x,
invrendertargetdim.y,
invrendertargetdim.y);
- gl_Position = gl_Vertex;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_fifth_pass()
@@ -53,8 +56,8 @@ void vert_dof_fifth_pass()
vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
color_uv1 = vec2(0.5, 1.5) * invrendertargetdim;
- uvcoordsvar = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
+ uvcoordsvar = vec4(uvs, 0.0, 0.0);
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void main()
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
index 1dc49b52be1..7aa6786d292 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
@@ -1,14 +1,17 @@
+uniform mat4 ProjectionMatrix;
+
/* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
* we change the factors from the article to fit the OpennGL model. */
#ifdef PERSP_MATRIX
+
/* perspective camera code */
vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
{
float d = 2.0 * depth - 1.0;
- float zview = -gl_ProjectionMatrix[3][2] / (d + gl_ProjectionMatrix[2][2]);
+ float zview = -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
}
@@ -18,7 +21,7 @@ vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
vec4 d = 2.0 * depth - vec4(1.0);
/* return positive value, so sign differs! */
- return vec4(gl_ProjectionMatrix[3][2]) / (d + vec4(gl_ProjectionMatrix[2][2]));
+ return vec4(ProjectionMatrix[3][2]) / (d + vec4(ProjectionMatrix[2][2]));
}
#else
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
index f19ff4ec65a..4904010c841 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
@@ -1,3 +1,4 @@
+
// color buffer
uniform sampler2D colorbuffer;
@@ -9,8 +10,10 @@ uniform sampler1D ssao_concentric_tex;
// depth buffer
uniform sampler2D depthbuffer;
+
// coordinates on framebuffer in normalized (0.0-1.0) uv space
-varying vec4 uvcoordsvar;
+in vec4 uvcoordsvar;
+out vec4 FragColor;
/* ssao_params.x : pixel scale for the ssao radious */
/* ssao_params.y : factor for the ssao darkening */
@@ -33,7 +36,7 @@ vec3 calculate_view_space_normal(in vec3 viewposition)
float calculate_ssao_factor(float depth)
{
/* take the normalized ray direction here */
- vec2 rotX = texture2D(jitter_tex, uvcoordsvar.xy * ssao_sample_params.yz).rg;
+ vec2 rotX = texture(jitter_tex, uvcoordsvar.xy * ssao_sample_params.yz).rg;
vec2 rotY = vec2(-rotX.y, rotX.x);
/* occlusion is zero in full depth */
@@ -46,9 +49,9 @@ float calculate_ssao_factor(float depth)
/* find the offset in screen space by multiplying a point
* in camera space at the depth of the point by the projection matrix. */
vec2 offset;
- float homcoord = gl_ProjectionMatrix[2][3] * position.z + gl_ProjectionMatrix[3][3];
- offset.x = gl_ProjectionMatrix[0][0] * ssao_params.x / homcoord;
- offset.y = gl_ProjectionMatrix[1][1] * ssao_params.x / homcoord;
+ float homcoord = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3];
+ offset.x = ProjectionMatrix[0][0] * ssao_params.x / homcoord;
+ offset.y = ProjectionMatrix[1][1] * ssao_params.x / homcoord;
/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
offset *= 0.5;
@@ -57,7 +60,7 @@ float calculate_ssao_factor(float depth)
int num_samples = int(ssao_sample_params.x);
for (x = 0; x < num_samples; x++) {
- vec2 dir_sample = texture1D(ssao_concentric_tex, (float(x) + 0.5) / ssao_sample_params.x).rg;
+ vec2 dir_sample = texture(ssao_concentric_tex, (float(x) + 0.5) / ssao_sample_params.x).rg;
/* rotate with random direction to get jittered result */
vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY));
@@ -67,7 +70,7 @@ float calculate_ssao_factor(float depth)
if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
continue;
- float depth_new = texture2D(depthbuffer, uvcoords).r;
+ float depth_new = texture(depthbuffer, uvcoords).r;
if (depth_new != 1.0) {
vec3 pos_new = get_view_space_from_depth(uvcoords, viewvecs[0].xyz, viewvecs[1].xyz, depth_new);
vec3 dir = pos_new - position;
@@ -87,8 +90,8 @@ float calculate_ssao_factor(float depth)
void main()
{
- float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
- vec4 scene_col = texture2D(colorbuffer, uvcoordsvar.xy);
+ float depth = texture(depthbuffer, uvcoordsvar.xy).r;
+ vec4 scene_col = texture(colorbuffer, uvcoordsvar.xy);
vec3 final_color = mix(scene_col.rgb, ssao_color.rgb, calculate_ssao_factor(depth));
- gl_FragColor = vec4(final_color.rgb, scene_col.a);
+ FragColor = vec4(final_color.rgb, scene_col.a);
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
deleted file mode 100644
index 5194e414520..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-varying vec4 uvcoordsvar;
-
-//very simple shader for full screen FX, just pass values on
-
-void main()
-{
- uvcoordsvar = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
index fe630dbeddb..7586050b258 100644
--- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
@@ -1,10 +1,11 @@
+
+uniform mat4 ProjectionMatrix;
+
uniform int PrimitiveIdBase;
uniform int osd_active_uv_offset;
-#if __VERSION__ >= 150
- layout(lines_adjacency) in;
- layout(triangle_strip, max_vertices = 4) out;
-#endif
+layout(lines_adjacency) in;
+layout(triangle_strip, max_vertices = 4) out;
in block {
VertexData v;
@@ -69,7 +70,7 @@ void emit_flat(int index, vec3 normal)
set_mtface_vertex_attrs(st);
- gl_Position = gl_ProjectionMatrix * inpt[index].v.position;
+ gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
@@ -90,7 +91,7 @@ void emit_smooth(int index)
set_mtface_vertex_attrs(st);
- gl_Position = gl_ProjectionMatrix * inpt[index].v.position;
+ gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl
new file mode 100644
index 00000000000..727c3c0a832
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl
@@ -0,0 +1,11 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform vec4 color;
+uniform sampler2D image;
+
+void main()
+{
+ fragColor = texture(image, texCoord_interp).r * color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl
new file mode 100644
index 00000000000..ef8935cc7ba
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl
@@ -0,0 +1,11 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform vec4 color;
+uniform sampler2D image;
+
+void main()
+{
+ fragColor = texture(image, texCoord_interp) * color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl
new file mode 100644
index 00000000000..bcbe1f577fd
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl
@@ -0,0 +1,16 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform float znear;
+uniform float zfar;
+uniform sampler2D image;
+
+void main()
+{
+ float depth = texture(image, texCoord_interp).r;
+
+ /* normalize */
+ fragColor.rgb = vec3((2.0f * znear) / (zfar + znear - (depth * (zfar - znear))));
+ fragColor.a = 1.0f;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl
new file mode 100644
index 00000000000..7f3e7df40ac
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl
@@ -0,0 +1,34 @@
+
+/* Keep these in sync with GPU_shader.h */
+#define INTERLACE_ROW 0
+#define INTERLACE_COLUMN 1
+#define INTERLACE_CHECKERBOARD 2
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform int interlace_id;
+uniform sampler2DRect image_a;
+uniform sampler2DRect image_b;
+
+bool interlace()
+{
+ if (interlace_id == INTERLACE_CHECKERBOARD) {
+ return (int(gl_FragCoord.x + gl_FragCoord.y) & 1) != 0;
+ }
+ else if (interlace_id == INTERLACE_ROW) {
+ return (int(gl_FragCoord.y) & 1) != 0;
+ }
+ else if (interlace_id == INTERLACE_COLUMN) {
+ return (int(gl_FragCoord.x) & 1) != 0;
+ }
+}
+
+void main()
+{
+ if (interlace()) {
+ fragColor = texture(image_a, texCoord_interp);
+ } else {
+ fragColor = texture(image_b, texCoord_interp);
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl
new file mode 100644
index 00000000000..c2b25cc8011
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl
@@ -0,0 +1,30 @@
+
+/* Display a linear image texture into sRGB space */
+
+uniform sampler2D image;
+
+in vec2 texCoord_interp;
+
+out vec4 fragColor;
+
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308)
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ else
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+}
+
+void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
+{
+ col_to.r = linearrgb_to_srgb(col_from.r);
+ col_to.g = linearrgb_to_srgb(col_from.g);
+ col_to.b = linearrgb_to_srgb(col_from.b);
+ col_to.a = col_from.a;
+}
+
+void main() {
+ fragColor = texture(image, texCoord_interp.st);
+
+ linearrgb_to_srgb(fragColor, fragColor);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl
new file mode 100644
index 00000000000..4a45d03175e
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl
@@ -0,0 +1,12 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform sampler2D image;
+uniform vec4 color;
+
+void main()
+{
+ fragColor.a = texture(image, texCoord_interp).a * color.a;
+ fragColor.rgb = color.rgb;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl
new file mode 100644
index 00000000000..51092d56e5e
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl
@@ -0,0 +1,12 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform float alpha;
+uniform sampler2D image;
+
+void main()
+{
+ fragColor = texture(image, texCoord_interp);
+ fragColor.a *= alpha;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl
new file mode 100644
index 00000000000..7d9ce9d2003
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl
@@ -0,0 +1,12 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform float alpha;
+uniform sampler2DRect image;
+
+void main()
+{
+ fragColor = texture(image, texCoord_interp);
+ fragColor.a *= alpha;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl
new file mode 100644
index 00000000000..64662247d69
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl
@@ -0,0 +1,16 @@
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform sampler2D image;
+uniform vec4 color;
+uniform vec4 shuffle;
+
+void main()
+{
+ vec4 sample = texture(image, texCoord_interp);
+ fragColor = vec4(sample.r * shuffle.r +
+ sample.g * shuffle.g +
+ sample.b * shuffle.b +
+ sample.a * shuffle.a) * color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl
new file mode 100644
index 00000000000..74c8f6f3103
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl
@@ -0,0 +1,122 @@
+
+
+/* This shader essentially operates in Object space, where it aligns given geometry with bone, scales it accordingly
+ * to given radii, and then does usual basic solid operations.
+ * Note that if one of head/tail radius is negative, it assumes it only works on the other end of the bone
+ * (used to draw head/tail spheres). */
+
+
+uniform mat4 ViewMatrix;
+uniform mat4 ObjectModelMatrix;
+uniform mat4 ViewProjectionMatrix;
+
+
+/* ---- Instanciated Attribs ---- */
+in vec4 pos; /* w encodes head (== 0.0f), tail (== 1.0f) or in-between. */
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec4 color;
+
+in float radius_head;
+in float radius_tail;
+
+
+out vec3 normal;
+flat out vec4 finalColor;
+
+
+void main()
+{
+ /* We get head/tail in object space. */
+ vec4 head = InstanceModelMatrix * vec4(0.0f, 0.0f, 0.0f, 1.0f);
+ vec4 tail = InstanceModelMatrix * vec4(0.0f, 1.0f, 0.0f, 1.0f);
+
+ /* We need rotation from bone mat, but not scaling. */
+ mat3 bone_mat = mat3(InstanceModelMatrix);
+ bone_mat[0] = normalize(bone_mat[0]);
+ bone_mat[1] = normalize(bone_mat[1]);
+ bone_mat[2] = normalize(bone_mat[2]);
+
+ mat3 nor_mat = transpose(inverse(mat3(ViewMatrix * ObjectModelMatrix) * bone_mat));
+
+ /* Where does this comes from???? Don't know why, but is mandatory anyway... :/ */
+ const float size = 2.0f;
+
+ head.xyz *= size;
+ tail.xyz *= size;
+
+ bool head_only = (radius_tail < 0.0f);
+ bool tail_only = (radius_head < 0.0f);
+ /* == 0: head; == 1: tail; in-between: along bone. */
+ float head_fac = head_only ? 0.0f : (tail_only ? 1.0f : pos.w);
+
+ vec4 ob_pos;
+ vec4 ob_bone_origin;
+ float radius;
+
+ /* head */
+ if (head_fac <= 0.0f) {
+ if (!head_only) {
+ /* We are drawing the body itself, need to adjust start/end positions and radius! */
+ vec3 bone_vec = tail.xyz - head.xyz;
+ float len = length(bone_vec);
+
+ if (len > (radius_head + radius_tail)) {
+ float fac = (len - radius_head) / len;
+ radius = fac * radius_head + (1.0f - fac) * radius_tail;
+ bone_vec /= len;
+ ob_bone_origin = vec4(head.xyz + bone_vec * radius_head * size, 1.0f);
+ }
+ else {
+ radius = (radius_head + radius_tail) / 2.0f;
+ ob_bone_origin = (head + tail) / 2.0f;
+ }
+ }
+ else {
+ radius = radius_head;
+ ob_bone_origin = head;
+ }
+ }
+ /* tail */
+ else if (head_fac >= 1.0f) {
+ if (!tail_only) {
+ /* We are drawing the body itself, need to adjust start/end positions and radius! */
+ vec3 bone_vec = tail.xyz - head.xyz;
+ float len = length(bone_vec);
+
+ if (len > (radius_head + radius_tail)) {
+ float fac = (len - radius_tail) / len;
+ radius = fac * radius_tail + (1.0f - fac) * radius_head;
+ bone_vec /= len;
+ ob_bone_origin = vec4(tail.xyz - bone_vec * radius_tail * size, 1.0f);
+ }
+ else {
+ radius = (radius_head + radius_tail) / 2.0f;
+ ob_bone_origin = (head + tail) / 2.0f;
+ }
+ }
+ else {
+ radius = radius_tail;
+ ob_bone_origin = tail;
+ }
+ }
+ /* Body of the bone */
+#if 0 /* Note: not used currently! */
+ else {
+ float tail_fac = 1.0f - head_fac;
+ radius = radius_head * head_fac + radius_tail * tail_fac;
+ ob_bone_origin = head * head_fac + tail * tail_fac;
+ }
+#endif
+
+ /* Yep, since input pos is unit sphere coordinates, it's also our normal. */
+ vec3 nor = pos.xyz;
+ ob_pos = pos * radius * size;
+ ob_pos.xyz = bone_mat * ob_pos.xyz;
+ ob_pos.w = 1.0f;
+
+ gl_Position = ViewProjectionMatrix * ObjectModelMatrix * (ob_pos + ob_bone_origin);
+ normal = normalize(nor_mat * nor);
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl
new file mode 100644
index 00000000000..a36eb1dec77
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl
@@ -0,0 +1,103 @@
+
+
+/* This shader takes a 2D shape, puts it in 3D Object space such that is stays aligned with view and bone,
+ * and scales head/tail/distance according to per-instance attributes
+ * (and 'role' of current vertex, encoded in zw input, head or tail, and inner or outer for distance outline).
+ * It is used for both the distance outline drawing, and the wire version of envelope bone.
+ * Note that if one of head/tail radius is negative, it assumes it only works on the other end of the bone
+ * (used to draw head/tail spheres). */
+
+
+uniform mat4 ViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat4 ObjectModelMatrix;
+
+
+/* ---- Instanciated Attribs ---- */
+in vec4 pos; /* z encodes head (== 0.0f), tail (== 1.0f) or in-between; w encodes inner (0.0f) or outer border. */
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec4 color;
+
+in float radius_head;
+in float radius_tail;
+in float distance;
+
+
+flat out vec4 finalColor;
+
+
+void main()
+{
+ /* We get head/tail in object space. */
+ mat4 bone_mat = InstanceModelMatrix;
+ vec4 head = bone_mat * vec4(0.0f, 0.0f, 0.0f, 1.0f);
+ vec4 tail = bone_mat * vec4(0.0f, 1.0f, 0.0f, 1.0f);
+
+ /* We generate our XY axes in object space, Y axis being aligned with bone in view space. */
+ mat4 obview_mat = ViewMatrix * ObjectModelMatrix;
+ mat4 iobview_mat = inverse(obview_mat);
+
+ vec4 view_bone_vec = obview_mat * normalize(tail - head);
+ view_bone_vec.z = 0.0f;
+ if (length(view_bone_vec.xy) <= 1e-5f) {
+ /* A bit weak, but will do the job for now.
+ * Ideally we could compute head/tail radius in view space, and take larger one... */
+ if (view_bone_vec.x > view_bone_vec.y) {
+ view_bone_vec.x = 1e-5f;
+ }
+ else {
+ view_bone_vec.y = 1e-5f;
+ }
+ }
+ vec3 bone_axis_y = normalize((iobview_mat * view_bone_vec).xyz);
+ vec3 bone_axis_x = normalize(cross(bone_axis_y, iobview_mat[2].xyz));
+
+ /* Where does this comes from???? Don't know why, but is mandatory anyway... :/ */
+ float size = 2.0f;
+
+ head.xyz *= size;
+ tail.xyz *= size;
+
+ bool head_only = (radius_tail < 0.0f);
+ bool tail_only = (radius_head < 0.0f);
+ /* == 0: head; == 1: tail; in-between: along bone. */
+ float head_fac = head_only ? 0.0f : (tail_only ? 1.0f : pos.z);
+ bool do_distance_offset = (pos.w != 0.0f) && (distance >= 0.0f);
+
+ vec2 xy_pos = pos.xy;
+ vec4 ob_pos;
+
+ vec4 ob_bone_origin;
+ float radius;
+
+ /* head */
+ if (head_fac <= 0.0f) {
+ radius = radius_head;
+ ob_bone_origin = head;
+ }
+ /* tail */
+ else if (head_fac >= 1.0f) {
+ radius = radius_tail;
+ ob_bone_origin = tail;
+ }
+ /* Body of the bone */
+#if 0 /* Note: not used currently! */
+ else {
+ float tail_fac = 1.0f - head_fac;
+ radius = radius_head * head_fac + radius_tail * tail_fac;
+ ob_bone_origin = head * head_fac + tail * tail_fac;
+ }
+#endif
+
+ if (do_distance_offset) {
+ radius += distance;
+ }
+
+ xy_pos = xy_pos * radius * size;
+
+ ob_pos = ob_bone_origin + vec4(bone_axis_x * xy_pos.x + bone_axis_y * xy_pos.y, 1.0f);
+ gl_Position = ProjectionMatrix * obview_mat * ob_pos;
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl
new file mode 100644
index 00000000000..aec8fd9b0a1
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl
@@ -0,0 +1,50 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in float pos;
+
+/* ---- Per instance Attribs ---- */
+in vec3 color;
+in vec4 corners[2]; /* trouble fetching vec2 */
+in float depth;
+in vec4 tria;
+in mat4 InstanceModelMatrix;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ vec3 pPos;
+
+ if (pos == 1.0) {
+ pPos = vec3(corners[0].xy, depth);
+ }
+ else if (pos == 2.0) {
+ pPos = vec3(corners[0].zw, depth);
+ }
+ else if (pos == 3.0) {
+ pPos = vec3(corners[1].xy, depth);
+ }
+ else if (pos == 4.0) {
+ pPos = vec3(corners[1].zw, depth);
+ }
+ else if (pos == 5.0) {
+ pPos = vec3(tria.xy, depth);
+ }
+ else if (pos == 6.0) {
+ vec2 ofs = tria.xy - corners[0].xy;
+ ofs.x = -ofs.x;
+ pPos = vec3(corners[1].zw + ofs, depth);
+ }
+ else if (pos == 7.0) {
+ pPos = vec3(tria.zw, depth);
+ }
+ else {
+ pPos = vec3(0.0);
+ }
+
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pPos, 1.0);
+
+ finalColor = vec4(color, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl
new file mode 100644
index 00000000000..142df70e68a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl
@@ -0,0 +1,25 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos;
+
+/* ---- Per instance Attribs ---- */
+in vec3 color;
+in float start;
+in float end;
+in mat4 InstanceModelMatrix;
+
+uniform float size;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ float len = end - start;
+ vec3 sta = vec3(0.0, 0.0, -start);
+
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * -len + sta, 1.0);
+ gl_PointSize = size;
+ finalColor = vec4(color, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl
new file mode 100644
index 00000000000..6f580ef3ff6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl
@@ -0,0 +1,57 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. This geometry shader
+// decides which edge type to use if endpoints disagree.
+
+uniform mat4 ProjectionMatrix;
+
+uniform bool drawFront = true;
+uniform bool drawBack = true;
+uniform bool drawSilhouette = true;
+
+layout(lines) in;
+layout(line_strip, max_vertices = 2) out;
+
+in vec4 MV_pos[];
+in float edgeClass[];
+in vec3 fCol[];
+
+flat out vec4 finalColor;
+
+void emitLine(vec4 color)
+{
+ gl_Position = ProjectionMatrix * MV_pos[0];
+ EmitVertex();
+ gl_Position = ProjectionMatrix * MV_pos[1];
+ finalColor = color;
+ EmitVertex();
+ EndPrimitive();
+}
+
+void main()
+{
+ float finalEdgeClass = max(edgeClass[0], edgeClass[1]);
+
+ if (finalEdgeClass > 0.0f) {
+ // front-facing edge
+ if (drawFront)
+ emitLine(vec4(fCol[0], 0.75));
+ }
+ else if (finalEdgeClass < 0.0f) {
+ // back-facing edge
+ if (drawBack)
+ emitLine(vec4(fCol[0], 0.5));
+ }
+ else {
+ // exactly one face is front-facing, silhouette edge
+ if (drawSilhouette)
+ emitLine(vec4(fCol[0], 1.0));
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
new file mode 100644
index 00000000000..5d1e949c1d4
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
@@ -0,0 +1,64 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. We use a geometry
+// shader to resolve this properly.
+
+uniform mat4 ViewMatrix;
+
+in vec3 pos;
+in vec3 N1, N2; // normals of faces this edge joins (object coords)
+
+/* instance attrib */
+in vec3 color;
+in mat4 InstanceModelMatrix;
+
+out vec4 MV_pos;
+out float edgeClass;
+out vec3 fCol;
+
+// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
+
+mat3 NormalMatrix;
+
+bool front(vec3 N, vec3 eye)
+{
+ return dot(NormalMatrix * N, eye) > 0.0;
+}
+
+void main()
+{
+ vec3 eye;
+
+ mat4 ModelViewMatrix = ViewMatrix * InstanceModelMatrix;
+
+ MV_pos = ModelViewMatrix * vec4(pos, 1.0);
+
+ NormalMatrix = transpose(inverse(mat3(ModelViewMatrix)));
+
+ /* if persp */
+ if (ViewMatrix[3][3] == 0.0) {
+ eye = normalize(-MV_pos.xyz);
+ }
+ else {
+ eye = vec3(0.0, 0.0, 1.0);
+ }
+
+ bool face_1_front = front(N1, eye);
+ bool face_2_front = front(N2, eye);
+
+ if (face_1_front && face_2_front)
+ edgeClass = 1.0; // front-facing edge
+ else if (face_1_front || face_2_front)
+ edgeClass = 0.0; // exactly one face is front-facing, silhouette edge
+ else
+ edgeClass = -1.0; // back-facing edge
+
+ fCol = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
new file mode 100644
index 00000000000..195d4849d99
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
@@ -0,0 +1,29 @@
+
+uniform mat4 ViewMatrix;
+uniform mat4 ViewProjectionMatrix;
+uniform mat4 ObjectModelMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos;
+in vec3 nor;
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec4 color;
+
+out vec3 normal;
+flat out vec4 finalColor;
+
+void main()
+{
+ mat4 FinalModelMatrix = ObjectModelMatrix * InstanceModelMatrix;
+ mat4 ModelViewProjectionMatrix = ViewProjectionMatrix * FinalModelMatrix;
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attrib */
+ mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * FinalModelMatrix)));
+
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ normal = NormalMatrix * nor;
+
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl
new file mode 100644
index 00000000000..2ee74b3eae0
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl
@@ -0,0 +1,32 @@
+
+uniform mat4 ViewProjectionMatrix;
+uniform vec3 screen_vecs[2];
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos; /* using Z as axis id */
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec3 color;
+in float size;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ vec3 offset = vec3(0.0);
+
+#ifdef AXIS_NAME
+ if (pos.z == 0.0)
+ offset = vec3(1.125, 0.0, 0.0);
+ else if (pos.z == 1.0)
+ offset = vec3(0.0, 1.125, 0.0);
+ else
+ offset = vec3(0.0, 0.0, 1.125);
+ offset *= size;
+#endif
+
+ vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y;
+ gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset, 1.0) + vec4(screen_pos * size, 0.0));
+ finalColor = vec4(color, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl
new file mode 100644
index 00000000000..ba0ac29fb79
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl
@@ -0,0 +1,29 @@
+
+uniform mat4 ViewProjectionMatrix;
+uniform vec3 screen_vecs[2];
+uniform float size;
+uniform float pixel_size;
+
+/* ---- Instanciated Attribs ---- */
+in vec2 pos;
+
+/* ---- Per instance Attribs ---- */
+in vec3 world_pos;
+in vec3 color;
+
+flat out vec4 finalColor;
+
+float mul_project_m4_v3_zfac(in vec3 co)
+{
+ return (ViewProjectionMatrix[0][3] * co.x) +
+ (ViewProjectionMatrix[1][3] * co.y) +
+ (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatrix[3][3];
+}
+
+void main()
+{
+ float pix_size = mul_project_m4_v3_zfac(world_pos) * pixel_size;
+ vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y;
+ gl_Position = ViewProjectionMatrix * vec4(world_pos + screen_pos * size * pix_size, 1.0);
+ finalColor = vec4(color, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl
new file mode 100644
index 00000000000..10a2ba61a2c
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl
@@ -0,0 +1,22 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos;
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec3 color;
+#ifdef UNIFORM_SCALE
+in float size;
+#else
+in vec3 size;
+#endif
+
+flat out vec4 finalColor;
+
+void main()
+{
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * size, 1.0);
+ finalColor = vec4(color, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_vert.glsl
new file mode 100644
index 00000000000..eac167e8045
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_vert.glsl
@@ -0,0 +1,13 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos;
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+
+void main()
+{
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl
new file mode 100644
index 00000000000..7f445369833
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl
@@ -0,0 +1,31 @@
+
+in vec4 radii;
+in vec4 finalColor;
+in vec4 finalOutlineColor;
+out vec4 fragColor;
+
+void main() {
+ vec2 quad = abs(gl_PointCoord - vec2(0.5));
+ float dist = quad.x + quad.y;
+
+// transparent outside of point
+// --- 0 ---
+// smooth transition
+// --- 1 ---
+// pure outline color
+// --- 2 ---
+// smooth transition
+// --- 3 ---
+// pure point color
+// ...
+// dist = 0 at center of point
+
+ float mid_stroke = 0.5 * (radii[1] + radii[2]);
+
+ vec4 backgroundColor = vec4(finalOutlineColor.rgb, 0.0);
+
+ if (dist > mid_stroke)
+ fragColor = mix(finalOutlineColor, backgroundColor, smoothstep(radii[1], radii[0], dist));
+ else
+ fragColor = mix(finalColor, finalOutlineColor, smoothstep(radii[3], radii[2], dist));
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl
new file mode 100644
index 00000000000..b86d6fd70fe
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl
@@ -0,0 +1,34 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+const float pixel_fudge = sqrt(2.0);
+const float outline_width = 1.25 * pixel_fudge;
+
+in vec2 pos;
+in float size;
+in vec4 color;
+in vec4 outlineColor;
+out vec4 finalColor;
+out vec4 finalOutlineColor;
+out vec4 radii;
+
+void main() {
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+
+ // pass through unchanged
+ gl_PointSize = size + pixel_fudge; // 0.5 pixel_fudge on either side
+ finalColor = color;
+ finalOutlineColor = outlineColor;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * gl_PointSize;
+
+ // start at the outside and progress toward the center
+ radii[0] = radius;
+ radii[1] = radius - pixel_fudge;
+ radii[2] = radius - outline_width;
+ radii[3] = radius - outline_width - pixel_fudge;
+
+ // convert to PointCoord units
+ radii /= size;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 5c52b7fd153..581d00a1081 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1,11 +1,27 @@
+
+uniform mat4 ModelViewMatrix;
+#ifndef EEVEE_ENGINE
+uniform mat4 ProjectionMatrix;
+#endif
+uniform mat4 ViewMatrix;
+uniform mat4 ModelMatrix;
+uniform mat4 ModelMatrixInverse;
+uniform mat4 ModelViewMatrixInverse;
+uniform mat4 ViewMatrixInverse;
+uniform mat4 ProjectionMatrixInverse;
+uniform mat3 NormalMatrix;
+uniform vec4 CameraTexCoFactors;
+
+out vec4 fragColor;
+
/* Converters */
float convert_rgba_to_float(vec4 color)
{
#ifdef USE_NEW_SHADING
- return color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
+ return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
#else
- return (color.r + color.g + color.b) / 3.0;
+ return (color.r + color.g + color.b) * 0.333333;
#endif
}
@@ -53,7 +69,7 @@ void rgb_to_hsv(vec4 rgb, out vec4 outcol)
h = 0.0;
}
else {
- c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta;
+ c = (vec3(cmax) - rgb.xyz) / cdelta;
if (rgb.x == cmax) h = c[2] - c[1];
else if (rgb.y == cmax) h = 2.0 + c[0] - c[2];
@@ -155,15 +171,18 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
normal.y = -2.0 * ((color.g) - 0.5);
normal.z = -2.0 * ((color.b) - 0.5);
}
-
+#ifndef M_PI
#define M_PI 3.14159265358979323846
-#define M_1_PI 0.31830988618379069
+#endif
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
/*********** SHADER NODES ***************/
void vcol_attribute(vec4 attvcol, out vec4 vcol)
{
- vcol = vec4(attvcol.x, attvcol.y, attvcol.z, 1.0);
+ vcol = vec4(attvcol.xyz, 1.0);
}
void uv_attribute(vec2 attuv, out vec3 uv)
@@ -177,7 +196,7 @@ void geom(
out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback)
{
local = co;
- view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
+ view = (ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
global = (viewinvmat * vec4(local, 1.0)).xyz;
orco = attorco;
uv_attribute(attuv, uv);
@@ -419,13 +438,13 @@ void squeeze(float val, float width, float center, out float outval)
void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
{
outvec = v1 + v2;
- outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0;
+ outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
}
void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
{
outvec = v1 - v2;
- outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0;
+ outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
}
void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
@@ -441,7 +460,7 @@ void vec_math_mix(float strength, vec3 v1, vec3 v2, out vec3 outvec)
void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
{
- outvec = vec3(0, 0, 0);
+ outvec = vec3(0);
outval = dot(v1, v2);
}
@@ -483,9 +502,9 @@ void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
{
- outvec.x = texture2D(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x;
- outvec.y = texture2D(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y;
- outvec.z = texture2D(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z;
+ outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x;
+ outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y;
+ outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z;
if (fac != 1.0)
outvec = (outvec * fac) + (vec * (1.0 - fac));
@@ -494,9 +513,9 @@ void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
{
- outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
- outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
- outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
+ outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
+ outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
+ outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
if (fac != 1.0)
outcol = (outcol * fac) + (col * (1.0 - fac));
@@ -816,22 +835,23 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
{
- outcol = texture2D(colormap, vec2(fac, 0.0));
+ outcol = texture(colormap, vec2(fac, 0.0));
outalpha = outcol.a;
}
void rgbtobw(vec4 color, out float outval)
{
#ifdef USE_NEW_SHADING
- outval = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
+ vec3 factors = vec3(0.2126, 0.7152, 0.0722);
#else
- outval = color.r * 0.35 + color.g * 0.45 + color.b * 0.2; /* keep these factors in sync with texture.h:RGBTOBW */
+ vec3 factors = vec3(0.35, 0.45, 0.2); /* keep these factors in sync with texture.h:RGBTOBW */
#endif
+ outval = dot(color.rgb, factors);
}
void invert(float fac, vec4 col, out vec4 outcol)
{
- outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac);
+ outcol.xyz = mix(col.xyz, vec3(1.0) - col.xyz, fac);
outcol.w = col.w;
}
@@ -916,12 +936,12 @@ void texture_flip_blend(vec3 vec, out vec3 outvec)
void texture_blend_lin(vec3 vec, out float outval)
{
- outval = (1.0 + vec.x) / 2.0;
+ outval = (1.0 + vec.x) * 0.5;
}
void texture_blend_quad(vec3 vec, out float outval)
{
- outval = max((1.0 + vec.x) / 2.0, 0.0);
+ outval = max((1.0 + vec.x) * 0.5, 0.0);
outval *= outval;
}
@@ -932,12 +952,12 @@ void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal
value = wi;
color = vec4(wi, wi, wi, 1.0);
- normal = vec3(0.0, 0.0, 0.0);
+ normal = vec3(0.0);
}
void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
{
- color = texture2D(ima, (vec.xy + vec2(1.0, 1.0)) * 0.5);
+ color = texture(ima, (vec.xy + vec2(1.0)) * 0.5);
value = color.a;
normal.x = 2.0 * (color.r - 0.5);
@@ -955,7 +975,7 @@ void texco_orco(vec3 attorco, out vec3 orco)
void texco_uv(vec2 attuv, out vec3 uv)
{
/* disabled for now, works together with leaving out mtex_2d_mapping
- uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */
+ uv = vec3(attuv * 2.0 - vec2(1.0), 0.0); */
uv = vec3(attuv, 0.0);
}
@@ -1277,11 +1297,7 @@ void mtex_har_divide(float har, out float outhar)
void mtex_har_multiply_clamp(float har, out float outhar)
{
- har *= 128.0;
-
- if (har < 1.0) outhar = 1.0;
- else if (har > 511.0) outhar = 511.0;
- else outhar = har;
+ outhar = clamp(har * 128.0, 1.0, 511.0);
}
void mtex_alpha_from_col(vec4 col, out float alpha)
@@ -1350,14 +1366,14 @@ vec3 mtex_2d_mapping(vec3 vec)
void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color)
{
- color = textureCube(ima, co);
+ color = texture(ima, co);
value = 1.0;
}
void mtex_cube_map_refl_from_refldir(
samplerCube ima, vec3 reflecteddirection, out float value, out vec4 color)
{
- color = textureCube(ima, reflecteddirection);
+ color = texture(ima, reflecteddirection);
value = color.a;
}
@@ -1368,13 +1384,13 @@ void mtex_cube_map_refl(
vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0));
vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix));
vec3 reflecteddirection = reflect(viewdirection, normaldirection);
- color = textureCube(ima, reflecteddirection);
+ color = texture(ima, reflecteddirection);
value = 1.0;
}
void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
{
- color = texture2D(ima, texco.xy);
+ color = texture(ima, texco.xy);
value = 1.0;
}
@@ -1385,7 +1401,7 @@ void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
// It needs to be done because in Blender
// the normal used points inward.
// Should this ever change this negate must be removed.
- vec4 color = texture2D(ima, texco.xy);
+ vec4 color = texture(ima, texco.xy);
normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
}
@@ -1413,8 +1429,8 @@ void mtex_bump_init_objspace(
out float fPrevMagnitude_out, out vec3 vNacc_out,
out vec3 vR1, out vec3 vR2, out float fDet)
{
- mat3 obj2view = to_mat3(gl_ModelViewMatrix);
- mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse);
+ mat3 obj2view = to_mat3(ModelViewMatrix);
+ mat3 view2obj = to_mat3(ModelViewMatrixInverse);
vec3 vSigmaS = view2obj * dFdx(surf_pos);
vec3 vSigmaT = view2obj * dFdy(surf_pos);
@@ -1481,9 +1497,9 @@ void mtex_bump_tap3(
vec2 STul = texco.xy + dFdy(texco.xy);
float Hll, Hlr, Hul;
- rgbtobw(texture2D(ima, STll), Hll);
- rgbtobw(texture2D(ima, STlr), Hlr);
- rgbtobw(texture2D(ima, STul), Hul);
+ rgbtobw(texture(ima, STll), Hll);
+ rgbtobw(texture(ima, STlr), Hlr);
+ rgbtobw(texture(ima, STul), Hul);
dBs = hScale * (Hlr - Hll);
dBt = hScale * (Hul - Hll);
@@ -1508,10 +1524,10 @@ void mtex_bump_bicubic(
vec2 STd = texco.xy - 0.5 * TexDy;
vec2 STu = texco.xy + 0.5 * TexDy;
- rgbtobw(texture2D(ima, STl), Hl);
- rgbtobw(texture2D(ima, STr), Hr);
- rgbtobw(texture2D(ima, STd), Hd);
- rgbtobw(texture2D(ima, STu), Hu);
+ rgbtobw(texture(ima, STl), Hl);
+ rgbtobw(texture(ima, STr), Hr);
+ rgbtobw(texture(ima, STd), Hd);
+ rgbtobw(texture(ima, STu), Hu);
vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
@@ -1597,11 +1613,11 @@ void mtex_bump_tap5(
vec2 STu = texco.xy + 0.5 * TexDy;
float Hc, Hl, Hr, Hd, Hu;
- rgbtobw(texture2D(ima, STc), Hc);
- rgbtobw(texture2D(ima, STl), Hl);
- rgbtobw(texture2D(ima, STr), Hr);
- rgbtobw(texture2D(ima, STd), Hd);
- rgbtobw(texture2D(ima, STu), Hu);
+ rgbtobw(texture(ima, STc), Hc);
+ rgbtobw(texture(ima, STl), Hl);
+ rgbtobw(texture(ima, STr), Hr);
+ rgbtobw(texture(ima, STd), Hd);
+ rgbtobw(texture(ima, STu), Hu);
dBs = hScale * (Hr - Hl);
dBt = hScale * (Hu - Hd);
@@ -1618,7 +1634,7 @@ void mtex_bump_deriv(
// this variant using a derivative map is described here
// http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
vec2 dim = vec2(ima_x, ima_y);
- vec2 dBduv = hScale * dim * (2.0 * texture2D(ima, texco.xy).xy - 1.0);
+ vec2 dBduv = hScale * dim * (2.0 * texture(ima, texco.xy).xy - 1.0);
dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y;
dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y;
@@ -1670,7 +1686,7 @@ void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
{
- outnormal = normalize(gl_NormalMatrix * texnormal);
+ outnormal = normalize(NormalMatrix * texnormal);
}
void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
@@ -1727,7 +1743,7 @@ void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coef
void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
{
- visifac = texture2D(curvemap, vec2(dist / lampdist, 0.0)).x;
+ visifac = texture(curvemap, vec2(dist / lampdist, 0.0)).x;
}
void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
@@ -1794,7 +1810,7 @@ void lamp_visibility_clamp(float visifac, out float outvisifac)
void world_paper_view(vec3 vec, out vec3 outvec)
{
vec3 nvec = normalize(vec);
- outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
+ outvec = (ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
}
void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
@@ -1828,7 +1844,7 @@ void world_blend(vec3 vec, out float blend)
void shade_view(vec3 co, out vec3 view)
{
/* handle perspective/orthographic */
- view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
+ view = (ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
}
void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
@@ -2020,7 +2036,7 @@ void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
if (i > 0.0)
outcol = i * lampcol * col;
else
- outcol = vec3(0.0, 0.0, 0.0);
+ outcol = vec3(0.0);
}
void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
@@ -2177,12 +2193,12 @@ void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
{
- outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0));
+ outcol = col1 + max(col2, vec4(0.0));
}
void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
{
- outcol = col + max(col1 * col2, vec4(0.0, 0.0, 0.0, 0.0));
+ outcol = col + max(col1 * col2, vec4(0.0));
}
void env_apply(vec4 col, vec3 hor, vec3 zen, vec4 f, mat4 vm, vec3 vn, out vec4 outcol)
@@ -2219,7 +2235,7 @@ void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
void ramp_rgbtobw(vec3 color, out float outval)
{
- outval = color.r * 0.3 + color.g * 0.58 + color.b * 0.12;
+ outval = dot(color, vec3(0.3, 0.58, 0.12));
}
void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb)
@@ -2255,10 +2271,12 @@ void test_shadowbuf(
//float bias = (1.5 - inp*inp)*shadowbias;
co.z -= shadowbias * co.w;
- if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0)
- result = shadow2DProj(shadowmap, co).x;
- else
+ if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) {
+ result = textureProj(shadowmap, co);
+ }
+ else {
result = 1.0;
+ }
}
}
@@ -2272,7 +2290,7 @@ void test_shadowbuf_vsm(
else {
vec4 co = shadowpersmat * vec4(rco, 1.0);
if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) {
- vec2 moments = texture2DProj(shadowmap, co).rg;
+ vec2 moments = textureProj(shadowmap, co).rg;
float dist = co.z / co.w;
float p = 0.0;
@@ -2331,7 +2349,7 @@ void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec
vec4 co = shadowpersmat * vec4(rco, 1.0);
- result = texture2DProj(cookie, co);
+ result = textureProj(cookie, co);
}
void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
@@ -2346,7 +2364,7 @@ void shade_mist_factor(
if (enable == 1.0) {
float fac, zcor;
- zcor = (gl_ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
+ zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
if (misttype == 0.0) fac *= fac;
@@ -2421,7 +2439,7 @@ float hypot(float x, float y)
void generated_from_orco(vec3 orco, out vec3 generated)
{
- generated = orco * 0.5 + vec3(0.5);
+ generated = orco;
}
int floor_to_int(float x)
@@ -2434,7 +2452,6 @@ int quick_floor(float x)
return int(x) - ((x < 0) ? 1 : 0);
}
-#ifdef BIT_OPERATIONS
float integer_noise(int n)
{
int nn;
@@ -2499,7 +2516,6 @@ vec3 cellnoise_color(vec3 p)
return vec3(r, g, b);
}
-#endif // BIT_OPERATIONS
float floorfrac(float x, out int i)
{
@@ -2562,6 +2578,17 @@ vec3 rotate_vector(vec3 p, vec3 n, float theta) {
#define NUM_LIGHTS 3
+struct glLight {
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 halfVector;
+};
+
+layout(std140) uniform lightSource {
+ glLight glLightSource[NUM_LIGHTS];
+};
+
/* bsdfs */
void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
@@ -2571,8 +2598,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
/* directional lights */
for (int i = 0; i < NUM_LIGHTS; i++) {
- vec3 light_position = gl_LightSource[i].position.xyz;
- vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
+ vec3 light_position = glLightSource[i].position.xyz;
+ vec3 light_diffuse = glLightSource[i].diffuse.rgb;
float bsdf = max(dot(N, light_position), 0.0);
L += light_diffuse * bsdf;
@@ -2588,10 +2615,10 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
/* directional lights */
for (int i = 0; i < NUM_LIGHTS; i++) {
- vec3 light_position = gl_LightSource[i].position.xyz;
- vec3 H = gl_LightSource[i].halfVector.xyz;
- vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
- vec3 light_specular = gl_LightSource[i].specular.rgb;
+ vec3 light_position = glLightSource[i].position.xyz;
+ vec3 H = glLightSource[i].halfVector.xyz;
+ vec3 light_diffuse = glLightSource[i].diffuse.rgb;
+ vec3 light_specular = glLightSource[i].specular.rgb;
/* we mix in some diffuse so low roughness still shows up */
float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness);
@@ -2662,12 +2689,12 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
/* directional lights */
for (int i = 0; i < NUM_LIGHTS; i++) {
- vec3 light_position_world = gl_LightSource[i].position.xyz;
- vec3 light_position = normalize(gl_NormalMatrix * light_position_world);
+ vec3 light_position_world = glLightSource[i].position.xyz;
+ vec3 light_position = normalize(NormalMatrix * light_position_world);
vec3 H = normalize(light_position + V);
- vec3 light_specular = gl_LightSource[i].specular.rgb;
+ vec3 light_specular = glLightSource[i].specular.rgb;
float NdotL = dot(N, light_position);
float NdotV = dot(N, V);
@@ -2677,7 +2704,7 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
if (NdotL >= 0.0 && NdotV >= 0.0) {
float NdotH = dot(N, H);
- float Cdlum = 0.3 * base_color.r + 0.6 * base_color.g + 0.1 * base_color.b; // luminance approx.
+ float Cdlum = dot(base_color.rgb, vec3(0.3, 0.6, 0.1)); // luminance approx.
vec3 Ctint = Cdlum > 0 ? base_color.rgb / Cdlum : vec3(1.0); // normalize lum. to isolate hue+sat
vec3 Cspec0 = mix(specular * 0.08 * mix(vec3(1.0), Ctint, specular_tint), base_color.rgb, metallic);
@@ -2791,14 +2818,29 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
{
- vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
- vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+ vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (ProjectionMatrixInverse * v);
vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
- worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+#ifdef WORLD_BACKGROUND
+ worldvec = (ViewMatrixInverse * co).xyz;
+#else
+ worldvec = (ModelViewMatrixInverse * co).xyz;
+#endif
}
-void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+#if defined(PROBE_CAPTURE) || defined(WORLD_BACKGROUND)
+void environment_default_vector(out vec3 worldvec)
+{
+#ifdef WORLD_BACKGROUND
+ background_transform_to_world(viewPosition, worldvec);
+#else
+ worldvec = normalize(worldPosition);
+#endif
+}
+#endif
+
+void node_background(vec4 color, float strength, out vec4 result)
{
result = color * strength;
}
@@ -2820,7 +2862,7 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
void node_fresnel(float ior, vec3 N, vec3 I, out float result)
{
/* handle perspective/orthographic */
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
float eta = max(ior, 0.00001);
result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
@@ -2832,7 +2874,7 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float
{
/* fresnel */
float eta = max(1.0 - blend, 0.00001);
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
@@ -2874,19 +2916,47 @@ void node_uvmap(vec3 attr_uv, out vec3 outvec)
outvec = attr_uv;
}
+void tangent_orco_x(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3(0.0, (orco_in.z - 0.5) * -0.5, (orco_in.y - 0.5) * 0.5);
+}
+
+void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3((orco_in.z - 0.5) * -0.5, 0.0, (orco_in.x - 0.5) * 0.5);
+}
+
+void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3((orco_in.y - 0.5) * -0.5, (orco_in.x - 0.5) * 0.5, 0.0);
+}
+
+void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
+{
+ tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz;
+}
+
+void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
+{
+ N = (toworld * vec4(N, 0.0)).xyz;
+ T = (objmat * vec4(orco, 0.0)).xyz;
+ T = cross(N, normalize(cross(T, N)));
+}
+
void node_geometry(
- vec3 I, vec3 N, mat4 toworld,
+ vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld,
out vec3 position, out vec3 normal, out vec3 tangent,
out vec3 true_normal, out vec3 incoming, out vec3 parametric,
out float backfacing, out float pointiness)
{
position = (toworld * vec4(I, 1.0)).xyz;
normal = (toworld * vec4(N, 0.0)).xyz;
- tangent = vec3(0.0);
+ tangent_orco_z(orco, orco);
+ node_tangent(N, orco, objmat, toworld, tangent);
true_normal = normal;
/* handle perspective/orthographic */
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
incoming = -(toworld * vec4(I_view, 0.0)).xyz;
parametric = vec3(0.0);
@@ -2900,12 +2970,12 @@ void node_tex_coord(
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection)
{
- generated = attr_orco * 0.5 + vec3(0.5);
+ generated = attr_orco;
normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz);
uv = attr_uv;
object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
camera = vec3(I.xy, -I.z);
- vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
+ vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
vec3 shade_I;
@@ -2920,13 +2990,20 @@ void node_tex_coord_background(
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection)
{
- vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
- vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+ vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (ProjectionMatrixInverse * v);
vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
co = normalize(co);
- vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+
+#ifdef PROBE_CAPTURE
+ vec3 coords = normalize(worldPosition);
+#elif defined(WORLD_BACKGROUND)
+ vec3 coords = (ViewMatrixInverse * co).xyz;
+#else
+ vec3 coords = (ModelViewMatrixInverse * co).xyz;
+#endif
generated = coords;
normal = -coords;
@@ -2934,13 +3011,17 @@ void node_tex_coord_background(
object = coords;
camera = vec3(co.xy, -co.z);
- window = (gl_ProjectionMatrix[3][3] == 0.0) ?
+ window = (ProjectionMatrix[3][3] == 0.0) ?
vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
reflection = -coords;
}
+#if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER))
+#define node_tex_coord node_tex_coord_background
+#endif
+
/* textures */
float calc_gradient(vec3 p, int gradient_type)
@@ -3007,7 +3088,6 @@ void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 c
fac = check ? 1.0 : 0.0;
}
-#ifdef BIT_OPERATIONS
vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias,
float brick_width, float row_height,
float offset_amount, int offset_frequency,
@@ -3043,7 +3123,6 @@ vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bi
return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist));
}
}
-#endif
void node_tex_brick(vec3 co,
vec4 color1, vec4 color2,
@@ -3054,7 +3133,6 @@ void node_tex_brick(vec3 co,
float squash_amount, float squash_frequency,
out vec4 color, out float fac)
{
-#ifdef BIT_OPERATIONS
vec2 f2 = calc_brick_texture(co * scale,
mortar_size, mortar_smooth, bias,
brick_width, row_height,
@@ -3068,10 +3146,6 @@ void node_tex_brick(vec3 co,
}
color = mix(color1, mortar, f);
fac = f;
-#else
- color = vec4(1.0);
- fac = 1.0;
-#endif
}
void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
@@ -3086,7 +3160,15 @@ void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color
float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
- color = texture2D(ima, vec2(u, v));
+ /* Fix pole bleeding */
+ float half_width = 0.5 / float(textureSize(ima, 0).x);
+ v = clamp(v, half_width, 1.0 - half_width);
+
+ /* Fix u = 0 seam */
+ /* This is caused by texture filtering, since uv don't have smooth derivatives
+ * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
+ * texels. So we force the highest mipmap and don't do anisotropic filtering. */
+ color = textureLod(ima, vec2(u, v), 0.0);
}
void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
@@ -3102,7 +3184,7 @@ void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
float u = 0.5 * (nco.x + 1.0);
float v = 0.5 * (nco.z + 1.0);
- color = texture2D(ima, vec2(u, v));
+ color = texture(ima, vec2(u, v));
}
void node_tex_environment_empty(vec3 co, out vec4 color)
@@ -3112,7 +3194,7 @@ void node_tex_environment_empty(vec3 co, out vec4 color)
void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
{
- color = texture2D(ima, co.xy);
+ color = texture(ima, co.xy);
alpha = color.a;
}
@@ -3180,13 +3262,13 @@ void node_tex_image_box(vec3 texco,
}
color = vec4(0);
if (weight.x > 0.0) {
- color += weight.x * texture2D(ima, texco.yz);
+ color += weight.x * texture(ima, texco.yz);
}
if (weight.y > 0.0) {
- color += weight.y * texture2D(ima, texco.xz);
+ color += weight.y * texture(ima, texco.xz);
}
if (weight.z > 0.0) {
- color += weight.z * texture2D(ima, texco.yx);
+ color += weight.z * texture(ima, texco.yx);
}
alpha = color.a;
@@ -3259,7 +3341,6 @@ void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec
fac = (color.x + color.y + color.z) / 3.0;
}
-#ifdef BIT_OPERATIONS
float noise_fade(float t)
{
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
@@ -3322,10 +3403,9 @@ float noise_turbulence(vec3 p, float octaves, int hard)
float fscale = 1.0;
float amp = 1.0;
float sum = 0.0;
- int i, n;
octaves = clamp(octaves, 0.0, 16.0);
- n = int(octaves);
- for (i = 0; i <= n; i++) {
+ int n = int(octaves);
+ for (int i = 0; i <= n; i++) {
float t = noise(fscale * p);
if (hard != 0) {
t = abs(2.0 * t - 1.0);
@@ -3335,7 +3415,7 @@ float noise_turbulence(vec3 p, float octaves, int hard)
fscale *= 2.0;
}
float rmd = octaves - floor(octaves);
- if (rmd != 0.0) {
+ if (rmd != 0.0) {
float t = noise(fscale * p);
if (hard != 0) {
t = abs(2.0 * t - 1.0);
@@ -3350,11 +3430,9 @@ float noise_turbulence(vec3 p, float octaves, int hard)
return sum;
}
}
-#endif // BIT_OPERATIONS
void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
{
-#ifdef BIT_OPERATIONS
vec3 p = co * scale;
int hard = 0;
if (distortion != 0.0) {
@@ -3370,15 +3448,8 @@ void node_tex_noise(vec3 co, float scale, float detail, float distortion, out ve
noise_turbulence(vec3(p.y, p.x, p.z), detail, hard),
noise_turbulence(vec3(p.y, p.z, p.x), detail, hard),
1);
-#else // BIT_OPERATIONS
- color = vec4(1.0);
- fac = 1.0;
-#endif // BIT_OPERATIONS
}
-
-#ifdef BIT_OPERATIONS
-
/* Musgrave fBm
*
* H: fractal increment parameter
@@ -3394,9 +3465,8 @@ float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves)
float value = 0.0;
float pwr = 1.0;
float pwHL = pow(lacunarity, -H);
- int i;
- for (i = 0; i < int(octaves); i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += snoise(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -3422,9 +3492,8 @@ float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octa
float value = 1.0;
float pwr = 1.0;
float pwHL = pow(lacunarity, -H);
- int i;
- for (i = 0; i < int(octaves); i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * snoise(p) + 1.0);
pwr *= pwHL;
p *= lacunarity;
@@ -3450,13 +3519,12 @@ float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float oct
float value, increment, rmd;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
- int i;
/* first unscaled octave of function; later octaves are scaled */
value = offset + snoise(p);
p *= lacunarity;
- for (i = 1; i < int(octaves); i++) {
+ for (int i = 1; i < int(octaves); i++) {
increment = (snoise(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -3485,13 +3553,12 @@ float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, flo
float result, signal, weight, rmd;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
- int i;
result = snoise(p) + offset;
weight = gain * result;
p *= lacunarity;
- for (i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
+ for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0)
weight = 1.0;
@@ -3522,14 +3589,13 @@ float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, flo
float result, signal, weight;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
- int i;
signal = offset - abs(snoise(p));
signal *= signal;
result = signal;
weight = 1.0;
- for (i = 1; i < int(octaves); i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = clamp(signal * gain, 0.0, 1.0);
signal = offset - abs(snoise(p));
@@ -3551,19 +3617,18 @@ float svm_musgrave(int type,
float gain,
vec3 p)
{
- if (type == 0 /*NODE_MUSGRAVE_MULTIFRACTAL*/)
+ if (type == 0 /* NODE_MUSGRAVE_MULTIFRACTAL */)
return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
- else if (type == 1 /*NODE_MUSGRAVE_FBM*/)
+ else if (type == 1 /* NODE_MUSGRAVE_FBM */)
return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
- else if (type == 2 /*NODE_MUSGRAVE_HYBRID_MULTIFRACTAL*/)
+ else if (type == 2 /* NODE_MUSGRAVE_HYBRID_MULTIFRACTAL */)
return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
- else if (type == 3 /*NODE_MUSGRAVE_RIDGED_MULTIFRACTAL*/)
+ else if (type == 3 /* NODE_MUSGRAVE_RIDGED_MULTIFRACTAL */)
return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
- else if (type == 4 /*NODE_MUSGRAVE_HETERO_TERRAIN*/)
+ else if (type == 4 /* NODE_MUSGRAVE_HETERO_TERRAIN */)
return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
return 0.0;
}
-#endif // #ifdef BIT_OPERATIONS
void node_tex_musgrave(vec3 co,
float scale,
@@ -3576,7 +3641,6 @@ void node_tex_musgrave(vec3 co,
out vec4 color,
out float fac)
{
-#ifdef BIT_OPERATIONS
fac = svm_musgrave(int(type),
dimension,
lacunarity,
@@ -3585,9 +3649,6 @@ void node_tex_musgrave(vec3 co,
1.0,
gain,
co * scale);
-#else
- fac = 1.0;
-#endif
color = vec4(fac, fac, fac, 1.0);
}
@@ -3599,7 +3660,6 @@ void node_tex_sky(vec3 co, out vec4 color)
void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out float fac)
{
-#ifdef BIT_OPERATIONS
vec3 p = co * scale;
int xx, yy, zz, xi, yi, zi;
float da[4];
@@ -3664,13 +3724,8 @@ void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out
color = vec4(cellnoise_color(pa[0]), 1);
fac = (color.x + color.y + color.z) * (1.0 / 3.0);
}
-#else // BIT_OPERATIONS
- color = vec4(1.0);
- fac = 1.0;
-#endif // BIT_OPERATIONS
}
-#ifdef BIT_OPERATIONS
float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile)
{
float n;
@@ -3692,22 +3747,16 @@ float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int
return (n < 0.0) ? n + 1.0 : n;
}
}
-#endif // BIT_OPERATIONS
void node_tex_wave(
vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile,
out vec4 color, out float fac)
{
-#ifdef BIT_OPERATIONS
float f;
f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile));
color = vec4(f, f, f, 1.0);
fac = f;
-#else // BIT_OPERATIONS
- color = vec4(1.0);
- fac = 1;
-#endif // BIT_OPERATIONS
}
/* light path */
@@ -3727,13 +3776,21 @@ void node_light_path(
out float transparent_depth,
out float transmission_depth)
{
+#ifndef PROBE_CAPTURE
is_camera_ray = 1.0;
- is_shadow_ray = 0.0;
- is_diffuse_ray = 0.0;
is_glossy_ray = 0.0;
- is_singular_ray = 0.0;
+ is_diffuse_ray = 0.0;
is_reflection_ray = 0.0;
is_transmission_ray = 0.0;
+#else
+ is_camera_ray = 0.0;
+ is_glossy_ray = 1.0;
+ is_diffuse_ray = 1.0;
+ is_reflection_ray = 1.0;
+ is_transmission_ray = 1.0;
+#endif
+ is_shadow_ray = 0.0;
+ is_singular_ray = 0.0;
ray_length = 1.0;
ray_depth = 1.0;
diffuse_depth = 1.0;
@@ -3800,30 +3857,62 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
void node_output_world(vec4 surface, vec4 volume, out vec4 result)
{
- result = surface;
+ result = vec4(surface.rgb, 1.0);
+}
+
+void convert_metallic_to_specular(vec4 basecol, float metallic, float specular_fac, out vec4 diffuse, out vec4 f0)
+{
+ vec4 dielectric = vec4(0.034) * specular_fac * 2.0;
+ diffuse = mix(basecol, vec4(0.0), metallic);
+ f0 = mix(dielectric, basecol, metallic);
+}
+
+/* TODO : clean this ifdef mess */
+/* EEVEE output */
+#ifdef EEVEE_ENGINE
+void world_normals_get(out vec3 N)
+{
+ N = gl_FrontFacing ? worldNormal : -worldNormal;
}
+void node_output_metallic(
+ vec4 basecol, float metallic, float specular, float roughness, vec4 emissive, float transp, vec3 normal,
+ float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+ float occlusion, out vec4 result)
+{
+ vec4 diffuse, f0;
+ convert_metallic_to_specular(basecol, metallic, specular, diffuse, f0);
+
+ result = vec4(eevee_surface_lit(normal, diffuse.rgb, f0.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp);
+}
+
+void node_output_specular(
+ vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
+ float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+ float occlusion, out vec4 result)
+{
+ result = vec4(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp);
+}
+#endif
+
/* ********************** matcap style render ******************** */
void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
{
vec3 normal;
- vec2 tex;
#ifndef USE_OPENSUBDIV
/* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors
* between shader stages and we want the full range of the normal */
- normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0);
- if (normal.z < 0.0) {
- normal.z = 0.0;
- }
+ normal = 2.0 * N.xyz - vec3(1.0);
+ normal.z = max(normal.z, 0.0);
normal = normalize(normal);
#else
normal = inpt.v.normal;
- mask = vec4(1.0, 1.0, 1.0, 1.0);
+ mask = vec4(1.0);
#endif
- tex.x = 0.5 + 0.49 * normal.x;
- tex.y = 0.5 + 0.49 * normal.y;
- result = texture2D(ima, tex) * mask;
+ vec2 tex = 0.49 * normal.xy + vec2(0.5);
+
+ result = texture(ima, tex) * mask;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl
new file mode 100644
index 00000000000..fef81cf58fe
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl
@@ -0,0 +1,24 @@
+
+uniform vec4 color;
+
+in vec2 radii;
+out vec4 fragColor;
+
+void main() {
+ float dist = length(gl_PointCoord - vec2(0.5));
+
+// transparent outside of point
+// --- 0 ---
+// smooth transition
+// --- 1 ---
+// pure point color
+// ...
+// dist = 0 at center of point
+
+ fragColor.rgb = color.rgb;
+ fragColor.a = mix(color.a, 0.0, smoothstep(radii[1], radii[0], dist));
+
+ if (fragColor.a == 0.0) {
+ discard;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl
new file mode 100644
index 00000000000..852c76fcb26
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl
@@ -0,0 +1,17 @@
+
+uniform vec4 color;
+
+out vec4 fragColor;
+
+void main()
+{
+ vec2 centered = gl_PointCoord - vec2(0.5);
+ float dist_squared = dot(centered, centered);
+ const float rad_squared = 0.25;
+
+ // round point with jaggy edges
+ if (dist_squared > rad_squared)
+ discard;
+
+ fragColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl
new file mode 100644
index 00000000000..eae5ee633ae
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl
@@ -0,0 +1,36 @@
+
+uniform vec4 color;
+uniform vec4 outlineColor;
+
+in vec4 radii;
+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 point 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(color, outlineColor, smoothstep(radii[3], radii[2], dist));
+ }
+
+ if (fragColor.a == 0.0) {
+ discard;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl
new file mode 100644
index 00000000000..2d2724bb686
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl
@@ -0,0 +1,16 @@
+
+in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ vec2 centered = gl_PointCoord - vec2(0.5);
+ float dist_squared = dot(centered, centered);
+ const float rad_squared = 0.25;
+
+ // round point with jaggy edges
+ if (dist_squared > rad_squared)
+ discard;
+
+ fragColor = finalColor;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl
new file mode 100644
index 00000000000..9b7d4bfc6d6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl
@@ -0,0 +1,31 @@
+
+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/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
index b485d2cce86..78241a798a2 100644
--- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
@@ -1,16 +1,19 @@
uniform vec2 ScaleU;
uniform sampler2D textureSource;
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
void main()
{
vec4 color = vec4(0.0);
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-3.0 * ScaleU.x, -3.0 * ScaleU.y)) * 0.015625;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-2.0 * ScaleU.x, -2.0 * ScaleU.y)) * 0.09375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-1.0 * ScaleU.x, -1.0 * ScaleU.y)) * 0.234375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(0.0, 0.0)) * 0.3125;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y)) * 0.234375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y)) * 0.09375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y)) * 0.015625;
+ color += texture(textureSource, texCoord_interp.st + vec2(-3.0 * ScaleU.x, -3.0 * ScaleU.y)) * 0.015625;
+ color += texture(textureSource, texCoord_interp.st + vec2(-2.0 * ScaleU.x, -2.0 * ScaleU.y)) * 0.09375;
+ color += texture(textureSource, texCoord_interp.st + vec2(-1.0 * ScaleU.x, -1.0 * ScaleU.y)) * 0.234375;
+ color += texture(textureSource, texCoord_interp.st + vec2(0.0, 0.0)) * 0.3125;
+ color += texture(textureSource, texCoord_interp.st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y)) * 0.234375;
+ color += texture(textureSource, texCoord_interp.st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y)) * 0.09375;
+ color += texture(textureSource, texCoord_interp.st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y)) * 0.015625;
- gl_FragColor = color;
+ fragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
index 5d00108b052..1319e386c65 100644
--- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
@@ -1,6 +1,12 @@
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+in vec2 uvs;
+out vec2 texCoord_interp;
+
void main()
{
- gl_Position = ftransform();
- gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ texCoord_interp = uvs;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl
new file mode 100644
index 00000000000..4d7131c4eb1
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl
@@ -0,0 +1,17 @@
+
+#ifndef USE_INSTANCE_COLOR
+uniform vec4 color;
+#endif
+uniform vec3 light;
+
+in vec3 normal;
+#ifdef USE_INSTANCE_COLOR
+flat in vec4 finalColor;
+# define color finalColor
+#endif
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = color * max(0.0, dot(normalize(normal), light));
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl
new file mode 100644
index 00000000000..6b13f408c84
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl
@@ -0,0 +1,14 @@
+
+uniform vec3 light;
+uniform float alpha;
+uniform float global;
+
+in vec3 normal;
+in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor * (global + (1.0 - global) * max(0.0, dot(normalize(normal), light)));
+ fragColor.a = alpha;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl
new file mode 100644
index 00000000000..58c5f292647
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl
@@ -0,0 +1,16 @@
+
+uniform vec3 light;
+
+#ifdef USE_FLAT_NORMAL
+flat in vec3 normal;
+flat in vec4 finalColor;
+#else
+in vec3 normal;
+in vec4 finalColor;
+#endif
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor * max(0.0, dot(normalize(normal), light));
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
index 6ded453225e..b57bd5b6a37 100644
--- a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
@@ -1,5 +1,6 @@
-varying vec3 coords;
+in vec3 coords;
+out vec4 fragColor;
uniform vec3 active_color;
uniform float step_size;
@@ -16,7 +17,7 @@ uniform sampler3D color_band_texture;
void main()
{
/* compute color and density from volume texture */
- vec4 soot = texture3D(soot_texture, coords);
+ vec4 soot = texture(soot_texture, coords);
#ifndef USE_COBA
vec3 soot_color;
@@ -24,7 +25,7 @@ void main()
soot_color = active_color * soot.rgb / soot.a;
}
else {
- soot_color = vec3(0, 0, 0);
+ soot_color = vec3(0);
}
float soot_density = density_scale * soot.a;
@@ -33,16 +34,14 @@ void main()
float soot_alpha = 1.0 - soot_transmittance;
/* shade */
- float shadow = texture3D(shadow_texture, coords).r;
+ float shadow = texture(shadow_texture, coords).r;
soot_color *= soot_transmittance * shadow;
/* premultiply alpha */
- vec4 color = vec4(soot_alpha * soot_color, soot_alpha);
+ fragColor = vec4(soot_alpha * soot_color, soot_alpha);
#else
- float color_band = texture3D(color_band_texture, coords).r;
- vec4 transfer_function = texture1D(transfer_texture, color_band);
- vec4 color = transfer_function * density_scale;
+ float color_band = texture(color_band_texture, coords).r;
+ vec4 transfer_function = texture(transfer_texture, color_band);
+ fragColor = transfer_function * density_scale;
#endif
-
- gl_FragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
index 297486ae26a..8c30e9baf9e 100644
--- a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
@@ -1,5 +1,7 @@
-varying vec3 coords;
+uniform mat4 ModelViewProjectionMatrix;
+
+out vec3 coords;
uniform vec3 min_location;
uniform vec3 invsize;
@@ -7,6 +9,7 @@ uniform vec3 ob_sizei;
void main()
{
- gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0);
+ // TODO: swap gl_Vertex for vec3 pos, update smoke setup code
+ gl_Position = ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0);
coords = (gl_Vertex.xyz - min_location) * invsize;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
new file mode 100644
index 00000000000..7ff90ad4f21
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
@@ -0,0 +1,15 @@
+
+flat in vec4 color_flat;
+noperspective in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform sampler2D glyph;
+
+void main()
+{
+ // input color replaces texture color
+ fragColor.rgb = color_flat.rgb;
+
+ // modulate input alpha & texture alpha
+ fragColor.a = color_flat.a * texture(glyph, texCoord_interp).r;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
new file mode 100644
index 00000000000..6129f49ce22
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
@@ -0,0 +1,16 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec2 pos;
+in vec2 texCoord;
+in vec4 color;
+flat out vec4 color_flat;
+noperspective out vec2 texCoord_interp;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+
+ color_flat = color;
+ texCoord_interp = texCoord;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
new file mode 100644
index 00000000000..5dd1352adc5
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
@@ -0,0 +1,9 @@
+
+uniform vec4 color;
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index db0068d2f3d..4ebd10d514f 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -1,3 +1,8 @@
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat3 NormalMatrix;
+
#ifdef USE_OPENSUBDIV
in vec3 normal;
in vec4 position;
@@ -7,8 +12,8 @@ out block {
} outpt;
#endif
-varying vec3 varposition;
-varying vec3 varnormal;
+out vec3 varposition;
+out vec3 varnormal;
#ifdef CLIP_WORKAROUND
varying float gl_ClipDistance[6];
@@ -89,11 +94,11 @@ void main()
vec3 normal = gl_Normal;
#endif
- vec4 co = gl_ModelViewMatrix * position;
+ vec4 co = ModelViewMatrix * position;
varposition = co.xyz;
- varnormal = normalize(gl_NormalMatrix * normal);
- gl_Position = gl_ProjectionMatrix * co;
+ varnormal = normalize(NormalMatrix * normal);
+ gl_Position = ProjectionMatrix * co;
#ifdef CLIP_WORKAROUND
int i;
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
index d45a4b316a8..89a2f391a12 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
@@ -1,7 +1,6 @@
-varying vec3 varposition;
-varying vec3 varnormal;
-
+out vec3 varposition;
+out vec3 varnormal;
/* Color, keep in sync with: gpu_shader_vertex.glsl */
diff --git a/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl b/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
index 3761bf350eb..6aad94bbf59 100644
--- a/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
@@ -2,7 +2,8 @@
* This fragment shader was initially found at http://fabiensanglard.net/shadowmappingVSM/index.php
*/
-varying vec4 v_position;
+in vec4 v_position;
+out vec4 fragColor;
void main()
{
@@ -17,5 +18,6 @@ void main()
float dy = dFdy(depth);
moment2 += 0.25 * (dx * dx + dy * dy);
- gl_FragColor = vec4(moment1, moment2, 0.0, 0.0);
+ fragColor = vec4(moment1, moment2, 0.0, 0.0);
+ // TODO: write to a 2-component target --^
}
diff --git a/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl b/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
index 224c3e78adc..def835156f7 100644
--- a/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
@@ -1,7 +1,10 @@
-varying vec4 v_position;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+out vec4 v_position;
void main()
{
- gl_Position = ftransform();
+ gl_Position = ModelViewProjectionMatrix * gl_Vertex;
v_position = gl_Position;
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index da0f505c4f3..4f22d873a30 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -96,6 +96,17 @@ enum {
IDP_STRING_SUB_BYTE = 1, /* arbitrary byte array, _not_ null terminated */
};
+/* IDP_GROUP */
+enum {
+ IDP_GROUP_SUB_NONE = 0, /* default */
+ IDP_GROUP_SUB_MODE_OBJECT = 1, /* object mode settings */
+ IDP_GROUP_SUB_MODE_EDIT = 2, /* mesh edit mode settings */
+ IDP_GROUP_SUB_ENGINE_RENDER = 3, /* render engine settings */
+ IDP_GROUP_SUB_OVERRIDE = 4, /* data override */
+ IDP_GROUP_SUB_MODE_PAINT_WEIGHT = 5, /* weight paint mode settings */
+ IDP_GROUP_SUB_MODE_PAINT_VERTEX = 6, /* vertex paint mode settings */
+};
+
/*->flag*/
enum {
IDP_FLAG_GHOST = 1 << 7, /* this means the property is set but RNA will return false when checking
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 1083400ece2..90d6bbb4f1e 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -180,6 +180,18 @@ typedef enum eMotionPaths_BakeFlag {
MOTIONPATH_BAKE_HAS_PATHS = (1 << 2)
} eMotionPath_BakeFlag;
+/* runtime */
+#
+#
+typedef struct bPoseChannelDrawData {
+ float solid_color[4];
+ float wire_color[4];
+
+ int bbone_matrix_len;
+ /* keep last */
+ float bbone_matrix[0][4][4];
+} bPoseChannelDrawData;
+
/* ************************************************ */
/* Poses */
@@ -238,6 +250,8 @@ typedef struct bPoseChannel {
float chan_mat[4][4]; /* matrix result of loc/quat/size, and where we put deform in, see next line */
float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat
* this matrix is object space */
+ float disp_mat[4][4]; /* for display, pose_mat with bone length applied */
+ float disp_tail_mat[4][4]; /* for display, pose_mat with bone length applied and translated to tail*/
float constinv[4][4]; /* inverse result of constraints.
* doesn't include effect of restposition, parent, and local transform*/
@@ -258,8 +272,10 @@ typedef struct bPoseChannel {
struct bPoseChannel *bbone_prev; /* next/prev bones to use as handle references when calculating bbones (optional) */
struct bPoseChannel *bbone_next;
-
+
void *temp; /* use for outliner */
+ /* Runtime data for color and bbone segment matrix. */
+ bPoseChannelDrawData *draw_data;
} bPoseChannel;
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index 52e40cbc098..4aa3edcc788 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -85,6 +85,13 @@ typedef struct Camera {
char sensor_fit;
char pad[7];
+ /* runtime only, used for drawing */
+ float drwcorners[4][2];
+ float drwtria[2][2];
+ float drwdepth, pad1;
+ float drwfocusmat[4][4];
+ float drwnormalmat[4][4];
+
/* Stereo settings */
struct CameraStereoSettings stereo;
} Camera;
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 902fa4ce987..e598c32173c 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -266,6 +266,7 @@ typedef struct Curve {
char pad2[2];
+ void *batch_cache;
} Curve;
#define CURVE_VFONT_ANY(cu) \
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 2d1ffaa53eb..0e0b1d669d9 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -92,13 +92,13 @@ typedef enum CustomDataType {
CD_MCOL = 6,
CD_ORIGINDEX = 7,
CD_NORMAL = 8,
-/* CD_POLYINDEX = 9, */
+ CD_FACEMAP = 9, /* exclusive face group, each face can only be part of one */
CD_PROP_FLT = 10,
CD_PROP_INT = 11,
CD_PROP_STR = 12,
CD_ORIGSPACE = 13, /* for modifier stack face location mapping */
CD_ORCO = 14,
- CD_MTEXPOLY = 15,
+/* CD_MTEXPOLY = 15, */ /* deprecated */
CD_MLOOPUV = 16,
CD_MLOOPCOL = 17,
CD_TANGENT = 18,
@@ -143,13 +143,13 @@ typedef enum CustomDataType {
#define CD_MASK_MCOL (1 << CD_MCOL)
#define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX)
#define CD_MASK_NORMAL (1 << CD_NORMAL)
-// #define CD_MASK_POLYINDEX (1 << CD_POLYINDEX)
+#define CD_MASK_FACEMAP (1 << CD_FACEMAP)
#define CD_MASK_PROP_FLT (1 << CD_PROP_FLT)
#define CD_MASK_PROP_INT (1 << CD_PROP_INT)
#define CD_MASK_PROP_STR (1 << CD_PROP_STR)
#define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE)
#define CD_MASK_ORCO (1 << CD_ORCO)
-#define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY)
+// #define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY) /* DEPRECATED */
#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV)
#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL)
#define CD_MASK_TANGENT (1 << CD_TANGENT)
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 0364d855f69..ba1bf1520ce 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -126,7 +126,7 @@ typedef enum eGPDpalettecolor_Flag {
PC_COLOR_LOCKED = (1 << 2),
/* do onion skinning */
PC_COLOR_ONIONSKIN = (1 << 3),
- /* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */
+ /* "volumetric" strokes */
PC_COLOR_VOLUMETRIC = (1 << 4),
/* Use High quality fill */
PC_COLOR_HQ_FILL = (1 << 5)
@@ -271,7 +271,7 @@ typedef enum eGPDlayer_Flag {
GP_LAYER_GHOST_PREVCOL = (1 << 8),
/* use custom color for ghosts after current frame */
GP_LAYER_GHOST_NEXTCOL = (1 << 9),
- /* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */
+ /* "volumetric" strokes */
GP_LAYER_VOLUMETRIC = (1 << 10),
/* Use high quality fill (instead of buggy legacy OpenGL Fill) */
GP_LAYER_HQ_FILL = (1 << 11),
@@ -298,6 +298,7 @@ typedef struct bGPdata {
short sbuffer_sflag; /* flags for stroke that cache represents */
void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
float scolor[4]; /* buffer color using palettes */
+ float sfill[4]; /* buffer fill color */
char pad[6]; /* padding for compiler alignment error */
short sflag; /* settings for palette color */
diff --git a/source/blender/makesdna/DNA_gpu_types.h b/source/blender/makesdna/DNA_gpu_types.h
index 967cb7284dc..be34309572f 100644
--- a/source/blender/makesdna/DNA_gpu_types.h
+++ b/source/blender/makesdna/DNA_gpu_types.h
@@ -38,6 +38,8 @@ typedef struct GPUDOFSettings {
float fstop;
float focal_length;
float sensor;
+ float rotation;
+ float ratio;
int num_blades;
int high_quality;
} GPUDOFSettings;
diff --git a/source/blender/makesdna/DNA_lattice_types.h b/source/blender/makesdna/DNA_lattice_types.h
index 242d6f0feeb..28a401676fc 100644
--- a/source/blender/makesdna/DNA_lattice_types.h
+++ b/source/blender/makesdna/DNA_lattice_types.h
@@ -69,6 +69,7 @@ typedef struct Lattice {
char vgroup[64]; /* multiply the influence, MAX_VGROUP_NAME */
struct EditLatt *editlatt;
+ void *batch_cache;
} Lattice;
/* ***************** LATTICE ********************* */
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
new file mode 100644
index 00000000000..1e6657ae29c
--- /dev/null
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -0,0 +1,148 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file DNA_layer_types.h
+ * \ingroup DNA
+ */
+
+#ifndef __DNA_LAYER_TYPES_H__
+#define __DNA_LAYER_TYPES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "DNA_listBase.h"
+
+typedef struct Base {
+ struct Base *next, *prev;
+ short flag;
+ short refcount;
+ short sx, sy;
+ struct Object *object;
+ unsigned int selcol;
+ unsigned int lay;
+ int flag_legacy;
+ int pad;
+ struct IDProperty *collection_properties; /* used by depsgraph, flushed from collection-tree */
+} Base;
+
+typedef struct CollectionOverride {
+ struct CollectionOverride *next, *prev;
+ char name[64]; /* MAX_NAME */
+ /* TODO proper data */
+} CollectionOverride;
+
+typedef struct SceneLayerEngineData {
+ struct SceneLayerEngineData *next, *prev;
+ struct DrawEngineType *engine_type;
+ void *storage;
+ void (*free)(void *storage);
+} SceneLayerEngineData;
+
+typedef struct LayerCollection {
+ struct LayerCollection *next, *prev;
+ struct SceneCollection *scene_collection;
+ short flag;
+ /* TODO(sergey): Get rid of this once we've got CoW in DEG, */
+ short flag_evaluated;
+ short pad[2];
+ ListBase object_bases; /* (ObjectBase *)LinkData->data - synced with collection->objects and collection->filter_objects */
+ ListBase overrides;
+ ListBase layer_collections; /* synced with collection->collections */
+ struct IDProperty *properties; /* overrides */
+ struct IDProperty *properties_evaluated;
+} LayerCollection;
+
+typedef struct SceneLayer {
+ struct SceneLayer *next, *prev;
+ char name[64]; /* MAX_NAME */
+ char engine[32]; /* render engine */
+ short active_collection;
+ short flag;
+ short pad[2];
+ ListBase object_bases; /* ObjectBase */
+ struct SceneStats *stats; /* default allocated now */
+ struct Base *basact;
+ ListBase layer_collections; /* LayerCollection */
+ struct IDProperty *properties; /* overrides */
+ struct IDProperty *properties_evaluated;
+
+ /* Runtime data */
+ ListBase drawdata; /* SceneLayerEngineData */
+} SceneLayer;
+
+typedef struct SceneCollection {
+ struct SceneCollection *next, *prev;
+ char name[64]; /* MAX_NAME */
+ char filter[64]; /* MAX_NAME */
+ int active_object_index; /* for UI */
+ int pad;
+ ListBase objects; /* (Object *)LinkData->data */
+ ListBase filter_objects; /* (Object *)LinkData->data */
+ ListBase scene_collections; /* nested collections */
+} SceneCollection;
+
+/* Base->flag */
+enum {
+ BASE_SELECTED = (1 << 0),
+ BASE_VISIBLED = (1 << 1),
+ BASE_SELECTABLED = (1 << 2),
+ BASE_FROMDUPLI = (1 << 3),
+ BASE_DIRTY_ENGINE_SETTINGS = (1 << 4),
+ BASE_FROM_SET = (1 << 5), /* To be set only by the depsgraph */
+};
+
+/* LayerCollection->flag */
+enum {
+ COLLECTION_VISIBLE = (1 << 0),
+ COLLECTION_SELECTABLE = (1 << 1),
+};
+
+/* SceneLayer->flag */
+enum {
+ SCENE_LAYER_RENDER = (1 << 0),
+ SCENE_LAYER_ENGINE_DIRTY = (1 << 1),
+};
+
+
+/* *************************************************************** */
+/* Engine Settings */
+
+/* CollectionEngineSettings->type */
+typedef enum CollectionEngineSettingsType {
+ COLLECTION_MODE_NONE = 0,
+ COLLECTION_MODE_OBJECT = 1,
+ COLLECTION_MODE_EDIT = 2,
+ COLLECTION_MODE_PAINT_WEIGHT = 5,
+ COLLECTION_MODE_PAINT_VERTEX = 6,
+} CollectionModeSettingsType;
+
+/* *************************************************************** */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DNA_LAYER_TYPES_H__ */
+
diff --git a/source/blender/makesdna/DNA_manipulator_types.h b/source/blender/makesdna/DNA_manipulator_types.h
new file mode 100644
index 00000000000..7b75806f7c0
--- /dev/null
+++ b/source/blender/makesdna/DNA_manipulator_types.h
@@ -0,0 +1,43 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file DNA_manipulator_types.h
+ * \ingroup DNA
+ */
+
+#ifndef __DNA_MANIPULATOR_TYPES_H__
+#define __DNA_MANIPULATOR_TYPES_H__
+
+typedef struct wmManipulatorGroup {
+ struct wmManipulatorGroup *next, *prev;
+
+ struct wmManipulatorGroupType *type;
+ ListBase manipulators;
+
+ void *py_instance; /* python stores the class instance here */
+ struct ReportList *reports; /* errors and warnings storage */
+
+ void *customdata;
+ void (*customdata_free)(void *); /* for freeing customdata from above */
+ int flag; /* private */
+ int pad;
+} wmManipulatorGroup;
+
+#endif /* __DNA_MANIPULATOR_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 0c500e366a7..09a4e42cb8f 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -90,6 +90,16 @@ typedef struct TexPaintSlot {
int pad;
} TexPaintSlot;
+/* Clay engine */
+
+/* MaterialRuntimeClay.flag */
+#define CLAY_OUTDATED 1
+
+/* MaterialEngineSettingsClay.type */
+#define CLAY_MATCAP_NONE 0
+#define CLAY_MATCAP_SIMPLE 1
+#define CLAY_MATCAP_COMPLETE 2
+
typedef struct Material {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
@@ -201,6 +211,10 @@ typedef struct Material {
char nmap_tangent_names[9][64]; /* [MAX_MTFACE+1][MAX_NAME]; +1 for empty name */
int nmap_tangent_names_count, pad5;
+ /* image to use for image/uv space, also bake target
+ * (not to be used shading/rendering pipeline, this is editor featyure only!). */
+ struct Image *edit_image;
+
struct TexPaintSlot *texpaintslot; /* cached slot for painting. Make sure to recalculate before use
* with refresh_texpaint_image_cache */
ListBase gpumaterial; /* runtime */
@@ -275,7 +289,7 @@ typedef struct Material {
#define MA_ONLYSHADOW 1024
#define MA_HALO_XALPHA 1024
#define MA_STAR 0x800
-#define MA_FACETEXTURE 0x800
+// #define MA_FACETEXTURE 0x800 /* deprecated */
#define MA_HALOTEX 0x1000
#define MA_HALOPUNO 0x2000
#define MA_ONLYCAST 0x2000
@@ -297,7 +311,7 @@ typedef struct Material {
/* qdn: a bit clumsy this, tangents needed for normal maps separated from shading */
#define MA_NORMAP_TANG 0x8000000
#define MA_GROUP_NOLAY 0x10000000
-#define MA_FACETEXTURE_ALPHA 0x20000000
+// #define MA_FACETEXTURE_ALPHA 0x20000000 /* deprecated */
#define MA_STR_B_UNITS 0x40000000
#define MA_STR_SURFDIFF 0x80000000
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 39e56925903..505b1f7157b 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -66,7 +66,6 @@ typedef struct Mesh {
/* BMESH ONLY */
/*new face structures*/
struct MPoly *mpoly;
- struct MTexPoly *mtpoly;
struct MLoop *mloop;
struct MLoopUV *mloopuv;
struct MLoopCol *mloopcol;
@@ -127,6 +126,7 @@ typedef struct Mesh {
short totcol;
struct Multires *mr DNA_DEPRECATED; /* deprecated multiresolution modeling data, only keep for loading old files */
+ void *batch_cache;
} Mesh;
/* deprecated by MTFace, only here for file reading */
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 3676066a399..d0a3c7bb95a 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -186,22 +186,9 @@ typedef struct MVertTri {
unsigned int tri[3];
} MVertTri;
-
-typedef struct MTexPoly {
- struct Image *tpage;
- char flag, transp;
- short mode, tile, pad;
-} MTexPoly;
-
-/* can copy from/to MTexPoly/MTFace */
-#define ME_MTEXFACE_CPY(dst, src) \
-{ \
- (dst)->tpage = (src)->tpage; \
- (dst)->flag = (src)->flag; \
- (dst)->transp = (src)->transp; \
- (dst)->mode = (src)->mode; \
- (dst)->tile = (src)->tile; \
-} (void)0
+//typedef struct MTexPoly {
+// void *pad;
+//} MTexPoly;
typedef struct MLoopUV {
float uv[2];
@@ -256,9 +243,6 @@ typedef struct MSelect {
/*tessellation uv face data*/
typedef struct MTFace {
float uv[4][2];
- struct Image *tpage;
- char flag, transp;
- short mode, tile, unwrap;
} MTFace;
/*Custom Data Properties*/
@@ -463,58 +447,4 @@ enum {
ME_FSEL = 2,
};
-/* mtface->flag */
-enum {
- // TF_SELECT = (1 << 0), /* use MFace hide flag (after 2.43), should be able to reuse after 2.44 */
- // TF_ACTIVE = (1 << 1), /* deprecated! */
- TF_SEL1 = (1 << 2),
- TF_SEL2 = (1 << 3),
- TF_SEL3 = (1 << 4),
- TF_SEL4 = (1 << 5),
-};
-
-/* mtface->mode */
-enum {
- TF_DYNAMIC = (1 << 0),
- TF_ALPHASORT = (1 << 1),
- TF_TEX = (1 << 2),
- TF_SHAREDVERT = (1 << 3),
- TF_LIGHT = (1 << 4),
-
- TF_CONVERTED = (1 << 5), /* tface converted to material */
-
- TF_SHAREDCOL = (1 << 6),
- // TF_TILES = (1 << 7), /* deprecated */
- TF_BILLBOARD = (1 << 8),
- TF_TWOSIDE = (1 << 9),
- TF_INVISIBLE = (1 << 10),
-
- TF_OBCOL = (1 << 11),
- TF_BILLBOARD2 = (1 << 12), /* with Z axis constraint */
- TF_SHADOW = (1 << 13),
- TF_BMFONT = (1 << 14),
-};
-
-/* mtface->transp, values 1-4 are used as flags in the GL, WARNING, TF_SUB cant work with this */
-enum {
- TF_SOLID = 0,
- TF_ADD = (1 << 0),
- TF_ALPHA = (1 << 1),
- TF_CLIP = (1 << 2), /* clipmap alpha/binary alpha all or nothing! */
-
- TF_SUB = 3, /* sub is not available in the user interface anymore */
-};
-
-/* mtface->unwrap */
-enum {
- TF_DEPRECATED1 = (1 << 0),
- TF_DEPRECATED2 = (1 << 1),
- TF_DEPRECATED3 = (1 << 2),
- TF_DEPRECATED4 = (1 << 3),
- TF_PIN1 = (1 << 4),
- TF_PIN2 = (1 << 5),
- TF_PIN3 = (1 << 6),
- TF_PIN4 = (1 << 7),
-};
-
#endif /* __DNA_MESHDATA_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 823a7f0812f..4959055ed10 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -418,7 +418,7 @@ typedef struct UVProjectModifierData {
/* the objects which do the projecting */
struct Object *projectors[10]; /* MOD_UVPROJECT_MAXPROJECTORS */
struct Image *image; /* the image to project */
- int flags;
+ int pad2;
int num_projectors;
float aspectx, aspecty;
float scalex, scaley;
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index ed14c4b9311..9413a21633b 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -112,6 +112,12 @@ typedef struct PartDeflect {
float f_noise; /* noise of force */
int seed; /* noise random seed */
+ /* Display Size */
+ float drawvec1[4]; /* Runtime only : start of the curve or draw scale */
+ float drawvec2[4]; /* Runtime only : end of the curve */
+ float drawvec_falloff_min[3], pad1; /* Runtime only */
+ float drawvec_falloff_max[3], pad2; /* Runtime only */
+
struct Object *f_source; /* force source object */
} PartDeflect;
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 6d79e6d49f8..72a21437b7d 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -65,6 +65,21 @@ typedef struct bDeformGroup {
/* need this flag for locking weights */
char flag, pad[7];
} bDeformGroup;
+
+/* Face Maps*/
+typedef struct bFaceMap {
+ struct bFaceMap *next, *prev;
+ char name[64]; /* MAX_VGROUP_NAME */
+} bFaceMap;
+
+/* Object Runtime display data */
+typedef struct ObjectEngineData {
+ struct ObjectEngineData *next, *prev;
+ struct DrawEngineType *engine_type;
+ void *storage;
+ void (*free)(void *storage);
+} ObjectEngineData;
+
#define MAX_VGROUP_NAME 64
/* bDeformGroup->flag */
@@ -142,7 +157,8 @@ typedef struct Object {
ListBase effect DNA_DEPRECATED; // XXX deprecated... keep for readfile
ListBase defbase; /* list of bDeformGroup (vertex groups) names and flag only */
ListBase modifiers; /* list of ModifierData structures */
-
+ ListBase fmaps; /* list of facemaps */
+
int mode; /* Local object mode */
int restore_mode; /* Keep track of what mode to return to after toggling a mode */
@@ -223,7 +239,10 @@ typedef struct Object {
float jump_speed;
float fall_speed;
unsigned char max_jumps;
- char pad2[3];
+ char pad2;
+
+ /* Depsgraph */
+ short base_flag; /* used by depsgraph, flushed from base */
/** Collision mask settings */
unsigned short col_group, col_mask;
@@ -248,6 +267,8 @@ typedef struct Object {
short index; /* custom index, for renderpasses */
unsigned short actdef; /* current deformation group, note: index starts at 1 */
+ unsigned short actfmap; /* current face map, note: index starts at 1 */
+ unsigned char pad5[6];
float col[4]; /* object color */
int gameflag;
@@ -299,6 +320,12 @@ typedef struct Object {
LodLevel *currentlod;
struct PreviewImage *preview;
+
+ struct IDProperty *base_collection_properties; /* used by depsgraph, flushed from base */
+
+ ListBase drawdata; /* runtime, ObjectEngineData */
+ int base_selection_color; /* flushed by depsgraph only */
+ int pad3[3];
} Object;
/* Warning, this is not used anymore because hooks are now modifiers */
diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h
index 984e3334414..81575beaac8 100644
--- a/source/blender/makesdna/DNA_outliner_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -38,6 +38,9 @@ struct ID;
typedef struct TreeStoreElem {
short type, nr, flag, used;
+
+ /* XXX We actually also store non-ID data in this pointer for identifying
+ * the TreeStoreElem for a TreeElement when rebuilding the tree. Ugly! */
struct ID *id;
} TreeStoreElem;
@@ -50,11 +53,14 @@ typedef struct TreeStore {
} TreeStore;
/* TreeStoreElem->flag */
-#define TSE_CLOSED 1
-#define TSE_SELECTED 2
-#define TSE_TEXTBUT 4
-#define TSE_CHILDSEARCH 8
-#define TSE_SEARCHMATCH 16
+enum {
+ TSE_CLOSED = (1 << 0),
+ TSE_SELECTED = (1 << 1),
+ TSE_TEXTBUT = (1 << 2),
+ TSE_CHILDSEARCH = (1 << 3),
+ TSE_SEARCHMATCH = (1 << 4),
+ TSE_HIGHLIGHTED = (1 << 5),
+};
/* TreeStoreElem->types */
#define TSE_NLA 1 /* NO ID */
@@ -96,6 +102,8 @@ typedef struct TreeStore {
#define TSE_KEYMAP_ITEM 35 /* NO ID */
#define TSE_ID_BASE 36 /* NO ID */
#define TSE_GP_LAYER 37 /* NO ID */
+#define TSE_LAYER_COLLECTION 38 /* NO ID */
+#define TSE_SCENE_COLLECTION 39 /* NO ID */
/* Check whether given TreeStoreElem should have a real ID in its ->id member. */
@@ -103,7 +111,8 @@ typedef struct TreeStore {
(!ELEM((_tse)->type, TSE_NLA, TSE_NLA_TRACK, TSE_DRIVER_BASE, \
TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, \
TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, \
- TSE_KEYMAP, TSE_KEYMAP_ITEM, TSE_ID_BASE, TSE_GP_LAYER))
+ TSE_KEYMAP, TSE_KEYMAP_ITEM, TSE_ID_BASE, TSE_GP_LAYER, \
+ TSE_SCENE_COLLECTION, TSE_LAYER_COLLECTION))
#endif
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 1deb9bf3787..5d9d7bd7be0 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -324,6 +324,8 @@ typedef struct ParticleSystem {
float dt_frac; /* current time step, as a fraction of a frame */
float _pad; /* spare capacity */
+
+ void *batch_cache;
} ParticleSystem;
typedef enum eParticleDrawFlag {
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index c2711c465e1..506e98edc7b 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -47,6 +47,8 @@ extern "C" {
#include "DNA_ID.h"
#include "DNA_freestyle_types.h"
#include "DNA_gpu_types.h"
+#include "DNA_layer_types.h"
+#include "DNA_material_types.h"
#include "DNA_userdef_types.h"
struct CurveMapping;
@@ -65,18 +67,13 @@ struct bGPdata;
struct bGPDbrush;
struct MovieClip;
struct ColorSpace;
+struct SceneCollection;
/* ************************************************************* */
/* Scene Data */
/* Base - Wrapper for referencing Objects in a Scene */
-typedef struct Base {
- struct Base *next, *prev;
- unsigned int lay, selcol;
- int flag;
- short sx, sy;
- struct Object *object;
-} Base;
+#define BaseLegacy Base
/* ************************************************************* */
/* Output Format Data */
@@ -578,6 +575,12 @@ typedef enum BakePassFilter {
#define R_BAKE_PASS_FILTER_ALL (~0)
+/* RenderEngineSettingsClay.options */
+typedef enum ClayFlagSettings {
+ CLAY_USE_AO = (1 << 0),
+ CLAY_USE_HSV = (1 << 1),
+} ClayFlagSettings;
+
/* *************************************************************** */
/* Render Data */
@@ -962,7 +965,7 @@ typedef struct GameData {
#define GAME_SHOW_DEBUG_PROPS (1 << 2)
#define GAME_SHOW_FRAMERATE (1 << 3)
#define GAME_SHOW_PHYSICS (1 << 4)
-#define GAME_DISPLAY_LISTS (1 << 5)
+// #define GAME_DISPLAY_LISTS (1 << 5) /* deprecated */
#define GAME_GLSL_NO_LIGHTS (1 << 6)
#define GAME_GLSL_NO_SHADERS (1 << 7)
#define GAME_GLSL_NO_SHADOWS (1 << 8)
@@ -1110,6 +1113,7 @@ typedef struct ParticleEditSettings {
int draw_step, fade_frames;
struct Scene *scene;
+ struct SceneLayer *scene_layer;
struct Object *object;
struct Object *shape_object;
} ParticleEditSettings;
@@ -1664,7 +1668,7 @@ typedef struct Scene {
struct Scene *set;
ListBase base;
- struct Base *basact; /* active base */
+ struct BaseLegacy *basact; /* active base */
struct Object *obedit; /* name replaces old G.obedit */
float cursor[3]; /* 3d cursor location */
@@ -1685,7 +1689,7 @@ typedef struct Scene {
struct Editing *ed; /* sequence editor data is allocated here */
struct ToolSettings *toolsettings; /* default allocated now */
- struct SceneStats *stats; /* default allocated now */
+ void *pad2;
struct DisplaySafeAreas safe_areas;
/* migrate or replace? depends on some internal things... */
@@ -1742,6 +1746,16 @@ typedef struct Scene {
struct RigidBodyWorld *rigidbody_world;
struct PreviewImage *preview;
+
+ ListBase render_layers;
+ struct SceneCollection *collection;
+ int active_layer;
+ int pad4;
+
+ IDProperty *collection_properties; /* settings to be overriden by layer collections */
+ IDProperty *layer_properties; /* settings to be override by workspaces */
+
+ int pad5[2];
} Scene;
/* **************** RENDERDATA ********************* */
@@ -1931,6 +1945,8 @@ enum {
/* scene->r.engine (scene.c) */
extern const char *RE_engine_id_BLENDER_RENDER;
extern const char *RE_engine_id_BLENDER_GAME;
+extern const char *RE_engine_id_BLENDER_CLAY;
+extern const char *RE_engine_id_BLENDER_EEVEE;
extern const char *RE_engine_id_CYCLES;
/* **************** SCENE ********************* */
@@ -1949,38 +1965,39 @@ extern const char *RE_engine_id_CYCLES;
/* depricate this! */
#define TESTBASE(v3d, base) ( \
- ((base)->flag & SELECT) && \
+ ((base)->flag_legacy & SELECT) && \
((base)->lay & v3d->lay) && \
(((base)->object->restrictflag & OB_RESTRICT_VIEW) == 0))
-#define TESTBASELIB(v3d, base) ( \
- ((base)->flag & SELECT) && \
- ((base)->lay & v3d->lay) && \
+
+#define TESTBASE_NEW(base) ( \
+ (((base)->flag & BASE_SELECTED) != 0) && \
+ (((base)->flag & BASE_VISIBLED) != 0))
+#define TESTBASELIB_NEW(base) ( \
+ (((base)->flag & BASE_SELECTED) != 0) && \
((base)->object->id.lib == NULL) && \
- (((base)->object->restrictflag & OB_RESTRICT_VIEW) == 0))
-#define TESTBASELIB_BGMODE(v3d, scene, base) ( \
- ((base)->flag & SELECT) && \
- ((base)->lay & (v3d ? v3d->lay : scene->lay)) && \
+ (((base)->flag & BASE_VISIBLED) != 0))
+#define TESTBASELIB_BGMODE_NEW(base) ( \
+ (((base)->flag & BASE_SELECTED) != 0) && \
((base)->object->id.lib == NULL) && \
- (((base)->object->restrictflag & OB_RESTRICT_VIEW) == 0))
-#define BASE_EDITABLE_BGMODE(v3d, scene, base) ( \
- ((base)->lay & (v3d ? v3d->lay : scene->lay)) && \
+ (((base)->flag & BASE_VISIBLED) != 0))
+#define BASE_EDITABLE_BGMODE_NEW(base) ( \
((base)->object->id.lib == NULL) && \
- (((base)->object->restrictflag & OB_RESTRICT_VIEW) == 0))
-#define BASE_SELECTABLE(v3d, base) ( \
- (base->lay & v3d->lay) && \
- (base->object->restrictflag & (OB_RESTRICT_SELECT | OB_RESTRICT_VIEW)) == 0)
-#define BASE_VISIBLE(v3d, base) ( \
- (base->lay & v3d->lay) && \
- (base->object->restrictflag & OB_RESTRICT_VIEW) == 0)
-#define BASE_VISIBLE_BGMODE(v3d, scene, base) ( \
- (base->lay & (v3d ? v3d->lay : scene->lay)) && \
- (base->object->restrictflag & OB_RESTRICT_VIEW) == 0)
+ (((base)->flag & BASE_VISIBLED) != 0))
+#define BASE_SELECTABLE_NEW(base) \
+ (((base)->flag & BASE_SELECTABLED) != 0)
+#define BASE_VISIBLE_NEW(base) ( \
+ ((base)->flag & BASE_VISIBLED) != 0)
#define FIRSTBASE scene->base.first
#define LASTBASE scene->base.last
#define BASACT (scene->basact)
#define OBACT (BASACT ? BASACT->object: NULL)
+#define FIRSTBASE_NEW (sl)->object_bases.first
+#define LASTBASE_NEW (sl)->object_bases.last
+#define BASACT_NEW ((sl)->basact)
+#define OBACT_NEW (BASACT_NEW ? BASACT_NEW->object: NULL)
+
#define V3D_CAMERA_LOCAL(v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : NULL)
#define V3D_CAMERA_SCENE(scene, v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : (scene)->camera)
@@ -1995,7 +2012,7 @@ extern const char *RE_engine_id_CYCLES;
#define TIME2FRA(a) ((((double) scene->r.frs_sec) * (double)(a)) / (double)scene->r.frs_sec_base)
#define FPS (((double) scene->r.frs_sec) / (double)scene->r.frs_sec_base)
-/* base->flag is in DNA_object_types.h */
+/* base->legacy_flag is in DNA_object_types.h */
/* toolsettings->snap_flag */
#define SCE_SNAP 1
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index e208ef39719..ce1f8d1a7d4 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -76,6 +76,8 @@ typedef struct bScreen {
struct wmTimer *animtimer; /* if set, screen has timer handler added in window */
void *context; /* context callback */
+
+ PreviewImage *preview;
} bScreen;
typedef struct ScrVert {
@@ -265,9 +267,10 @@ typedef struct ARegion {
ListBase ui_previews; /* uiPreview */
ListBase handlers; /* wmEventHandler */
ListBase panels_category; /* Panel categories runtime */
-
+
+ struct wmManipulatorMap *manipulator_map; /* manipulator-map of this region */
struct wmTimer *regiontimer; /* blend in/out */
-
+
char *headerstr; /* use this string to draw info */
void *regiondata; /* XXX 2.50, need spacedata equivalent? */
} ARegion;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 0e5d9bd33e6..833db376191 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -181,7 +181,8 @@ typedef enum eSpaceButtons_Context {
BCONTEXT_CONSTRAINT = 11,
BCONTEXT_BONE_CONSTRAINT = 12,
BCONTEXT_RENDER_LAYER = 13,
-
+ BCONTEXT_COLLECTION = 14,
+
/* always as last... */
BCONTEXT_TOT
} eSpaceButtons_Context;
@@ -273,21 +274,23 @@ typedef enum eSpaceOutliner_Flag {
/* SpaceOops->outlinevis */
typedef enum eSpaceOutliner_Mode {
- SO_ALL_SCENES = 0,
- SO_CUR_SCENE = 1,
- SO_VISIBLE = 2,
- SO_SELECTED = 3,
- SO_ACTIVE = 4,
- SO_SAME_TYPE = 5,
- SO_GROUPS = 6,
- SO_LIBRARIES = 7,
- /* SO_VERSE_SESSION = 8, */ /* deprecated! */
- /* SO_VERSE_MS = 9, */ /* deprecated! */
- SO_SEQUENCE = 10,
- SO_DATABLOCKS = 11,
- SO_USERDEF = 12,
- /* SO_KEYMAP = 13, */ /* deprecated! */
- SO_ID_ORPHANS = 14,
+ SO_ALL_SCENES = 0,
+ SO_CUR_SCENE = 1,
+ SO_VISIBLE = 2,
+ SO_SELECTED = 3,
+ SO_ACTIVE = 4,
+ SO_SAME_TYPE = 5,
+ SO_GROUPS = 6,
+ SO_LIBRARIES = 7,
+ /* SO_VERSE_SESSION = 8, */ /* deprecated! */
+ /* SO_VERSE_MS = 9, */ /* deprecated! */
+ SO_SEQUENCE = 10,
+ SO_DATABLOCKS = 11,
+ SO_USERDEF = 12,
+ /* SO_KEYMAP = 13, */ /* deprecated! */
+ SO_ID_ORPHANS = 14,
+ SO_ACT_LAYER = 15,
+ SO_COLLECTIONS = 16,
} eSpaceOutliner_Mode;
/* SpaceOops->storeflag */
@@ -710,7 +713,7 @@ typedef enum eFileSel_Params_Flag {
FILE_LINK = (1 << 2),
FILE_HIDE_DOT = (1 << 3),
FILE_AUTOSELECT = (1 << 4),
- FILE_ACTIVELAY = (1 << 5),
+ FILE_ACTIVE_COLLECTION = (1 << 5),
/* FILE_ATCURSOR = (1 << 6), */ /* deprecated */
FILE_DIRSEL_ONLY = (1 << 7),
FILE_FILTER = (1 << 8),
@@ -939,7 +942,7 @@ typedef enum eSpaceImage_Sticky {
/* SpaceImage->flag */
typedef enum eSpaceImage_Flag {
/* SI_BE_SQUARE = (1 << 0), */ /* deprecated */
- SI_EDITTILE = (1 << 1), /* XXX - not used but should be? */
+/* SI_EDITTILE = (1 << 1), */ /* deprecated */
SI_CLIP_UV = (1 << 2),
/* SI_DRAWTOOL = (1 << 3), */ /* deprecated */
SI_NO_DRAWFACES = (1 << 4),
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 5e7e7366e35..256d53eed0b 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -161,7 +161,7 @@ typedef struct ThemeUI {
/* Interface Elements (buttons, menus, icons) */
uiWidgetColors wcol_regular, wcol_tool, wcol_text;
uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
- uiWidgetColors wcol_num, wcol_numslider;
+ uiWidgetColors wcol_num, wcol_numslider, wcol_tab;
uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item, wcol_tooltip;
uiWidgetColors wcol_box, wcol_scroll, wcol_progress, wcol_list_item, wcol_pie_menu;
@@ -495,6 +495,8 @@ typedef struct UserDef {
short tb_leftmouse, tb_rightmouse;
struct SolidLight light[3];
short tw_hotspot, tw_flag, tw_handlesize, tw_size;
+ short manipulator_flag, manipulator_scale;
+ int pad3;
short textimeout, texcollectrate;
short wmdrawmethod; /* removed wmpad */
short dragthreshold;
@@ -788,8 +790,6 @@ typedef enum eText_Draw_Options {
USER_TEXT_DISABLE_AA = (1 << 0),
} eText_Draw_Options;
-/* tw_flag (transform widget) */
-
/* gp_settings (Grease Pencil Settings) */
typedef enum eGP_UserdefSettings {
GP_PAINT_DOSMOOTH = (1 << 0),
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 4c243507e82..f50222859f1 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -45,6 +45,7 @@ struct SmoothView3DStore;
struct wmTimer;
struct Material;
struct GPUFX;
+struct GPUViewport;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@@ -65,6 +66,12 @@ struct GPUFX;
/* The near/far thing is a Win EXCEPTION. Thus, leave near/far in the
* code, and patch for windows. */
+
+typedef struct View3DDebug {
+ float znear, zfar;
+ char background;
+ char pad[7];
+} View3DDebug;
/* Background Picture in 3D-View */
typedef struct BGpic {
@@ -111,7 +118,7 @@ typedef struct RegionView3D {
struct wmTimer *smooth_timer;
- /* transform widget matrix */
+ /* transform manipulator matrix */
float twmat[4][4];
float viewquat[4]; /* view rotation, must be kept normalized */
@@ -130,7 +137,7 @@ typedef struct RegionView3D {
char pad[3];
float ofs_lock[2]; /* normalized offset for locked view: (-1, -1) bottom left, (1, 1) upper right */
- short twdrawflag;
+ short twdrawflag; /* XXX can easily get rid of this (Julian) */
short rflag;
@@ -147,6 +154,7 @@ typedef struct RegionView3D {
float rot_axis[3];
struct GPUFX *compositor;
+ struct GPUViewport *viewport;
} RegionView3D;
/* 3D ViewPort Struct */
@@ -202,7 +210,7 @@ typedef struct View3D {
short gridsubdiv; /* Number of subdivisions in the grid between each highlighted grid line */
char gridflag;
- /* transform widget info */
+ /* transform manipulator info */
char twtype, twmode, twflag;
short flag3;
@@ -217,7 +225,6 @@ typedef struct View3D {
char multiview_eye; /* multiview current eye - for internal use */
- /* built-in shader effects (eGPUFXFlags) */
char pad3[4];
/* note, 'fx_settings.dof' is currently _not_ allocated,
@@ -244,6 +251,7 @@ typedef struct View3D {
short prev_drawtype;
short pad1;
float pad2;
+ View3DDebug debug;
} View3D;
@@ -320,6 +328,13 @@ typedef struct View3D {
/* View3d->flag3 (short) */
#define V3D_SHOW_WORLD (1 << 0)
+/* View3d->debug.background */
+enum {
+ V3D_DEBUG_BACKGROUND_NONE = (1 << 0),
+ V3D_DEBUG_BACKGROUND_GRADIENT = (1 << 1),
+ V3D_DEBUG_BACKGROUND_WORLD = (1 << 2),
+};
+
/* View3D->around */
enum {
/* center of the bounding box */
@@ -366,8 +381,8 @@ enum {
/* View3d->twflag */
/* USE = user setting, DRAW = based on selection */
#define V3D_USE_MANIPULATOR 1
-#define V3D_DRAW_MANIPULATOR 2
-/* #define V3D_CALC_MANIPULATOR 4 */ /*UNUSED*/
+#define V3D_DRAW_MANIPULATOR (1 << 1)
+#define V3D_SHADED_MANIPULATORS (1 << 2)
/* BGPic->flag */
/* may want to use 1 for select ? */
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 5fd4c9fd407..f3d3faecbb4 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -128,6 +128,7 @@ typedef struct World {
/* nodes */
struct bNodeTree *nodetree;
+ float mistend, pad1; /* runtime : miststa + mistdist, used for drawing camera */
ListBase gpumaterial; /* runtime */
} World;
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 2cea8715a65..e761d68ca64 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -77,6 +77,7 @@ static const char *includefiles[] = {
"DNA_image_types.h",
"DNA_texture_types.h",
"DNA_lamp_types.h",
+ "DNA_manipulator_types.h",
"DNA_material_types.h",
"DNA_vfont_types.h",
"DNA_meta_types.h",
@@ -130,6 +131,7 @@ static const char *includefiles[] = {
"DNA_freestyle_types.h",
"DNA_linestyle_types.h",
"DNA_cachefile_types.h",
+ "DNA_layer_types.h",
/* see comment above before editing! */
/* empty string to indicate end of includefiles */
@@ -1289,6 +1291,7 @@ int main(int argc, char **argv)
#include "DNA_image_types.h"
#include "DNA_texture_types.h"
#include "DNA_lamp_types.h"
+#include "DNA_manipulator_types.h"
#include "DNA_material_types.h"
#include "DNA_vfont_types.h"
#include "DNA_meta_types.h"
@@ -1342,4 +1345,5 @@ int main(int argc, char **argv)
#include "DNA_freestyle_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_cachefile_types.h"
+#include "DNA_layer_types.h"
/* end of list */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index a1af3f98274..127977c23bb 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -106,6 +106,7 @@ extern StructRNA RNA_ClothCollisionSettings;
extern StructRNA RNA_ClothModifier;
extern StructRNA RNA_ClothSettings;
extern StructRNA RNA_CloudsTexture;
+extern StructRNA RNA_CollectionEngineSettings;
extern StructRNA RNA_CollectionProperty;
extern StructRNA RNA_CollisionModifier;
extern StructRNA RNA_CollisionSensor;
@@ -230,6 +231,7 @@ extern StructRNA RNA_EnvironmentMapTexture;
extern StructRNA RNA_Event;
extern StructRNA RNA_ExplodeModifier;
extern StructRNA RNA_ExpressionController;
+extern StructRNA RNA_FaceMap;
extern StructRNA RNA_FCurve;
extern StructRNA RNA_FCurveSample;
extern StructRNA RNA_FFmpegSettings;
@@ -317,6 +319,8 @@ extern StructRNA RNA_LaplacianSmoothModifier;
extern StructRNA RNA_Lattice;
extern StructRNA RNA_LatticeModifier;
extern StructRNA RNA_LatticePoint;
+extern StructRNA RNA_LayerCollection;
+extern StructRNA RNA_LayerCollectionOverride;
extern StructRNA RNA_Library;
extern StructRNA RNA_LimitDistanceConstraint;
extern StructRNA RNA_LimitLocationConstraint;
@@ -498,12 +502,15 @@ extern StructRNA RNA_RenderLayer;
extern StructRNA RNA_RenderPass;
extern StructRNA RNA_RenderResult;
extern StructRNA RNA_RenderSettings;
+extern StructRNA RNA_RenderEngineSettings;
+extern StructRNA RNA_RenderEngineSettingsClay;
extern StructRNA RNA_RigidBodyWorld;
extern StructRNA RNA_RigidBodyObject;
extern StructRNA RNA_RigidBodyJointConstraint;
extern StructRNA RNA_SPHFluidSettings;
extern StructRNA RNA_Scene;
extern StructRNA RNA_SceneGameData;
+extern StructRNA RNA_SceneLayer;
extern StructRNA RNA_SceneRenderLayer;
extern StructRNA RNA_SceneSequence;
extern StructRNA RNA_SceneObjects;
@@ -745,7 +752,7 @@ const char *RNA_struct_ui_description_raw(const StructRNA *type);
const char *RNA_struct_translation_context(const StructRNA *type);
int RNA_struct_ui_icon(const StructRNA *type);
-PropertyRNA *RNA_struct_name_property(StructRNA *type);
+PropertyRNA *RNA_struct_name_property(const StructRNA *type);
PropertyRNA *RNA_struct_iterator_property(StructRNA *type);
StructRNA *RNA_struct_base(StructRNA *type);
@@ -1185,7 +1192,7 @@ int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *re
/* ID */
-short RNA_type_to_ID_code(StructRNA *type);
+short RNA_type_to_ID_code(const StructRNA *type);
StructRNA *ID_code_to_RNA_type(short idcode);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 6e62313b00a..54938b236d5 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -37,6 +37,14 @@
extern "C" {
#endif
+#ifdef UNIT_TEST
+#define RNA_MAX_ARRAY_LENGTH 64
+#else
+#define RNA_MAX_ARRAY_LENGTH 32
+#endif
+
+#define RNA_MAX_ARRAY_DIMENSION 3
+
/* Blender RNA */
BlenderRNA *RNA_create(void);
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 1c9b3593d17..b9bb741bcde 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -61,6 +61,7 @@ extern EnumPropertyItem rna_enum_object_modifier_type_items[];
extern EnumPropertyItem rna_enum_constraint_type_items[];
extern EnumPropertyItem rna_enum_boidrule_type_items[];
extern EnumPropertyItem rna_enum_sequence_modifier_type_items[];
+extern EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[];
extern EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[];
extern EnumPropertyItem rna_enum_modifier_triangulate_ngon_method_items[];
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index cd04f9e8a6d..99ef0f9c8c4 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -282,6 +282,7 @@ typedef struct CollectionPropertyIterator {
union {
ArrayIterator array;
ListBaseIterator listbase;
+ void *custom;
} internal;
int idprop;
int level;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 6a08d762920..020c3a755c1 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -189,6 +189,10 @@ if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
+if(WITH_CLAY_ENGINE)
+ add_definitions(-DWITH_CLAY_ENGINE)
+endif()
+
if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
@@ -338,6 +342,7 @@ blender_include_dirs(
../../bmesh
../../blentranslation
../../depsgraph
+ ../../draw
../../gpu
../../imbuf
../../ikplugin
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index a74758a4f71..4291e5b63ae 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -136,7 +136,7 @@ static int rna_ID_name_editable(PointerRNA *ptr, const char **UNUSED(r_info))
return PROP_EDITABLE;
}
-short RNA_type_to_ID_code(StructRNA *type)
+short RNA_type_to_ID_code(const StructRNA *type)
{
if (RNA_struct_is_a(type, &RNA_Action)) return ID_AC;
if (RNA_struct_is_a(type, &RNA_Armature)) return ID_AR;
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index a299302f04f..facb7116b67 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -560,7 +560,7 @@ const char *RNA_struct_translation_context(const StructRNA *type)
return type->translation_context;
}
-PropertyRNA *RNA_struct_name_property(StructRNA *type)
+PropertyRNA *RNA_struct_name_property(const StructRNA *type)
{
return type->nameproperty;
}
@@ -1799,7 +1799,7 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
* parts of the code that need it still, so we have this exception */
if (prop->flag & PROP_CONTEXT_UPDATE) {
if (C) {
- if (prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
+ if ((prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) == PROP_CONTEXT_PROPERTY_UPDATE) {
((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
}
else {
@@ -2765,6 +2765,9 @@ char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
int length;
BLI_assert(RNA_property_type(prop) == PROP_STRING);
+ if (!ptr->data) {
+ return NULL;
+ }
length = RNA_property_string_length(ptr, prop);
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index ac348c1750c..1948f425083 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -360,17 +360,23 @@ static void rna_Brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
/*WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL); */
}
-static void rna_Brush_main_tex_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Brush_main_tex_update(bContext *C, PointerRNA *ptr)
{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Brush *br = (Brush *)ptr->data;
- BKE_paint_invalidate_overlay_tex(scene, br->mtex.tex);
+ BKE_paint_invalidate_overlay_tex(scene, sl, br->mtex.tex);
rna_Brush_update(bmain, scene, ptr);
}
-static void rna_Brush_secondary_tex_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Brush_secondary_tex_update(bContext *C, PointerRNA *ptr)
{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
Brush *br = (Brush *)ptr->data;
- BKE_paint_invalidate_overlay_tex(scene, br->mask_mtex.tex);
+ BKE_paint_invalidate_overlay_tex(scene, sl, br->mask_mtex.tex);
rna_Brush_update(bmain, scene, ptr);
}
@@ -426,14 +432,17 @@ static void rna_Brush_icon_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poi
WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
}
-static void rna_TextureSlot_brush_angle_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_TextureSlot_brush_angle_update(bContext *C, PointerRNA *ptr)
{
+ Scene *scene = CTX_data_scene(C);
MTex *mtex = ptr->data;
/* skip invalidation of overlay for stencil mode */
- if (mtex->mapping != MTEX_MAP_MODE_STENCIL)
- BKE_paint_invalidate_overlay_tex(scene, mtex->tex);
+ if (mtex->mapping != MTEX_MAP_MODE_STENCIL) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ BKE_paint_invalidate_overlay_tex(scene, sl, mtex->tex);
+ }
- rna_TextureSlot_update(bmain, scene, ptr);
+ rna_TextureSlot_update(C, ptr);
}
static void rna_Brush_set_size(PointerRNA *ptr, int value)
@@ -647,39 +656,46 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "rot");
RNA_def_property_range(prop, 0, M_PI * 2);
RNA_def_property_ui_text(prop, "Angle", "Brush texture rotation");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_brush_angle_update");
prop = RNA_def_property(srna, "map_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode");
RNA_def_property_enum_items(prop, prop_map_mode_items);
RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "tex_paint_map_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode");
RNA_def_property_enum_items(prop, prop_tex_paint_map_mode_items);
RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "mask_map_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode");
RNA_def_property_enum_items(prop, prop_mask_paint_map_mode_items);
RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "use_rake", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "brush_angle_mode", MTEX_ANGLE_RAKE);
RNA_def_property_ui_text(prop, "Rake", "");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "use_random", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "brush_angle_mode", MTEX_ANGLE_RANDOM);
RNA_def_property_ui_text(prop, "Random", "");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "random_angle", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_range(prop, 0, M_PI * 2);
RNA_def_property_ui_text(prop, "Random Angle", "Brush texture random angle");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
TEXTURE_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
@@ -1338,7 +1354,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mtex.tex");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Texture", "");
RNA_def_property_update(prop, NC_TEXTURE, "rna_Brush_main_tex_update");
@@ -1350,7 +1366,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "mask_texture", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_mtex.tex");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Mask Texture", "");
RNA_def_property_update(prop, NC_TEXTURE, "rna_Brush_secondary_tex_update");
diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c
index 09fdeb15b10..a3b1d584ef5 100644
--- a/source/blender/makesrna/intern/rna_cachefile.c
+++ b/source/blender/makesrna/intern/rna_cachefile.c
@@ -63,7 +63,7 @@ static void rna_CacheFile_update_handle(Main *bmain, Scene *scene, PointerRNA *p
CacheFile *cache_file = ptr->data;
if ((cache_file->flag & CACHEFILE_DIRTY) != 0) {
- BKE_cachefile_clean(scene, cache_file);
+ BKE_cachefile_clean(bmain, cache_file);
BLI_freelistN(&cache_file->object_paths);
cache_file->flag &= ~CACHEFILE_DIRTY;
}
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index d7a679e9702..360bd5691cd 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -101,12 +101,38 @@ static PointerRNA rna_Context_main_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_BlendData, CTX_data_main(C));
}
+static PointerRNA rna_Context_depsgraph_get(PointerRNA *ptr)
+{
+ bContext *C = (bContext *)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Depsgraph, CTX_data_depsgraph(C));
+}
+
static PointerRNA rna_Context_scene_get(PointerRNA *ptr)
{
bContext *C = (bContext *)ptr->data;
return rna_pointer_inherit_refine(ptr, &RNA_Scene, CTX_data_scene(C));
}
+static PointerRNA rna_Context_scene_layer_get(PointerRNA *ptr)
+{
+ bContext *C = (bContext *)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, CTX_data_scene_layer(C));
+}
+
+static PointerRNA rna_Context_scene_collection_get(PointerRNA *ptr)
+{
+ bContext *C = (bContext *)ptr->data;
+ ptr->id.data = CTX_data_scene(C);
+ return rna_pointer_inherit_refine(ptr, &RNA_SceneCollection, CTX_data_scene_collection(C));
+}
+
+static PointerRNA rna_Context_layer_collection_get(PointerRNA *ptr)
+{
+ bContext *C = (bContext *)ptr->data;
+ ptr->id.data = CTX_data_scene(C);
+ return rna_pointer_inherit_refine(ptr, &RNA_LayerCollection, CTX_data_layer_collection(C));
+}
+
static PointerRNA rna_Context_tool_settings_get(PointerRNA *ptr)
{
bContext *C = (bContext *)ptr->data;
@@ -198,11 +224,31 @@ void RNA_def_context(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "BlendData");
RNA_def_property_pointer_funcs(prop, "rna_Context_main_get", NULL, NULL, NULL);
+ prop = RNA_def_property(srna, "depsgraph", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Depsgraph");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_depsgraph_get", NULL, NULL, NULL);
+
prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Scene");
RNA_def_property_pointer_funcs(prop, "rna_Context_scene_get", NULL, NULL, NULL);
+ prop = RNA_def_property(srna, "render_layer", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "SceneLayer");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_scene_layer_get", NULL, NULL, NULL);
+
+ prop = RNA_def_property(srna, "scene_collection", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "SceneCollection");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_scene_collection_get", NULL, NULL, NULL);
+
+ prop = RNA_def_property(srna, "layer_collection", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "LayerCollection");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_layer_collection_get", NULL, NULL, NULL);
+
prop = RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "ToolSettings");
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index 2748bd8b877..d90f754bf23 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -40,9 +40,14 @@
#ifdef RNA_RUNTIME
+#include "BLI_iterator.h"
#include "BKE_report.h"
+#include "DNA_object_types.h"
#include "DEG_depsgraph_debug.h"
+#include "DEG_depsgraph_query.h"
+
+#include "MEM_guardedalloc.h"
static void rna_Depsgraph_debug_graphviz(Depsgraph *graph, const char *filename)
{
@@ -79,6 +84,32 @@ static void rna_Depsgraph_debug_stats(Depsgraph *graph, ReportList *reports)
ops, rels, outer);
}
+static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Depsgraph *graph = (Depsgraph *)ptr->data;
+ iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
+ DEG_objects_iterator_begin(iter->internal.custom, graph);
+ iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
+}
+
+static void rna_Depsgraph_objects_next(CollectionPropertyIterator *iter)
+{
+ DEG_objects_iterator_next(iter->internal.custom);
+ iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
+}
+
+static void rna_Depsgraph_objects_end(CollectionPropertyIterator *iter)
+{
+ DEG_objects_iterator_end(iter->internal.custom);
+ MEM_freeN(iter->internal.custom);
+}
+
+static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter)
+{
+ Object *ob = ((BLI_Iterator *)iter->internal.custom)->current;
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ob);
+}
+
#else
static void rna_def_depsgraph(BlenderRNA *brna)
@@ -86,6 +117,7 @@ static void rna_def_depsgraph(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
+ PropertyRNA *prop;
srna = RNA_def_struct(brna, "Depsgraph", NULL);
RNA_def_struct_ui_text(srna, "Dependency Graph", "");
@@ -101,6 +133,12 @@ static void rna_def_depsgraph(BlenderRNA *brna)
func = RNA_def_function(srna, "debug_stats", "rna_Depsgraph_debug_stats");
RNA_def_function_ui_description(func, "Report the number of elements in the Dependency Graph");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
+
+ prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_collection_funcs(prop, "rna_Depsgraph_objects_begin", "rna_Depsgraph_objects_next",
+ "rna_Depsgraph_objects_end", "rna_Depsgraph_objects_get",
+ NULL, NULL, NULL, NULL);
}
void RNA_def_depsgraph(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index aa02a3c159d..2a5a0011279 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -53,9 +53,9 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((GroupObject *)internal->link)->ob);
}
-static void rna_Group_objects_link(Group *group, bContext *C, ReportList *reports, Object *object)
+static void rna_Group_objects_link(Group *group, ReportList *reports, Object *object)
{
- if (!BKE_group_object_add(group, object, CTX_data_scene(C), NULL)) {
+ if (!BKE_group_object_add(group, object)) {
BKE_reportf(reports, RPT_ERROR, "Object '%s' already in group '%s'", object->id.name + 2, group->id.name + 2);
return;
}
@@ -63,9 +63,9 @@ static void rna_Group_objects_link(Group *group, bContext *C, ReportList *report
WM_main_add_notifier(NC_OBJECT | ND_DRAW, &object->id);
}
-static void rna_Group_objects_unlink(Group *group, bContext *C, ReportList *reports, Object *object)
+static void rna_Group_objects_unlink(Group *group, ReportList *reports, Object *object)
{
- if (!BKE_group_object_unlink(group, object, CTX_data_scene(C), NULL)) {
+ if (!BKE_group_object_unlink(group, object)) {
BKE_reportf(reports, RPT_ERROR, "Object '%s' not in group '%s'", object->id.name + 2, group->id.name + 2);
return;
}
@@ -91,7 +91,7 @@ static void rna_def_group_objects(BlenderRNA *brna, PropertyRNA *cprop)
/* add object */
func = RNA_def_function(srna, "link", "rna_Group_objects_link");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Add this object to a group");
/* object to add */
parm = RNA_def_pointer(func, "object", "Object", "", "Object to add");
@@ -100,7 +100,7 @@ static void rna_def_group_objects(BlenderRNA *brna, PropertyRNA *cprop)
/* remove object */
func = RNA_def_function(srna, "unlink", "rna_Group_objects_unlink");
RNA_def_function_ui_description(func, "Remove this object to a group");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
/* object to remove */
parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 344c1781b46..936674a1e96 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -56,9 +56,6 @@
#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
-#include "GPU_draw.h"
-#include "GPU_debug.h"
-
#include "DNA_image_types.h"
#include "DNA_scene_types.h"
@@ -251,6 +248,8 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int f
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLint)filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLint)mag);
+ /* TODO(merwin): validate input (dimensions, filter, mag) before calling OpenGL
+ * instead of trusting input & testing for error after */
error = glGetError();
if (error) {
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index dfd5af788f6..75fc9a17b07 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -236,7 +236,7 @@ int rna_object_shapekey_index_set(struct ID *id, PointerRNA value, int current);
/* named internal so as not to conflict with obj.update() rna func */
void rna_Object_internal_update_data(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
void rna_Mesh_update_draw(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
-void rna_TextureSlot_update(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
+void rna_TextureSlot_update(struct bContext *C, struct PointerRNA *ptr);
/* basic poll functions for object types */
int rna_Armature_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
@@ -279,7 +279,7 @@ void RNA_api_material(StructRNA *srna);
void RNA_api_mesh(struct StructRNA *srna);
void RNA_api_meta(struct StructRNA *srna);
void RNA_api_object(struct StructRNA *srna);
-void RNA_api_object_base(struct StructRNA *srna);
+void RNA_api_object_base_legacy(struct StructRNA *srna);
void RNA_api_pose(struct StructRNA *srna);
void RNA_api_pose_channel(struct StructRNA *srna);
void RNA_api_scene(struct StructRNA *srna);
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index df591659fdb..c412d110e5e 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -45,15 +45,6 @@ struct GHash;
struct Main;
struct Scene;
-#ifdef UNIT_TEST
-#define RNA_MAX_ARRAY_LENGTH 64
-#else
-#define RNA_MAX_ARRAY_LENGTH 32
-#endif
-
-#define RNA_MAX_ARRAY_DIMENSION 3
-
-
/* store local properties here */
#define RNA_IDP_UI "_RNA_UI"
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index c110dbff6c4..244820f5a49 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -1587,6 +1587,7 @@ void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Main_particles_is_updated_get", NULL);
}
+
void RNA_def_main_palettes(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index b293f20dd95..8779d2b65e7 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1887,6 +1887,12 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Light Group", "Limit lighting to lamps in this Group");
RNA_def_property_update(prop, 0, "rna_Material_update");
+ prop = RNA_def_property(srna, "edit_image", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "edit_image");
+ RNA_def_property_struct_type(prop, "Image");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Edit Image", "Image to use for UV-mapping");
+
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "index");
RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Material Index\" render pass");
@@ -1964,18 +1970,6 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shadow Type", "How to draw shadows");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop = RNA_def_property(srna, "use_face_texture", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE);
- RNA_def_property_ui_text(prop, "Face Textures",
- "Replace the object's base color with color from UV map image textures");
- RNA_def_property_update(prop, 0, "rna_Material_update");
-
- prop = RNA_def_property(srna, "use_face_texture_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE_ALPHA);
- RNA_def_property_ui_text(prop, "Face Textures Alpha",
- "Replace the object's base alpha value with alpha from UV map image textures");
- RNA_def_property_update(prop, 0, "rna_Material_update");
-
prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode2", MA_CASTSHADOW);
RNA_def_property_ui_text(prop, "Cast Shadows",
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index ad5f320625c..004c6f4c5f5 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -237,6 +237,20 @@ static void rna_Mesh_update_data_edit_color(Main *bmain, Scene *scene, PointerRN
}
}
+static void rna_Mesh_update_data_edit_weight(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ BKE_mesh_batch_cache_dirty(rna_mesh(ptr), BKE_MESH_BATCH_DIRTY_PAINT);
+
+ rna_Mesh_update_data(bmain, scene, ptr);
+}
+
+
+static void rna_Mesh_update_data_edit_active_color(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ BKE_mesh_batch_cache_dirty(rna_mesh(ptr), BKE_MESH_BATCH_DIRTY_PAINT);
+
+ rna_Mesh_update_data(bmain, scene, ptr);
+}
static void rna_Mesh_update_select(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
@@ -262,6 +276,9 @@ static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
me->editflag &= ~ME_EDIT_PAINT_FACE_SEL;
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_PAINT);
+
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -271,6 +288,9 @@ static void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr)
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
me->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_PAINT);
+
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -747,13 +767,6 @@ static void rna_CustomDataLayer_active_set(PointerRNA *ptr, CustomData *data, in
if (render) CustomData_set_layer_render(data, type, n);
else CustomData_set_layer_active(data, type, n);
- /* sync loop layer */
- if (type == CD_MTEXPOLY) {
- CustomData *ldata = rna_mesh_ldata(ptr);
- if (render) CustomData_set_layer_render(ldata, CD_MLOOPUV, n);
- else CustomData_set_layer_active(ldata, CD_MLOOPUV, n);
- }
-
BKE_mesh_update_customdata_pointers(me, true);
}
@@ -858,6 +871,36 @@ static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr)
return (me->edit_btmesh) ? 0 : me->totloop;
}
+static int rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr)
+{
+ return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV, 1);
+}
+
+static int rna_MeshUVLoopLayer_active_get(PointerRNA *ptr)
+{
+ return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV, 0);
+}
+
+static int rna_MeshUVLoopLayer_clone_get(PointerRNA *ptr)
+{
+ return rna_CustomDataLayer_clone_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV);
+}
+
+static void rna_MeshUVLoopLayer_active_render_set(PointerRNA *ptr, int value)
+{
+ rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV, 1);
+}
+
+static void rna_MeshUVLoopLayer_active_set(PointerRNA *ptr, int value)
+{
+ rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV, 0);
+}
+
+static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, int value)
+{
+ rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV);
+}
+
/* face uv_textures */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(tessface_uv_texture, fdata, CD_MTFACE)
@@ -909,57 +952,6 @@ static void rna_MeshTextureFaceLayer_clone_set(PointerRNA *ptr, int value)
rna_CustomDataLayer_clone_set(ptr, rna_mesh_fdata(ptr), value, CD_MTFACE);
}
-/* poly uv_textures */
-
-DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_texture, pdata, CD_MTEXPOLY)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_texture, pdata, CD_MTEXPOLY, active, MeshTexturePolyLayer)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_texture, pdata, CD_MTEXPOLY, clone, MeshTexturePolyLayer)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_texture, pdata, CD_MTEXPOLY, stencil, MeshTexturePolyLayer)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_texture, pdata, CD_MTEXPOLY, render, MeshTexturePolyLayer)
-
-static void rna_MeshTexturePolyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
- rna_iterator_array_begin(iter, layer->data, sizeof(MTexPoly), (me->edit_btmesh) ? 0 : me->totpoly, 0, NULL);
-}
-
-static int rna_MeshTexturePolyLayer_data_length(PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- return (me->edit_btmesh) ? 0 : me->totpoly;
-}
-
-static int rna_MeshTexturePolyLayer_active_render_get(PointerRNA *ptr)
-{
- return rna_CustomDataLayer_active_get(ptr, rna_mesh_pdata(ptr), CD_MTEXPOLY, 1);
-}
-
-static int rna_MeshTexturePolyLayer_active_get(PointerRNA *ptr)
-{
- return rna_CustomDataLayer_active_get(ptr, rna_mesh_pdata(ptr), CD_MTEXPOLY, 0);
-}
-
-static int rna_MeshTexturePolyLayer_clone_get(PointerRNA *ptr)
-{
- return rna_CustomDataLayer_clone_get(ptr, rna_mesh_pdata(ptr), CD_MTEXPOLY);
-}
-
-static void rna_MeshTexturePolyLayer_active_render_set(PointerRNA *ptr, int value)
-{
- rna_CustomDataLayer_active_set(ptr, rna_mesh_pdata(ptr), value, CD_MTEXPOLY, 1);
-}
-
-static void rna_MeshTexturePolyLayer_active_set(PointerRNA *ptr, int value)
-{
- rna_CustomDataLayer_active_set(ptr, rna_mesh_pdata(ptr), value, CD_MTEXPOLY, 0);
-}
-
-static void rna_MeshTexturePolyLayer_clone_set(PointerRNA *ptr, int value)
-{
- rna_CustomDataLayer_clone_set(ptr, rna_mesh_pdata(ptr), value, CD_MTEXPOLY);
-}
-
/* vertex_color_layers */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(tessface_vertex_color, fdata, CD_MCOL)
@@ -1183,42 +1175,6 @@ static int rna_MeshPaintMaskLayer_data_length(PointerRNA *ptr)
/* End paint mask */
-static void rna_TexturePoly_image_set(PointerRNA *ptr, PointerRNA value)
-{
- MTexPoly *tf = (MTexPoly *)ptr->data;
- ID *id = value.data;
-
- if (id) {
- /* special exception here, individual faces don't count
- * as reference, but we do ensure the refcount is not zero */
- if (id->us == 0)
- id_us_plus(id);
- else
- id_lib_extern(id);
- }
-
- tf->tpage = (struct Image *)id;
-}
-
-/* while this is supposed to be readonly,
- * keep it to support importers that only make tessfaces */
-static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value)
-{
- MTFace *tf = (MTFace *)ptr->data;
- ID *id = value.data;
-
- if (id) {
- /* special exception here, individual faces don't count
- * as reference, but we do ensure the refcount is not zero */
- if (id->us == 0)
- id_us_plus(id);
- else
- id_lib_extern(id);
- }
-
- tf->tpage = (struct Image *)id;
-}
-
static int rna_MeshTessFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
MFace *face = (MFace *)ptr->data;
@@ -1369,14 +1325,6 @@ static char *rna_MeshTextureFaceLayer_path(PointerRNA *ptr)
return BLI_sprintfN("tessface_uv_textures[\"%s\"]", name_esc);
}
-static char *rna_MeshTexturePolyLayer_path(PointerRNA *ptr)
-{
- CustomDataLayer *cdl = ptr->data;
- char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
- return BLI_sprintfN("uv_textures[\"%s\"]", name_esc);
-}
-
static char *rna_VertCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
@@ -1472,11 +1420,6 @@ static char *rna_MeshTextureFace_path(PointerRNA *ptr)
return rna_FaceCustomData_data_path(ptr, "tessface_uv_textures", CD_MTFACE);
}
-static char *rna_MeshTexturePoly_path(PointerRNA *ptr)
-{
- return rna_PolyCustomData_data_path(ptr, "uv_textures", CD_MTEXPOLY);
-}
-
static char *rna_MeshColorLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
@@ -1757,23 +1700,23 @@ DEFINE_CUSTOMDATA_PROPERTY_API(polygon, int, CD_PROP_INT, pdata, totpoly, MeshPo
DEFINE_CUSTOMDATA_PROPERTY_API(polygon, string, CD_PROP_STR, pdata, totpoly, MeshPolygonStringPropertyLayer)
#undef DEFINE_CUSTOMDATA_PROPERTY_API
-static PointerRNA rna_Mesh_uv_texture_new(struct Mesh *me, const char *name)
+static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me, const char *name)
{
PointerRNA ptr;
- CustomData *pdata;
+ CustomData *ldata;
CustomDataLayer *cdl = NULL;
int index = ED_mesh_uv_texture_add(me, name, false);
if (index != -1) {
- pdata = rna_mesh_pdata_helper(me);
- cdl = &pdata->layers[CustomData_get_layer_index_n(pdata, CD_MTEXPOLY, index)];
+ ldata = rna_mesh_ldata_helper(me);
+ cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_MLOOPUV, index)];
}
- RNA_pointer_create(&me->id, &RNA_MeshTexturePolyLayer, cdl, &ptr);
+ RNA_pointer_create(&me->id, &RNA_MeshUVLoopLayer, cdl, &ptr);
return ptr;
}
-static void rna_Mesh_uv_texture_layers_remove(struct Mesh *me, ReportList *reports, CustomDataLayer *layer)
+static void rna_Mesh_uv_layers_remove(struct Mesh *me, ReportList *reports, CustomDataLayer *layer)
{
if (ED_mesh_uv_texture_remove_named(me, layer->name) == false) {
BKE_reportf(reports, RPT_ERROR, "Texture layer '%s' not found", layer->name);
@@ -1848,10 +1791,6 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void)
(void)rna_Mesh_uv_layer_render_index_get;
(void)rna_Mesh_uv_layer_render_index_set;
(void)rna_Mesh_uv_layer_render_set;
- (void)rna_Mesh_uv_texture_render_get;
- (void)rna_Mesh_uv_texture_render_index_get;
- (void)rna_Mesh_uv_texture_render_index_set;
- (void)rna_Mesh_uv_texture_render_set;
(void)rna_Mesh_vertex_color_render_get;
(void)rna_Mesh_vertex_color_render_index_get;
(void)rna_Mesh_vertex_color_render_index_set;
@@ -1883,7 +1822,7 @@ static void rna_def_mvert_group(BlenderRNA *brna)
prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Weight", "Vertex Weight");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_weight");
}
static void rna_def_mvert(BlenderRNA *brna)
@@ -2253,6 +2192,24 @@ static void rna_def_mloopuv(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "Name of UV map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoopLayer_active_get", "rna_MeshUVLoopLayer_active_set");
+ RNA_def_property_ui_text(prop, "Active", "Set the map as active for display and editing");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+ prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoopLayer_active_render_get",
+ "rna_MeshUVLoopLayer_active_render_set");
+ RNA_def_property_ui_text(prop, "Active Render", "Set the map as active for rendering");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+ prop = RNA_def_property(srna, "active_clone", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "active_clone", 0);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoopLayer_clone_get", "rna_MeshUVLoopLayer_clone_set");
+ RNA_def_property_ui_text(prop, "Active Clone", "Set the map as active for cloning");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
srna = RNA_def_struct(brna, "MeshUVLoop", NULL);
RNA_def_struct_sdna(srna, "MLoopUV");
RNA_def_struct_path_func(srna, "rna_MeshUVLoop_path");
@@ -2322,13 +2279,6 @@ static void rna_def_mtface(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_MeshTextureFace_path");
RNA_def_struct_ui_icon(srna, ICON_FACESEL_HLT);
- prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tpage");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_TextureFace_image_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Image", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
/* these are for editing only, access at loops now */
#if 0
prop = RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE);
@@ -2383,84 +2333,6 @@ static void rna_def_mtface(BlenderRNA *brna)
}
-static void rna_def_mtexpoly(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-#if 0 /* BMESH_TODO: needed later when do another todo */
- int uv_dim[] = {4, 2};
-#endif
-
- srna = RNA_def_struct(brna, "MeshTexturePolyLayer", NULL);
- RNA_def_struct_ui_text(srna, "Mesh UV Map", "UV map with assigned image textures in a Mesh data-block");
- RNA_def_struct_sdna(srna, "CustomDataLayer");
- RNA_def_struct_path_func(srna, "rna_MeshTexturePolyLayer_path");
- RNA_def_struct_ui_icon(srna, ICON_GROUP_UVS);
-
- prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
- RNA_def_property_ui_text(prop, "Name", "Name of UV map");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_MeshTexturePolyLayer_active_get", "rna_MeshTexturePolyLayer_active_set");
- RNA_def_property_ui_text(prop, "Active", "Set the map as active for display and editing");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0);
- RNA_def_property_boolean_funcs(prop, "rna_MeshTexturePolyLayer_active_render_get",
- "rna_MeshTexturePolyLayer_active_render_set");
- RNA_def_property_ui_text(prop, "Active Render", "Set the map as active for rendering");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "active_clone", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "active_clone", 0);
- RNA_def_property_boolean_funcs(prop, "rna_MeshTexturePolyLayer_clone_get", "rna_MeshTexturePolyLayer_clone_set");
- RNA_def_property_ui_text(prop, "Active Clone", "Set the map as active for cloning");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshTexturePoly");
- RNA_def_property_ui_text(prop, "Data", "");
- RNA_def_property_collection_funcs(prop, "rna_MeshTexturePolyLayer_data_begin", "rna_iterator_array_next",
- "rna_iterator_array_end", "rna_iterator_array_get",
- "rna_MeshTexturePolyLayer_data_length", NULL, NULL, NULL);
-
- srna = RNA_def_struct(brna, "MeshTexturePoly", NULL);
- RNA_def_struct_sdna(srna, "MTexPoly");
- RNA_def_struct_ui_text(srna, "Mesh UV Map Face", "UV map and image texture for a face");
- RNA_def_struct_path_func(srna, "rna_MeshTexturePoly_path");
- RNA_def_struct_ui_icon(srna, ICON_FACESEL_HLT);
-
- prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tpage");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_TexturePoly_image_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Image", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
-#if 0 /* moved to MeshUVLoopLayer */
- prop = RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TF_SEL1);
- RNA_def_property_array(prop, 4);
- RNA_def_property_ui_text(prop, "UV Selected", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
-
- prop = RNA_def_property(srna, "pin_uv", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "unwrap", TF_PIN1);
- RNA_def_property_array(prop, 4);
- RNA_def_property_ui_text(prop, "UV Pinned", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
-
- prop = RNA_def_property(srna, "uv_raw", PROP_FLOAT, PROP_NONE);
- RNA_def_property_multi_array(prop, 2, uv_dim);
- RNA_def_property_float_sdna(prop, NULL, "uv");
- RNA_def_property_ui_text(prop, "UV", "Fixed size UV coordinates array");
-#endif
-}
-
static void rna_def_mcol(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2927,13 +2799,13 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Mesh_vertex_color_active_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color");
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_vertex_color_active_index_get",
"rna_Mesh_vertex_color_active_index_set", "rna_Mesh_vertex_color_index_range");
RNA_def_property_ui_text(prop, "Active Vertex Color Index", "Active vertex color index");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color");
}
static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
@@ -2941,14 +2813,27 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
StructRNA *srna;
PropertyRNA *prop;
- /* FunctionRNA *func; */
- /* PropertyRNA *parm; */
+ FunctionRNA *func;
+ PropertyRNA *parm;
RNA_def_property_srna(cprop, "UVLoopLayers");
srna = RNA_def_struct(brna, "UVLoopLayers", NULL);
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "UV Loop Layers", "Collection of uv loop layers");
+ func = RNA_def_function(srna, "new", "rna_Mesh_uv_layers_new");
+ RNA_def_function_ui_description(func, "Add a UV map layer to Mesh");
+ RNA_def_string(func, "name", "UVMap", 0, "", "UV map name");
+ parm = RNA_def_pointer(func, "layer", "MeshUVLoopLayer", "", "The newly created layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_Mesh_uv_layers_remove");
+ RNA_def_function_ui_description(func, "Remove a vertex color layer");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "layer", "MeshUVLoopLayer", "", "The layer to remove");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_active_get",
@@ -3113,7 +2998,6 @@ static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_function_return(func, parm);
-
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_uv_texture_active_get",
@@ -3123,49 +3007,7 @@ static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tessface_uv_texture_active_index_get",
- "rna_Mesh_tessface_uv_texture_active_index_set", "rna_Mesh_uv_texture_index_range");
- RNA_def_property_ui_text(prop, "Active UV Map Index", "Active UV Map index");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-}
-
-
-static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-
- FunctionRNA *func;
- PropertyRNA *parm;
-
- RNA_def_property_srna(cprop, "UVTextures");
- srna = RNA_def_struct(brna, "UVTextures", NULL);
- RNA_def_struct_sdna(srna, "Mesh");
- RNA_def_struct_ui_text(srna, "UV Maps", "Collection of UV maps");
-
- func = RNA_def_function(srna, "new", "rna_Mesh_uv_texture_new");
- RNA_def_function_ui_description(func, "Add a UV map layer to Mesh");
- RNA_def_string(func, "name", "UVMap", 0, "", "UV map name");
- parm = RNA_def_pointer(func, "layer", "MeshTexturePolyLayer", "", "The newly created layer");
- RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
- RNA_def_function_return(func, parm);
-
- func = RNA_def_function(srna, "remove", "rna_Mesh_uv_texture_layers_remove");
- RNA_def_function_ui_description(func, "Remove a vertex color layer");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_pointer(func, "layer", "MeshTexturePolyLayer", "", "The layer to remove");
- RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
-
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
- RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_active_get",
- "rna_Mesh_uv_texture_active_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
- RNA_def_property_ui_text(prop, "Active UV Map", "Active UV Map");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_funcs(prop, "rna_Mesh_uv_texture_active_index_get",
- "rna_Mesh_uv_texture_active_index_set", "rna_Mesh_uv_texture_index_range");
+ "rna_Mesh_tessface_uv_texture_active_index_set", "rna_Mesh_uv_layer_index_range");
RNA_def_property_ui_text(prop, "Active UV Map Index", "Active UV Map index");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
@@ -3337,41 +3179,6 @@ static void rna_def_mesh(BlenderRNA *brna)
"All UV maps for tessellated faces (read-only, for use by renderers)");
rna_def_tessface_uv_textures(brna, prop);
- /* UV maps */
- prop = RNA_def_property(srna, "uv_textures", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
- RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_textures_begin", NULL, NULL, NULL,
- "rna_Mesh_uv_textures_length", NULL, NULL, NULL);
- RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
- RNA_def_property_ui_text(prop, "UV Maps", "All UV maps");
- rna_def_uv_textures(brna, prop);
-
- prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
- RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_clone_get",
- "rna_Mesh_uv_texture_clone_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Clone UV Map", "UV map to be used as cloning source");
-
- prop = RNA_def_property(srna, "uv_texture_clone_index", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_funcs(prop, "rna_Mesh_uv_texture_clone_index_get",
- "rna_Mesh_uv_texture_clone_index_set", "rna_Mesh_uv_texture_index_range");
- RNA_def_property_ui_text(prop, "Clone UV Map Index", "Clone UV map index");
-
- prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
- RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_stencil_get",
- "rna_Mesh_uv_texture_stencil_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Mask UV Map", "UV map to mask the painted area");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "uv_texture_stencil_index", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_funcs(prop, "rna_Mesh_uv_texture_stencil_index_get",
- "rna_Mesh_uv_texture_stencil_index_set", "rna_Mesh_uv_texture_index_range");
- RNA_def_property_ui_text(prop, "Mask UV Map Index", "Mask UV map index");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
/* Tessellated face colors - used by renderers */
prop = RNA_def_property(srna, "tessface_vertex_colors", PROP_COLLECTION, PROP_NONE);
@@ -3712,7 +3519,6 @@ void RNA_def_mesh(BlenderRNA *brna)
rna_def_mpolygon(brna);
rna_def_mloopuv(brna);
rna_def_mtface(brna);
- rna_def_mtexpoly(brna);
rna_def_mcol(brna);
rna_def_mloopcol(brna);
rna_def_mproperties(brna);
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 9b0a25560f9..677397eb859 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -48,6 +48,7 @@
#include "DNA_mesh_types.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_tangent.h"
#include "BKE_mesh_mapping.h"
#include "ED_mesh.h"
@@ -92,7 +93,7 @@ static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *
BKE_mesh_calc_normals_split(mesh);
}
- BKE_mesh_loop_tangents(mesh, uvmap, r_looptangents, reports);
+ BKE_mesh_calc_loop_tangent_single(mesh, uvmap, r_looptangents, reports);
}
static void rna_Mesh_free_tangents(Mesh *mesh)
diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h
index 0f42596ff13..05274e13e1e 100644
--- a/source/blender/makesrna/intern/rna_mesh_utils.h
+++ b/source/blender/makesrna/intern/rna_mesh_utils.h
@@ -101,12 +101,6 @@
for (layer = data->layers + layer_index, a = 0; layer_index + a < data->totlayer; layer++, a++) { \
if (value.data == layer) { \
CustomData_set_layer_##active_type(data, layer_type, a); \
- \
- /* keep loops in sync */ \
- if (layer_type == CD_MTEXPOLY) { \
- CustomData *ldata = rna_mesh_ldata_helper(me); \
- CustomData_set_layer_##active_type(ldata, CD_MLOOPUV, a); \
- } \
BKE_mesh_update_customdata_pointers(me, true); \
return; \
} \
@@ -131,11 +125,6 @@
CustomData *data = rna_mesh_##customdata_type(ptr); \
if (data) { \
CustomData_set_layer_##active_type(data, layer_type, value); \
- /* keep loops in sync */ \
- if (layer_type == CD_MTEXPOLY) { \
- CustomData *ldata = rna_mesh_ldata_helper(me); \
- CustomData_set_layer_##active_type(ldata, CD_MLOOPUV, value); \
- } \
BKE_mesh_update_customdata_pointers(me, true); \
} \
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1a8dd05a7b5..333ff895e58 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -933,19 +933,19 @@ static EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(bConte
if (ob_src) {
DerivedMesh *dm_src;
- CustomData *pdata;
+ CustomData *ldata;
int num_data, i;
dm_src = object_get_derived_final(ob_src, false);
if (dm_src != NULL) {
- pdata = dm_src->getPolyDataLayout(dm_src);
- num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+ ldata = dm_src->getLoopDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
@@ -1024,18 +1024,18 @@ static EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf(bConte
if (ob_dst && ob_dst->data) {
Mesh *me_dst;
- CustomData *pdata;
+ CustomData *ldata;
int num_data, i;
me_dst = ob_dst->data;
- pdata = &me_dst->pdata;
- num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+ ldata = &me_dst->ldata;
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
@@ -2248,11 +2248,6 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertical Scale", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "use_image_override", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_UVPROJECT_OVERRIDEIMAGE);
- RNA_def_property_ui_text(prop, "Override Image", "Override faces' current images with the given image");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
srna = RNA_def_struct(brna, "UVProjector", NULL);
RNA_def_struct_ui_text(srna, "UVProjector", "UV projector used by the UV project modifier");
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index a167ab03ba1..7bae2d64474 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -47,6 +47,7 @@
#include "BKE_editmesh.h"
#include "BKE_group.h" /* needed for BKE_group_object_exists() */
#include "BKE_object_deform.h"
+#include "BKE_object_facemap.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -297,23 +298,14 @@ static void rna_Object_dependency_update(Main *bmain, Scene *UNUSED(scene), Poin
}
/* when changing the selection flag the scene needs updating */
-static void rna_Object_select_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
-{
- if (scene) {
- Object *ob = (Object *)ptr->id.data;
- short mode = (ob->flag & SELECT) ? BA_SELECT : BA_DESELECT;
- ED_base_object_select(BKE_scene_base_find(scene, ob), mode);
- }
-}
-
static void rna_Base_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
- Base *base = (Base *)ptr->data;
- short mode = (base->flag & BA_SELECT) ? BA_SELECT : BA_DESELECT;
+ BaseLegacy *base = (BaseLegacy *)ptr->data;
+ short mode = (base->flag_legacy & BA_SELECT) ? BA_SELECT : BA_DESELECT;
ED_base_object_select(base, mode);
}
-static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, Base *base, Object *ob)
+static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, BaseLegacy *base, Object *ob)
{
/* try to avoid scene sort */
if (scene == NULL) {
@@ -335,7 +327,7 @@ static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, Base *b
static void rna_Object_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
- Base *base;
+ BaseLegacy *base;
base = scene ? BKE_scene_base_find(scene, ob) : NULL;
if (!base)
@@ -351,7 +343,7 @@ static void rna_Object_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Base_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- Base *base = (Base *)ptr->data;
+ BaseLegacy *base = (BaseLegacy *)ptr->data;
Object *ob = (Object *)base->object;
rna_Object_layer_update__internal(bmain, scene, base, ob);
@@ -618,6 +610,87 @@ void rna_object_vgroup_name_set(PointerRNA *ptr, const char *value, char *result
result[0] = '\0';
}
+static void rna_FaceMap_name_set(PointerRNA *ptr, const char *value)
+{
+ Object *ob = (Object *)ptr->id.data;
+ bFaceMap *fmap = (bFaceMap *)ptr->data;
+ BLI_strncpy_utf8(fmap->name, value, sizeof(fmap->name));
+ BKE_object_facemap_unique_name(ob, fmap);
+}
+
+static int rna_FaceMap_index_get(PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+
+ return BLI_findindex(&ob->fmaps, ptr->data);
+}
+
+static PointerRNA rna_Object_active_face_map_get(PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+ return rna_pointer_inherit_refine(ptr, &RNA_FaceMap, BLI_findlink(&ob->fmaps, ob->actfmap - 1));
+}
+
+static int rna_Object_active_face_map_index_get(PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+ return ob->actfmap - 1;
+}
+
+static void rna_Object_active_face_map_index_set(PointerRNA *ptr, int value)
+{
+ Object *ob = (Object *)ptr->id.data;
+ ob->actfmap = value + 1;
+}
+
+static void rna_Object_active_face_map_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ Object *ob = (Object *)ptr->id.data;
+
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&ob->fmaps) - 1);
+}
+
+void rna_object_BKE_object_facemap_name_index_get(PointerRNA *ptr, char *value, int index)
+{
+ Object *ob = (Object *)ptr->id.data;
+ bFaceMap *fmap;
+
+ fmap = BLI_findlink(&ob->fmaps, index - 1);
+
+ if (fmap) BLI_strncpy(value, fmap->name, sizeof(fmap->name));
+ else value[0] = '\0';
+}
+
+int rna_object_BKE_object_facemap_name_index_length(PointerRNA *ptr, int index)
+{
+ Object *ob = (Object *)ptr->id.data;
+ bFaceMap *fmap;
+
+ fmap = BLI_findlink(&ob->fmaps, index - 1);
+ return (fmap) ? strlen(fmap->name) : 0;
+}
+
+void rna_object_BKE_object_facemap_name_index_set(PointerRNA *ptr, const char *value, short *index)
+{
+ Object *ob = (Object *)ptr->id.data;
+ *index = BKE_object_facemap_name_index(ob, value) + 1;
+}
+
+void rna_object_fmap_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen)
+{
+ Object *ob = (Object *)ptr->id.data;
+ bFaceMap *fmap = BKE_object_facemap_find_name(ob, value);
+ if (fmap) {
+ BLI_strncpy(result, value, maxlen); /* no need for BLI_strncpy_utf8, since this matches an existing group */
+ return;
+ }
+
+ result[0] = '\0';
+}
+
+
void rna_object_uvlayer_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen)
{
Object *ob = (Object *)ptr->id.data;
@@ -628,10 +701,10 @@ void rna_object_uvlayer_name_set(PointerRNA *ptr, const char *value, char *resul
if (ob->type == OB_MESH && ob->data) {
me = (Mesh *)ob->data;
- for (a = 0; a < me->pdata.totlayer; a++) {
- layer = &me->pdata.layers[a];
+ for (a = 0; a < me->ldata.totlayer; a++) {
+ layer = &me->ldata.layers[a];
- if (layer->type == CD_MTEXPOLY && STREQ(layer->name, value)) {
+ if (layer->type == CD_MLOOPUV && STREQ(layer->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
@@ -1117,7 +1190,7 @@ static void rna_Object_layer_set(PointerRNA *ptr, const int *values)
static void rna_Base_layer_set(PointerRNA *ptr, const int *values)
{
- Base *base = (Base *)ptr->data;
+ BaseLegacy *base = (BaseLegacy *)ptr->data;
unsigned int lay;
lay = rna_Object_layer_validate__internal(values, base->lay);
@@ -1462,6 +1535,69 @@ static float rna_VertexGroup_weight(ID *id, bDeformGroup *dg, ReportList *report
return weight;
}
+static bFaceMap *rna_Object_fmap_new(Object *ob, const char *name)
+{
+ bFaceMap *fmap = BKE_object_facemap_add_name(ob, name);
+
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
+
+ return fmap;
+}
+
+static void rna_Object_fmap_remove(Object *ob, ReportList *reports, PointerRNA *fmap_ptr)
+{
+ bFaceMap *fmap = fmap_ptr->data;
+ if (BLI_findindex(&ob->fmaps, fmap) == -1) {
+ BKE_reportf(reports, RPT_ERROR, "FaceMap '%s' not in object '%s'", fmap->name, ob->id.name + 2);
+ return;
+ }
+
+ BKE_object_facemap_remove(ob, fmap);
+ RNA_POINTER_INVALIDATE(fmap_ptr);
+
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
+}
+
+
+static void rna_Object_fmap_clear(Object *ob)
+{
+ BKE_object_facemap_clear(ob);
+
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
+}
+
+
+static void rna_FaceMap_face_add(ID *id, bFaceMap *fmap, ReportList *reports, int index_len,
+ int *index)
+{
+ Object *ob = (Object *)id;
+
+ if (BKE_object_is_in_editmode(ob)) {
+ BKE_report(reports, RPT_ERROR, "FaceMap.add(): cannot be called while object is in edit mode");
+ return;
+ }
+
+ while (index_len--)
+ ED_object_facemap_face_add(ob, fmap, *index++);
+
+ WM_main_add_notifier(NC_GEOM | ND_DATA, (ID *)ob->data);
+}
+
+static void rna_FaceMap_face_remove(ID *id, bFaceMap *fmap, ReportList *reports, int index_len, int *index)
+{
+ Object *ob = (Object *)id;
+
+ if (BKE_object_is_in_editmode(ob)) {
+ BKE_report(reports, RPT_ERROR, "FaceMap.add(): cannot be called while object is in edit mode");
+ return;
+ }
+
+ while (index_len--)
+ ED_object_facemap_face_remove(ob, fmap, *index++);
+
+ WM_main_add_notifier(NC_GEOM | ND_DATA, (ID *)ob->data);
+}
+
/* generic poll functions */
int rna_Lattice_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
@@ -1581,6 +1717,44 @@ static void rna_def_vertex_group(BlenderRNA *brna)
RNA_def_function_return(func, parm);
}
+static void rna_def_face_map(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ FunctionRNA *func;
+
+ srna = RNA_def_struct(brna, "FaceMap", NULL);
+ RNA_def_struct_sdna(srna, "bFaceMap");
+ RNA_def_struct_ui_text(srna, "Face Map", "Group of faces, each face can only be part of one map");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_TRIANGULATE);
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Name", "Face map name");
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_FaceMap_name_set");
+ /* update data because modifiers may use [#24761] */
+ RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data");
+
+ prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_int_funcs(prop, "rna_FaceMap_index_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Index", "Index number of the face map");
+
+ func = RNA_def_function(srna, "add", "rna_FaceMap_face_add");
+ RNA_def_function_ui_description(func, "Add vertices to the group");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ prop = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List", 0, 0);
+ RNA_def_parameter_flags(prop, PROP_DYNAMIC, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "remove", "rna_FaceMap_face_remove");
+ RNA_def_function_ui_description(func, "Remove a vertex from the group");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ prop = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List", 0, 0);
+ RNA_def_parameter_flags(prop, PROP_DYNAMIC, PARM_REQUIRED);
+}
+
static void rna_def_material_slot(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2108,6 +2282,54 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
}
+/* object.face_maps */
+static void rna_def_object_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+
+ PropertyRNA *prop;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "FaceMaps");
+ srna = RNA_def_struct(brna, "FaceMaps", NULL);
+ RNA_def_struct_sdna(srna, "Object");
+ RNA_def_struct_ui_text(srna, "Face Maps", "Collection of face maps");
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "FaceMap");
+ RNA_def_property_pointer_funcs(prop, "rna_Object_active_face_map_get",
+ "rna_Object_active_face_map_set", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Active Face Map", "Face maps of the object");
+ RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
+
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "actfmap");
+ RNA_def_property_int_funcs(prop, "rna_Object_active_face_map_index_get",
+ "rna_Object_active_face_map_index_set",
+ "rna_Object_active_face_map_index_range");
+ RNA_def_property_ui_text(prop, "Active Face Map Index", "Active index in face map array");
+ RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
+
+ /* face maps */ /* add_face_map */
+ func = RNA_def_function(srna, "new", "rna_Object_fmap_new");
+ RNA_def_function_ui_description(func, "Add face map to object");
+ RNA_def_string(func, "name", "Map", 0, "", "face map name"); /* optional */
+ parm = RNA_def_pointer(func, "fmap", "FaceMap", "", "New face map");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_Object_fmap_remove");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Delete vertex group from object");
+ parm = RNA_def_pointer(func, "group", "FaceMap", "", "Face map to remove");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+
+ func = RNA_def_function(srna, "clear", "rna_Object_fmap_clear");
+ RNA_def_function_ui_description(func, "Delete all vertex groups from object");
+}
static void rna_def_object_lodlevel(BlenderRNA *brna)
{
@@ -2247,11 +2469,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Local View Layers", "3D local view layers the object is on");
- prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
- RNA_def_property_ui_text(prop, "Select", "Object selection state");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_select_update");
-
/* for data access */
prop = RNA_def_property(srna, "bound_box", PROP_FLOAT, PROP_NONE);
RNA_def_property_multi_array(prop, 2, boundbox_dimsize);
@@ -2530,6 +2747,14 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertex Groups", "Vertex groups of the object");
rna_def_object_vertex_groups(brna, prop);
+
+ /* face maps */
+ prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "fmaps", NULL);
+ RNA_def_property_struct_type(prop, "FaceMap");
+ RNA_def_property_ui_text(prop, "Face Maps", "Maps of faces of the object");
+ rna_def_object_face_maps(brna, prop);
+
/* empty */
prop = RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype");
@@ -2624,6 +2849,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
+ prop = RNA_def_property(srna, "collection_properties", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "base_collection_properties->data.group", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollectionSettings");
+ RNA_def_property_ui_text(prop, "Collection Settings",
+ "Engine specific render settings to be overridden by collections");
+
/* anim */
rna_def_animdata_common(srna);
@@ -2900,14 +3131,14 @@ static void rna_def_dupli_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this dupli object");
}
-static void rna_def_object_base(BlenderRNA *brna)
+static void rna_def_object_base_legacy(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "ObjectBase", NULL);
+ srna = RNA_def_struct(brna, "ObjectBaseLegacy", NULL);
RNA_def_struct_sdna(srna, "Base");
- RNA_def_struct_ui_text(srna, "Object Base", "An object instance in a scene");
+ RNA_def_struct_ui_text(srna, "Object Base Legacy", "An object instance in a scene (deprecated)");
RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA);
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
@@ -2927,13 +3158,13 @@ static void rna_def_object_base(BlenderRNA *brna)
RNA_def_property_array(prop, 8);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Local View Layers", "3D local view layers the object base is on");
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", BA_SELECT);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag_legacy", BA_SELECT);
RNA_def_property_ui_text(prop, "Select", "Object base selection state");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Base_select_update");
-
- RNA_api_object_base(srna);
+
+ RNA_api_object_base_legacy(srna);
}
void RNA_def_object(BlenderRNA *brna)
@@ -2942,8 +3173,9 @@ void RNA_def_object(BlenderRNA *brna)
RNA_define_animate_sdna(false);
rna_def_object_game_settings(brna);
- rna_def_object_base(brna);
+ rna_def_object_base_legacy(brna);
rna_def_vertex_group(brna);
+ rna_def_face_map(brna);
rna_def_material_slot(brna);
rna_def_dupli_object(brna);
RNA_define_animate_sdna(true);
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 9b9f0705bb4..feaf44acba0 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -40,10 +40,14 @@
#include "RNA_define.h"
#include "DNA_constraint_types.h"
+#include "DNA_layer_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
+
+#include "DEG_depsgraph.h"
#include "rna_internal.h" /* own include */
@@ -88,7 +92,61 @@ static EnumPropertyItem space_items[] = {
#include "MEM_guardedalloc.h"
-#include "DEG_depsgraph.h"
+static void rna_Object_select_set(Object *ob, bContext *C, ReportList *reports, int action)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+
+ if (!base) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, sl->name);
+ return;
+ }
+
+ if (action == 2) { /* TOGGLE */
+ if ((base->flag & BASE_SELECTED) != 0) {
+ action = 1; /* DESELECT */
+ }
+ else {
+ action = 0; /* SELECT */
+ }
+ }
+
+ switch (action) {
+ case 1: /* DESELECT */
+ base->flag &= ~BASE_SELECTED;
+ break;
+ case 0: /* SELECT */
+ default:
+ BKE_scene_layer_base_select(sl, base);
+ break;
+ }
+}
+
+static int rna_Object_select_get(Object *ob, bContext *C, ReportList *reports)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+
+ if (!base) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, sl->name);
+ return -1;
+ }
+
+ return ((base->flag & BASE_SELECTED) != 0) ? 1 : 0;
+}
+
+static int rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+
+ if (!base) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, sl->name);
+ return -1;
+ }
+
+ return ((base->flag & BASE_VISIBLED) != 0) ? 1 : 0;
+}
/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */
static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan,
@@ -419,9 +477,9 @@ finally:
free_bvhtree_from_mesh(&treeData);
}
-/* ObjectBase */
+/* ObjectBaseLegacy */
-static void rna_ObjectBase_layers_from_view(Base *base, View3D *v3d)
+static void rna_ObjectBaseLegacy_layers_from_view(BaseLegacy *base, View3D *v3d)
{
base->lay = base->object->lay = v3d->lay;
}
@@ -510,6 +568,32 @@ void RNA_api_object(StructRNA *srna)
};
#endif
+ static EnumPropertyItem object_select_items[] = {
+ {0, "SELECT", 0, "Select", "Select object from the active render layer"},
+ {1, "DESELECT", 0, "Deselect", "Deselect object from the active render layer"},
+ {2, "TOGGLE", 0, "Toggle", "Toggle object selection from the active render layer"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* Special wrapper to access the base selection value */
+ func = RNA_def_function(srna, "select_set", "rna_Object_select_set");
+ RNA_def_function_ui_description(func, "Select the object (for the active render layer)");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm = RNA_def_enum(func, "action", object_select_items, 0, "Action", "Select mode");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "select_get", "rna_Object_select_get");
+ RNA_def_function_ui_description(func, "Get the object selection for the active render layer");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm = RNA_def_boolean(func, "result", 0, "", "Object selected");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "visible_get", "rna_Object_visible_get");
+ RNA_def_function_ui_description(func, "Get the object visibility for the active render layer");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm = RNA_def_boolean(func, "result", 0, "", "Object visible");
+ RNA_def_function_return(func, parm);
+
/* Matrix space conversion */
func = RNA_def_function(srna, "convert_space", "rna_Scene_mat_convert_space");
RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another");
@@ -713,12 +797,12 @@ void RNA_api_object(StructRNA *srna)
}
-void RNA_api_object_base(StructRNA *srna)
+void RNA_api_object_base_legacy(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
- func = RNA_def_function(srna, "layers_from_view", "rna_ObjectBase_layers_from_view");
+ func = RNA_def_function(srna, "layers_from_view", "rna_ObjectBaseLegacy_layers_from_view");
RNA_def_function_ui_description(func,
"Sets the object layers from a 3D View (use when adding an object in local view)");
parm = RNA_def_pointer(func, "view", "SpaceView3D", "", "");
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 514fca1b011..3bfa2da9fc1 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -94,6 +94,7 @@ static EnumPropertyItem empty_vortex_shape_items[] = {
#include "DNA_modifier_types.h"
#include "DNA_texture_types.h"
+#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
@@ -605,11 +606,11 @@ static void rna_EffectorWeight_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
if (id && GS(id->name) == ID_SCE) {
Scene *scene = (Scene *)id;
- Base *base;
-
- for (base = scene->base.first; base; base = base->next) {
- BKE_ptcache_object_reset(scene, base->object, PTCACHE_RESET_DEPSGRAPH);
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH);
}
+ FOREACH_SCENE_OBJECT_END
}
else {
DAG_id_tag_update(id, OB_RECALC_DATA | PSYS_RECALC_RESET);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 3c3d88c858f..067ce28fc59 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -2339,8 +2339,8 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "draw_size", PROP_INT, PROP_PIXEL);
- RNA_def_property_range(prop, 0, 1000);
- RNA_def_property_ui_range(prop, 0, 100, 1, -1);
+ RNA_def_property_range(prop, 1, 1000);
+ RNA_def_property_ui_range(prop, 1, 100, 1, -1);
RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in pixels (0=default)");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 44dcb72264a..267a81c81af 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -33,6 +33,8 @@
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -136,7 +138,7 @@ static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))
IMB_colormanagement_finish_glsl_draw();
}
-static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
+static void engine_update(RenderEngine *engine, Main *bmain, Depsgraph *graph, Scene *scene)
{
extern FunctionRNA rna_RenderEngine_update_func;
PointerRNA ptr;
@@ -148,24 +150,25 @@ static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "data", &bmain);
+ RNA_parameter_set_lookup(&list, "depsgraph", &graph);
RNA_parameter_set_lookup(&list, "scene", &scene);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
-static void engine_render(RenderEngine *engine, struct Scene *scene)
+static void engine_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
{
- extern FunctionRNA rna_RenderEngine_render_func;
+ extern FunctionRNA rna_RenderEngine_render_to_image_func;
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
- func = &rna_RenderEngine_render_func;
+ func = &rna_RenderEngine_render_to_image_func;
RNA_parameter_list_create(&list, &ptr, func);
- RNA_parameter_set_lookup(&list, "scene", &scene);
+ RNA_parameter_set_lookup(&list, "depsgraph", &depsgraph);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
@@ -216,15 +219,15 @@ static void engine_view_update(RenderEngine *engine, const struct bContext *cont
RNA_parameter_list_free(&list);
}
-static void engine_view_draw(RenderEngine *engine, const struct bContext *context)
+static void engine_render_to_view(RenderEngine *engine, const struct bContext *context)
{
- extern FunctionRNA rna_RenderEngine_view_draw_func;
+ extern FunctionRNA rna_RenderEngine_render_to_view_func;
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
- func = &rna_RenderEngine_view_draw_func;
+ func = &rna_RenderEngine_render_to_view_func;
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "context", &context);
@@ -251,6 +254,23 @@ static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *nt
RNA_parameter_list_free(&list);
}
+static void engine_collection_settings_create(RenderEngine *engine, struct IDProperty *props)
+{
+ extern FunctionRNA rna_RenderEngine_collection_settings_create_func;
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+ func = &rna_RenderEngine_collection_settings_create_func;
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "props", &props);
+ engine->type->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
static void engine_update_render_passes(RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl)
{
extern FunctionRNA rna_RenderEngine_update_render_passes_func;
@@ -289,7 +309,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
RenderEngineType *et, dummyet = {NULL};
RenderEngine dummyengine = {NULL};
PointerRNA dummyptr;
- int have_function[7];
+ int have_function[8];
/* setup dummy engine & engine type to store static properties in */
dummyengine.type = &dummyet;
@@ -326,14 +346,15 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
RNA_struct_blender_type_set(et->ext.srna, et);
et->update = (have_function[0]) ? engine_update : NULL;
- et->render = (have_function[1]) ? engine_render : NULL;
+ et->render_to_image = (have_function[1]) ? engine_render_to_image : NULL;
et->bake = (have_function[2]) ? engine_bake : NULL;
et->view_update = (have_function[3]) ? engine_view_update : NULL;
- et->view_draw = (have_function[4]) ? engine_view_draw : NULL;
+ et->render_to_view = (have_function[4]) ? engine_render_to_view : NULL;
et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL;
et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL;
+ et->collection_settings_create = (have_function[7]) ? engine_collection_settings_create : NULL;
- BLI_addtail(&R_engines, et);
+ RE_engines_register(bmain, et);
return et->ext.srna;
}
@@ -462,12 +483,13 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_ui_description(func, "Export scene data for render");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
RNA_def_pointer(func, "data", "BlendData", "", "");
+ RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
RNA_def_pointer(func, "scene", "Scene", "", "");
- func = RNA_def_function(srna, "render", NULL);
+ func = RNA_def_function(srna, "render_to_image", NULL);
RNA_def_function_ui_description(func, "Render scene into an image");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
- RNA_def_pointer(func, "scene", "Scene", "", "");
+ RNA_def_pointer(func, "desgraph", "Depsgraph", "", "");
func = RNA_def_function(srna, "bake", NULL);
RNA_def_function_ui_description(func, "Bake passes");
@@ -498,7 +520,7 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
RNA_def_pointer(func, "context", "Context", "", "");
- func = RNA_def_function(srna, "view_draw", NULL);
+ func = RNA_def_function(srna, "render_to_view", NULL);
RNA_def_function_ui_description(func, "Draw viewport render");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
RNA_def_pointer(func, "context", "Context", "", "");
@@ -510,6 +532,19 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_pointer(func, "node", "Node", "", "");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
+ func = RNA_def_function(srna, "update_render_passes", NULL);
+ RNA_def_function_ui_description(func, "Update the render passes that will be generated");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "scene", "Scene", "", "");
+ parm = RNA_def_pointer(func, "renderlayer", "SceneRenderLayer", "", "");
+
+ /* per-collection engine settings initialization */
+ func = RNA_def_function(srna, "collection_settings_create", NULL);
+ RNA_def_function_ui_description(func, "Create the per collection settings for the engine");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "collection_settings", "LayerCollectionSettings", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
+
/* tag for redraw */
func = RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
RNA_def_function_ui_description(func, "Request redraw for viewport rendering");
@@ -518,12 +553,6 @@ static void rna_def_render_engine(BlenderRNA *brna)
func = RNA_def_function(srna, "tag_update", "engine_tag_update");
RNA_def_function_ui_description(func, "Request update call for viewport rendering");
- func = RNA_def_function(srna, "update_render_passes", NULL);
- RNA_def_function_ui_description(func, "Update the render passes that will be generated");
- RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
- parm = RNA_def_pointer(func, "scene", "Scene", "", "");
- parm = RNA_def_pointer(func, "renderlayer", "SceneRenderLayer", "", "");
-
func = RNA_def_function(srna, "begin_result", "RE_engine_begin_result");
RNA_def_function_ui_description(func, "Create render result to write linear floating point render layers and passes");
parm = RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 20c3ab89b8e..4ff2e03ef9c 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -32,6 +32,7 @@
#include "DNA_particle_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
+#include "DNA_layer_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_userdef_types.h"
#include "DNA_world_types.h"
@@ -47,8 +48,12 @@
#include "BKE_editmesh.h"
#include "BKE_paint.h"
+#include "ED_object.h"
+
#include "GPU_extensions.h"
+#include "DRW_engine.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -432,6 +437,14 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = {
+ {COLLECTION_MODE_OBJECT, "OBJECT", 0, "Object", ""},
+ {COLLECTION_MODE_EDIT, "EDIT", 0, "Edit", ""},
+ {COLLECTION_MODE_PAINT_WEIGHT, "PAINT_WEIGHT", 0, "Weight Paint", ""},
+ {COLLECTION_MODE_PAINT_WEIGHT, "PAINT_VERTEX", 0, "Vertex Paint", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "DNA_anim_types.h"
@@ -446,16 +459,19 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
#include "MEM_guardedalloc.h"
#include "BKE_brush.h"
+#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_depsgraph.h"
+#include "BKE_idprop.h"
#include "BKE_mesh.h"
#include "BKE_sound.h"
#include "BKE_screen.h"
@@ -471,6 +487,9 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
#include "ED_keyframing.h"
#include "ED_image.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#ifdef WITH_FREESTYLE
#include "FRS_freestyle.h"
#endif
@@ -608,11 +627,11 @@ static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain, Scene *scene, Poi
static int rna_Scene_object_bases_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
{
Scene *scene = (Scene *)ptr->data;
- Base *base;
+ BaseLegacy *base;
for (base = scene->base.first; base; base = base->next) {
if (STREQLEN(base->object->id.name + 2, key, sizeof(base->object->id.name) - 2)) {
- *r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBase, base);
+ *r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBaseLegacy, base);
return true;
}
}
@@ -625,13 +644,13 @@ static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter)
ListBaseIterator *internal = &iter->internal.listbase;
/* we are actually iterating a Base list, so override get */
- return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base *)internal->link)->object);
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((BaseLegacy *)internal->link)->object);
}
-static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *reports, Object *ob)
+static BaseLegacy *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *reports, Object *ob)
{
Scene *scene_act = CTX_data_scene(C);
- Base *base;
+ BaseLegacy *base;
if (BKE_scene_base_find(scene, ob)) {
BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in scene '%s'", ob->id.name + 2, scene->id.name + 2);
@@ -662,7 +681,7 @@ static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *report
static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *ob)
{
- Base *base = BKE_scene_base_find(scene, ob);
+ BaseLegacy *base = BKE_scene_base_find(scene, ob);
if (!base) {
BKE_reportf(reports, RPT_ERROR, "Object '%s' is not in this scene '%s'", ob->id.name + 2, scene->id.name + 2);
return;
@@ -1749,23 +1768,25 @@ static void rna_Scene_use_nodes_update(bContext *C, PointerRNA *ptr)
static void rna_Physics_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
- Base *base;
-
- for (base = scene->base.first; base; base = base->next)
- BKE_ptcache_object_reset(scene, base->object, PTCACHE_RESET_DEPSGRAPH);
+ FOREACH_SCENE_OBJECT(scene, ob)
+ {
+ BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH);
+ }
+ FOREACH_SCENE_OBJECT_END
}
static void rna_Scene_editmesh_select_mode_set(PointerRNA *ptr, const int *value)
{
Scene *scene = (Scene *)ptr->id.data;
+ SceneLayer *sl = BKE_scene_layer_context_active(scene);
ToolSettings *ts = (ToolSettings *)ptr->data;
int flag = (value[0] ? SCE_SELECT_VERTEX : 0) | (value[1] ? SCE_SELECT_EDGE : 0) | (value[2] ? SCE_SELECT_FACE : 0);
if (flag) {
ts->selectmode = flag;
- if (scene->basact) {
- Mesh *me = BKE_mesh_from_object(scene->basact->object);
+ if (sl->basact) {
+ Mesh *me = BKE_mesh_from_object(sl->basact->object);
if (me && me->edit_btmesh && me->edit_btmesh->selectmode != flag) {
me->edit_btmesh->selectmode = flag;
EDBM_selectmode_set(me->edit_btmesh);
@@ -1774,12 +1795,13 @@ static void rna_Scene_editmesh_select_mode_set(PointerRNA *ptr, const int *value
}
}
-static void rna_Scene_editmesh_select_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Scene_editmesh_select_mode_update(Main *UNUSED(bmain), bContext *C, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
+ SceneLayer *sl = CTX_data_scene_layer(C);
Mesh *me = NULL;
- if (scene->basact) {
- me = BKE_mesh_from_object(scene->basact->object);
+ if (sl->basact) {
+ me = BKE_mesh_from_object(sl->basact->object);
if (me && me->edit_btmesh == NULL)
me = NULL;
}
@@ -1910,6 +1932,71 @@ static void rna_GameSettings_exit_key_set(PointerRNA *ptr, int value)
gm->exitkey = value;
}
+static StructRNA *rna_SceneLayerSettings_refine(PointerRNA *ptr)
+{
+ IDProperty *props = (IDProperty *)ptr->data;
+ BLI_assert(props && props->type == IDP_GROUP);
+
+ switch (props->subtype) {
+ case IDP_GROUP_SUB_ENGINE_RENDER:
+#ifdef WITH_CLAY_ENGINE
+ if (STREQ(props->name, RE_engine_id_BLENDER_CLAY)) {
+ return &RNA_SceneLayerEngineSettingsClay;
+ }
+#endif
+ if (STREQ(props->name, RE_engine_id_BLENDER_EEVEE)) {
+ return &RNA_SceneLayerEngineSettingsEevee;
+ }
+ break;
+ case IDP_GROUP_SUB_MODE_OBJECT:
+ case IDP_GROUP_SUB_MODE_EDIT:
+ case IDP_GROUP_SUB_MODE_PAINT_WEIGHT:
+ case IDP_GROUP_SUB_MODE_PAINT_VERTEX:
+ default:
+ BLI_assert(!"Mode not fully implemented");
+ break;
+ }
+
+ return &RNA_SceneLayerSettings;
+}
+
+static StructRNA *rna_LayerCollectionSettings_refine(PointerRNA *ptr)
+{
+ IDProperty *props = (IDProperty *)ptr->data;
+ BLI_assert(props && props->type == IDP_GROUP);
+
+ switch (props->subtype) {
+ case IDP_GROUP_SUB_ENGINE_RENDER:
+#ifdef WITH_CLAY_ENGINE
+ if (STREQ(props->name, RE_engine_id_BLENDER_CLAY)) {
+ return &RNA_LayerCollectionEngineSettingsClay;
+ }
+#endif
+ if (STREQ(props->name, RE_engine_id_BLENDER_EEVEE)) {
+ printf("Mode not fully implemented\n");
+ return &RNA_LayerCollectionSettings;
+ }
+ break;
+ case IDP_GROUP_SUB_MODE_OBJECT:
+ return &RNA_LayerCollectionModeSettingsObject;
+ break;
+ case IDP_GROUP_SUB_MODE_EDIT:
+ return &RNA_LayerCollectionModeSettingsEdit;
+ break;
+ case IDP_GROUP_SUB_MODE_PAINT_WEIGHT:
+ return &RNA_LayerCollectionModeSettingsPaintWeight;
+ break;
+ case IDP_GROUP_SUB_MODE_PAINT_VERTEX:
+ return &RNA_LayerCollectionModeSettingsPaintVertex;
+ break;
+ default:
+ BLI_assert(!"Mode not fully implemented");
+ break;
+ }
+
+ return &RNA_LayerCollectionSettings;
+}
+
static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[], int frame)
{
TimeMarker *marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
@@ -1965,9 +2052,11 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons
}
}
-static void rna_UnifiedPaintSettings_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_UnifiedPaintSettings_update(bContext *C, PointerRNA *UNUSED(ptr))
{
- Brush *br = BKE_paint_brush(BKE_paint_get_active(scene));
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Brush *br = BKE_paint_brush(BKE_paint_get_active(scene, sl));
WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
}
@@ -1990,11 +2079,11 @@ static void rna_UnifiedPaintSettings_unprojected_radius_set(PointerRNA *ptr, flo
ups->unprojected_radius = value;
}
-static void rna_UnifiedPaintSettings_radius_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_UnifiedPaintSettings_radius_update(bContext *C, PointerRNA *ptr)
{
/* changing the unified size should invalidate the overlay but also update the brush */
BKE_paint_invalidate_overlay_all();
- rna_UnifiedPaintSettings_update(bmain, scene, ptr);
+ rna_UnifiedPaintSettings_update(C, ptr);
}
static char *rna_UnifiedPaintSettings_path(PointerRNA *UNUSED(ptr))
@@ -2008,12 +2097,13 @@ static char *rna_CurvePaintSettings_path(PointerRNA *UNUSED(ptr))
}
/* generic function to recalc geometry */
-static void rna_EditMesh_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_EditMesh_update(Main *UNUSED(bmain), bContext *C, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
+ SceneLayer *sl = CTX_data_scene_layer(C);
Mesh *me = NULL;
- if (scene->basact) {
- me = BKE_mesh_from_object(scene->basact->object);
+ if (sl->basact) {
+ me = BKE_mesh_from_object(sl->basact->object);
if (me && me->edit_btmesh == NULL)
me = NULL;
}
@@ -2034,9 +2124,11 @@ static char *rna_MeshStatVis_path(PointerRNA *UNUSED(ptr))
* is not for general use and only for the few cases where changing scene
* settings and NOT for general purpose updates, possibly this should be
* given its own notifier. */
-static void rna_Scene_update_active_object_data(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Scene_update_active_object_data(bContext *C, PointerRNA *UNUSED(ptr))
{
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
+
if (ob) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, &ob->id);
@@ -2225,9 +2317,796 @@ static void rna_Stereo3dFormat_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
static int rna_gpu_is_hq_supported_get(PointerRNA *UNUSED(ptr))
{
- return GPU_instanced_drawing_support() && GPU_geometry_shader_support();
+ return true;
+}
+
+static void rna_SceneCollection_name_set(PointerRNA *ptr, const char *value)
+{
+ Scene *scene = (Scene *)ptr->id.data;
+ SceneCollection *sc = (SceneCollection *)ptr->data;
+ BKE_collection_rename(scene, sc, value);
+}
+
+static void rna_SceneCollection_filter_set(PointerRNA *ptr, const char *value)
+{
+ Scene *scene = (Scene *)ptr->id.data;
+ SceneCollection *sc = (SceneCollection *)ptr->data;
+ BLI_strncpy_utf8(sc->filter, value, sizeof(sc->filter));
+
+ TODO_LAYER_SYNC_FILTER;
+ (void)scene;
+}
+
+static PointerRNA rna_SceneCollection_objects_get(CollectionPropertyIterator *iter)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+
+ /* we are actually iterating a LinkData list, so override get */
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((LinkData *)internal->link)->data);
+}
+
+static int rna_SceneCollection_move_above(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_collection_move_above(scene, sc_dst, sc_src)) {
+ return 0;
+ }
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return 1;
+}
+
+static int rna_SceneCollection_move_below(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_collection_move_below(scene, sc_dst, sc_src)) {
+ return 0;
+ }
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return 1;
+}
+
+static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_collection_move_into(scene, sc_dst, sc_src)) {
+ return 0;
+ }
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return 1;
+}
+
+static SceneCollection *rna_SceneCollection_new(
+ ID *id, SceneCollection *sc_parent, Main *bmain, const char *name)
+{
+ Scene *scene = (Scene *)id;
+ SceneCollection *sc = BKE_collection_add(scene, sc_parent, name);
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return sc;
+}
+
+static void rna_SceneCollection_remove(
+ ID *id, SceneCollection *sc_parent, Main *bmain, ReportList *reports, PointerRNA *sc_ptr)
+{
+ Scene *scene = (Scene *)id;
+ SceneCollection *sc = sc_ptr->data;
+
+ const int index = BLI_findindex(&sc_parent->scene_collections, sc);
+ if (index == -1) {
+ BKE_reportf(reports, RPT_ERROR, "Collection '%s' is not a sub-collection of '%s'",
+ sc->name, sc_parent->name);
+ return;
+ }
+
+ if (!BKE_collection_remove(scene, sc)) {
+ BKE_reportf(reports, RPT_ERROR, "Collection '%s' could not be removed from collection '%s'",
+ sc->name, sc_parent->name);
+ return;
+ }
+
+ RNA_POINTER_INVALIDATE(sc_ptr);
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+}
+
+static int rna_SceneCollection_objects_active_index_get(PointerRNA *ptr)
+{
+ SceneCollection *sc = (SceneCollection *)ptr->data;
+ return sc->active_object_index;
}
+static void rna_SceneCollection_objects_active_index_set(PointerRNA *ptr, int value)
+{
+ SceneCollection *sc = (SceneCollection *)ptr->data;
+ sc->active_object_index = value;
+}
+
+static void rna_SceneCollection_objects_active_index_range(
+ PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ SceneCollection *sc = (SceneCollection *)ptr->data;
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&sc->objects) - 1);
+}
+
+void rna_SceneCollection_object_link(
+ ID *id, SceneCollection *sc, Main *bmain, ReportList *reports, Object *ob)
+{
+ Scene *scene = (Scene *)id;
+
+ if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in collection '%s'", ob->id.name + 2, sc->name);
+ return;
+ }
+
+ BKE_collection_object_add(scene, sc, ob);
+
+ /* TODO(sergey): Only update relations for the current scene. */
+ DAG_relations_tag_update(bmain);
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene);
+}
+
+static void rna_SceneCollection_object_unlink(
+ ID *id, SceneCollection *sc, Main *bmain, ReportList *reports, Object *ob)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' is not in collection '%s'", ob->id.name + 2, sc->name);
+ return;
+ }
+
+ BKE_collection_object_remove(bmain, scene, sc, ob, false);
+
+ /* needed otherwise the depgraph will contain freed objects which can crash, see [#20958] */
+ DAG_relations_tag_update(bmain);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene);
+}
+
+/****** layer collection engine settings *******/
+
+#define RNA_LAYER_ENGINE_GET_SET(_TYPE_, _ENGINE_, _MODE_, _NAME_) \
+static _TYPE_ rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_get(PointerRNA *ptr) \
+{ \
+ IDProperty *props = (IDProperty *)ptr->data; \
+ return BKE_collection_engine_property_value_get_##_TYPE_(props, #_NAME_); \
+} \
+ \
+static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr, _TYPE_ value) \
+{ \
+ IDProperty *props = (IDProperty *)ptr->data; \
+ BKE_collection_engine_property_value_set_##_TYPE_(props, #_NAME_, value); \
+}
+
+#define RNA_LAYER_ENGINE_GET_SET_ARRAY(_TYPE_, _ENGINE_, _MODE_, _NAME_, _LEN_) \
+static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_get(PointerRNA *ptr, _TYPE_ *values) \
+{ \
+ IDProperty *props = (IDProperty *)ptr->data; \
+ IDProperty *idprop = IDP_GetPropertyFromGroup(props, #_NAME_); \
+ if (idprop != NULL) { \
+ memcpy(values, IDP_Array(idprop), sizeof(_TYPE_) * idprop->len); \
+ } \
+} \
+ \
+static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr, const _TYPE_ *values) \
+{ \
+ IDProperty *props = (IDProperty *)ptr->data; \
+ BKE_collection_engine_property_value_set_##_TYPE_##_array(props, #_NAME_, values); \
+}
+
+#define RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(float, Clay, COLLECTION_MODE_NONE, _NAME_)
+
+#define RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT_ARRAY(_NAME_, _LEN_) \
+ RNA_LAYER_ENGINE_GET_SET_ARRAY(float, Clay, COLLECTION_MODE_NONE, _NAME_, _LEN_)
+
+#define RNA_LAYER_ENGINE_CLAY_GET_SET_INT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(int, Clay, COLLECTION_MODE_NONE, _NAME_)
+
+#define RNA_LAYER_ENGINE_CLAY_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, Clay, COLLECTION_MODE_NONE, _NAME_)
+
+#define RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(float, Eevee, COLLECTION_MODE_NONE, _NAME_)
+
+#define RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(int, Eevee, COLLECTION_MODE_NONE, _NAME_)
+
+#define RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, Eevee, COLLECTION_MODE_NONE, _NAME_)
+
+/* mode engines */
+
+#define RNA_LAYER_MODE_OBJECT_GET_SET_FLOAT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(float, ObjectMode, COLLECTION_MODE_OBJECT, _NAME_)
+
+#define RNA_LAYER_MODE_OBJECT_GET_SET_INT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(int, ObjectMode, COLLECTION_MODE_OBJECT, _NAME_)
+
+#define RNA_LAYER_MODE_OBJECT_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, ObjectMode, COLLECTION_MODE_OBJECT, _NAME_)
+
+#define RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(float, EditMode, COLLECTION_MODE_EDIT, _NAME_)
+
+#define RNA_LAYER_MODE_EDIT_GET_SET_INT(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(int, EditMode, COLLECTION_MODE_EDIT, _NAME_)
+
+#define RNA_LAYER_MODE_EDIT_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, EditMode, COLLECTION_MODE_EDIT, _NAME_)
+
+#define RNA_LAYER_MODE_PAINT_WEIGHT_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, PaintWeightMode, COLLECTION_MODE_PAINT_WEIGHT, _NAME_)
+
+#define RNA_LAYER_MODE_PAINT_VERTEX_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, PaintVertexMode, COLLECTION_MODE_PAINT_VERTEX, _NAME_)
+
+/* clay engine */
+#ifdef WITH_CLAY_ENGINE
+/* SceneLayer settings. */
+RNA_LAYER_ENGINE_CLAY_GET_SET_INT(ssao_samples)
+
+/* LayerCollection settings. */
+RNA_LAYER_ENGINE_CLAY_GET_SET_INT(matcap_icon)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_rotation)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_hue)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_saturation)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(matcap_value)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_factor_cavity)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_factor_edge)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_distance)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(ssao_attenuation)
+RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(hair_brightness_randomness)
+#endif /* WITH_CLAY_ENGINE */
+
+/* eevee engine */
+/* SceneLayer settings. */
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(dof_enable)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bokeh_max_size)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bokeh_threshold)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(bloom_enable)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_threshold)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_knee)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_radius)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_intensity)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(motion_blur_enable)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(motion_blur_samples)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(motion_blur_shutter)
+
+/* object engine */
+RNA_LAYER_MODE_OBJECT_GET_SET_BOOL(show_wire)
+RNA_LAYER_MODE_OBJECT_GET_SET_BOOL(show_backface_culling)
+
+/* mesh engine */
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(show_occlude_wire)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(show_weight)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(face_normals_show)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(vert_normals_show)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(loop_normals_show)
+RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(normals_length)
+RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(backwire_opacity)
+
+/* weight paint engine */
+RNA_LAYER_MODE_PAINT_WEIGHT_GET_SET_BOOL(use_shading)
+RNA_LAYER_MODE_PAINT_WEIGHT_GET_SET_BOOL(use_wire)
+
+/* vertex paint engine */
+RNA_LAYER_MODE_PAINT_VERTEX_GET_SET_BOOL(use_shading)
+RNA_LAYER_MODE_PAINT_VERTEX_GET_SET_BOOL(use_wire)
+
+#undef RNA_LAYER_ENGINE_GET_SET
+
+static void rna_SceneLayerEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+}
+
+static void rna_LayerCollectionEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+}
+
+static void rna_LayerCollectionEngineSettings_wire_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
+
+ if (ob != NULL && ob->type == OB_MESH) {
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_PAINT);
+ }
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+}
+
+/***********************************/
+
+static void engine_settings_use(IDProperty *root, IDProperty *props, PointerRNA *props_ptr, const char *identifier)
+{
+ PropertyRNA *prop = RNA_struct_find_property(props_ptr, identifier);
+
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ {
+ float value = BKE_collection_engine_property_value_get_float(props, identifier);
+ BKE_collection_engine_property_add_float(root, identifier, value);
+ break;
+ }
+ case PROP_ENUM:
+ {
+ int value = BKE_collection_engine_property_value_get_int(props, identifier);
+ BKE_collection_engine_property_add_int(root, identifier, value);
+ break;
+ }
+ case PROP_INT:
+ {
+ int value = BKE_collection_engine_property_value_get_int(props, identifier);
+ BKE_collection_engine_property_add_int(root, identifier, value);
+ break;
+ }
+ case PROP_BOOLEAN:
+ {
+ int value = BKE_collection_engine_property_value_get_int(props, identifier);
+ BKE_collection_engine_property_add_bool(root, identifier, value);
+ break;
+ }
+ case PROP_STRING:
+ case PROP_POINTER:
+ case PROP_COLLECTION:
+ default:
+ break;
+ }
+}
+
+static void rna_SceneLayerSettings_name_get(PointerRNA *ptr, char *value)
+{
+ IDProperty *props = (IDProperty *)ptr->data;
+ strcpy(value, props->name);
+}
+
+static int rna_SceneLayerSettings_name_length(PointerRNA *ptr)
+{
+ IDProperty *props = (IDProperty *)ptr->data;
+ return strnlen(props->name, sizeof(props->name));
+}
+
+static void rna_SceneLayerSettings_use(ID *id, IDProperty *props, const char *identifier)
+{
+ Scene *scene = (Scene *)id;
+ PointerRNA scene_props_ptr;
+ IDProperty *scene_props;
+
+ scene_props = BKE_scene_layer_engine_scene_get(scene, COLLECTION_MODE_NONE, props->name);
+ RNA_pointer_create(id, &RNA_SceneLayerSettings, scene_props, &scene_props_ptr);
+
+ engine_settings_use(props, scene_props, &scene_props_ptr, identifier);
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(id, 0);
+}
+
+static void rna_SceneLayerSettings_unuse(ID *id, IDProperty *props, const char *identifier)
+{
+ IDProperty *prop_to_remove = IDP_GetPropertyFromGroup(props, identifier);
+ IDP_FreeFromGroup(props, prop_to_remove);
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(id, 0);
+}
+
+static void rna_LayerCollectionSettings_name_get(PointerRNA *ptr, char *value)
+{
+ IDProperty *props = (IDProperty *)ptr->data;
+ strcpy(value, props->name);
+}
+
+static int rna_LayerCollectionSettings_name_length(PointerRNA *ptr)
+{
+ IDProperty *props = (IDProperty *)ptr->data;
+ return strnlen(props->name, sizeof(props->name));
+}
+
+static void rna_LayerCollectionSettings_use(ID *id, IDProperty *props, const char *identifier)
+{
+ Scene *scene = (Scene *)id;
+ PointerRNA scene_props_ptr;
+ IDProperty *scene_props;
+
+ scene_props = BKE_layer_collection_engine_scene_get(scene, COLLECTION_MODE_NONE, props->name);
+ RNA_pointer_create(id, &RNA_LayerCollectionSettings, scene_props, &scene_props_ptr);
+ engine_settings_use(props, scene_props, &scene_props_ptr, identifier);
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(id, 0);
+}
+
+static void rna_LayerCollectionSettings_unuse(ID *id, IDProperty *props, const char *identifier)
+{
+ IDProperty *prop_to_remove = IDP_GetPropertyFromGroup(props, identifier);
+ IDP_FreeFromGroup(props, prop_to_remove);
+
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(id, 0);
+}
+
+static void rna_LayerCollection_name_get(PointerRNA *ptr, char *value)
+{
+ SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection;
+ strcpy(value, sc->name);
+}
+
+static int rna_LayerCollection_name_length(PointerRNA *ptr)
+{
+ SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection;
+ return strnlen(sc->name, sizeof(sc->name));
+}
+
+static void rna_LayerCollection_name_set(PointerRNA *ptr, const char *value)
+{
+ Scene *scene = (Scene *)ptr->id.data;
+ SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection;
+ BKE_collection_rename(scene, sc, value);
+}
+
+static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *iter)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+ Base *base = ((LinkData *)internal->link)->data;
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object);
+}
+
+static int rna_LayerCollection_move_above(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_layer_collection_move_above(scene, lc_dst, lc_src)) {
+ return 0;
+ }
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return 1;
+}
+
+static int rna_LayerCollection_move_below(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_layer_collection_move_below(scene, lc_dst, lc_src)) {
+ return 0;
+ }
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return 1;
+}
+
+static int rna_LayerCollection_move_into(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst)
+{
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_layer_collection_move_into(scene, lc_dst, lc_src)) {
+ return 0;
+ }
+
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return 1;
+}
+
+static void rna_LayerCollection_flag_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+}
+
+static int rna_LayerCollections_active_collection_index_get(PointerRNA *ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ return sl->active_collection;
+}
+
+static void rna_LayerCollections_active_collection_index_set(PointerRNA *ptr, int value)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ int num_collections = BKE_layer_collection_count(sl);
+ sl->active_collection = min_ff(value, num_collections - 1);
+}
+
+static void rna_LayerCollections_active_collection_index_range(
+ PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ *min = 0;
+ *max = max_ii(0, BKE_layer_collection_count(sl) - 1);
+}
+
+static PointerRNA rna_LayerCollections_active_collection_get(PointerRNA *ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ LayerCollection *lc = BKE_layer_collection_get_active(sl);
+ return rna_pointer_inherit_refine(ptr, &RNA_LayerCollection, lc);
+}
+
+static void rna_LayerCollections_active_collection_set(PointerRNA *ptr, PointerRNA value)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ LayerCollection *lc = (LayerCollection *)value.data;
+ const int index = BKE_layer_collection_findindex(sl, lc);
+ if (index != -1) sl->active_collection = index;
+}
+
+LayerCollection * rna_SceneLayer_collection_link(
+ ID *id, SceneLayer *sl, Main *bmain, SceneCollection *sc)
+{
+ Scene *scene = (Scene *)id;
+ LayerCollection *lc = BKE_collection_link(sl, sc);
+
+ DAG_relations_tag_update(bmain);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(id, 0);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, scene);
+
+ return lc;
+}
+
+static void rna_SceneLayer_collection_unlink(
+ ID *id, SceneLayer *sl, Main *bmain, ReportList *reports, LayerCollection *lc)
+{
+ Scene *scene = (Scene *)id;
+
+ if (BLI_findindex(&sl->layer_collections, lc) == -1) {
+ BKE_reportf(reports, RPT_ERROR, "Layer collection '%s' is not in '%s'", lc->scene_collection->name, sl->name);
+ return;
+ }
+
+ BKE_collection_unlink(sl, lc);
+
+ DAG_relations_tag_update(bmain);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(id, 0);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene);
+}
+
+static PointerRNA rna_LayerObjects_active_object_get(PointerRNA *ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Object, sl->basact ? sl->basact->object : NULL);
+}
+
+static void rna_LayerObjects_active_object_set(PointerRNA *ptr, PointerRNA value)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ if (value.data)
+ sl->basact = BKE_scene_layer_base_find(sl, (Object *)value.data);
+ else
+ sl->basact = NULL;
+}
+
+static void rna_SceneLayer_name_set(PointerRNA *ptr, const char *value)
+{
+ Scene *scene = (Scene *)ptr->id.data;
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ char oldname[sizeof(sl->name)];
+
+ BLI_strncpy(oldname, sl->name, sizeof(sl->name));
+
+ BLI_strncpy_utf8(sl->name, value, sizeof(sl->name));
+ BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
+
+ if (scene->nodetree) {
+ bNode *node;
+ int index = BLI_findindex(&scene->render_layers, sl);
+
+ for (node = scene->nodetree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_R_LAYERS && node->id == NULL) {
+ if (node->custom1 == index)
+ BLI_strncpy(node->name, sl->name, NODE_MAXSTR);
+ }
+ }
+ }
+}
+
+static PointerRNA rna_SceneLayer_objects_get(CollectionPropertyIterator *iter)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+
+ /* we are actually iterating a ObjectBase list, so override get */
+ Base *base = (Base *)internal->link;
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object);
+}
+
+static int rna_SceneLayer_objects_selected_skip(CollectionPropertyIterator *iter, void *UNUSED(data))
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+ Base *base = (Base *)internal->link;
+
+ if ((base->flag & BASE_SELECTED) != 0) {
+ return 0;
+ }
+
+ return 1;
+};
+
+static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ rna_iterator_listbase_begin(iter, &sl->object_bases, rna_SceneLayer_objects_selected_skip);
+}
+
+static void rna_SceneLayer_engine_set(PointerRNA *ptr, int value)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ RenderEngineType *type = BLI_findlink(&R_engines, value);
+
+ if (type)
+ BKE_scene_layer_engine_set(sl, type->idname);
+}
+
+static EnumPropertyItem *rna_SceneLayer_engine_itemf(
+ bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ RenderEngineType *type;
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ int a = 0, totitem = 0;
+
+ for (type = R_engines.first; type; type = type->next, a++) {
+ tmp.value = a;
+ tmp.identifier = type->idname;
+ tmp.name = type->name;
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static int rna_SceneLayer_engine_get(PointerRNA *ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ RenderEngineType *type;
+ int a = 0;
+
+ for (type = R_engines.first; type; type = type->next, a++)
+ if (STREQ(type->idname, sl->engine))
+ return a;
+
+ return 0;
+}
+
+static void rna_SceneLayer_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr))
+{
+ ED_render_engine_changed(bmain);
+}
+
+static int rna_SceneLayer_multiple_engines_get(PointerRNA *UNUSED(ptr))
+{
+ return (BLI_listbase_count(&R_engines) > 1);
+}
+
+static void rna_SceneLayer_update_tagged(SceneLayer *UNUSED(sl), bContext *C)
+{
+ Depsgraph *graph = CTX_data_depsgraph(C);
+ DEG_OBJECT_ITER(graph, ob)
+ {
+ /* Don't do anything, we just need to run the iterator to flush
+ * the base info to the objects. */
+ UNUSED_VARS(ob);
+ }
+ DEG_OBJECT_ITER_END
+}
+
+static int rna_SceneLayer_active_layer_index_get(PointerRNA *ptr)
+{
+ Scene *scene = (Scene *)ptr->data;
+ return scene->active_layer;
+}
+
+static void rna_SceneLayer_active_layer_index_set(PointerRNA *ptr, int value)
+{
+ Scene *scene = (Scene *)ptr->data;
+ int num_layers = BLI_listbase_count(&scene->render_layers);
+ scene->active_layer = min_ff(value, num_layers - 1);
+}
+
+static void rna_SceneLayer_active_layer_index_range(
+ PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ Scene *scene = (Scene *)ptr->data;
+
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&scene->render_layers) - 1);
+}
+
+static PointerRNA rna_SceneLayer_active_layer_get(PointerRNA *ptr)
+{
+ Scene *scene = (Scene *)ptr->data;
+ SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer);
+
+ return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, sl);
+}
+
+static void rna_SceneLayer_active_layer_set(PointerRNA *ptr, PointerRNA value)
+{
+ Scene *scene = (Scene *)ptr->data;
+ SceneLayer *sl = (SceneLayer *)value.data;
+ const int index = BLI_findindex(&scene->render_layers, sl);
+ if (index != -1) scene->active_layer = index;
+}
+
+static SceneLayer *rna_SceneLayer_new(
+ ID *id, Scene *UNUSED(sce), Main *bmain, const char *name)
+{
+ Scene *scene = (Scene *)id;
+ SceneLayer *sl = BKE_scene_layer_add(scene, name);
+
+ DAG_id_tag_update(&scene->id, 0);
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ return sl;
+}
+
+static void rna_SceneLayer_remove(
+ ID *id, Scene *UNUSED(sce), Main *bmain, ReportList *reports, PointerRNA *sl_ptr)
+{
+ Scene *scene = (Scene *)id;
+ SceneLayer *sl = sl_ptr->data;
+
+ if (!BKE_scene_layer_remove(bmain, scene, sl)) {
+ BKE_reportf(reports, RPT_ERROR, "Render layer '%s' could not be removed from scene '%s'",
+ sl->name, scene->id.name + 2);
+ return;
+ }
+
+ RNA_POINTER_INVALIDATE(sl_ptr);
+
+ DAG_id_tag_update(&scene->id, 0);
+ DAG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+}
+
+static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ Base *base = (Base *)ptr->data;
+ short mode = (base->flag & BASE_SELECTED) ? BA_SELECT : BA_DESELECT;
+ ED_object_base_select(base, mode);
+}
#else
/* Grease Pencil Interpolation tool settings */
@@ -2605,6 +3484,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Sculpt", "");
prop = RNA_def_property(srna, "use_auto_normalize", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_normalize", 1);
RNA_def_property_ui_text(prop, "WPaint Auto-Normalize",
"Ensure all bone-deforming vertex groups add up "
@@ -2612,6 +3492,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
prop = RNA_def_property(srna, "use_multipaint", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_boolean_sdna(prop, NULL, "multipaint", 1);
RNA_def_property_ui_text(prop, "WPaint Multi-Paint",
"Paint across the weights of all selected bones, "
@@ -2619,12 +3500,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
prop = RNA_def_property(srna, "vertex_group_user", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_sdna(prop, NULL, "weightuser");
RNA_def_property_enum_items(prop, draw_groupuser_items);
RNA_def_property_ui_text(prop, "Mask Non-Group Vertices", "Display unweighted vertices");
RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
prop = RNA_def_property(srna, "vertex_group_subset", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_sdna(prop, NULL, "vgroupsubset");
RNA_def_property_enum_items(prop, vertex_group_select_items);
RNA_def_property_ui_text(prop, "Subset", "Filter Vertex groups for Display");
@@ -2935,6 +3818,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_editmesh_select_mode_set");
RNA_def_property_ui_text(prop, "Mesh Selection Mode", "Which mesh elements selection works on");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_Scene_editmesh_select_mode_update");
prop = RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_FACTOR);
@@ -3070,6 +3954,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
* from the active brush */
prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL);
RNA_def_property_int_funcs(prop, NULL, "rna_UnifiedPaintSettings_size_set", NULL);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS * 10);
RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, -1);
RNA_def_property_ui_text(prop, "Radius", "Radius of the brush");
@@ -3077,6 +3962,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_funcs(prop, NULL, "rna_UnifiedPaintSettings_unprojected_radius_set", NULL);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_range(prop, 0.001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001, 1, 0, -1);
RNA_def_property_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units");
@@ -3084,6 +3970,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "alpha");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 3);
@@ -3092,6 +3979,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "weight");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 3);
@@ -3099,12 +3987,14 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "rgb");
RNA_def_property_ui_text(prop, "Color", "");
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
prop = RNA_def_property(srna, "secondary_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "secondary_rgb");
RNA_def_property_ui_text(prop, "Secondary Color", "");
@@ -3246,6 +4136,7 @@ static void rna_def_statvis(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, stat_type);
RNA_def_property_ui_text(prop, "Type", "Type of data to visualize/check");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
@@ -3256,6 +4147,7 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 0.001, 3);
RNA_def_property_ui_text(prop, "Overhang Min", "Minimum angle to display");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
prop = RNA_def_property(srna, "overhang_max", PROP_FLOAT, PROP_ANGLE);
@@ -3264,12 +4156,14 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 3);
RNA_def_property_ui_text(prop, "Overhang Max", "Maximum angle to display");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
prop = RNA_def_property(srna, "overhang_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "overhang_axis");
RNA_def_property_enum_items(prop, rna_enum_object_axis_items);
RNA_def_property_ui_text(prop, "Axis", "");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
@@ -3280,6 +4174,7 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1000.0);
RNA_def_property_ui_range(prop, 0.0f, 100.0, 0.001, 3);
RNA_def_property_ui_text(prop, "Thickness Min", "Minimum for measuring thickness");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
prop = RNA_def_property(srna, "thickness_max", PROP_FLOAT, PROP_DISTANCE);
@@ -3288,12 +4183,14 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1000.0);
RNA_def_property_ui_range(prop, 0.0f, 100.0, 0.001, 3);
RNA_def_property_ui_text(prop, "Thickness Max", "Maximum for measuring thickness");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
prop = RNA_def_property(srna, "thickness_samples", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "thickness_samples");
RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "Samples", "Number of samples to test per face");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
/* distort */
@@ -3303,6 +4200,7 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 3);
RNA_def_property_ui_text(prop, "Distort Min", "Minimum angle to display");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
prop = RNA_def_property(srna, "distort_max", PROP_FLOAT, PROP_ANGLE);
@@ -3311,6 +4209,7 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 3);
RNA_def_property_ui_text(prop, "Distort Max", "Maximum angle to display");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
/* sharp */
@@ -3320,6 +4219,7 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f), 10, 3);
RNA_def_property_ui_text(prop, "Distort Min", "Minimum angle to display");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
prop = RNA_def_property(srna, "sharp_max", PROP_FLOAT, PROP_ANGLE);
@@ -3328,6 +4228,7 @@ static void rna_def_statvis(BlenderRNA *brna)
RNA_def_property_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f), 10, 3);
RNA_def_property_ui_text(prop, "Distort Max", "Maximum angle to display");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_EditMesh_update");
}
@@ -4840,11 +5741,6 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
"Respect the frame rate from the Physics panel in the world properties "
"rather than rendering as many frames as possible");
- prop = RNA_def_property(srna, "use_display_lists", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_DISPLAY_LISTS);
- RNA_def_property_ui_text(prop, "Display Lists",
- "Use display lists to speed up rendering by keeping geometry on the GPU");
-
prop = RNA_def_property(srna, "use_deprecation_warnings", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_IGNORE_DEPRECATION_WARNINGS);
RNA_def_property_ui_text(prop, "Deprecation Warnings",
@@ -5004,11 +5900,23 @@ static void rna_def_gpu_dof_fx(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, "rna_GPUDOFSettings_blades_set", NULL);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_ui_text(prop, "Rotation", "Rotation of blades in apperture");
+ RNA_def_property_range(prop, -M_PI, M_PI);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "ratio", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Ratio", "Distortion to simulate anamorphic lens bokeh");
+ RNA_def_property_range(prop, 0.0000001f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.25f, 4.0f, 0.1, 3);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "use_high_quality", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "high_quality", 1);
RNA_def_property_ui_text(prop, "High Quality", "Use high quality depth of field");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ /* NOTE: high quality is always supported */
prop = RNA_def_property(srna, "is_hq_supported", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_gpu_is_hq_supported_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -5089,6 +5997,912 @@ static void rna_def_gpu_fx(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUFXSettings_fx_update");
}
+/* Render Layers and Collections */
+
+static void rna_def_scene_collections(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "SceneCollections");
+ srna = RNA_def_struct(brna, "SceneCollections", NULL);
+ RNA_def_struct_sdna(srna, "SceneCollection");
+ RNA_def_struct_ui_text(srna, "Scene Collection", "Collection of scene collections");
+
+ func = RNA_def_function(srna, "new", "rna_SceneCollection_new");
+ RNA_def_function_ui_description(func, "Add a collection to scene");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_string(func, "name", "SceneCollection", 0, "", "New name for the collection (not unique)");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "result", "SceneCollection", "", "Newly created collection");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_SceneCollection_remove");
+ RNA_def_function_ui_description(func, "Remove a collection layer");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "layer", "SceneCollection", "", "Collection to remove");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
+}
+
+static void rna_def_collection_objects(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+ PropertyRNA *prop;
+
+ RNA_def_property_srna(cprop, "CollectionObjects");
+ srna = RNA_def_struct(brna, "CollectionObjects", NULL);
+ RNA_def_struct_sdna(srna, "SceneCollection");
+ RNA_def_struct_ui_text(srna, "Collection Objects", "Objects of a collection");
+
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop, "rna_SceneCollection_objects_active_index_get",
+ "rna_SceneCollection_objects_active_index_set",
+ "rna_SceneCollection_objects_active_index_range");
+ RNA_def_property_ui_text(prop, "Active Object Index", "Active index in collection objects array");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+
+ func = RNA_def_function(srna, "link", "rna_SceneCollection_object_link");
+ RNA_def_function_ui_description(func, "Link an object to collection");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "object", "Object", "", "Object to add to collection");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "unlink", "rna_SceneCollection_object_unlink");
+ RNA_def_function_ui_description(func, "Unlink object from collection");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove from collection");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+}
+
+static void rna_def_scene_collection(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ srna = RNA_def_struct(brna, "SceneCollection", NULL);
+ RNA_def_struct_ui_text(srna, "Scene Collection", "Collection");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneCollection_name_set");
+ RNA_def_property_ui_text(prop, "Name", "Collection name");
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+
+ prop = RNA_def_property(srna, "filter", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneCollection_filter_set");
+ RNA_def_property_ui_text(prop, "Filter", "Filter to dynamically include objects based on their names (e.g., CHAR_*)");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+
+ prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "scene_collections", NULL);
+ RNA_def_property_struct_type(prop, "SceneCollection");
+ RNA_def_property_ui_text(prop, "SceneCollections", "");
+ rna_def_scene_collections(brna, prop);
+
+ prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "objects", NULL);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SceneCollection_objects_get", NULL, NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Objects", "All the objects directly added to this collection (not including sub-collection objects)");
+ rna_def_collection_objects(brna, prop);
+
+ prop = RNA_def_property(srna, "filters_objects", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "filter_objects", NULL);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SceneCollection_objects_get", NULL, NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Filter Objects", "All the objects dynamically added to this collection via the filter");
+
+ /* Functions */
+ func = RNA_def_function(srna, "move_above", "rna_SceneCollection_move_above");
+ RNA_def_function_ui_description(func, "Move collection after another");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Reference collection above which the collection will move");
+ parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "move_below", "rna_SceneCollection_move_below");
+ RNA_def_function_ui_description(func, "Move collection before another");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Reference collection below which the collection will move");
+ parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "move_into", "rna_SceneCollection_move_into");
+ RNA_def_function_ui_description(func, "Move collection into another");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Collection to insert into");
+ parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
+ RNA_def_function_return(func, parm);
+}
+
+static void rna_def_layer_collection_override(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LayerCollectionOverride", NULL);
+ RNA_def_struct_sdna(srna, "CollectionOverride");
+ RNA_def_struct_ui_text(srna, "Collection Override", "Collection Override");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Name", "Collection name");
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+}
+
+
+#ifdef WITH_CLAY_ENGINE
+static void rna_def_scene_layer_engine_settings_clay(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "SceneLayerEngineSettingsClay", "SceneLayerSettings");
+ RNA_def_struct_ui_text(srna, "Clay Scene Layer Settings", "Clay Engine settings");
+
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+ prop = RNA_def_property(srna, "ssao_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_samples_get",
+ "rna_LayerEngineSettings_Clay_ssao_samples_set", NULL);
+ RNA_def_property_ui_text(prop, "Samples", "Number of samples");
+ RNA_def_property_range(prop, 1, 500);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+#endif /* WITH_CLAY_ENGINE */
+
+static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "SceneLayerEngineSettingsEevee", "SceneLayerSettings");
+ RNA_def_struct_ui_text(srna, "Eevee Scene Layer Settings", "Eevee Engine settings");
+
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+ /* Depth of Field */
+ prop = RNA_def_property(srna, "dof_enable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_dof_enable_get",
+ "rna_LayerEngineSettings_Eevee_dof_enable_set");
+ RNA_def_property_ui_text(prop, "Depth of Field", "Enable depth of field using the values from the active camera");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "bokeh_max_size", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bokeh_max_size_get",
+ "rna_LayerEngineSettings_Eevee_bokeh_max_size_set", NULL);
+ RNA_def_property_ui_text(prop, "Max Size", "Max size of the bokeh shape for the depth of field (lower values increase performance)");
+ RNA_def_property_range(prop, 0.0f, 2000.0f);
+ RNA_def_property_ui_range(prop, 2.0f, 200.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "bokeh_threshold", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bokeh_threshold_get",
+ "rna_LayerEngineSettings_Eevee_bokeh_threshold_set", NULL);
+ RNA_def_property_ui_text(prop, "Sprite Threshold", "Brightness threshold for using sprite base depth of field");
+ RNA_def_property_range(prop, 0.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ /* Bloom */
+ prop = RNA_def_property(srna, "bloom_enable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_enable_get",
+ "rna_LayerEngineSettings_Eevee_bloom_enable_set");
+ RNA_def_property_ui_text(prop, "Bloom", "High brighness pixels generate a glowing effect");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "bloom_threshold", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_threshold_get",
+ "rna_LayerEngineSettings_Eevee_bloom_threshold_set", NULL);
+ RNA_def_property_ui_text(prop, "Threshold", "Filters out pixels under this level of brightness");
+ RNA_def_property_range(prop, 0.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "bloom_knee", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_knee_get",
+ "rna_LayerEngineSettings_Eevee_bloom_knee_set", NULL);
+ RNA_def_property_ui_text(prop, "Knee", "Makes transition between under/over-threshold gradual");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "bloom_radius", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_radius_get",
+ "rna_LayerEngineSettings_Eevee_bloom_radius_set", NULL);
+ RNA_def_property_ui_text(prop, "Radius", "Bloom spread distance");
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "bloom_intensity", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_intensity_get",
+ "rna_LayerEngineSettings_Eevee_bloom_intensity_set", NULL);
+ RNA_def_property_ui_text(prop, "Intensity", "Blend factor");
+ RNA_def_property_range(prop, 0.0f, 10000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ /* Motion blur */
+ prop = RNA_def_property(srna, "motion_blur_enable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_motion_blur_enable_get",
+ "rna_LayerEngineSettings_Eevee_motion_blur_enable_set");
+ RNA_def_property_ui_text(prop, "Motion Blur", "Enable motion blur effect (only in camera view)");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_motion_blur_samples_get",
+ "rna_LayerEngineSettings_Eevee_motion_blur_samples_set", NULL);
+ RNA_def_property_ui_text(prop, "Samples", "Number of samples to take with motion blur");
+ RNA_def_property_range(prop, 1, 64);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_motion_blur_shutter_get",
+ "rna_LayerEngineSettings_Eevee_motion_blur_shutter_set", NULL);
+ RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
+ RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+
+#ifdef WITH_CLAY_ENGINE
+static void rna_def_layer_collection_engine_settings_clay(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem clay_matcap_items[] = {
+ {ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""},
+ {ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""},
+ {ICON_MATCAP_03, "03", ICON_MATCAP_03, "", ""},
+ {ICON_MATCAP_04, "04", ICON_MATCAP_04, "", ""},
+ {ICON_MATCAP_05, "05", ICON_MATCAP_05, "", ""},
+ {ICON_MATCAP_06, "06", ICON_MATCAP_06, "", ""},
+ {ICON_MATCAP_07, "07", ICON_MATCAP_07, "", ""},
+ {ICON_MATCAP_08, "08", ICON_MATCAP_08, "", ""},
+ {ICON_MATCAP_09, "09", ICON_MATCAP_09, "", ""},
+ {ICON_MATCAP_10, "10", ICON_MATCAP_10, "", ""},
+ {ICON_MATCAP_11, "11", ICON_MATCAP_11, "", ""},
+ {ICON_MATCAP_12, "12", ICON_MATCAP_12, "", ""},
+ {ICON_MATCAP_13, "13", ICON_MATCAP_13, "", ""},
+ {ICON_MATCAP_14, "14", ICON_MATCAP_14, "", ""},
+ {ICON_MATCAP_15, "15", ICON_MATCAP_15, "", ""},
+ {ICON_MATCAP_16, "16", ICON_MATCAP_16, "", ""},
+ {ICON_MATCAP_17, "17", ICON_MATCAP_17, "", ""},
+ {ICON_MATCAP_18, "18", ICON_MATCAP_18, "", ""},
+ {ICON_MATCAP_19, "19", ICON_MATCAP_19, "", ""},
+ {ICON_MATCAP_20, "20", ICON_MATCAP_20, "", ""},
+ {ICON_MATCAP_21, "21", ICON_MATCAP_21, "", ""},
+ {ICON_MATCAP_22, "22", ICON_MATCAP_22, "", ""},
+ {ICON_MATCAP_23, "23", ICON_MATCAP_23, "", ""},
+ {ICON_MATCAP_24, "24", ICON_MATCAP_24, "", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "LayerCollectionEngineSettingsClay", "LayerCollectionSettings");
+ RNA_def_struct_ui_text(srna, "Collections Clay Engine Settings", "Engine specific settings for this collection");
+
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+ prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_icon_get", "rna_LayerEngineSettings_Clay_matcap_icon_set", NULL);
+ RNA_def_property_enum_items(prop, clay_matcap_items);
+ RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture by this material");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "matcap_rotation", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_rotation_get", "rna_LayerEngineSettings_Clay_matcap_rotation_set", NULL);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Matcap Rotation", "Orientation of the matcap on the model");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "matcap_hue", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_hue_get", "rna_LayerEngineSettings_Clay_matcap_hue_set", NULL);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Matcap Hue Shift", "Hue correction of the matcap");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "matcap_saturation", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_saturation_get", "rna_LayerEngineSettings_Clay_matcap_saturation_set", NULL);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Matcap Saturation", "Saturation correction of the matcap");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "matcap_value", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_matcap_value_get", "rna_LayerEngineSettings_Clay_matcap_value_set", NULL);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Matcap Value", "Value correction of the matcap");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "ssao_factor_cavity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_factor_cavity_get", "rna_LayerEngineSettings_Clay_ssao_factor_cavity_set", NULL);
+ RNA_def_property_ui_text(prop, "Cavity Strength", "Strength of the Cavity effect");
+ RNA_def_property_range(prop, 0.0f, 250.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "ssao_factor_edge", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_factor_edge_get", "rna_LayerEngineSettings_Clay_ssao_factor_edge_set", NULL);
+ RNA_def_property_ui_text(prop, "Edge Strength", "Strength of the Edge effect");
+ RNA_def_property_range(prop, 0.0f, 250.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "ssao_distance", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_distance_get", "rna_LayerEngineSettings_Clay_ssao_distance_set", NULL);
+ RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the Cavity/Edge effect");
+ RNA_def_property_range(prop, 0.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "ssao_attenuation", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_ssao_attenuation_get", "rna_LayerEngineSettings_Clay_ssao_attenuation_set", NULL);
+ RNA_def_property_ui_text(prop, "Attenuation", "Attenuation constant");
+ RNA_def_property_range(prop, 1.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, 1.0f, 100.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "hair_brightness_randomness", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Clay_hair_brightness_randomness_get", "rna_LayerEngineSettings_Clay_hair_brightness_randomness_set", NULL);
+ RNA_def_property_ui_text(prop, "Hair Brightness Randomness", "Brightness randomness for hair");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+#endif /* WITH_CLAY_ENGINE */
+
+static void rna_def_layer_collection_mode_settings_object(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LayerCollectionModeSettingsObject", "LayerCollectionSettings");
+ RNA_def_struct_ui_text(srna, "Collections Object Mode Settings", "Object Mode specific settings for this collection");
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+
+ prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Wire", "Add the object's wireframe over solid drawing");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_ObjectMode_show_wire_get", "rna_LayerEngineSettings_ObjectMode_show_wire_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "show_backface_culling", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Backface Culling", "");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_ObjectMode_show_backface_culling_get", "rna_LayerEngineSettings_ObjectMode_show_backface_culling_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+
+static void rna_def_layer_collection_mode_settings_edit(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LayerCollectionModeSettingsEdit", "LayerCollectionSettings");
+ RNA_def_struct_ui_text(srna, "Collections Edit Mode Settings", "Edit Mode specific settings to be overridden per collection");
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+
+ prop = RNA_def_property(srna, "show_occlude_wire", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Hidden Wire", "Use hidden wireframe display");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_show_occlude_wire_get", "rna_LayerEngineSettings_EditMode_show_occlude_wire_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "show_weight", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Weights", "Draw weights in editmode");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_show_weight_get", "rna_LayerEngineSettings_EditMode_show_weight_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "face_normals_show", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Draw Normals", "Display face normals as lines");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_face_normals_show_get", "rna_LayerEngineSettings_EditMode_face_normals_show_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "vert_normals_show", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Draw Vertex Normals", "Display vertex normals as lines");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_vert_normals_show_get", "rna_LayerEngineSettings_EditMode_vert_normals_show_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "loop_normals_show", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Draw Split Normals", "Display vertex-per-face normals as lines");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_loop_normals_show_get", "rna_LayerEngineSettings_EditMode_loop_normals_show_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "normals_length", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_ui_text(prop, "Normal Size", "Display size for normals in the 3D view");
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_EditMode_normals_length_get", "rna_LayerEngineSettings_EditMode_normals_length_set", NULL);
+ RNA_def_property_range(prop, 0.00001, 1000.0);
+ RNA_def_property_ui_range(prop, 0.01, 10.0, 10.0, 2);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "backwire_opacity", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_ui_text(prop, "Backwire Opacity", "Opacity when rendering transparent wires");
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_EditMode_backwire_opacity_get", "rna_LayerEngineSettings_EditMode_backwire_opacity_set", NULL);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+
+static void rna_def_layer_collection_mode_settings_paint_weight(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LayerCollectionModeSettingsPaintWeight", "LayerCollectionSettings");
+ RNA_def_struct_ui_text(srna, "Collections Weight Paint Mode Settings", "Weight Paint Mode specific settings to be overridden per collection");
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+
+ prop = RNA_def_property(srna, "use_shading", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Use Shading", "Whether to use shaded or shadeless drawing");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_PaintWeightMode_use_shading_get", "rna_LayerEngineSettings_PaintWeightMode_use_shading_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "use_wire", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Wire", "Whether to overlay wireframe onto the mesh");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_PaintWeightMode_use_wire_get", "rna_LayerEngineSettings_PaintWeightMode_use_wire_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_wire_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+
+static void rna_def_layer_collection_mode_settings_paint_vertex(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LayerCollectionModeSettingsPaintVertex", "LayerCollectionSettings");
+ RNA_def_struct_ui_text(srna, "Collections Vertex Paint Mode Settings", "Vertex Paint Mode specific settings to be overridden per collection");
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+
+ prop = RNA_def_property(srna, "use_shading", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Use Shading", "Whether to use shaded or shadeless drawing");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_PaintVertexMode_use_shading_get", "rna_LayerEngineSettings_PaintVertexMode_use_shading_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "use_wire", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Wire", "Whether to overlay wireframe onto the mesh");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_PaintVertexMode_use_wire_get", "rna_LayerEngineSettings_PaintVertexMode_use_wire_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_wire_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+
+static void rna_def_scene_layer_settings(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ srna = RNA_def_struct(brna, "SceneLayerSettings", NULL);
+ RNA_def_struct_sdna(srna, "IDProperty");
+ RNA_def_struct_ui_text(srna, "Scene Layer Settings",
+ "Engine specific settings that can be overriden by SceneLayer");
+ RNA_def_struct_refine_func(srna, "rna_SceneLayerSettings_refine");
+
+ RNA_define_verify_sdna(0);
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_SceneLayerSettings_name_get", "rna_SceneLayerSettings_name_length", NULL);
+ RNA_def_property_ui_text(prop, "Name", "Engine Name");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_struct_name_property(srna, prop);
+
+ func = RNA_def_function(srna, "use", "rna_SceneLayerSettings_use");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Initialize this property to use");
+ parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to set");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "unuse", "rna_SceneLayerSettings_unuse");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Remove the property");
+ parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to unset");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+#ifdef WITH_CLAY_ENGINE
+ rna_def_scene_layer_engine_settings_clay(brna);
+#endif
+ rna_def_scene_layer_engine_settings_eevee(brna);
+
+#if 0
+ rna_def_scene_layer_mode_settings_object(brna);
+ rna_def_scene_layer_mode_settings_edit(brna);
+ rna_def_scene_layer_mode_settings_paint_weight(brna);
+ rna_def_scene_layer_mode_settings_paint_vertex(brna);
+#endif
+
+ RNA_define_verify_sdna(1);
+}
+
+static void rna_def_layer_collection_settings(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ srna = RNA_def_struct(brna, "LayerCollectionSettings", NULL);
+ RNA_def_struct_sdna(srna, "IDProperty");
+ RNA_def_struct_ui_text(srna, "Layer Collection Settings",
+ "Engine specific settings that can be overriden by LayerCollection");
+ RNA_def_struct_refine_func(srna, "rna_LayerCollectionSettings_refine");
+
+ RNA_define_verify_sdna(0);
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_LayerCollectionSettings_name_get", "rna_LayerCollectionSettings_name_length", NULL);
+ RNA_def_property_ui_text(prop, "Name", "Engine Name");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_struct_name_property(srna, prop);
+
+ func = RNA_def_function(srna, "use", "rna_LayerCollectionSettings_use");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Initialize this property to use");
+ parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to set");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "unuse", "rna_LayerCollectionSettings_unuse");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Remove the property");
+ parm = RNA_def_string(func, "identifier", NULL, 0, "Property Name", "Name of the property to unset");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+#ifdef WITH_CLAY_ENGINE
+ rna_def_layer_collection_engine_settings_clay(brna);
+#endif
+
+ rna_def_layer_collection_mode_settings_object(brna);
+ rna_def_layer_collection_mode_settings_edit(brna);
+ rna_def_layer_collection_mode_settings_paint_weight(brna);
+ rna_def_layer_collection_mode_settings_paint_vertex(brna);
+
+ RNA_define_verify_sdna(1);
+}
+
+static void rna_def_layer_collection(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ srna = RNA_def_struct(brna, "LayerCollection", NULL);
+ RNA_def_struct_ui_text(srna, "Layer Collection", "Layer collection");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_LayerCollection_name_get", "rna_LayerCollection_name_length", "rna_LayerCollection_name_set");
+ RNA_def_property_ui_text(prop, "Name", "Collection name");
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+
+ prop = RNA_def_property(srna, "collection", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "scene_collection");
+ RNA_def_property_struct_type(prop, "SceneCollection");
+ RNA_def_property_ui_text(prop, "Collection", "Collection this layer collection is wrapping");
+
+ prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "layer_collections", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollection");
+ RNA_def_property_ui_text(prop, "Layer Collections", "");
+
+ prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_LayerCollection_objects_get", NULL, NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Objects", "All the objects directly or indirectly added to this collection (not including sub-collection objects)");
+
+ prop = RNA_def_property(srna, "overrides", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "overrides", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollectionOverride");
+ RNA_def_property_ui_text(prop, "Collection Overrides", "");
+
+ /* Override settings */
+ prop = RNA_def_property(srna, "engine_overrides", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "properties->data.group", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollectionSettings");
+ RNA_def_property_ui_text(prop, "Collection Settings", "Override of engine specific render settings");
+
+ /* Functions */
+ func = RNA_def_function(srna, "move_above", "rna_LayerCollection_move_above");
+ RNA_def_function_ui_description(func, "Move collection after another");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "lc_dst", "LayerCollection", "Collection", "Reference collection above which the collection will move");
+ parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "move_below", "rna_LayerCollection_move_below");
+ RNA_def_function_ui_description(func, "Move collection before another");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "lc_dst", "LayerCollection", "Collection", "Reference collection below which the collection will move");
+ parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "move_into", "rna_LayerCollection_move_into");
+ RNA_def_function_ui_description(func, "Move collection into another");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "lc_dst", "LayerCollection", "Collection", "Collection to insert into");
+ parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
+ RNA_def_function_return(func, parm);
+
+ /* Flags */
+ prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_VISIBLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
+ RNA_def_property_ui_text(prop, "Hide", "Restrict visiblity");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_flag_update");
+
+ prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_SELECTABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 1);
+ RNA_def_property_ui_text(prop, "Hide Selectable", "Restrict selection");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_flag_update");
+
+ /* TODO_LAYER_OVERRIDE */
+}
+
+static void rna_def_layer_collections(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *prop;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "LayerCollections");
+ srna = RNA_def_struct(brna, "LayerCollections", NULL);
+ RNA_def_struct_sdna(srna, "SceneLayer");
+ RNA_def_struct_ui_text(srna, "Layer Collections", "Collections of render layer");
+
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "active_collection");
+ RNA_def_property_int_funcs(prop, "rna_LayerCollections_active_collection_index_get",
+ "rna_LayerCollections_active_collection_index_set",
+ "rna_LayerCollections_active_collection_index_range");
+ RNA_def_property_ui_text(prop, "Active Collection Index", "Active index in layer collection array");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL);
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "LayerCollection");
+ RNA_def_property_pointer_funcs(prop, "rna_LayerCollections_active_collection_get",
+ "rna_LayerCollections_active_collection_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Active Layer Collection", "Active Layer Collection");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL);
+
+ func = RNA_def_function(srna, "link", "rna_SceneLayer_collection_link");
+ RNA_def_function_ui_description(func, "Link a collection to render layer");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_pointer(func, "scene_collection", "SceneCollection", "", "Collection to add to render layer");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "result", "LayerCollection", "", "Newly created layer collection");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "unlink", "rna_SceneLayer_collection_unlink");
+ RNA_def_function_ui_description(func, "Unlink a collection from render layer");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "layer_collection", "LayerCollection", "", "Layer collection to remove from render layer");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+}
+
+static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ RNA_def_property_srna(cprop, "LayerObjects");
+ srna = RNA_def_struct(brna, "LayerObjects", NULL);
+ RNA_def_struct_sdna(srna, "SceneLayer");
+ RNA_def_struct_ui_text(srna, "Layer Objects", "Collections of objects");
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_funcs(prop, "rna_LayerObjects_active_object_get", "rna_LayerObjects_active_object_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+ RNA_def_property_ui_text(prop, "Active Object", "Active object for this layer");
+ /* Could call: ED_base_object_activate(C, rl->basact);
+ * but would be a bad level call and it seems the notifier is enough */
+ RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+
+ prop = RNA_def_property(srna, "selected", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_collection_funcs(prop, "rna_LayerObjects_selected_begin", "rna_iterator_listbase_next",
+ "rna_iterator_listbase_end", "rna_SceneLayer_objects_get",
+ NULL, NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Selected Objects", "All the selected objects of this layer");
+}
+
+static void rna_def_scene_layer(BlenderRNA *brna)
+{
+ FunctionRNA *func;
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem engine_items[] = {
+ {0, "BLENDER_RENDER", 0, "Blender Render", "Use the Blender internal rendering engine for rendering"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "SceneLayer", NULL);
+ RNA_def_struct_ui_text(srna, "Render Layer", "Render layer");
+ RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneLayer_name_set");
+ RNA_def_property_ui_text(prop, "Name", "Render layer name");
+ RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+
+ prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "layer_collections", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollection");
+ RNA_def_property_ui_text(prop, "Layer Collections", "");
+ rna_def_layer_collections(brna, prop);
+
+ prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SceneLayer_objects_get", NULL, NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Objects", "All the objects in this layer");
+ rna_def_layer_objects(brna, prop);
+
+ /* layer options */
+ prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SCENE_LAYER_RENDER);
+ RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the render layer");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL);
+
+ /* Override settings */
+ prop = RNA_def_property(srna, "engine_overrides", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "properties->data.group", NULL);
+ RNA_def_property_struct_type(prop, "SceneLayerSettings");
+ RNA_def_property_ui_text(prop, "Layer Settings", "Override of engine specific render settings");
+
+ /* engine */
+ prop = RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, engine_items);
+ RNA_def_property_enum_funcs(prop, "rna_SceneLayer_engine_get", "rna_SceneLayer_engine_set",
+ "rna_SceneLayer_engine_itemf");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering");
+ RNA_def_property_update(prop, NC_WINDOW, "rna_SceneLayer_engine_update");
+
+ prop = RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_SceneLayer_multiple_engines_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available");
+
+ /* debug update routine */
+ func = RNA_def_function(srna, "update", "rna_SceneLayer_update_tagged");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func,
+ "Update data tagged to be updated from previous access to data or operators");
+}
+
+static void rna_def_scene_layers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+ PropertyRNA *prop;
+
+ RNA_def_property_srna(cprop, "SceneLayers");
+ srna = RNA_def_struct(brna, "SceneLayers", NULL);
+ RNA_def_struct_sdna(srna, "Scene");
+ RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers");
+
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "active_layer");
+ RNA_def_property_int_funcs(prop, "rna_SceneLayer_active_layer_index_get",
+ "rna_SceneLayer_active_layer_index_set",
+ "rna_SceneLayer_active_layer_index_range");
+ RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL);
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "SceneLayer");
+ RNA_def_property_pointer_funcs(prop, "rna_SceneLayer_active_layer_get",
+ "rna_SceneLayer_active_layer_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Active Render Layer", "Active Render Layer");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL);
+
+ func = RNA_def_function(srna, "new", "rna_SceneLayer_new");
+ RNA_def_function_ui_description(func, "Add a render layer to scene");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ parm = RNA_def_string(func, "name", "SceneLayer", 0, "", "New name for the render layer (not unique)");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "result", "SceneLayer", "", "Newly created render layer");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_SceneLayer_remove");
+ RNA_def_function_ui_description(func, "Remove a render layer");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "layer", "SceneLayer", "", "Render layer to remove");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
+}
+
+static void rna_def_object_base(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ObjectBase", NULL);
+ RNA_def_struct_sdna(srna, "Base");
+ RNA_def_struct_ui_text(srna, "Object Base", "An object instance in a render layer");
+ RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA);
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "object");
+ RNA_def_property_ui_text(prop, "Object", "Object this base links to");
+
+ prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_SELECTED);
+ RNA_def_property_ui_text(prop, "Select", "Object base selection state");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_select_update");
+}
+
+/* TODO LAYERS: legacy SceneRenderLayers, to be removed */
static void rna_def_scene_render_layer(BlenderRNA *brna)
{
@@ -6801,7 +8615,7 @@ static void rna_def_scene_objects(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "object", "Object", "", "Object to add to scene");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
- parm = RNA_def_pointer(func, "base", "ObjectBase", "", "The newly created base");
+ parm = RNA_def_pointer(func, "base", "ObjectBaseLegacy", "", "The newly created base");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "unlink", "rna_Scene_object_unlink");
@@ -6836,7 +8650,7 @@ static void rna_def_scene_bases(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "Scene Bases", "Collection of scene bases");
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "ObjectBase");
+ RNA_def_property_struct_type(prop, "ObjectBaseLegacy");
RNA_def_property_pointer_sdna(prop, NULL, "basact");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Base", "Active object base in the scene");
@@ -7080,7 +8894,7 @@ void RNA_def_scene(BlenderRNA *brna)
/* Bases/Objects */
prop = RNA_def_property(srna, "object_bases", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "base", NULL);
- RNA_def_property_struct_type(prop, "ObjectBase");
+ RNA_def_property_struct_type(prop, "ObjectBaseLegacy");
RNA_def_property_ui_text(prop, "Bases", "");
RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL,
"rna_Scene_object_bases_lookup_string", NULL);
@@ -7329,7 +9143,20 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "r");
RNA_def_property_struct_type(prop, "RenderSettings");
RNA_def_property_ui_text(prop, "Render Data", "");
-
+
+ /* Render Engine Data */
+ prop = RNA_def_property(srna, "layer_properties", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "layer_properties->data.group", NULL);
+ RNA_def_property_struct_type(prop, "SceneLayerSettings");
+ RNA_def_property_ui_text(prop, "Layer Settings",
+ "Engine specific render settings to be overridden by layers");
+
+ prop = RNA_def_property(srna, "collection_properties", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "collection_properties->data.group", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollectionSettings");
+ RNA_def_property_ui_text(prop, "Collection Settings",
+ "Engine specific render settings to be overridden by collections");
+
/* Safe Areas */
prop = RNA_def_property(srna, "safe_areas", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "safe_areas");
@@ -7399,6 +9226,8 @@ void RNA_def_scene(BlenderRNA *brna)
/* Statistics */
func = RNA_def_function(srna, "statistics", "ED_info_stats_string");
+ parm = RNA_def_pointer(func, "scene_layer", "SceneLayer", "", "Active layer");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", "");
RNA_def_function_return(func, parm);
@@ -7445,6 +9274,19 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Depsgraph");
RNA_def_property_ui_text(prop, "Dependency Graph", "Dependencies in the scene data");
+ /* Layer and Collections */
+ prop = RNA_def_property(srna, "render_layers", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "render_layers", NULL);
+ RNA_def_property_struct_type(prop, "SceneLayer");
+ RNA_def_property_ui_text(prop, "Render Layers", "");
+ rna_def_scene_layers(brna, prop);
+
+ prop = RNA_def_property(srna, "master_collection", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "collection");
+ RNA_def_property_struct_type(prop, "SceneCollection");
+ RNA_def_property_ui_text(prop, "Master Collection", "Collection that contains all other collections");
+
/* Nestled Data */
/* *** Non-Animated *** */
RNA_define_animate_sdna(false);
@@ -7460,8 +9302,15 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_transform_orientation(brna);
rna_def_selected_uv_element(brna);
rna_def_display_safe_areas(brna);
+ rna_def_scene_collection(brna);
+ rna_def_layer_collection(brna);
+ rna_def_layer_collection_override(brna);
+ rna_def_scene_layer(brna);
+ rna_def_object_base(brna);
RNA_define_animate_sdna(true);
/* *** Animated *** */
+ rna_def_scene_layer_settings(brna);
+ rna_def_layer_collection_settings(brna);
rna_def_scene_render_data(brna);
rna_def_scene_render_layer(brna);
rna_def_gpu_fx(brna);
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index a80e4c60127..f9f4e1dcdb4 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -86,8 +86,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
BPy_BEGIN_ALLOW_THREADS;
#endif
- /* It's possible that here we're including layers which were never visible before. */
- BKE_scene_update_for_newframe_ex(G.main->eval_ctx, G.main, scene, (1 << 20) - 1, true);
+ BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
@@ -112,7 +111,7 @@ static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect)
if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) {
BMEditMesh *em;
em = BKE_editmesh_from_object(ob);
- if (EDBM_mtexpoly_check(em)) {
+ if (EDBM_uv_check(em)) {
ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1);
return;
}
@@ -153,14 +152,14 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int previe
}
static void rna_Scene_ray_cast(
- Scene *scene, float origin[3], float direction[3], float ray_dist,
+ Scene *scene, SceneLayer *sl, float origin[3], float direction[3], float ray_dist,
int *r_success, float r_location[3], float r_normal[3], int *r_index,
Object **r_ob, float r_obmat[16])
{
normalize_v3(direction);
SnapObjectContext *sctx = ED_transform_snap_object_context_create(
- G.main, scene, 0);
+ G.main, scene, sl, 0);
bool ret = ED_transform_snap_object_project_ray_ex(
sctx,
@@ -270,6 +269,7 @@ static void rna_Scene_alembic_export(
/* Note: This definition must match to the generated function call */
static void rna_Scene_collada_export(
Scene *scene,
+ bContext *C,
const char *filepath,
int apply_modifiers,
@@ -280,7 +280,6 @@ static void rna_Scene_collada_export(
int include_shapekeys,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
int include_material_textures,
int use_texture_copies,
int triangulate,
@@ -293,6 +292,7 @@ static void rna_Scene_collada_export(
int keep_bind_info)
{
collada_export(scene,
+ CTX_data_scene_layer(C),
filepath,
apply_modifiers,
@@ -305,7 +305,6 @@ static void rna_Scene_collada_export(
deform_bones_only,
active_uv_only,
- include_uv_textures,
include_material_textures,
use_texture_copies,
@@ -350,6 +349,8 @@ void RNA_api_scene(StructRNA *srna)
/* Ray Cast */
func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast");
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
+ parm = RNA_def_pointer(func, "scene_layer", "SceneLayer", "", "Scene Layer");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
/* ray start and end */
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
@@ -403,9 +404,6 @@ void RNA_api_scene(StructRNA *srna)
RNA_def_boolean(func, "active_uv_only", false, "Only Selected UV Map", "Export only the selected UV Map");
- RNA_def_boolean(func, "include_uv_textures", false,
- "Include UV Textures", "Export textures assigned to the object UV Maps");
-
RNA_def_boolean(func, "include_material_textures", false,
"Include Material Textures", "Export textures assigned to the object Materials");
@@ -436,6 +434,8 @@ void RNA_api_scene(StructRNA *srna)
"Keep Bind Info",
"Store bind pose information in custom bone properties for later use during Collada export");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
#endif
#ifdef WITH_ALEMBIC
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 40aea37d9d2..418527b85f2 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -148,10 +148,12 @@ static PointerRNA rna_ParticleBrush_curve_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_CurveMapping, NULL);
}
-static void rna_ParticleEdit_redo(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_ParticleEdit_redo(bContext *C, PointerRNA *UNUSED(ptr))
{
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
if (!edit)
return;
@@ -159,19 +161,21 @@ static void rna_ParticleEdit_redo(Main *UNUSED(bmain), Scene *scene, PointerRNA
psys_free_path_cache(edit->psys, edit);
}
-static void rna_ParticleEdit_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_ParticleEdit_update(Main *UNUSED(bmain), Scene *UNUSED(scene), bContext *C, PointerRNA *UNUSED(ptr))
{
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if (ob) DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
+
static void rna_ParticleEdit_tool_set(PointerRNA *ptr, int value)
{
ParticleEditSettings *pset = (ParticleEditSettings *)ptr->data;
/* redraw hair completely if weight brush is/was used */
- if ((pset->brushtype == PE_BRUSH_WEIGHT || value == PE_BRUSH_WEIGHT) && pset->scene) {
- Object *ob = (pset->scene->basact) ? pset->scene->basact->object : NULL;
+ if ((pset->brushtype == PE_BRUSH_WEIGHT || value == PE_BRUSH_WEIGHT) && pset->scene_layer) {
+ Object *ob = (pset->scene_layer->basact) ? pset->scene_layer->basact->object : NULL;
if (ob) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
@@ -183,9 +187,10 @@ static void rna_ParticleEdit_tool_set(PointerRNA *ptr, int value)
static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
#if 0
+ Scene *scene = CTX_data_scene(C);
PTCacheEdit *edit = PE_get_current(scene, ob);
ParticleSystem *psys = edit ? edit->psys : NULL;
#else
@@ -211,14 +216,14 @@ static int rna_ParticleEdit_editable_get(PointerRNA *ptr)
{
ParticleEditSettings *pset = (ParticleEditSettings *)ptr->data;
- return (pset->object && pset->scene && PE_get_current(pset->scene, pset->object));
+ return (pset->object && pset->scene && PE_get_current(pset->scene, pset->scene_layer, pset->object));
}
static int rna_ParticleEdit_hair_get(PointerRNA *ptr)
{
ParticleEditSettings *pset = (ParticleEditSettings *)ptr->data;
if (pset->scene) {
- PTCacheEdit *edit = PE_get_current(pset->scene, pset->object);
+ PTCacheEdit *edit = PE_get_current(pset->scene, pset->scene_layer, pset->object);
return (edit && edit->psys);
}
@@ -253,9 +258,10 @@ static int rna_Brush_mode_poll(PointerRNA *ptr, PointerRNA value)
return brush->ob_mode & mode;
}
-static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Sculpt_update(bContext *C, Scene *scene, PointerRNA *UNUSED(ptr))
{
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if (ob) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -268,9 +274,10 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU
}
}
-static void rna_Sculpt_ShowDiffuseColor_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Sculpt_ShowDiffuseColor_update(bContext *C, Scene *scene, PointerRNA *UNUSED(ptr))
{
- Object *ob = (scene->basact) ? scene->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if (ob && ob->sculpt) {
Sculpt *sd = scene->toolsettings->sculpt;
@@ -329,9 +336,11 @@ static void rna_ImaPaint_viewport_update(Main *UNUSED(bmain), Scene *UNUSED(scen
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
}
-static void rna_ImaPaint_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_ImaPaint_mode_update(bContext *C, PointerRNA *UNUSED(ptr))
{
- Object *ob = OBACT;
+ Scene *scene = CTX_data_scene(C);\
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if (ob && ob->type == OB_MESH) {
/* of course we need to invalidate here */
@@ -344,9 +353,11 @@ static void rna_ImaPaint_mode_update(Main *UNUSED(bmain), Scene *scene, PointerR
}
}
-static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr))
{
- Object *ob = OBACT;
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if (ob && ob->type == OB_MESH) {
GPU_drawobject_free(ob->derivedFinal);
@@ -355,19 +366,22 @@ static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *scene, Point
}
}
-static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
{
- Object *ob = OBACT;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
bScreen *sc;
Image *ima = scene->toolsettings->imapaint.canvas;
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
+ SpaceLink *slink;
+ for (slink = sa->spacedata.first; slink; slink = slink->next) {
+ if (slink->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)slink;
if (!sima->pin)
ED_space_image_set(sima, scene, scene->obedit, ima);
@@ -582,12 +596,14 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Deform Only",
"Use only deformation modifiers (temporary disable all "
"constructive modifiers except multi-resolution)");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
prop = RNA_def_property(srna, "show_diffuse_color", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_SHOW_DIFFUSE);
RNA_def_property_ui_text(prop, "Show Diffuse Color",
"Show diffuse color of object and overlay sculpt mask on top of it");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowDiffuseColor_update");
prop = RNA_def_property(srna, "detail_size", PROP_FLOAT, PROP_PIXEL);
@@ -613,6 +629,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Smooth Shading",
"Show faces in dynamic-topology mode with smooth "
"shading rather than flat shaded");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE);
@@ -740,12 +757,12 @@ static void rna_def_image_paint(BlenderRNA *brna)
prop = RNA_def_property(srna, "stencil_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "stencil");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Stencil Image", "Image used as stencil");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
prop = RNA_def_property(srna, "canvas", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Canvas", "Image used as canvas");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_canvas_update");
@@ -787,6 +804,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_range(prop, 512, 16384);
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_items(prop, paint_type_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of operation for projection painting");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
@@ -866,6 +884,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "selectmode");
RNA_def_property_enum_items(prop, select_mode_items);
RNA_def_property_ui_text(prop, "Selection Mode", "Particle select and display mode");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_update");
prop = RNA_def_property(srna, "use_preserve_length", PROP_BOOLEAN, PROP_NONE);
@@ -888,6 +907,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_fade_time", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_FADE_TIME);
RNA_def_property_ui_text(prop, "Fade Time", "Fade paths and keys further away from current frame");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_update");
prop = RNA_def_property(srna, "use_auto_velocity", PROP_BOOLEAN, PROP_NONE);
@@ -895,6 +915,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Auto Velocity", "Calculate point velocities automatically");
prop = RNA_def_property(srna, "show_particles", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_DRAW_PART);
RNA_def_property_ui_text(prop, "Draw Particles", "Draw actual particles");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_redo");
@@ -915,6 +936,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Brush", "");
prop = RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_text(prop, "Steps", "How many steps to draw the path with");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_redo");
@@ -922,9 +944,11 @@ static void rna_def_particle_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "fade_frames", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 1, 100);
RNA_def_property_ui_text(prop, "Frames", "How many frames to fade");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_update");
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_sdna(prop, NULL, "edittype");
RNA_def_property_enum_items(prop, edit_type_items);
RNA_def_property_ui_text(prop, "Type", "");
@@ -945,7 +969,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Object", "The edited object");
prop = RNA_def_property(srna, "shape_object", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Shape Object", "Outer shape to use for tools");
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Mesh_object_poll");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_redo");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index f2e856bf1ba..0eedcb25b4c 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -208,6 +208,7 @@ static EnumPropertyItem buttons_context_items[] = {
{BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
{BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"},
{BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
+ {BCONTEXT_COLLECTION, "COLLECTION", ICON_COLLAPSEMENU, "Collection", "Collection"},
{0, NULL, 0, NULL, NULL}
};
@@ -254,6 +255,7 @@ EnumPropertyItem rna_enum_file_sort_items[] = {
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
#include "BKE_nla.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
@@ -699,7 +701,7 @@ static int rna_SpaceView3D_viewport_shade_get(PointerRNA *ptr)
View3D *v3d = (View3D *)ptr->data;
int drawtype = v3d->drawtype;
- if (drawtype == OB_RENDER && !(type && type->view_draw))
+ if (drawtype == OB_RENDER && !(type && type->render_to_view))
return OB_SOLID;
return drawtype;
@@ -729,7 +731,7 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_TEXTURE);
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_MATERIAL);
- if (type && type->view_draw)
+ if (type && type->render_to_view)
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_RENDER);
RNA_enum_item_end(&item, &totitem);
@@ -816,7 +818,11 @@ static int rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr)
{
SpaceImage *sima = (SpaceImage *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
- return ED_space_image_check_show_maskedit(sc->scene, sima);
+
+ TODO_LAYER_CONTEXT; /* get SceneLayer from context/window/workspace instead */
+ SceneLayer *sl = BKE_scene_layer_context_active(sc->scene);
+
+ return ED_space_image_check_show_maskedit(sl, sima);
}
static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value)
@@ -1076,6 +1082,10 @@ static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSED(C),
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE);
}
+ if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_COLLECTION);
+ }
+
if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD);
}
@@ -1261,10 +1271,11 @@ static void rna_SpaceDopeSheetEditor_action_set(PointerRNA *ptr, PointerRNA valu
}
}
-static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, bContext *C, Scene *UNUSED(scene), PointerRNA *ptr)
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
- Object *obact = (scene->basact) ? scene->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *obact = OBACT_NEW;
/* we must set this action to be the one used by active object (if not pinned) */
if (obact /* && saction->pin == 0*/) {
@@ -1336,10 +1347,11 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, Po
}
}
-static void rna_SpaceDopeSheetEditor_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_SpaceDopeSheetEditor_mode_update(bContext *C, PointerRNA *ptr)
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
- Object *obact = (scene->basact) ? scene->basact->object : NULL;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *obact = OBACT_NEW;
/* special exceptions for ShapeKey Editor mode */
if (saction->mode == SACTCONT_SHAPEKEY) {
@@ -2101,6 +2113,9 @@ static void rna_def_space_outliner(BlenderRNA *brna)
{SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display user preference data"},
{SO_ID_ORPHANS, "ORPHAN_DATA", 0, "Orphan Data",
"Display data-blocks which are unused and/or will be lost when the file is reloaded"},
+ {SO_ACT_LAYER, "ACT_LAYER", 0, "Active Render Layer", "Display the collections of the active render layer"},
+ {SO_COLLECTIONS, "MASTER_COLLECTION", 0, "Master Collection Tree", "Display all collections based on the "
+ "master collection hierarchy"},
{0, NULL, 0, NULL, NULL}
};
@@ -3406,6 +3421,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceDopeSheetEditor_action_set", NULL,
"rna_Action_actedit_assign_poll");
RNA_def_property_ui_text(prop, "Action", "Action displayed and edited in this space");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_SpaceDopeSheetEditor_action_update");
/* mode */
@@ -3413,6 +3429,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, "rna_SpaceDopeSheetEditor_mode_update");
/* display */
@@ -4395,14 +4412,10 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Backdrop Zoom", "Backdrop zoom factor");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
- prop = RNA_def_property(srna, "backdrop_x", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "backdrop_offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xof");
- RNA_def_property_ui_text(prop, "Backdrop X", "Backdrop X offset");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
-
- prop = RNA_def_property(srna, "backdrop_y", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "yof");
- RNA_def_property_ui_text(prop, "Backdrop Y", "Backdrop Y offset");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_text(prop, "Backdrop Offset", "Backdrop offset");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
prop = RNA_def_property(srna, "backdrop_channels", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 1e88585a286..a05cc8edb11 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -225,7 +225,7 @@ static void rna_Texture_type_set(PointerRNA *ptr, int value)
BKE_texture_type_set(tex, value);
}
-void rna_TextureSlot_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+void rna_TextureSlot_update(bContext *C, PointerRNA *ptr)
{
ID *id = ptr->id.data;
@@ -245,8 +245,10 @@ void rna_TextureSlot_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
break;
case ID_BR:
{
+ Scene *scene = CTX_data_scene(C);
MTex *mtex = ptr->data;
- BKE_paint_invalidate_overlay_tex(scene, mtex->tex);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ BKE_paint_invalidate_overlay_tex(scene, sl, mtex->tex);
WM_main_add_notifier(NC_BRUSH, id);
break;
}
@@ -645,7 +647,7 @@ static void rna_def_mtex(BlenderRNA *brna)
prop = RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tex");
RNA_def_property_struct_type(prop, "Texture");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Texture", "Texture data-block used by this texture slot");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, "rna_TextureSlot_update");
@@ -653,6 +655,7 @@ static void rna_def_mtex(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_TextureSlot_name_get", "rna_TextureSlot_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Texture slot name");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
@@ -660,12 +663,13 @@ static void rna_def_mtex(BlenderRNA *brna)
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "ofs");
RNA_def_property_ui_range(prop, -10, 10, 10, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Offset", "Fine tune of the texture mapping X, Y and Z locations");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
- RNA_def_property_flag(prop, PROP_PROPORTIONAL);
+ RNA_def_property_flag(prop, PROP_PROPORTIONAL | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_range(prop, -100, 100, 10, 2);
RNA_def_property_ui_text(prop, "Size", "Set scaling for the texture's X, Y and Z sizes");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
@@ -673,6 +677,7 @@ static void rna_def_mtex(BlenderRNA *brna)
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "r");
RNA_def_property_array(prop, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Color",
"Default color for textures that don't return RGB or when RGB to intensity is enabled");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
@@ -680,26 +685,31 @@ static void rna_def_mtex(BlenderRNA *brna)
prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "blendtype");
RNA_def_property_enum_items(prop, blend_type_items);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Blend Type", "Mode used to apply the texture");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "use_stencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_STENCIL);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Stencil", "Use this texture as a blending value on the next texture");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_NEGATIVE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Negate", "Invert the values of the texture to reverse its effect");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "use_rgb_to_intensity", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_RGBTOINT);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "RGB to Intensity", "Convert texture RGB values to intensity (gray) values");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "def_var");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Default Value",
"Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard");
@@ -708,6 +718,7 @@ static void rna_def_mtex(BlenderRNA *brna)
prop = RNA_def_property(srna, "output_node", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "which_output");
RNA_def_property_enum_items(prop, output_node_items);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_funcs(prop, "rna_TextureSlot_output_node_get", NULL, "rna_TextureSlot_output_node_itemf");
RNA_def_property_ui_text(prop, "Output Node", "Which output node to use, for node-based textures");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 46775af21db..abad70a46d2 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -671,7 +671,31 @@ void RNA_api_ui_layout(StructRNA *srna)
"Identifier of property in data giving the type of the ID-blocks to use");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
api_ui_item_common_text(func);
-
+
+ func = RNA_def_function(srna, "template_search", "uiTemplateSearch");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ parm = RNA_def_string(func, "search_property", NULL, 0, "", "Identifier of search collection property");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new item for the collection");
+ RNA_def_string(func, "unlink", NULL, 0, "", "Operator identifier to unlink or delete the active "
+ "item from the collection");
+
+ func = RNA_def_function(srna, "template_search_preview", "uiTemplateSearchPreview");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ parm = RNA_def_string(func, "search_property", NULL, 0, "", "Identifier of search collection property");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new item for the collection");
+ RNA_def_string(func, "unlink", NULL, 0, "", "Operator identifier to unlink or delete the active "
+ "item from the collection");
+ RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
+ RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX);
+
func = RNA_def_function(srna, "template_path_builder", "rna_uiTemplatePathBuilder");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
@@ -888,6 +912,15 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_pointer(func, "item", "KeyMapItem", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ func = RNA_def_function(srna, "template_override_property", "uiTemplateOverrideProperty");
+ parm = RNA_def_pointer(func, "collection_render_overrides", "AnyType", "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ parm = RNA_def_pointer(func, "scene_collection_properties", "AnyType", "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+ parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in collection_properties");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_string(func, "custom_template", NULL, 0, "", "Optional template to use for property");
+
func = RNA_def_function(srna, "template_component_menu", "uiTemplateComponentMenu");
RNA_def_function_ui_description(func, "Item. Display expanded property in a popup menu");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 7c1ef6b0d87..202ba63c850 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -119,6 +119,7 @@ static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr)
ED_node_shader_default(C, &wrld->id);
rna_World_update(CTX_data_main(C), CTX_data_scene(C), ptr);
+ rna_World_draw_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
#else
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index ad2b862141c..d6a7b94505f 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -114,10 +114,6 @@ set(SRC
intern/MOD_weightvg_util.h
)
-if(WITH_LEGACY_DEPSGRAPH)
- add_definitions(-DWITH_LEGACY_DEPSGRAPH)
-endif()
-
if(WITH_ALEMBIC)
add_definitions(-DWITH_ALEMBIC)
list(APPEND INC
@@ -162,4 +158,7 @@ if(WITH_OPENSUBDIV)
add_definitions(-DWITH_OPENSUBDIV)
endif()
+# So we can have special tricks in modifier system.
+add_definitions(${GL_DEFINITIONS})
+
blender_add_lib(bf_modifiers "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 2400dbcb898..8f26077ea82 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -50,8 +50,6 @@
#include "MEM_guardedalloc.h"
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
@@ -99,22 +97,6 @@ static void foreachObjectLink(
walk(userData, ob, &amd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
-
- if (amd->object) {
- DagNode *curNode = dag_get_node(forest, amd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Armature Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -221,7 +203,6 @@ ModifierTypeInfo modifierType_Armature = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 2b739dc0093..78a5631bb94 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -53,7 +53,7 @@
#include "MOD_util.h"
-#include "depsgraph_private.h"
+#include "DEG_depsgraph.h"
/* Due to cyclic dependencies it's possible that curve used for
* deformation here is not evaluated at the time of evaluating
@@ -101,40 +101,6 @@ static void foreachObjectLink(
walk(userData, ob, &amd->offset_ob, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- ArrayModifierData *amd = (ArrayModifierData *) md;
-
- if (amd->start_cap) {
- DagNode *curNode = dag_get_node(forest, amd->start_cap);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
- if (amd->end_cap) {
- DagNode *curNode = dag_get_node(forest, amd->end_cap);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
- if (amd->curve_ob) {
- DagNode *curNode = dag_get_node(forest, amd->curve_ob);
- curNode->eval_flags |= DAG_EVAL_NEED_CURVE_PATH;
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
- if (amd->offset_ob) {
- DagNode *curNode = dag_get_node(forest, amd->offset_ob);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -797,7 +763,6 @@ ModifierTypeInfo modifierType_Array = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 5874029ae08..17b0cd4d7f5 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -213,7 +213,6 @@ ModifierTypeInfo modifierType_Bevel = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index f86d8b99f3c..e649c8821fa 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -49,8 +49,6 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
-
#include "MOD_boolean_util.h"
#include "MOD_util.h"
@@ -104,22 +102,6 @@ static void foreachObjectLink(
walk(userData, ob, &bmd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- BooleanModifierData *bmd = (BooleanModifierData *) md;
-
- if (bmd->object) {
- DagNode *curNode = dag_get_node(forest, bmd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Boolean Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -460,7 +442,6 @@ ModifierTypeInfo modifierType_Boolean = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index a364eef2974..d2467a8fc4a 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -322,7 +322,6 @@ ModifierTypeInfo modifierType_Build = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index ddcf1852dc6..2dcc01b89d9 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -45,9 +45,6 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
static void initData(ModifierData *md)
@@ -105,22 +102,6 @@ static void foreachObjectLink(
walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- CastModifierData *cmd = (CastModifierData *) md;
-
- if (cmd->object) {
- DagNode *curNode = dag_get_node(forest, cmd->object);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
- "Cast Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -513,7 +494,6 @@ ModifierTypeInfo modifierType_Cast = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index e8c39770a14..00161366b93 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -53,8 +53,6 @@
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
static void initData(ModifierData *md)
@@ -117,26 +115,6 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
dm->release(dm);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- Scene *scene, Object *ob, DagNode *obNode)
-{
- ClothModifierData *clmd = (ClothModifierData *) md;
-
- if (clmd) {
- /* Actual code uses get_collisionobjects */
-#ifdef WITH_LEGACY_DEPSGRAPH
- dag_add_collision_relations(forest, scene, ob, obNode, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
- dag_add_forcefield_relations(forest, scene, ob, obNode, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
-#else
- (void)forest;
- (void)scene;
- (void)ob;
- (void)obNode;
-#endif
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -146,7 +124,7 @@ static void updateDepsgraph(ModifierData *md,
ClothModifierData *clmd = (ClothModifierData *)md;
if (clmd != NULL) {
/* Actual code uses get_collisionobjects */
- DEG_add_collision_relations(node, scene, ob, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
+ DEG_add_collision_relations(node, scene, ob, clmd->coll_parms->group, eModifierType_Collision, NULL, true, "Cloth Collision");
DEG_add_forcefield_relations(node, scene, ob, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
}
@@ -262,7 +240,6 @@ ModifierTypeInfo modifierType_Cloth = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index e7ff0a90fbc..a2a4b2e1274 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -265,7 +265,6 @@ ModifierTypeInfo modifierType_Collision = {
/* requiredDataMask */ NULL,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index 77fd84a2948..0718b0f85fa 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -759,7 +759,6 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 09444476bfe..d9acce0a780 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -45,10 +45,9 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
-
static void initData(ModifierData *md)
{
CurveModifierData *cmd = (CurveModifierData *) md;
@@ -92,23 +91,6 @@ static void foreachObjectLink(
walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- CurveModifierData *cmd = (CurveModifierData *) md;
-
- if (cmd->object) {
- DagNode *curNode = dag_get_node(forest, cmd->object);
- curNode->eval_flags |= DAG_EVAL_NEED_CURVE_PATH;
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -178,7 +160,6 @@ ModifierTypeInfo modifierType_Curve = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index a2210893602..9fd23598cb6 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -50,8 +50,6 @@
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
-#include "depsgraph_private.h"
-
/**************************************
* Modifiers functions. *
**************************************/
@@ -127,22 +125,6 @@ static void foreachObjectLink(
walk(userData, ob, &dtmd->ob_source, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- DagNode *curNode;
-
- if (dtmd->ob_source) {
- curNode = dag_get_node(forest, dtmd->ob_source);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "DataTransfer Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -254,7 +236,6 @@ ModifierTypeInfo modifierType_DataTransfer = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 617ae5a89f3..bcb52e4e0ca 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -227,7 +227,6 @@ ModifierTypeInfo modifierType_Decimate = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 3325f05025f..c422aa05b12 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -50,7 +50,6 @@
#include "BKE_deform.h"
#include "BKE_object.h"
-#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
@@ -159,31 +158,6 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
return ((!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) || dmd->strength == 0.0f);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData *) md;
-
- if (dmd->map_object && dmd->texmapping == MOD_DISP_MAP_OBJECT) {
- DagNode *curNode = dag_get_node(forest, dmd->map_object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier");
- }
-
-
- if (dmd->texmapping == MOD_DISP_MAP_GLOBAL ||
- (ELEM(dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) &&
- dmd->space == MOD_DISP_SPACE_GLOBAL))
- {
- dag_add_relation(forest, obNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -449,7 +423,6 @@ ModifierTypeInfo modifierType_Displace = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index bb75d655802..2497e0b9aab 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -36,10 +36,10 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_dynamicpaint.h"
+#include "BKE_layer.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
@@ -78,7 +78,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ ||
surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE)
{
- dataMask |= CD_MASK_MLOOPUV | CD_MASK_MTEXPOLY;
+ dataMask |= CD_MASK_MLOOPUV;
}
/* mcol */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT ||
@@ -95,7 +95,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
if (pmd->brush) {
if (pmd->brush->flags & MOD_DPAINT_USE_MATERIAL) {
- dataMask |= CD_MASK_MLOOPUV | CD_MASK_MTEXPOLY;
+ dataMask |= CD_MASK_MLOOPUV;
}
}
return dataMask;
@@ -109,7 +109,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* dont apply dynamic paint on orco dm stack */
if (!(flag & MOD_APPLY_ORCO)) {
- return dynamicPaint_Modifier_do(pmd, md->scene, ob, dm);
+ return dynamicPaint_Modifier_do(pmd, md->scene, BKE_scene_layer_context_active(md->scene), ob, dm);
}
return dm;
}
@@ -119,34 +119,6 @@ static bool is_brush_cb(Object *UNUSED(ob), ModifierData *pmd)
return ((DynamicPaintModifierData *)pmd)->brush != NULL;
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *scene,
- Object *ob,
- DagNode *obNode)
-{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *) md;
-
- /* add relation from canvases to all brush objects */
- if (pmd && pmd->canvas) {
-#ifdef WITH_LEGACY_DEPSGRAPH
- for (DynamicPaintSurface *surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
- if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
- dag_add_forcefield_relations(forest, scene, ob, obNode, surface->effector_weights, true, 0, "Dynamic Paint Field");
- }
-
- /* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
- dag_add_collision_relations(forest, scene, ob, obNode, surface->brush_group, -1, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
- }
-#else
- (void)forest;
- (void)scene;
- (void)ob;
- (void)obNode;
-#endif
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -162,7 +134,7 @@ static void updateDepsgraph(ModifierData *md,
}
/* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
- DEG_add_collision_relations(node, scene, ob, surface->brush_group, -1, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
+ DEG_add_collision_relations(node, scene, ob, surface->brush_group, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
}
}
}
@@ -221,7 +193,6 @@ ModifierTypeInfo modifierType_DynamicPaint = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index 4441edb299b..f239807a7d3 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -157,7 +157,6 @@ ModifierTypeInfo modifierType_EdgeSplit = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index ca7b3ce8039..24ce2e3cc8e 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -1059,7 +1059,6 @@ ModifierTypeInfo modifierType_Explode = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c
index c202c5e1cb4..3e7141c3ce3 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim.c
@@ -41,9 +41,9 @@
#include "BKE_cdderivedmesh.h"
+#include "BKE_layer.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MOD_fluidsim_util.h"
@@ -100,33 +100,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
return result ? result : dm;
}
-static void updateDepgraph(
- ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain), Scene *scene,
- Object *ob, DagNode *obNode)
-{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
- Base *base;
-
- if (fluidmd && fluidmd->fss) {
- if (fluidmd->fss->type == OB_FLUIDSIM_DOMAIN) {
- for (base = scene->base.first; base; base = base->next) {
- Object *ob1 = base->object;
- if (ob1 != ob) {
- FluidsimModifierData *fluidmdtmp =
- (FluidsimModifierData *)modifiers_findByType(ob1, eModifierType_Fluidsim);
-
- /* only put dependencies from NON-DOMAIN fluids in here */
- if (fluidmdtmp && fluidmdtmp->fss && (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN)) {
- DagNode *curNode = dag_get_node(forest, ob1);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Fluidsim Object");
- }
- }
- }
- }
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -136,9 +109,8 @@ static void updateDepsgraph(ModifierData *md,
FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
if (fluidmd && fluidmd->fss) {
if (fluidmd->fss->type == OB_FLUIDSIM_DOMAIN) {
- Base *base;
- for (base = scene->base.first; base; base = base->next) {
- Object *ob1 = base->object;
+ FOREACH_SCENE_OBJECT(scene, ob1)
+ {
if (ob1 != ob) {
FluidsimModifierData *fluidmdtmp =
(FluidsimModifierData *)modifiers_findByType(ob1, eModifierType_Fluidsim);
@@ -149,6 +121,7 @@ static void updateDepsgraph(ModifierData *md,
}
}
}
+ FOREACH_SCENE_OBJECT_END
}
}
}
@@ -180,7 +153,6 @@ ModifierTypeInfo modifierType_Fluidsim = {
/* requiredDataMask */ NULL,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 56c494ff3c0..08103292a8b 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -47,7 +47,6 @@
#include "BKE_colortools.h"
-#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
@@ -118,24 +117,6 @@ static void foreachObjectLink(
walk(userData, ob, &hmd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- HookModifierData *hmd = (HookModifierData *) md;
-
- if (hmd->object) {
- DagNode *curNode = dag_get_node(forest, hmd->object);
-
- if (hmd->subtarget[0])
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Hook Modifier");
- else
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -427,7 +408,6 @@ ModifierTypeInfo modifierType_Hook = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index ce3fdc4bbe8..56a2e217a2a 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -775,7 +775,6 @@ ModifierTypeInfo modifierType_LaplacianDeform = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index f1216ff462a..1295a75d9e7 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -561,7 +561,6 @@ ModifierTypeInfo modifierType_LaplacianSmooth = {
/* requiredDataMask */ required_data_mask,
/* freeData */ NULL,
/* isDisabled */ is_disabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index dc246084dca..8c723f1c4be 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -44,8 +44,6 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
static void initData(ModifierData *md)
@@ -91,22 +89,6 @@ static void foreachObjectLink(
walk(userData, ob, &lmd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- LatticeModifierData *lmd = (LatticeModifierData *) md;
-
- if (lmd->object) {
- DagNode *latNode = dag_get_node(forest, lmd->object);
-
- dag_add_relation(forest, latNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Lattice Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -169,7 +151,6 @@ ModifierTypeInfo modifierType_Lattice = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index dcc7fe4d4f1..11c0fae9a75 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -50,7 +50,6 @@
#include "BKE_modifier.h"
#include "BKE_deform.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "BLI_strict_flags.h"
@@ -77,24 +76,6 @@ static void foreachObjectLink(
walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- MaskModifierData *mmd = (MaskModifierData *)md;
-
- if (mmd->ob_arm) {
- bArmature *arm = (bArmature *)mmd->ob_arm->data;
- DagNode *armNode = dag_get_node(forest, mmd->ob_arm);
-
- /* tag relationship in depsgraph, but also on the armature */
- dag_add_relation(forest, armNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mask Modifier");
- arm->flag |= ARM_HAS_VIZ_DEPS;
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -401,7 +382,6 @@ ModifierTypeInfo modifierType_Mask = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index aa3e3ebcf7e..0d96032c515 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -313,7 +313,6 @@ ModifierTypeInfo modifierType_MeshCache = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 406ce398ee0..b544710ace0 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -47,8 +47,6 @@
#include "BKE_deform.h"
#include "BKE_editmesh.h"
-#include "depsgraph_private.h"
-
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
@@ -122,23 +120,6 @@ static void foreachObjectLink(
walk(userData, ob, &mmd->object, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
-
- if (mmd->object) {
- DagNode *curNode = dag_get_node(forest, mmd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA | DAG_RL_DATA_OB | DAG_RL_OB_OB,
- "Mesh Deform Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -534,7 +515,6 @@ ModifierTypeInfo modifierType_MeshDeform = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index f0edcc31a10..df13cadd184 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -36,7 +36,6 @@
#include "BKE_library_query.h"
#include "BKE_scene.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MOD_modifiertypes.h"
@@ -155,23 +154,6 @@ static void foreachIDLink(ModifierData *md, Object *ob,
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *bmain,
- struct Scene *scene,
- Object *ob, DagNode *obNode)
-{
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
-
- if (mcmd->cache_file != NULL) {
- DagNode *curNode = dag_get_node(forest, mcmd->cache_file);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Cache File Modifier");
- }
-
- UNUSED_VARS(bmain, scene, ob);
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *bmain,
struct Scene *scene,
@@ -205,7 +187,6 @@ ModifierTypeInfo modifierType_MeshSequenceCache = {
/* requiredDataMask */ NULL,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index 9705edc580c..e0c37e8a0ce 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -45,7 +45,6 @@
#include "MEM_guardedalloc.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
static void initData(ModifierData *md)
@@ -75,21 +74,6 @@ static void foreachObjectLink(
walk(userData, ob, &mmd->mirror_ob, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- MirrorModifierData *mmd = (MirrorModifierData *) md;
-
- if (mmd->mirror_ob) {
- DagNode *latNode = dag_get_node(forest, mmd->mirror_ob);
-
- dag_add_relation(forest, latNode, obNode, DAG_RL_OB_DATA, "Mirror Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -375,7 +359,6 @@ ModifierTypeInfo modifierType_Mirror = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 90ad1bdfdc2..aba184b7d40 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -161,7 +161,6 @@ ModifierTypeInfo modifierType_Multires = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c
index d9d9ba2966d..3fb780f566d 100644
--- a/source/blender/modifiers/intern/MOD_none.c
+++ b/source/blender/modifiers/intern/MOD_none.c
@@ -67,7 +67,6 @@ ModifierTypeInfo modifierType_None = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 20eae751ca4..fa4d33f2e95 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -42,8 +42,6 @@
#include "BKE_mesh.h"
#include "BKE_deform.h"
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
@@ -511,20 +509,6 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
return !is_valid_target(enmd);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- NormalEditModifierData *enmd = (NormalEditModifierData *) md;
-
- if (enmd->target) {
- DagNode *Node = dag_get_node(forest, enmd->target);
-
- dag_add_relation(forest, Node, obNode, DAG_RL_OB_DATA, "NormalEdit Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -562,7 +546,6 @@ ModifierTypeInfo modifierType_NormalEdit = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index e77cc655c16..4a6b79b71b6 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -397,7 +397,6 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd)
/* add uvs */
if (CustomData_number_of_layers(&result->loopData, CD_MLOOPUV) < MAX_MTFACE) {
gogd.mloopuvs = CustomData_add_layer(&result->loopData, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4);
- CustomData_add_layer(&result->polyData, CD_MTEXPOLY, CD_CALLOC, NULL, num_polys);
if (gogd.mloopuvs) { /* unlikely to fail */
gogd.ix = 1.0 / gogd.rx;
@@ -597,7 +596,6 @@ ModifierTypeInfo modifierType_Ocean = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index fbf5a958254..316d51b9581 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -51,7 +51,6 @@
#include "BKE_particle.h"
#include "BKE_pointcache.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
static void initData(ModifierData *md)
@@ -110,24 +109,6 @@ static bool isDisabled(ModifierData *md, int useRenderParams)
return false;
}
-
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
-
- if (pimd->ob) {
- DagNode *curNode = dag_get_node(forest, pimd->ob);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "Particle Instance Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -460,7 +441,6 @@ ModifierTypeInfo modifierType_ParticleInstance = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index d8cccca415c..a3b9d808b17 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -231,7 +231,6 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index b85898c07e9..fb5c12399a4 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -231,7 +231,6 @@ ModifierTypeInfo modifierType_Remesh = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 87859cd240a..f62c68b56c9 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -46,7 +46,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_library_query.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MOD_modifiertypes.h"
@@ -1057,24 +1056,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
return result;
}
-
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- ScrewModifierData *ltmd = (ScrewModifierData *) md;
-
- if (ltmd->ob_axis) {
- DagNode *curNode = dag_get_node(forest, ltmd->ob_axis);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "Screw Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -1118,7 +1099,6 @@ ModifierTypeInfo modifierType_Screw = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index 97aae733532..6c8bd06c196 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -138,7 +138,6 @@ ModifierTypeInfo modifierType_ShapeKey = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index a14747bc153..32241d8390a 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -45,8 +45,6 @@
#include "BKE_modifier.h"
#include "BKE_shrinkwrap.h"
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
static bool dependsOnNormals(ModifierData *md);
@@ -143,23 +141,6 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editD
dm->release(dm);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *) md;
-
- if (smd->target)
- dag_add_relation(forest, dag_get_node(forest, smd->target), obNode,
- DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
-
- if (smd->auxTarget)
- dag_add_relation(forest, dag_get_node(forest, smd->auxTarget), obNode,
- DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -209,7 +190,6 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index 379eaea5b0c..4660afc0977 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -44,9 +44,6 @@
#include "BKE_modifier.h"
#include "BKE_deform.h"
-
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
#define BEND_EPS 0.000001f
@@ -293,18 +290,6 @@ static void foreachObjectLink(
walk(userData, ob, &smd->origin, IDWALK_CB_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
-
- if (smd->origin)
- dag_add_relation(forest, dag_get_node(forest, smd->origin), obNode, DAG_RL_OB_DATA, "SimpleDeform Modifier");
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -381,7 +366,6 @@ ModifierTypeInfo modifierType_SimpleDeform = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 8ed623734be..4b84aeb335a 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -1950,7 +1950,6 @@ ModifierTypeInfo modifierType_Skin = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index c105a3ab3a7..a11b0f887ea 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -47,13 +47,13 @@
#include "BKE_cdderivedmesh.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_smoke.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
static void initData(ModifierData *md)
@@ -109,7 +109,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (flag & MOD_APPLY_ORCO)
return dm;
- return smokeModifier_do(smd, md->scene, ob, dm);
+ return smokeModifier_do(smd, md->scene, BKE_scene_layer_context_active(md->scene), ob, dm);
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -129,28 +129,6 @@ static bool is_coll_cb(Object *UNUSED(ob), ModifierData *md)
return (smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll;
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *scene, struct Object *ob,
- DagNode *obNode)
-{
- SmokeModifierData *smd = (SmokeModifierData *) md;
-
- if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
- /* Actual code uses get_collisionobjects */
-#ifdef WITH_LEGACY_DEPSGRAPH
- dag_add_collision_relations(forest, scene, ob, obNode, smd->domain->fluid_group, ob->lay|scene->lay, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
- dag_add_collision_relations(forest, scene, ob, obNode, smd->domain->coll_group, ob->lay|scene->lay, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
- dag_add_forcefield_relations(forest, scene, ob, obNode, smd->domain->effector_weights, true, PFIELD_SMOKEFLOW, "Smoke Force Field");
-#else
- (void)forest;
- (void)scene;
- (void)ob;
- (void)obNode;
-#endif
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -161,8 +139,8 @@ static void updateDepsgraph(ModifierData *md,
if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
/* Actual code uses get_collisionobjects */
- DEG_add_collision_relations(node, scene, ob, smd->domain->fluid_group, ob->lay|scene->lay, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
- DEG_add_collision_relations(node, scene, ob, smd->domain->coll_group, ob->lay|scene->lay, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
+ DEG_add_collision_relations(node, scene, ob, smd->domain->fluid_group, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
+ DEG_add_collision_relations(node, scene, ob, smd->domain->coll_group, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
DEG_add_forcefield_relations(node, scene, ob, smd->domain->effector_weights, true, PFIELD_SMOKEFLOW, "Smoke Force Field");
}
@@ -208,7 +186,6 @@ ModifierTypeInfo modifierType_Smoke = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index d45c8528510..f0f20acb8ea 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -261,7 +261,6 @@ ModifierTypeInfo modifierType_Smooth = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index a0bbe5da04a..5468b8a61f0 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -40,10 +40,10 @@
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_layer.h"
#include "BKE_particle.h"
#include "BKE_softbody.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MOD_modifiertypes.h"
@@ -54,7 +54,7 @@ static void deformVerts(ModifierData *md, Object *ob,
int numVerts,
ModifierApplyFlag UNUSED(flag))
{
- sbObjectStep(md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts);
+ sbObjectStep(md->scene, BKE_scene_layer_context_active(md->scene), ob, (float)md->scene->r.cfra, vertexCos, numVerts);
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -62,25 +62,6 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
-static void updateDepgraph(ModifierData *UNUSED(md), DagForest *forest,
- struct Main *UNUSED(bmain),
- Scene *scene, Object *ob, DagNode *obNode)
-{
- if (ob->soft) {
-#ifdef WITH_LEGACY_DEPSGRAPH
- /* Actual code uses ccd_build_deflector_hash */
- dag_add_collision_relations(forest, scene, ob, obNode, ob->soft->collision_group, ob->lay, eModifierType_Collision, NULL, false, "Softbody Collision");
-
- dag_add_forcefield_relations(forest, scene, ob, obNode, ob->soft->effector_weights, true, 0, "Softbody Field");
-#else
- (void)forest;
- (void)scene;
- (void)ob;
- (void)obNode;
-#endif
- }
-}
-
static void updateDepsgraph(ModifierData *UNUSED(md),
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -89,7 +70,7 @@ static void updateDepsgraph(ModifierData *UNUSED(md),
{
if (ob->soft) {
/* Actual code uses ccd_build_deflector_hash */
- DEG_add_collision_relations(node, scene, ob, ob->soft->collision_group, ob->lay, eModifierType_Collision, NULL, false, "Softbody Collision");
+ DEG_add_collision_relations(node, scene, ob, ob->soft->collision_group, eModifierType_Collision, NULL, false, "Softbody Collision");
DEG_add_forcefield_relations(node, scene, ob, ob->soft->effector_weights, true, 0, "Softbody Field");
}
@@ -116,7 +97,6 @@ ModifierTypeInfo modifierType_Softbody = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 911b6997058..e589cb7d713 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -973,7 +973,6 @@ ModifierTypeInfo modifierType_Solidify = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 8711384e1ee..407fd63d5c3 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -46,10 +46,12 @@
#include "BKE_cdderivedmesh.h"
-#include "BKE_depsgraph.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#include "MOD_modifiertypes.h"
#include "intern/CCGSubSurf.h"
@@ -133,7 +135,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
modifier_setError(md, "OpenSubdiv is not supported in paint modes");
}
- else if ((DAG_get_eval_flags_for_object(md->scene, ob) & DAG_EVAL_NEED_CPU) == 0) {
+ else if ((DEG_get_eval_flags_for_id(md->scene->depsgraph, &ob->id) & DAG_EVAL_NEED_CPU) == 0) {
subsurf_flags |= SUBSURF_USE_GPU_BACKEND;
do_cddm_convert = false;
}
@@ -146,12 +148,16 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
result = subsurf_make_derived_from_derived(derivedData, smd, NULL, subsurf_flags);
result->cd_flag = derivedData->cd_flag;
- if (do_cddm_convert) {
+ {
DerivedMesh *cddm = CDDM_copy(result);
result->release(result);
result = cddm;
}
+#ifndef WITH_OPESUBDIV
+ (void) do_cddm_convert;
+#endif
+
return result;
}
@@ -211,7 +217,6 @@ ModifierTypeInfo modifierType_Subsurf = {
/* requiredDataMask */ NULL,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c
index e5b0f9c0001..ea68f540236 100644
--- a/source/blender/modifiers/intern/MOD_surface.c
+++ b/source/blender/modifiers/intern/MOD_surface.c
@@ -186,7 +186,6 @@ ModifierTypeInfo modifierType_Surface = {
/* requiredDataMask */ NULL,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 79e3eb5f3df..f6288dc9be0 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -11,8 +11,6 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
-
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
@@ -168,21 +166,6 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
walk(userData, ob, &smd->target, IDWALK_NOP);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
-
- if (smd->target) {
- DagNode *curNode = dag_get_node(forest, smd->target);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA, "Surface Deform Modifier");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -1219,7 +1202,6 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/* requiredDataMask */ NULL,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index 6fad2756f82..a5d826a69ba 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -118,7 +118,6 @@ ModifierTypeInfo modifierType_Triangulate = {
/* requiredDataMask */ NULL, //requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 78dc1ea8bcb..362df031f92 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -46,6 +46,7 @@
#include "BKE_camera.h"
#include "BKE_library_query.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_DerivedMesh.h"
@@ -53,14 +54,13 @@
#include "MEM_guardedalloc.h"
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
static void initData(ModifierData *md)
{
UVProjectModifierData *umd = (UVProjectModifierData *) md;
- umd->flags = 0;
+
umd->num_projectors = 1;
umd->aspectx = umd->aspecty = 1.0f;
umd->scalex = umd->scaley = 1.0f;
@@ -80,7 +80,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(
CustomDataMask dataMask = 0;
/* ask for UV coordinates */
- dataMask |= CD_MLOOPUV | CD_MTEXPOLY;
+ dataMask |= CD_MLOOPUV;
return dataMask;
}
@@ -105,25 +105,6 @@ static void foreachIDLink(ModifierData *md, Object *ob,
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- UVProjectModifierData *umd = (UVProjectModifierData *) md;
- int i;
-
- for (i = 0; i < umd->num_projectors; ++i) {
- if (umd->projectors[i]) {
- DagNode *curNode = dag_get_node(forest, umd->projectors[i]);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "UV Project Modifier");
- }
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -151,12 +132,10 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
{
float (*coords)[3], (*co)[3];
MLoopUV *mloop_uv;
- MTexPoly *mtexpoly, *mt = NULL;
int i, numVerts, numPolys, numLoops;
Image *image = umd->image;
MPoly *mpoly, *mp;
MLoop *mloop;
- const bool override_image = (umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0;
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
int num_projectors = 0;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
@@ -241,10 +220,6 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
mloop_uv = CustomData_duplicate_referenced_layer_named(&dm->loopData,
CD_MLOOPUV, uvname, numLoops);
- /* can be NULL */
- mt = mtexpoly = CustomData_duplicate_referenced_layer_named(&dm->polyData,
- CD_MTEXPOLY, uvname, numPolys);
-
numVerts = dm->getNumVerts(dm);
coords = MEM_mallocN(sizeof(*coords) * numVerts,
@@ -263,9 +238,14 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
mpoly = dm->getPolyArray(dm);
mloop = dm->getLoopArray(dm);
+ Image **ob_image_array = NULL;
+ if (image) {
+ ob_image_array = BKE_object_material_edit_image_get_array(ob);
+ }
+
/* apply coords as UVs, and apply image if tfaces are new */
- for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp, ++mt) {
- if (override_image || !image || (mtexpoly == NULL || mt->tpage == image)) {
+ for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
+ if (!image || (mp->mat_nr < ob->totcol ? ob_image_array[mp->mat_nr] : NULL) == image) {
if (num_projectors == 1) {
if (projectors[0].uci) {
unsigned int fidx = mp->totloop - 1;
@@ -328,13 +308,13 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
}
}
-
- if (override_image && mtexpoly) {
- mt->tpage = image;
- }
}
MEM_freeN(coords);
+
+ if (ob_image_array) {
+ MEM_freeN(ob_image_array);
+ }
if (free_uci) {
int j;
@@ -385,7 +365,6 @@ ModifierTypeInfo modifierType_UVProject = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index b3fc3842635..7ee0a7e3108 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -40,8 +40,6 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "depsgraph_private.h"
-
#include "MOD_util.h"
@@ -225,34 +223,9 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
walk(userData, ob, &umd->object_src, IDWALK_CB_NOP);
}
-static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode,
- Object *obj, const char *bonename)
-{
- if (obj) {
- DagNode *curNode = dag_get_node(forest, obj);
-
- if (bonename[0])
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVWarp Modifier");
- else
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVWarp Modifier");
- }
-}
-
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- UVWarpModifierData *umd = (UVWarpModifierData *) md;
-
- uv_warp_deps_object_bone(forest, obNode, umd->object_src, umd->bone_src);
- uv_warp_deps_object_bone(forest, obNode, umd->object_dst, umd->bone_dst);
-}
-
-static void uv_warp_deps_object_bone_new(struct DepsNodeHandle *node,
- Object *object,
- const char *bonename)
+static void uv_warp_deps_object_bone(struct DepsNodeHandle *node,
+ Object *object,
+ const char *bonename)
{
if (object != NULL) {
if (bonename[0])
@@ -270,8 +243,8 @@ static void updateDepsgraph(ModifierData *md,
{
UVWarpModifierData *umd = (UVWarpModifierData *) md;
- uv_warp_deps_object_bone_new(node, umd->object_src, umd->bone_src);
- uv_warp_deps_object_bone_new(node, umd->object_dst, umd->bone_dst);
+ uv_warp_deps_object_bone(node, umd->object_src, umd->bone_src);
+ uv_warp_deps_object_bone(node, umd->object_dst, umd->bone_dst);
}
ModifierTypeInfo modifierType_UVWarp = {
@@ -293,7 +266,6 @@ ModifierTypeInfo modifierType_UVWarp = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index b340356467a..c9a9e20df23 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -42,8 +42,6 @@
#include "BKE_texture.h"
#include "BKE_colortools.h"
-#include "depsgraph_private.h"
-
#include "RE_shader_ext.h"
#include "MOD_util.h"
@@ -139,27 +137,6 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- WarpModifierData *wmd = (WarpModifierData *) md;
-
- if (wmd->object_from && wmd->object_to) {
- DagNode *fromNode = dag_get_node(forest, wmd->object_from);
- DagNode *toNode = dag_get_node(forest, wmd->object_to);
-
- dag_add_relation(forest, fromNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier1");
- dag_add_relation(forest, toNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier2");
- }
-
- if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object) {
- DagNode *curNode = dag_get_node(forest, wmd->map_object);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier3");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -391,7 +368,6 @@ ModifierTypeInfo modifierType_Warp = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index f0c4940816e..73e96f87c66 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -49,8 +49,6 @@
#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "depsgraph_private.h"
-
#include "MEM_guardedalloc.h"
#include "RE_shader_ext.h"
@@ -131,29 +129,6 @@ static void foreachTexLink(ModifierData *md, Object *ob,
walk(userData, ob, md, "texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- Scene *UNUSED(scene),
- Object *UNUSED(ob),
- DagNode *obNode)
-{
- WaveModifierData *wmd = (WaveModifierData *) md;
-
- if (wmd->objectcenter) {
- DagNode *curNode = dag_get_node(forest, wmd->objectcenter);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
- "Wave Modifier");
- }
-
- if (wmd->map_object) {
- DagNode *curNode = dag_get_node(forest, wmd->map_object);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
- "Wave Modifer");
- }
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -397,7 +372,6 @@ ModifierTypeInfo modifierType_Wave = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index cd30b54350c..e6603b81bfd 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -46,7 +46,6 @@
#include "BKE_modifier.h"
#include "BKE_texture.h" /* Texture masking. */
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MEM_guardedalloc.h"
@@ -143,26 +142,6 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "mask_texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
- DagNode *curNode;
-
- if (wmd->mask_tex_map_obj && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
- curNode = dag_get_node(forest, wmd->mask_tex_map_obj);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGEdit Modifier");
- }
-
- if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL)
- dag_add_relation(forest, obNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGEdit Modifier");
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -306,7 +285,6 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 1b3188c83b3..df07cffe63f 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -43,7 +43,6 @@
#include "BKE_modifier.h"
#include "BKE_texture.h" /* Texture masking. */
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MEM_guardedalloc.h"
@@ -192,26 +191,6 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "mask_texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
- DagNode *curNode;
-
- if (wmd->mask_tex_map_obj && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
- curNode = dag_get_node(forest, wmd->mask_tex_map_obj);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGMix Modifier");
- }
-
- if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL)
- dag_add_relation(forest, obNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGMix Modifier");
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -438,7 +417,6 @@ ModifierTypeInfo modifierType_WeightVGMix = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 2c87838aeab..70b413ca685 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -47,7 +47,6 @@
#include "BKE_modifier.h"
#include "BKE_texture.h" /* Texture masking. */
-#include "depsgraph_private.h"
#include "DEG_depsgraph_build.h"
#include "MEM_guardedalloc.h"
@@ -343,32 +342,6 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "mask_texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *UNUSED(bmain),
- struct Scene *UNUSED(scene),
- Object *UNUSED(ob), DagNode *obNode)
-{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
- DagNode *curNode;
-
- if (wmd->proximity_ob_target) {
- curNode = dag_get_node(forest, wmd->proximity_ob_target);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGProximity Modifier");
- }
-
- if (wmd->mask_tex_map_obj && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
- curNode = dag_get_node(forest, wmd->mask_tex_map_obj);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGProximity Modifier");
- }
-
- if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL)
- dag_add_relation(forest, obNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "WeightVGProximity Modifier");
-}
-
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
@@ -617,7 +590,6 @@ ModifierTypeInfo modifierType_WeightVGProximity = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ updateDepgraph,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index adadd4834d4..0c295f91012 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -132,7 +132,6 @@ ModifierTypeInfo modifierType_Wireframe = {
/* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index c5a3c70100b..b57e33e85c7 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -186,6 +186,8 @@ set(SRC
shader/nodes/node_shader_hair_info.c
shader/nodes/node_shader_output_lamp.c
shader/nodes/node_shader_output_material.c
+ shader/nodes/node_shader_output_metallic.c
+ shader/nodes/node_shader_output_specular.c
shader/nodes/node_shader_output_world.c
shader/nodes/node_shader_output_linestyle.c
shader/nodes/node_shader_particle_info.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 804c1897a27..c05c1a55144 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -120,6 +120,8 @@ void register_node_type_sh_uvalongstroke(void);
void register_node_type_sh_output_lamp(void);
void register_node_type_sh_output_material(void);
+void register_node_type_sh_output_metallic(void);
+void register_node_type_sh_output_specular(void);
void register_node_type_sh_output_world(void);
void register_node_type_sh_output_linestyle(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 02422a8622a..f4c79266033 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -67,6 +67,8 @@ DefNode( ShaderNode, SH_NODE_COMBRGB, 0, "COMBR
DefNode( ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
DefNode( ShaderNode, SH_NODE_OUTPUT_MATERIAL, def_sh_output, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" )
+DefNode( ShaderNode, SH_NODE_OUTPUT_METALLIC, def_sh_output, "OUTPUT_METALLIC", OutputMetallic, "Material Metallic Output", "")
+DefNode( ShaderNode, SH_NODE_OUTPUT_SPECULAR, def_sh_output, "OUTPUT_SPECULAR", OutputSpecular, "Material Specular Output", "")
DefNode( ShaderNode, SH_NODE_OUTPUT_LAMP, def_sh_output, "OUTPUT_LAMP", OutputLamp, "Lamp Output", "" )
DefNode( ShaderNode, SH_NODE_OUTPUT_WORLD, def_sh_output, "OUTPUT_WORLD", OutputWorld, "World Output", "" )
DefNode( ShaderNode, SH_NODE_OUTPUT_LINESTYLE, def_sh_output_linestyle,"OUTPUT_LINESTYLE", OutputLineStyle, "Line Style Output", "" )
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 40d1cfdfcb0..b5d77e99328 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -79,7 +79,8 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre
{
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
if ((snode->shaderfrom == SNODE_SHADER_OBJECT) ||
(BKE_scene_use_new_shading_nodes(scene) == false))
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h
index 4cb39e0f13b..79c58cb5715 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.h
@@ -76,6 +76,7 @@
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
+#include "GPU_lamp.h"
#include "GPU_material.h"
diff --git a/source/blender/nodes/shader/nodes/node_shader_background.c b/source/blender/nodes/shader/nodes/node_shader_background.c
index b387529e456..e4d635994b4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_background.c
+++ b/source/blender/nodes/shader/nodes/node_shader_background.c
@@ -42,7 +42,7 @@ static bNodeSocketTemplate sh_node_background_out[] = {
static int node_shader_gpu_background(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_background", in, out, GPU_builtin(GPU_VIEW_NORMAL));
+ return GPU_stack_link(mat, "node_background", in, out);
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index 553ea65154f..79833034498 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -45,6 +45,7 @@ static int node_shader_gpu_geometry(GPUMaterial *mat, bNode *UNUSED(node), bNode
{
return GPU_stack_link(mat, "node_geometry", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_attribute(CD_ORCO, ""), GPU_builtin(GPU_OBJECT_MATRIX),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c
index 789df09d898..ad6b4acdd48 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output.c
@@ -32,6 +32,8 @@
#include "node_shader_util.h"
+#include "BKE_scene.h"
+
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_output_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
@@ -74,6 +76,10 @@ static int gpu_shader_output(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecDat
GPU_material_enable_alpha(mat);
#endif
+ if (BKE_scene_uses_blender_eevee(GPU_material_scene(mat))) {
+ return false;
+ }
+
GPU_stack_link(mat, "output_node", in, out, &outlink);
GPU_material_output_link(mat, outlink);
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.c b/source/blender/nodes/shader/nodes/node_shader_output_material.c
index 336536b21ee..bbb72651ee5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_material.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_material.c
@@ -27,6 +27,8 @@
#include "../node_shader_util.h"
+#include "BKE_scene.h"
+
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_output_material_in[] = {
@@ -40,6 +42,10 @@ static int node_shader_gpu_output_material(GPUMaterial *mat, bNode *UNUSED(node)
{
GPUNodeLink *outlink;
+ if (BKE_scene_uses_blender_eevee(GPU_material_scene(mat))) {
+ return false;
+ }
+
GPU_stack_link(mat, "node_output_material", in, out, &outlink);
GPU_material_output_link(mat, outlink);
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_metallic.c b/source/blender/nodes/shader/nodes/node_shader_output_metallic.c
new file mode 100644
index 00000000000..b8182acfc7f
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output_metallic.c
@@ -0,0 +1,90 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_output_metallic_in[] = {
+ { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 1, N_("Emissive Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Clear Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Clear Coat Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Clear Coat Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Ambient Occlusion"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { -1, 0, "" }
+};
+
+static int node_shader_gpu_output_metallic(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+ static float one = 1.0f;
+
+ /* Normals */
+ if (!in[6].link) {
+ GPU_link(mat, "world_normals_get", &in[6].link);
+ }
+
+ /* Clearcoat Normals */
+ if (!in[9].link) {
+ GPU_link(mat, "world_normals_get", &in[9].link);
+ }
+
+ /* Occlusion */
+ if (!in[10].link) {
+ GPU_link(mat, "set_value", GPU_uniform(&one), &in[10].link);
+ }
+
+ GPU_stack_link(mat, "node_output_metallic", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return true;
+}
+
+
+/* node type definition */
+void register_node_type_sh_output_metallic(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_METALLIC, "Metallic Material Output", NODE_CLASS_OUTPUT, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_output_metallic_in, NULL);
+ node_type_init(&ntype, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_output_metallic);
+
+ /* Do not allow muting output node. */
+ node_type_internal_links(&ntype, NULL);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_specular.c b/source/blender/nodes/shader/nodes/node_shader_output_specular.c
new file mode 100644
index 00000000000..25bcf9642f9
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output_specular.c
@@ -0,0 +1,89 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_output_specular_in[] = {
+ { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f},
+ { SOCK_RGBA, 1, N_("Specular"), 0.03f, 0.03f, 0.03f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 1, N_("Emissive Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Clear Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Clear Coat Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Clear Coat Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Ambient Occlusion"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { -1, 0, "" }
+};
+
+static int node_shader_gpu_output_specular(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+ static float one = 1.0f;
+
+ /* Normals */
+ if (!in[5].link) {
+ GPU_link(mat, "world_normals_get", &in[5].link);
+ }
+
+ /* Clearcoat Normals */
+ if (!in[8].link) {
+ GPU_link(mat, "world_normals_get", &in[8].link);
+ }
+
+ /* Occlusion */
+ if (!in[9].link) {
+ GPU_link(mat, "set_value", GPU_uniform(&one), &in[9].link);
+ }
+
+ GPU_stack_link(mat, "node_output_specular", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return true;
+}
+
+
+/* node type definition */
+void register_node_type_sh_output_specular(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_SPECULAR, "Specular Material Output", NODE_CLASS_OUTPUT, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_output_specular_in, NULL);
+ node_type_init(&ntype, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_output_specular);
+
+ /* Do not allow muting output node. */
+ node_type_internal_links(&ntype, NULL);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c
index 7aa7fb43221..9c853f9d86f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c
@@ -41,6 +41,28 @@ static void node_shader_init_tangent(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = attr;
}
+static int node_shader_gpu_tangent(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ NodeShaderTangent *attr = node->storage;
+
+ if (attr->direction_type == SHD_TANGENT_UVMAP) {
+ return GPU_stack_link(mat, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, ""), GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ }
+ else {
+ GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+
+ if (attr->axis == SHD_TANGENT_AXIS_X)
+ GPU_link(mat, "tangent_orco_x", orco, &orco);
+ else if (attr->axis == SHD_TANGENT_AXIS_Y)
+ GPU_link(mat, "tangent_orco_y", orco, &orco);
+ else
+ GPU_link(mat, "tangent_orco_z", orco, &orco);
+
+ return GPU_stack_link(mat, "node_tangent", in, out, GPU_builtin(GPU_VIEW_NORMAL), orco,
+ GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ }
+}
+
/* node type definition */
void register_node_type_sh_tangent(void)
{
@@ -51,6 +73,7 @@ void register_node_type_sh_tangent(void)
node_type_socket_templates(&ntype, NULL, sh_node_tangent_out);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, node_shader_init_tangent);
+ node_type_gpu(&ntype, node_shader_gpu_tangent);
node_type_storage(&ntype, "NodeShaderTangent", node_free_standard_storage, node_copy_standard_storage);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index be393582a42..23571e24501 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -48,14 +48,14 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
GPUMatType type = GPU_Material_get_type(mat);
- if (type == GPU_MATERIAL_TYPE_MESH) {
- return GPU_stack_link(mat, "node_tex_coord", in, out,
+ if (type == GPU_MATERIAL_TYPE_WORLD) {
+ return GPU_stack_link(mat, "node_tex_coord_background", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
}
else {
- return GPU_stack_link(mat, "node_tex_coord_background", in, out,
+ return GPU_stack_link(mat, "node_tex_coord", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 2f8f95b0675..e090f26ab6b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -69,8 +69,10 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
if (type == GPU_MATERIAL_TYPE_MESH)
in[0].link = GPU_builtin(GPU_VIEW_POSITION);
- else
+ else if (type == GPU_MATERIAL_TYPE_WORLD)
GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
+ else
+ GPU_link(mat, "environment_default_vector", &in[0].link);
}
node_shader_gpu_tex_mapping(mat, node, in, out);
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 714665c303b..3b53d29d147 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -62,7 +62,8 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
{
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
- Object *ob = OBACT;
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ Object *ob = OBACT_NEW;
Tex *tx = NULL;
if (snode->texfrom == SNODE_TEX_OBJECT) {
diff --git a/source/blender/python/bmesh/CMakeLists.txt b/source/blender/python/bmesh/CMakeLists.txt
index c7b86acc8f9..4d3230fa3e9 100644
--- a/source/blender/python/bmesh/CMakeLists.txt
+++ b/source/blender/python/bmesh/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../bmesh
../../blenkernel
../../blenlib
+ ../../depsgraph
../../makesdna
../../../../intern/guardedalloc
)
diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c
index d5973baeadb..d6189f7c1eb 100644
--- a/source/blender/python/bmesh/bmesh_py_api.c
+++ b/source/blender/python/bmesh/bmesh_py_api.c
@@ -156,11 +156,6 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args,
{
extern void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_destructive);
- BMEditMesh *em = me->edit_btmesh;
- BMesh *bm = em->bm;
-
- /* python won't ensure matching uv/mtex */
- BM_mesh_cd_validate(bm);
EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive);
}
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index b20c03bee28..88445cfd62b 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -34,10 +34,11 @@
#include "DNA_object_types.h"
#include "DNA_material_types.h"
-#include "BKE_depsgraph.h"
#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
+#include "DEG_depsgraph.h"
+
#include "bmesh.h"
#include <Python.h>
@@ -913,14 +914,11 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
bm = self->bm;
- /* python won't ensure matching uv/mtex */
- BM_mesh_cd_validate(bm);
-
BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0}));
/* we could have the user do this but if they forget blender can easy crash
* since the references arrays for the objects derived meshes are now invalid */
- DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&me->id, OB_RECALC_DATA);
Py_RETURN_NONE;
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 908f6b5a734..47dead028a4 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -104,9 +104,6 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__bevel_weight_doc,
PyDoc_STRVAR(bpy_bmlayeraccess_collection__crease_doc,
"Edge crease for subsurf - float in [0 - 1].\n\n:type: :class:`BMLayerCollection`"
);
-PyDoc_STRVAR(bpy_bmlayeraccess_collection__tex_doc,
-"Accessor for :class:`BMTexPoly` layer (TODO).\n\ntype: :class:`BMLayerCollection`" // TYPE DOESN'T EXIST YET
-);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__uv_doc,
"Accessor for :class:`BMLoopUV` UV (as a 2D Vector).\n\ntype: :class:`BMLayerCollection`"
);
@@ -222,8 +219,6 @@ static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = {
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__int_doc, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STR},
- {(char *)"tex", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__tex_doc, (void *)CD_MTEXPOLY},
-
#ifdef WITH_FREESTYLE
{(char *)"freestyle", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__freestyle_face_doc, (void *)CD_FREESTYLE_FACE},
#endif
@@ -998,11 +993,6 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len);
break;
}
- case CD_MTEXPOLY:
- {
- ret = BPy_BMTexPoly_CreatePyObject(value);
- break;
- }
case CD_MLOOPUV:
{
ret = BPy_BMLoopUV_CreatePyObject(value);
@@ -1101,11 +1091,6 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
}
break;
}
- case CD_MTEXPOLY:
- {
- ret = BPy_BMTexPoly_AssignPyObject(value, py_value);
- break;
- }
case CD_MLOOPUV:
{
ret = BPy_BMLoopUV_AssignPyObject(value, py_value);
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 92c11a03433..f6926e8437d 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -47,96 +47,6 @@
#include "../generic/python_utildefines.h"
-
-/* Mesh BMTexPoly
- * ************** */
-
-#define BPy_BMTexPoly_Check(v) (Py_TYPE(v) == &BPy_BMTexPoly_Type)
-
-typedef struct BPy_BMTexPoly {
- PyObject_VAR_HEAD
- MTexPoly *data;
-} BPy_BMTexPoly;
-
-extern PyObject *pyrna_id_CreatePyObject(ID *id);
-extern bool pyrna_id_FromPyObject(PyObject *obj, ID **id);
-
-PyDoc_STRVAR(bpy_bmtexpoly_image_doc,
-"Image or None.\n\n:type: :class:`bpy.types.Image`"
-);
-static PyObject *bpy_bmtexpoly_image_get(BPy_BMTexPoly *self, void *UNUSED(closure))
-{
- return pyrna_id_CreatePyObject((ID *)self->data->tpage);
-}
-
-static int bpy_bmtexpoly_image_set(BPy_BMTexPoly *self, PyObject *value, void *UNUSED(closure))
-{
- ID *id;
-
- if (value == Py_None) {
- id = NULL;
- }
- else if (pyrna_id_FromPyObject(value, &id) && id && GS(id->name) == ID_IM) {
- /* pass */
- }
- else {
- PyErr_Format(PyExc_KeyError, "BMTexPoly.image = x"
- "expected an image or None, not '%.200s'",
- Py_TYPE(value)->tp_name);
- return -1;
- }
-
- id_lib_extern(id);
- self->data->tpage = (struct Image *)id;
-
- return 0;
-}
-
-static PyGetSetDef bpy_bmtexpoly_getseters[] = {
- /* attributes match rna_def_mtpoly */
- {(char *)"image", (getter)bpy_bmtexpoly_image_get, (setter)bpy_bmtexpoly_image_set, (char *)bpy_bmtexpoly_image_doc, NULL},
-
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
-};
-
-static PyTypeObject BPy_BMTexPoly_Type; /* bm.loops.layers.uv.active */
-
-static void bm_init_types_bmtexpoly(void)
-{
- BPy_BMTexPoly_Type.tp_basicsize = sizeof(BPy_BMTexPoly);
-
- BPy_BMTexPoly_Type.tp_name = "BMTexPoly";
-
- BPy_BMTexPoly_Type.tp_doc = NULL; // todo
-
- BPy_BMTexPoly_Type.tp_getset = bpy_bmtexpoly_getseters;
-
- BPy_BMTexPoly_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-
- PyType_Ready(&BPy_BMTexPoly_Type);
-}
-
-int BPy_BMTexPoly_AssignPyObject(struct MTexPoly *mtpoly, PyObject *value)
-{
- if (UNLIKELY(!BPy_BMTexPoly_Check(value))) {
- PyErr_Format(PyExc_TypeError, "expected BMTexPoly, not a %.200s", Py_TYPE(value)->tp_name);
- return -1;
- }
- else {
- *((MTexPoly *)mtpoly) = *(((BPy_BMTexPoly *)value)->data);
- return 0;
- }
-}
-
-PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mtpoly)
-{
- BPy_BMTexPoly *self = PyObject_New(BPy_BMTexPoly, &BPy_BMTexPoly_Type);
- self->data = mtpoly;
- return (PyObject *)self;
-}
-
-/* --- End Mesh BMTexPoly --- */
-
/* Mesh Loop UV
* ************ */
@@ -798,7 +708,6 @@ PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert)
/* call to init all types */
void BPy_BM_init_types_meshdata(void)
{
- bm_init_types_bmtexpoly();
bm_init_types_bmloopuv();
bm_init_types_bmloopcol();
bm_init_types_bmdvert();
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
index 07d8a46cc65..c8ae2596f99 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
@@ -40,15 +40,11 @@ typedef struct BPy_BMGenericMeshData {
void *data;
} BPy_BMGenericMeshData;
-struct MTexPoly;
struct MLoopUV;
struct MLoopCol;
struct MDeformVert;
struct MVertSkin;
-int BPy_BMTexPoly_AssignPyObject(struct MTexPoly *mloopuv, PyObject *value);
-PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mloopuv);
-
int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 3ea10228ad4..ed4726e2ab7 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -185,11 +185,13 @@
#define GLbitfield_ref(num) &bgl_var##num
#define GLbitfield_def(num) /* unsigned */ int GLbitfield_var(num)
+#if 0
/* typedef signed char GLbyte; */
#define GLbyte_str "b"
#define GLbyte_var(num) bgl_var##num
#define GLbyte_ref(num) &bgl_var##num
#define GLbyte_def(num) signed char GLbyte_var(num)
+#endif
/* typedef short GLshort; */
#define GLshort_str "h"
@@ -227,11 +229,13 @@
#define GLubyte_ref(num) &bgl_var##num
#define GLubyte_def(num) /* unsigned */ char GLubyte_var(num)
+#if 0
/* typedef unsigned short GLushort; */
#define GLushort_str "H"
#define GLushort_var(num) bgl_var##num
#define GLushort_ref(num) &bgl_var##num
#define GLushort_def(num) /* unsigned */ short GLushort_var(num)
+#endif
/* typedef unsigned int GLuint; */
#define GLuint_str "I"
@@ -1015,358 +1019,71 @@ static PyObject *Method_##funcname (PyObject *UNUSED(self), PyObject *args) \
ret_ret_##ret; \
}
-#define BGLU_Wrap(funcname, ret, arg_list) \
-static PyObject *Method_##funcname (PyObject *UNUSED(self), PyObject *args) \
-{ \
- arg_def arg_list; \
- ret_def_##ret; \
- if (!PyArg_ParseTuple(args, arg_str arg_list, arg_ref arg_list)) { \
- return NULL; \
- } \
- ret_set_##ret glu##funcname (arg_var arg_list); \
- ret_ret_##ret; \
-}
-
/* GL_VERSION_1_0 */
-BGL_Wrap(Accum, void, (GLenum, GLfloat))
-BGL_Wrap(AlphaFunc, void, (GLenum, GLfloat))
-BGL_Wrap(Begin, void, (GLenum))
-BGL_Wrap(Bitmap, void, (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat, GLubyteP))
BGL_Wrap(BlendFunc, void, (GLenum, GLenum))
-BGL_Wrap(CallList, void, (GLuint))
-BGL_Wrap(CallLists, void, (GLsizei, GLenum, GLvoidP))
BGL_Wrap(Clear, void, (GLbitfield))
-BGL_Wrap(ClearAccum, void, (GLfloat, GLfloat, GLfloat, GLfloat))
BGL_Wrap(ClearColor, void, (GLfloat, GLfloat, GLfloat, GLfloat))
BGL_Wrap(ClearDepth, void, (GLdouble))
-BGL_Wrap(ClearIndex, void, (GLfloat))
BGL_Wrap(ClearStencil, void, (GLint))
-BGL_Wrap(ClipPlane, void, (GLenum, GLdoubleP))
-BGL_Wrap(Color3b, void, (GLbyte, GLbyte, GLbyte))
-BGL_Wrap(Color3bv, void, (GLbyteP))
-BGL_Wrap(Color3d, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Color3dv, void, (GLdoubleP))
-BGL_Wrap(Color3f, void, (GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Color3fv, void, (GLfloatP))
-BGL_Wrap(Color3i, void, (GLint, GLint, GLint))
-BGL_Wrap(Color3iv, void, (GLintP))
-BGL_Wrap(Color3s, void, (GLshort, GLshort, GLshort))
-BGL_Wrap(Color3sv, void, (GLshortP))
-BGL_Wrap(Color3ub, void, (GLubyte, GLubyte, GLubyte))
-BGL_Wrap(Color3ubv, void, (GLubyteP))
-BGL_Wrap(Color3ui, void, (GLuint, GLuint, GLuint))
-BGL_Wrap(Color3uiv, void, (GLuintP))
-BGL_Wrap(Color3us, void, (GLushort, GLushort, GLushort))
-BGL_Wrap(Color3usv, void, (GLushortP))
-BGL_Wrap(Color4b, void, (GLbyte, GLbyte, GLbyte, GLbyte))
-BGL_Wrap(Color4bv, void, (GLbyteP))
-BGL_Wrap(Color4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Color4dv, void, (GLdoubleP))
-BGL_Wrap(Color4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Color4fv, void, (GLfloatP))
-BGL_Wrap(Color4i, void, (GLint, GLint, GLint, GLint))
-BGL_Wrap(Color4iv, void, (GLintP))
-BGL_Wrap(Color4s, void, (GLshort, GLshort, GLshort, GLshort))
-BGL_Wrap(Color4sv, void, (GLshortP))
-BGL_Wrap(Color4ub, void, (GLubyte, GLubyte, GLubyte, GLubyte))
-BGL_Wrap(Color4ubv, void, (GLubyteP))
-BGL_Wrap(Color4ui, void, (GLuint, GLuint, GLuint, GLuint))
-BGL_Wrap(Color4uiv, void, (GLuintP))
-BGL_Wrap(Color4us, void, (GLushort, GLushort, GLushort, GLushort))
-BGL_Wrap(Color4usv, void, (GLushortP))
BGL_Wrap(ColorMask, void, (GLboolean, GLboolean, GLboolean, GLboolean))
-BGL_Wrap(ColorMaterial, void, (GLenum, GLenum))
-BGL_Wrap(CopyPixels, void, (GLint, GLint, GLsizei, GLsizei, GLenum))
BGL_Wrap(CullFace, void, (GLenum))
-BGL_Wrap(DeleteLists, void, (GLuint, GLsizei))
BGL_Wrap(DepthFunc, void, (GLenum))
BGL_Wrap(DepthMask, void, (GLboolean))
BGL_Wrap(DepthRange, void, (GLdouble, GLdouble))
BGL_Wrap(Disable, void, (GLenum))
BGL_Wrap(DrawBuffer, void, (GLenum))
-BGL_Wrap(DrawPixels, void, (GLsizei, GLsizei, GLenum, GLenum, GLvoidP))
-BGL_Wrap(EdgeFlag, void, (GLboolean))
-BGL_Wrap(EdgeFlagv, void, (GLbooleanP))
BGL_Wrap(Enable, void, (GLenum))
-BGL_Wrap(End, void, (void))
-BGL_Wrap(EndList, void, (void))
-BGL_Wrap(EvalCoord1d, void, (GLdouble))
-BGL_Wrap(EvalCoord1dv, void, (GLdoubleP))
-BGL_Wrap(EvalCoord1f, void, (GLfloat))
-BGL_Wrap(EvalCoord1fv, void, (GLfloatP))
-BGL_Wrap(EvalCoord2d, void, (GLdouble, GLdouble))
-BGL_Wrap(EvalCoord2dv, void, (GLdoubleP))
-BGL_Wrap(EvalCoord2f, void, (GLfloat, GLfloat))
-BGL_Wrap(EvalCoord2fv, void, (GLfloatP))
-BGL_Wrap(EvalMesh1, void, (GLenum, GLint, GLint))
-BGL_Wrap(EvalMesh2, void, (GLenum, GLint, GLint, GLint, GLint))
-BGL_Wrap(EvalPoint1, void, (GLint))
-BGL_Wrap(EvalPoint2, void, (GLint, GLint))
-BGL_Wrap(FeedbackBuffer, void, (GLsizei, GLenum, GLfloatP))
BGL_Wrap(Finish, void, (void))
BGL_Wrap(Flush, void, (void))
-BGL_Wrap(Fogf, void, (GLenum, GLfloat))
-BGL_Wrap(Fogfv, void, (GLenum, GLfloatP))
-BGL_Wrap(Fogi, void, (GLenum, GLint))
-BGL_Wrap(Fogiv, void, (GLenum, GLintP))
BGL_Wrap(FrontFace, void, (GLenum))
-BGL_Wrap(Frustum, void, (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(GenLists, GLuint, (GLsizei))
BGL_Wrap(GetBooleanv, void, (GLenum, GLbooleanP))
-BGL_Wrap(GetClipPlane, void, (GLenum, GLdoubleP))
BGL_Wrap(GetDoublev, void, (GLenum, GLdoubleP))
BGL_Wrap(GetError, GLenum, (void))
BGL_Wrap(GetFloatv, void, (GLenum, GLfloatP))
BGL_Wrap(GetIntegerv, void, (GLenum, GLintP))
-BGL_Wrap(GetLightfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(GetLightiv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(GetMapdv, void, (GLenum, GLenum, GLdoubleP))
-BGL_Wrap(GetMapfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(GetMapiv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(GetMaterialfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(GetMaterialiv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(GetPixelMapfv, void, (GLenum, GLfloatP))
-BGL_Wrap(GetPixelMapuiv, void, (GLenum, GLuintP))
-BGL_Wrap(GetPixelMapusv, void, (GLenum, GLushortP))
-BGL_Wrap(GetPolygonStipple, void, (GLubyteP))
BGL_Wrap(GetString, GLstring, (GLenum))
-BGL_Wrap(GetTexEnvfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(GetTexEnviv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(GetTexGendv, void, (GLenum, GLenum, GLdoubleP))
-BGL_Wrap(GetTexGenfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(GetTexGeniv, void, (GLenum, GLenum, GLintP))
BGL_Wrap(GetTexImage, void, (GLenum, GLint, GLenum, GLenum, GLvoidP))
BGL_Wrap(GetTexLevelParameterfv, void, (GLenum, GLint, GLenum, GLfloatP))
BGL_Wrap(GetTexLevelParameteriv, void, (GLenum, GLint, GLenum, GLintP))
BGL_Wrap(GetTexParameterfv, void, (GLenum, GLenum, GLfloatP))
BGL_Wrap(GetTexParameteriv, void, (GLenum, GLenum, GLintP))
BGL_Wrap(Hint, void, (GLenum, GLenum))
-BGL_Wrap(IndexMask, void, (GLuint))
-BGL_Wrap(Indexd, void, (GLdouble))
-BGL_Wrap(Indexdv, void, (GLdoubleP))
-BGL_Wrap(Indexf, void, (GLfloat))
-BGL_Wrap(Indexfv, void, (GLfloatP))
-BGL_Wrap(Indexi, void, (GLint))
-BGL_Wrap(Indexiv, void, (GLintP))
-BGL_Wrap(Indexs, void, (GLshort))
-BGL_Wrap(Indexsv, void, (GLshortP))
-BGL_Wrap(InitNames, void, (void))
BGL_Wrap(IsEnabled, GLboolean, (GLenum))
-BGL_Wrap(IsList, GLboolean, (GLuint))
-BGL_Wrap(LightModelf, void, (GLenum, GLfloat))
-BGL_Wrap(LightModelfv, void, (GLenum, GLfloatP))
-BGL_Wrap(LightModeli, void, (GLenum, GLint))
-BGL_Wrap(LightModeliv, void, (GLenum, GLintP))
-BGL_Wrap(Lightf, void, (GLenum, GLenum, GLfloat))
-BGL_Wrap(Lightfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(Lighti, void, (GLenum, GLenum, GLint))
-BGL_Wrap(Lightiv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(LineStipple, void, (GLint, GLushort))
BGL_Wrap(LineWidth, void, (GLfloat))
-BGL_Wrap(ListBase, void, (GLuint))
-BGL_Wrap(LoadIdentity, void, (void))
-BGL_Wrap(LoadMatrixd, void, (GLdoubleP))
-BGL_Wrap(LoadMatrixf, void, (GLfloatP))
-BGL_Wrap(LoadName, void, (GLuint))
BGL_Wrap(LogicOp, void, (GLenum))
-BGL_Wrap(Map1d, void, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdoubleP))
-BGL_Wrap(Map1f, void, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloatP))
-BGL_Wrap(Map2d, void, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdoubleP))
-BGL_Wrap(Map2f, void, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloatP))
-BGL_Wrap(MapGrid1d, void, (GLint, GLdouble, GLdouble))
-BGL_Wrap(MapGrid1f, void, (GLint, GLfloat, GLfloat))
-BGL_Wrap(MapGrid2d, void, (GLint, GLdouble, GLdouble, GLint, GLdouble, GLdouble))
-BGL_Wrap(MapGrid2f, void, (GLint, GLfloat, GLfloat, GLint, GLfloat, GLfloat))
-BGL_Wrap(Materialf, void, (GLenum, GLenum, GLfloat))
-BGL_Wrap(Materialfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(Materiali, void, (GLenum, GLenum, GLint))
-BGL_Wrap(Materialiv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(MatrixMode, void, (GLenum))
-BGL_Wrap(MultMatrixd, void, (GLdoubleP))
-BGL_Wrap(MultMatrixf, void, (GLfloatP))
-BGL_Wrap(NewList, void, (GLuint, GLenum))
-BGL_Wrap(Normal3b, void, (GLbyte, GLbyte, GLbyte))
-BGL_Wrap(Normal3bv, void, (GLbyteP))
-BGL_Wrap(Normal3d, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Normal3dv, void, (GLdoubleP))
-BGL_Wrap(Normal3f, void, (GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Normal3fv, void, (GLfloatP))
-BGL_Wrap(Normal3i, void, (GLint, GLint, GLint))
-BGL_Wrap(Normal3iv, void, (GLintP))
-BGL_Wrap(Normal3s, void, (GLshort, GLshort, GLshort))
-BGL_Wrap(Normal3sv, void, (GLshortP))
-BGL_Wrap(Ortho, void, (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(PassThrough, void, (GLfloat))
-BGL_Wrap(PixelMapfv, void, (GLenum, GLsizei, GLfloatP))
-BGL_Wrap(PixelMapuiv, void, (GLenum, GLsizei, GLuintP))
-BGL_Wrap(PixelMapusv, void, (GLenum, GLsizei, GLushortP))
BGL_Wrap(PixelStoref, void, (GLenum, GLfloat))
BGL_Wrap(PixelStorei, void, (GLenum, GLint))
-BGL_Wrap(PixelTransferf, void, (GLenum, GLfloat))
-BGL_Wrap(PixelTransferi, void, (GLenum, GLint))
-BGL_Wrap(PixelZoom, void, (GLfloat, GLfloat))
BGL_Wrap(PointSize, void, (GLfloat))
BGL_Wrap(PolygonMode, void, (GLenum, GLenum))
-BGL_Wrap(PolygonStipple, void, (GLubyteP))
-BGL_Wrap(PopAttrib, void, (void))
-BGL_Wrap(PopMatrix, void, (void))
-BGL_Wrap(PopName, void, (void))
-BGL_Wrap(PushAttrib, void, (GLbitfield))
-BGL_Wrap(PushMatrix, void, (void))
-BGL_Wrap(PushName, void, (GLuint))
-BGL_Wrap(RasterPos2d, void, (GLdouble, GLdouble))
-BGL_Wrap(RasterPos2dv, void, (GLdoubleP))
-BGL_Wrap(RasterPos2f, void, (GLfloat, GLfloat))
-BGL_Wrap(RasterPos2fv, void, (GLfloatP))
-BGL_Wrap(RasterPos2i, void, (GLint, GLint))
-BGL_Wrap(RasterPos2iv, void, (GLintP))
-BGL_Wrap(RasterPos2s, void, (GLshort, GLshort))
-BGL_Wrap(RasterPos2sv, void, (GLshortP))
-BGL_Wrap(RasterPos3d, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(RasterPos3dv, void, (GLdoubleP))
-BGL_Wrap(RasterPos3f, void, (GLfloat, GLfloat, GLfloat))
-BGL_Wrap(RasterPos3fv, void, (GLfloatP))
-BGL_Wrap(RasterPos3i, void, (GLint, GLint, GLint))
-BGL_Wrap(RasterPos3iv, void, (GLintP))
-BGL_Wrap(RasterPos3s, void, (GLshort, GLshort, GLshort))
-BGL_Wrap(RasterPos3sv, void, (GLshortP))
-BGL_Wrap(RasterPos4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(RasterPos4dv, void, (GLdoubleP))
-BGL_Wrap(RasterPos4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(RasterPos4fv, void, (GLfloatP))
-BGL_Wrap(RasterPos4i, void, (GLint, GLint, GLint, GLint))
-BGL_Wrap(RasterPos4iv, void, (GLintP))
-BGL_Wrap(RasterPos4s, void, (GLshort, GLshort, GLshort, GLshort))
-BGL_Wrap(RasterPos4sv, void, (GLshortP))
BGL_Wrap(ReadBuffer, void, (GLenum))
BGL_Wrap(ReadPixels, void, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoidP))
-BGL_Wrap(Rectd, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Rectdv, void, (GLdoubleP, GLdoubleP))
-BGL_Wrap(Rectf, void, (GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Rectfv, void, (GLfloatP, GLfloatP))
-BGL_Wrap(Recti, void, (GLint, GLint, GLint, GLint))
-BGL_Wrap(Rectiv, void, (GLintP, GLintP))
-BGL_Wrap(Rects, void, (GLshort, GLshort, GLshort, GLshort))
-BGL_Wrap(Rectsv, void, (GLshortP, GLshortP))
-BGL_Wrap(RenderMode, GLint, (GLenum))
-BGL_Wrap(Rotated, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Rotatef, void, (GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Scaled, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Scalef, void, (GLfloat, GLfloat, GLfloat))
BGL_Wrap(Scissor, void, (GLint, GLint, GLsizei, GLsizei))
-BGL_Wrap(SelectBuffer, void, (GLsizei, GLuintP))
-BGL_Wrap(ShadeModel, void, (GLenum))
BGL_Wrap(StencilFunc, void, (GLenum, GLint, GLuint))
BGL_Wrap(StencilMask, void, (GLuint))
BGL_Wrap(StencilOp, void, (GLenum, GLenum, GLenum))
-BGL_Wrap(TexCoord1d, void, (GLdouble))
-BGL_Wrap(TexCoord1dv, void, (GLdoubleP))
-BGL_Wrap(TexCoord1f, void, (GLfloat))
-BGL_Wrap(TexCoord1fv, void, (GLfloatP))
-BGL_Wrap(TexCoord1i, void, (GLint))
-BGL_Wrap(TexCoord1iv, void, (GLintP))
-BGL_Wrap(TexCoord1s, void, (GLshort))
-BGL_Wrap(TexCoord1sv, void, (GLshortP))
-BGL_Wrap(TexCoord2d, void, (GLdouble, GLdouble))
-BGL_Wrap(TexCoord2dv, void, (GLdoubleP))
-BGL_Wrap(TexCoord2f, void, (GLfloat, GLfloat))
-BGL_Wrap(TexCoord2fv, void, (GLfloatP))
-BGL_Wrap(TexCoord2i, void, (GLint, GLint))
-BGL_Wrap(TexCoord2iv, void, (GLintP))
-BGL_Wrap(TexCoord2s, void, (GLshort, GLshort))
-BGL_Wrap(TexCoord2sv, void, (GLshortP))
-BGL_Wrap(TexCoord3d, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(TexCoord3dv, void, (GLdoubleP))
-BGL_Wrap(TexCoord3f, void, (GLfloat, GLfloat, GLfloat))
-BGL_Wrap(TexCoord3fv, void, (GLfloatP))
-BGL_Wrap(TexCoord3i, void, (GLint, GLint, GLint))
-BGL_Wrap(TexCoord3iv, void, (GLintP))
-BGL_Wrap(TexCoord3s, void, (GLshort, GLshort, GLshort))
-BGL_Wrap(TexCoord3sv, void, (GLshortP))
-BGL_Wrap(TexCoord4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(TexCoord4dv, void, (GLdoubleP))
-BGL_Wrap(TexCoord4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(TexCoord4fv, void, (GLfloatP))
-BGL_Wrap(TexCoord4i, void, (GLint, GLint, GLint, GLint))
-BGL_Wrap(TexCoord4iv, void, (GLintP))
-BGL_Wrap(TexCoord4s, void, (GLshort, GLshort, GLshort, GLshort))
-BGL_Wrap(TexCoord4sv, void, (GLshortP))
-BGL_Wrap(TexEnvf, void, (GLenum, GLenum, GLfloat))
-BGL_Wrap(TexEnvfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(TexEnvi, void, (GLenum, GLenum, GLint))
-BGL_Wrap(TexEnviv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(TexGend, void, (GLenum, GLenum, GLdouble))
-BGL_Wrap(TexGendv, void, (GLenum, GLenum, GLdoubleP))
-BGL_Wrap(TexGenf, void, (GLenum, GLenum, GLfloat))
-BGL_Wrap(TexGenfv, void, (GLenum, GLenum, GLfloatP))
-BGL_Wrap(TexGeni, void, (GLenum, GLenum, GLint))
-BGL_Wrap(TexGeniv, void, (GLenum, GLenum, GLintP))
BGL_Wrap(TexImage1D, void, (GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, GLvoidP))
BGL_Wrap(TexImage2D, void, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, GLvoidP))
BGL_Wrap(TexParameterf, void, (GLenum, GLenum, GLfloat))
BGL_Wrap(TexParameterfv, void, (GLenum, GLenum, GLfloatP))
BGL_Wrap(TexParameteri, void, (GLenum, GLenum, GLint))
BGL_Wrap(TexParameteriv, void, (GLenum, GLenum, GLintP))
-BGL_Wrap(Translated, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Translatef, void, (GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Vertex2d, void, (GLdouble, GLdouble))
-BGL_Wrap(Vertex2dv, void, (GLdoubleP))
-BGL_Wrap(Vertex2f, void, (GLfloat, GLfloat))
-BGL_Wrap(Vertex2fv, void, (GLfloatP))
-BGL_Wrap(Vertex2i, void, (GLint, GLint))
-BGL_Wrap(Vertex2iv, void, (GLintP))
-BGL_Wrap(Vertex2s, void, (GLshort, GLshort))
-BGL_Wrap(Vertex2sv, void, (GLshortP))
-BGL_Wrap(Vertex3d, void, (GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Vertex3dv, void, (GLdoubleP))
-BGL_Wrap(Vertex3f, void, (GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Vertex3fv, void, (GLfloatP))
-BGL_Wrap(Vertex3i, void, (GLint, GLint, GLint))
-BGL_Wrap(Vertex3iv, void, (GLintP))
-BGL_Wrap(Vertex3s, void, (GLshort, GLshort, GLshort))
-BGL_Wrap(Vertex3sv, void, (GLshortP))
-BGL_Wrap(Vertex4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(Vertex4dv, void, (GLdoubleP))
-BGL_Wrap(Vertex4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(Vertex4fv, void, (GLfloatP))
-BGL_Wrap(Vertex4i, void, (GLint, GLint, GLint, GLint))
-BGL_Wrap(Vertex4iv, void, (GLintP))
-BGL_Wrap(Vertex4s, void, (GLshort, GLshort, GLshort, GLshort))
-BGL_Wrap(Vertex4sv, void, (GLshortP))
BGL_Wrap(Viewport, void, (GLint, GLint, GLsizei, GLsizei))
/* GL_VERSION_1_1 */
-BGL_Wrap(AreTexturesResident, GLboolean, (GLsizei, GLuintP, GLbooleanP))
-BGL_Wrap(ArrayElement, void, (GLint))
BGL_Wrap(BindTexture, void, (GLenum, GLuint))
-BGL_Wrap(ColorPointer, void, (GLint, GLenum, GLsizei, GLvoidP))
BGL_Wrap(CopyTexImage1D, void, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint))
BGL_Wrap(CopyTexImage2D, void, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint))
BGL_Wrap(CopyTexSubImage1D, void, (GLenum, GLint, GLint, GLint, GLint, GLsizei))
BGL_Wrap(CopyTexSubImage2D, void, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei))
BGL_Wrap(DeleteTextures, void, (GLsizei, GLuintP))
-BGL_Wrap(DisableClientState, void, (GLenum))
BGL_Wrap(DrawArrays, void, (GLenum, GLint, GLsizei))
BGL_Wrap(DrawElements, void, (GLenum, GLsizei, GLenum, GLvoidP))
-BGL_Wrap(EdgeFlagPointer, void, (GLsizei, GLvoidP))
-BGL_Wrap(EnableClientState, void, (GLenum))
BGL_Wrap(GenTextures, void, (GLsizei, GLuintP))
-BGL_Wrap(GetPointerv, void, (GLenum, GLvoidP))
-BGL_Wrap(IndexPointer, void, (GLenum, GLsizei, GLvoidP))
-BGL_Wrap(Indexub, void, (GLubyte))
-BGL_Wrap(Indexubv, void, (GLubyteP))
-BGL_Wrap(InterleavedArrays, void, (GLenum, GLsizei, GLvoidP))
BGL_Wrap(IsTexture, GLboolean, (GLuint))
-BGL_Wrap(NormalPointer, void, (GLenum, GLsizei, GLvoidP))
BGL_Wrap(PolygonOffset, void, (GLfloat, GLfloat))
-BGL_Wrap(PopClientAttrib, void, (void))
-BGL_Wrap(PrioritizeTextures, void, (GLsizei, GLuintP, GLfloatP))
-BGL_Wrap(PushClientAttrib, void, (GLbitfield))
-BGL_Wrap(TexCoordPointer, void, (GLint, GLenum, GLsizei, GLvoidP))
BGL_Wrap(TexSubImage1D, void, (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, GLvoidP))
BGL_Wrap(TexSubImage2D, void, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoidP))
-BGL_Wrap(VertexPointer, void, (GLint, GLenum, GLsizei, GLvoidP))
/* GL_VERSION_1_2 */
@@ -1378,7 +1095,6 @@ BGL_Wrap(TexSubImage3D, void, (GLenum, GLint, GLint, GLint, GLi
/* GL_VERSION_1_3 */
BGL_Wrap(ActiveTexture, void, (GLenum))
-BGL_Wrap(ClientActiveTexture, void, (GLenum))
BGL_Wrap(CompressedTexImage1D, void, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, GLvoidP))
BGL_Wrap(CompressedTexImage2D, void, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, GLvoidP))
BGL_Wrap(CompressedTexImage3D, void, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, GLvoidP))
@@ -1386,42 +1102,6 @@ BGL_Wrap(CompressedTexSubImage1D, void, (GLenum, GLint, GLint, GLsizei, G
BGL_Wrap(CompressedTexSubImage2D, void, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, GLvoidP))
BGL_Wrap(CompressedTexSubImage3D, void, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, GLvoidP))
BGL_Wrap(GetCompressedTexImage, void, (GLenum, GLint, GLvoidP))
-BGL_Wrap(LoadTransposeMatrixd, void, (GLdoubleP))
-BGL_Wrap(LoadTransposeMatrixf, void, (GLfloatP))
-BGL_Wrap(MultTransposeMatrixd, void, (GLdoubleP))
-BGL_Wrap(MultTransposeMatrixf, void, (GLfloatP))
-BGL_Wrap(MultiTexCoord1d, void, (GLenum, GLdouble))
-BGL_Wrap(MultiTexCoord1dv, void, (GLenum, GLdoubleP))
-BGL_Wrap(MultiTexCoord1f, void, (GLenum, GLfloat))
-BGL_Wrap(MultiTexCoord1fv, void, (GLenum, GLfloatP))
-BGL_Wrap(MultiTexCoord1i, void, (GLenum, GLint))
-BGL_Wrap(MultiTexCoord1iv, void, (GLenum, GLintP))
-BGL_Wrap(MultiTexCoord1s, void, (GLenum, GLshort))
-BGL_Wrap(MultiTexCoord1sv, void, (GLenum, GLshortP))
-BGL_Wrap(MultiTexCoord2d, void, (GLenum, GLdouble, GLdouble))
-BGL_Wrap(MultiTexCoord2dv, void, (GLenum, GLdoubleP))
-BGL_Wrap(MultiTexCoord2f, void, (GLenum, GLfloat, GLfloat))
-BGL_Wrap(MultiTexCoord2fv, void, (GLenum, GLfloatP))
-BGL_Wrap(MultiTexCoord2i, void, (GLenum, GLint, GLint))
-BGL_Wrap(MultiTexCoord2iv, void, (GLenum, GLintP))
-BGL_Wrap(MultiTexCoord2s, void, (GLenum, GLshort, GLshort))
-BGL_Wrap(MultiTexCoord2sv, void, (GLenum, GLshortP))
-BGL_Wrap(MultiTexCoord3d, void, (GLenum, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(MultiTexCoord3dv, void, (GLenum, GLdoubleP))
-BGL_Wrap(MultiTexCoord3f, void, (GLenum, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(MultiTexCoord3fv, void, (GLenum, GLfloatP))
-BGL_Wrap(MultiTexCoord3i, void, (GLenum, GLint, GLint, GLint))
-BGL_Wrap(MultiTexCoord3iv, void, (GLenum, GLintP))
-BGL_Wrap(MultiTexCoord3s, void, (GLenum, GLshort, GLshort, GLshort))
-BGL_Wrap(MultiTexCoord3sv, void, (GLenum, GLshortP))
-BGL_Wrap(MultiTexCoord4d, void, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble))
-BGL_Wrap(MultiTexCoord4dv, void, (GLenum, GLdoubleP))
-BGL_Wrap(MultiTexCoord4f, void, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat))
-BGL_Wrap(MultiTexCoord4fv, void, (GLenum, GLfloatP))
-BGL_Wrap(MultiTexCoord4i, void, (GLenum, GLint, GLint, GLint, GLint))
-BGL_Wrap(MultiTexCoord4iv, void, (GLenum, GLintP))
-BGL_Wrap(MultiTexCoord4s, void, (GLenum, GLshort, GLshort, GLshort, GLshort))
-BGL_Wrap(MultiTexCoord4sv, void, (GLenum, GLshortP))
BGL_Wrap(SampleCoverage, void, (GLfloat, GLboolean))
@@ -1587,44 +1267,7 @@ BGL_Wrap(TexImage3DMultisample, void, (GLenum, GLsizei, GLenum, GLsizei
/* GL_VERSION_3_3 */
-BGL_Wrap(ColorP3ui, void, (GLenum, GLuint))
-BGL_Wrap(ColorP3uiv, void, (GLenum, GLuintP))
-BGL_Wrap(ColorP4ui, void, (GLenum, GLuint))
-BGL_Wrap(ColorP4uiv, void, (GLenum, GLuintP))
-BGL_Wrap(MultiTexCoordP1ui, void, (GLenum, GLenum, GLuint))
-BGL_Wrap(MultiTexCoordP1uiv, void, (GLenum, GLenum, GLuintP))
-BGL_Wrap(MultiTexCoordP2ui, void, (GLenum, GLenum, GLuint))
-BGL_Wrap(MultiTexCoordP2uiv, void, (GLenum, GLenum, GLuintP))
-BGL_Wrap(MultiTexCoordP3ui, void, (GLenum, GLenum, GLuint))
-BGL_Wrap(MultiTexCoordP3uiv, void, (GLenum, GLenum, GLuintP))
-BGL_Wrap(MultiTexCoordP4ui, void, (GLenum, GLenum, GLuint))
-BGL_Wrap(MultiTexCoordP4uiv, void, (GLenum, GLenum, GLuintP))
-BGL_Wrap(NormalP3ui, void, (GLenum, GLuint))
-BGL_Wrap(NormalP3uiv, void, (GLenum, GLuintP))
-BGL_Wrap(SecondaryColorP3ui, void, (GLenum, GLuint))
-BGL_Wrap(SecondaryColorP3uiv, void, (GLenum, GLuintP))
-BGL_Wrap(TexCoordP1ui, void, (GLenum, GLuint))
-BGL_Wrap(TexCoordP1uiv, void, (GLenum, GLuintP))
-BGL_Wrap(TexCoordP2ui, void, (GLenum, GLuint))
-BGL_Wrap(TexCoordP2uiv, void, (GLenum, GLuintP))
-BGL_Wrap(TexCoordP3ui, void, (GLenum, GLuint))
-BGL_Wrap(TexCoordP3uiv, void, (GLenum, GLuintP))
-BGL_Wrap(TexCoordP4ui, void, (GLenum, GLuint))
-BGL_Wrap(TexCoordP4uiv, void, (GLenum, GLuintP))
-BGL_Wrap(VertexP2ui, void, (GLenum, GLuint))
-BGL_Wrap(VertexP2uiv, void, (GLenum, GLuintP))
-BGL_Wrap(VertexP3ui, void, (GLenum, GLuint))
-BGL_Wrap(VertexP3uiv, void, (GLenum, GLuintP))
-BGL_Wrap(VertexP4ui, void, (GLenum, GLuint))
-BGL_Wrap(VertexP4uiv, void, (GLenum, GLuintP))
-
-
-BGLU_Wrap(Perspective, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGLU_Wrap(LookAt, void, (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))
-BGLU_Wrap(Ortho2D, void, (GLdouble, GLdouble, GLdouble, GLdouble))
-BGLU_Wrap(PickMatrix, void, (GLdouble, GLdouble, GLdouble, GLdouble, GLintP))
-BGLU_Wrap(Project, GLint, (GLdouble, GLdouble, GLdouble, GLdoubleP, GLdoubleP, GLintP, GLdoubleP, GLdoubleP, GLdoubleP))
-BGLU_Wrap(UnProject, GLint, (GLdouble, GLdouble, GLdouble, GLdoubleP, GLdoubleP, GLintP, GLdoubleP, GLdoubleP, GLdoubleP))
+/* no new functions besides packed immediate mode (not part of core profile) */
/** \} */
@@ -1634,26 +1277,12 @@ BGLU_Wrap(UnProject, GLint, (GLdouble, GLdouble, GLdouble, GLdouble
/** \name Module Definition
* \{ */
-#define MethodDefu(func) {"glu"#func, Method_##func, METH_VARARGS, NULL}
-
-static struct PyMethodDef BGL_methods[] = {
- MethodDefu(Perspective),
- MethodDefu(LookAt),
- MethodDefu(Ortho2D),
- MethodDefu(PickMatrix),
- MethodDefu(Project),
- MethodDefu(UnProject),
- {NULL, NULL, 0, NULL}
-};
-
-#undef MethodDefu
-
static struct PyModuleDef BGL_module_def = {
PyModuleDef_HEAD_INIT,
"bgl", /* m_name */
NULL, /* m_doc */
0, /* m_size */
- BGL_methods, /* m_methods */
+ NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
@@ -1687,9 +1316,6 @@ static void py_module_dict_add_method(PyObject *submodule, PyObject *dict, PyMet
}
}
-/* TODO, expose to users */
-static bool use_deprecated = true;
-
PyObject *BPyInit_bgl(void)
{
PyObject *submodule, *dict;
@@ -1764,268 +1390,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(TexParameteriv);
PY_MOD_ADD_METHOD(Viewport);
}
- /* adding in GL_VERSION_1_0 removed from core profile */
- if (use_deprecated == true) {
- PY_MOD_ADD_METHOD(Accum);
- PY_MOD_ADD_METHOD(AlphaFunc);
- PY_MOD_ADD_METHOD(Begin);
- PY_MOD_ADD_METHOD(Bitmap);
- PY_MOD_ADD_METHOD(CallList);
- PY_MOD_ADD_METHOD(CallLists);
- PY_MOD_ADD_METHOD(ClearAccum);
- PY_MOD_ADD_METHOD(ClearIndex);
- PY_MOD_ADD_METHOD(ClipPlane);
- PY_MOD_ADD_METHOD(Color3b);
- PY_MOD_ADD_METHOD(Color3bv);
- PY_MOD_ADD_METHOD(Color3d);
- PY_MOD_ADD_METHOD(Color3dv);
- PY_MOD_ADD_METHOD(Color3f);
- PY_MOD_ADD_METHOD(Color3fv);
- PY_MOD_ADD_METHOD(Color3i);
- PY_MOD_ADD_METHOD(Color3iv);
- PY_MOD_ADD_METHOD(Color3s);
- PY_MOD_ADD_METHOD(Color3sv);
- PY_MOD_ADD_METHOD(Color3ub);
- PY_MOD_ADD_METHOD(Color3ubv);
- PY_MOD_ADD_METHOD(Color3ui);
- PY_MOD_ADD_METHOD(Color3uiv);
- PY_MOD_ADD_METHOD(Color3us);
- PY_MOD_ADD_METHOD(Color3usv);
- PY_MOD_ADD_METHOD(Color4b);
- PY_MOD_ADD_METHOD(Color4bv);
- PY_MOD_ADD_METHOD(Color4d);
- PY_MOD_ADD_METHOD(Color4dv);
- PY_MOD_ADD_METHOD(Color4f);
- PY_MOD_ADD_METHOD(Color4fv);
- PY_MOD_ADD_METHOD(Color4i);
- PY_MOD_ADD_METHOD(Color4iv);
- PY_MOD_ADD_METHOD(Color4s);
- PY_MOD_ADD_METHOD(Color4sv);
- PY_MOD_ADD_METHOD(Color4ub);
- PY_MOD_ADD_METHOD(Color4ubv);
- PY_MOD_ADD_METHOD(Color4ui);
- PY_MOD_ADD_METHOD(Color4uiv);
- PY_MOD_ADD_METHOD(Color4us);
- PY_MOD_ADD_METHOD(Color4usv);
- PY_MOD_ADD_METHOD(ColorMaterial);
- PY_MOD_ADD_METHOD(CopyPixels);
- PY_MOD_ADD_METHOD(DeleteLists);
- PY_MOD_ADD_METHOD(DrawPixels);
- PY_MOD_ADD_METHOD(EdgeFlag);
- PY_MOD_ADD_METHOD(EdgeFlagv);
- PY_MOD_ADD_METHOD(End);
- PY_MOD_ADD_METHOD(EndList);
- PY_MOD_ADD_METHOD(EvalCoord1d);
- PY_MOD_ADD_METHOD(EvalCoord1dv);
- PY_MOD_ADD_METHOD(EvalCoord1f);
- PY_MOD_ADD_METHOD(EvalCoord1fv);
- PY_MOD_ADD_METHOD(EvalCoord2d);
- PY_MOD_ADD_METHOD(EvalCoord2dv);
- PY_MOD_ADD_METHOD(EvalCoord2f);
- PY_MOD_ADD_METHOD(EvalCoord2fv);
- PY_MOD_ADD_METHOD(EvalMesh1);
- PY_MOD_ADD_METHOD(EvalMesh2);
- PY_MOD_ADD_METHOD(EvalPoint1);
- PY_MOD_ADD_METHOD(EvalPoint2);
- PY_MOD_ADD_METHOD(FeedbackBuffer);
- PY_MOD_ADD_METHOD(Fogf);
- PY_MOD_ADD_METHOD(Fogfv);
- PY_MOD_ADD_METHOD(Fogi);
- PY_MOD_ADD_METHOD(Fogiv);
- PY_MOD_ADD_METHOD(Frustum);
- PY_MOD_ADD_METHOD(GenLists);
- PY_MOD_ADD_METHOD(GetClipPlane);
- PY_MOD_ADD_METHOD(GetLightfv);
- PY_MOD_ADD_METHOD(GetLightiv);
- PY_MOD_ADD_METHOD(GetMapdv);
- PY_MOD_ADD_METHOD(GetMapfv);
- PY_MOD_ADD_METHOD(GetMapiv);
- PY_MOD_ADD_METHOD(GetMaterialfv);
- PY_MOD_ADD_METHOD(GetMaterialiv);
- PY_MOD_ADD_METHOD(GetPixelMapfv);
- PY_MOD_ADD_METHOD(GetPixelMapuiv);
- PY_MOD_ADD_METHOD(GetPixelMapusv);
- PY_MOD_ADD_METHOD(GetPolygonStipple);
- PY_MOD_ADD_METHOD(GetTexEnvfv);
- PY_MOD_ADD_METHOD(GetTexEnviv);
- PY_MOD_ADD_METHOD(GetTexGendv);
- PY_MOD_ADD_METHOD(GetTexGenfv);
- PY_MOD_ADD_METHOD(GetTexGeniv);
- PY_MOD_ADD_METHOD(IndexMask);
- PY_MOD_ADD_METHOD(Indexd);
- PY_MOD_ADD_METHOD(Indexdv);
- PY_MOD_ADD_METHOD(Indexf);
- PY_MOD_ADD_METHOD(Indexfv);
- PY_MOD_ADD_METHOD(Indexi);
- PY_MOD_ADD_METHOD(Indexiv);
- PY_MOD_ADD_METHOD(Indexs);
- PY_MOD_ADD_METHOD(Indexsv);
- PY_MOD_ADD_METHOD(InitNames);
- PY_MOD_ADD_METHOD(IsList);
- PY_MOD_ADD_METHOD(LightModelf);
- PY_MOD_ADD_METHOD(LightModelfv);
- PY_MOD_ADD_METHOD(LightModeli);
- PY_MOD_ADD_METHOD(LightModeliv);
- PY_MOD_ADD_METHOD(Lightf);
- PY_MOD_ADD_METHOD(Lightfv);
- PY_MOD_ADD_METHOD(Lighti);
- PY_MOD_ADD_METHOD(Lightiv);
- PY_MOD_ADD_METHOD(LineStipple);
- PY_MOD_ADD_METHOD(ListBase);
- PY_MOD_ADD_METHOD(LoadIdentity);
- PY_MOD_ADD_METHOD(LoadMatrixd);
- PY_MOD_ADD_METHOD(LoadMatrixf);
- PY_MOD_ADD_METHOD(LoadName);
- PY_MOD_ADD_METHOD(Map1d);
- PY_MOD_ADD_METHOD(Map1f);
- PY_MOD_ADD_METHOD(Map2d);
- PY_MOD_ADD_METHOD(Map2f);
- PY_MOD_ADD_METHOD(MapGrid1d);
- PY_MOD_ADD_METHOD(MapGrid1f);
- PY_MOD_ADD_METHOD(MapGrid2d);
- PY_MOD_ADD_METHOD(MapGrid2f);
- PY_MOD_ADD_METHOD(Materialf);
- PY_MOD_ADD_METHOD(Materialfv);
- PY_MOD_ADD_METHOD(Materiali);
- PY_MOD_ADD_METHOD(Materialiv);
- PY_MOD_ADD_METHOD(MatrixMode);
- PY_MOD_ADD_METHOD(MultMatrixd);
- PY_MOD_ADD_METHOD(MultMatrixf);
- PY_MOD_ADD_METHOD(NewList);
- PY_MOD_ADD_METHOD(Normal3b);
- PY_MOD_ADD_METHOD(Normal3bv);
- PY_MOD_ADD_METHOD(Normal3d);
- PY_MOD_ADD_METHOD(Normal3dv);
- PY_MOD_ADD_METHOD(Normal3f);
- PY_MOD_ADD_METHOD(Normal3fv);
- PY_MOD_ADD_METHOD(Normal3i);
- PY_MOD_ADD_METHOD(Normal3iv);
- PY_MOD_ADD_METHOD(Normal3s);
- PY_MOD_ADD_METHOD(Normal3sv);
- PY_MOD_ADD_METHOD(Ortho);
- PY_MOD_ADD_METHOD(PassThrough);
- PY_MOD_ADD_METHOD(PixelMapfv);
- PY_MOD_ADD_METHOD(PixelMapuiv);
- PY_MOD_ADD_METHOD(PixelMapusv);
- PY_MOD_ADD_METHOD(PixelTransferf);
- PY_MOD_ADD_METHOD(PixelTransferi);
- PY_MOD_ADD_METHOD(PixelZoom);
- PY_MOD_ADD_METHOD(PolygonStipple);
- PY_MOD_ADD_METHOD(PopAttrib);
- PY_MOD_ADD_METHOD(PopMatrix);
- PY_MOD_ADD_METHOD(PopName);
- PY_MOD_ADD_METHOD(PushAttrib);
- PY_MOD_ADD_METHOD(PushMatrix);
- PY_MOD_ADD_METHOD(PushName);
- PY_MOD_ADD_METHOD(RasterPos2d);
- PY_MOD_ADD_METHOD(RasterPos2dv);
- PY_MOD_ADD_METHOD(RasterPos2f);
- PY_MOD_ADD_METHOD(RasterPos2fv);
- PY_MOD_ADD_METHOD(RasterPos2i);
- PY_MOD_ADD_METHOD(RasterPos2iv);
- PY_MOD_ADD_METHOD(RasterPos2s);
- PY_MOD_ADD_METHOD(RasterPos2sv);
- PY_MOD_ADD_METHOD(RasterPos3d);
- PY_MOD_ADD_METHOD(RasterPos3dv);
- PY_MOD_ADD_METHOD(RasterPos3f);
- PY_MOD_ADD_METHOD(RasterPos3fv);
- PY_MOD_ADD_METHOD(RasterPos3i);
- PY_MOD_ADD_METHOD(RasterPos3iv);
- PY_MOD_ADD_METHOD(RasterPos3s);
- PY_MOD_ADD_METHOD(RasterPos3sv);
- PY_MOD_ADD_METHOD(RasterPos4d);
- PY_MOD_ADD_METHOD(RasterPos4dv);
- PY_MOD_ADD_METHOD(RasterPos4f);
- PY_MOD_ADD_METHOD(RasterPos4fv);
- PY_MOD_ADD_METHOD(RasterPos4i);
- PY_MOD_ADD_METHOD(RasterPos4iv);
- PY_MOD_ADD_METHOD(RasterPos4s);
- PY_MOD_ADD_METHOD(RasterPos4sv);
- PY_MOD_ADD_METHOD(Rectd);
- PY_MOD_ADD_METHOD(Rectdv);
- PY_MOD_ADD_METHOD(Rectf);
- PY_MOD_ADD_METHOD(Rectfv);
- PY_MOD_ADD_METHOD(Recti);
- PY_MOD_ADD_METHOD(Rectiv);
- PY_MOD_ADD_METHOD(Rects);
- PY_MOD_ADD_METHOD(Rectsv);
- PY_MOD_ADD_METHOD(RenderMode);
- PY_MOD_ADD_METHOD(Rotated);
- PY_MOD_ADD_METHOD(Rotatef);
- PY_MOD_ADD_METHOD(Scaled);
- PY_MOD_ADD_METHOD(Scalef);
- PY_MOD_ADD_METHOD(SelectBuffer);
- PY_MOD_ADD_METHOD(ShadeModel);
- PY_MOD_ADD_METHOD(TexCoord1d);
- PY_MOD_ADD_METHOD(TexCoord1dv);
- PY_MOD_ADD_METHOD(TexCoord1f);
- PY_MOD_ADD_METHOD(TexCoord1fv);
- PY_MOD_ADD_METHOD(TexCoord1i);
- PY_MOD_ADD_METHOD(TexCoord1iv);
- PY_MOD_ADD_METHOD(TexCoord1s);
- PY_MOD_ADD_METHOD(TexCoord1sv);
- PY_MOD_ADD_METHOD(TexCoord2d);
- PY_MOD_ADD_METHOD(TexCoord2dv);
- PY_MOD_ADD_METHOD(TexCoord2f);
- PY_MOD_ADD_METHOD(TexCoord2fv);
- PY_MOD_ADD_METHOD(TexCoord2i);
- PY_MOD_ADD_METHOD(TexCoord2iv);
- PY_MOD_ADD_METHOD(TexCoord2s);
- PY_MOD_ADD_METHOD(TexCoord2sv);
- PY_MOD_ADD_METHOD(TexCoord3d);
- PY_MOD_ADD_METHOD(TexCoord3dv);
- PY_MOD_ADD_METHOD(TexCoord3f);
- PY_MOD_ADD_METHOD(TexCoord3fv);
- PY_MOD_ADD_METHOD(TexCoord3i);
- PY_MOD_ADD_METHOD(TexCoord3iv);
- PY_MOD_ADD_METHOD(TexCoord3s);
- PY_MOD_ADD_METHOD(TexCoord3sv);
- PY_MOD_ADD_METHOD(TexCoord4d);
- PY_MOD_ADD_METHOD(TexCoord4dv);
- PY_MOD_ADD_METHOD(TexCoord4f);
- PY_MOD_ADD_METHOD(TexCoord4fv);
- PY_MOD_ADD_METHOD(TexCoord4i);
- PY_MOD_ADD_METHOD(TexCoord4iv);
- PY_MOD_ADD_METHOD(TexCoord4s);
- PY_MOD_ADD_METHOD(TexCoord4sv);
- PY_MOD_ADD_METHOD(TexEnvf);
- PY_MOD_ADD_METHOD(TexEnvfv);
- PY_MOD_ADD_METHOD(TexEnvi);
- PY_MOD_ADD_METHOD(TexEnviv);
- PY_MOD_ADD_METHOD(TexGend);
- PY_MOD_ADD_METHOD(TexGendv);
- PY_MOD_ADD_METHOD(TexGenf);
- PY_MOD_ADD_METHOD(TexGenfv);
- PY_MOD_ADD_METHOD(TexGeni);
- PY_MOD_ADD_METHOD(TexGeniv);
- PY_MOD_ADD_METHOD(Translated);
- PY_MOD_ADD_METHOD(Translatef);
- PY_MOD_ADD_METHOD(Vertex2d);
- PY_MOD_ADD_METHOD(Vertex2dv);
- PY_MOD_ADD_METHOD(Vertex2f);
- PY_MOD_ADD_METHOD(Vertex2fv);
- PY_MOD_ADD_METHOD(Vertex2i);
- PY_MOD_ADD_METHOD(Vertex2iv);
- PY_MOD_ADD_METHOD(Vertex2s);
- PY_MOD_ADD_METHOD(Vertex2sv);
- PY_MOD_ADD_METHOD(Vertex3d);
- PY_MOD_ADD_METHOD(Vertex3dv);
- PY_MOD_ADD_METHOD(Vertex3f);
- PY_MOD_ADD_METHOD(Vertex3fv);
- PY_MOD_ADD_METHOD(Vertex3i);
- PY_MOD_ADD_METHOD(Vertex3iv);
- PY_MOD_ADD_METHOD(Vertex3s);
- PY_MOD_ADD_METHOD(Vertex3sv);
- PY_MOD_ADD_METHOD(Vertex4d);
- PY_MOD_ADD_METHOD(Vertex4dv);
- PY_MOD_ADD_METHOD(Vertex4f);
- PY_MOD_ADD_METHOD(Vertex4fv);
- PY_MOD_ADD_METHOD(Vertex4i);
- PY_MOD_ADD_METHOD(Vertex4iv);
- PY_MOD_ADD_METHOD(Vertex4s);
- PY_MOD_ADD_METHOD(Vertex4sv);
- }
-
/* GL_VERSION_1_1 */
{
@@ -2043,27 +1407,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(TexSubImage1D);
PY_MOD_ADD_METHOD(TexSubImage2D);
}
- /* adding in GL_VERSION_1_1 removed from core profile */
- if (use_deprecated == true) {
- PY_MOD_ADD_METHOD(AreTexturesResident);
- PY_MOD_ADD_METHOD(ArrayElement);
- PY_MOD_ADD_METHOD(ColorPointer);
- PY_MOD_ADD_METHOD(DisableClientState);
- PY_MOD_ADD_METHOD(EdgeFlagPointer);
- PY_MOD_ADD_METHOD(EnableClientState);
- PY_MOD_ADD_METHOD(GetPointerv);
- PY_MOD_ADD_METHOD(IndexPointer);
- PY_MOD_ADD_METHOD(Indexub);
- PY_MOD_ADD_METHOD(Indexubv);
- PY_MOD_ADD_METHOD(InterleavedArrays);
- PY_MOD_ADD_METHOD(NormalPointer);
- PY_MOD_ADD_METHOD(PopClientAttrib);
- PY_MOD_ADD_METHOD(PrioritizeTextures);
- PY_MOD_ADD_METHOD(PushClientAttrib);
- PY_MOD_ADD_METHOD(TexCoordPointer);
- PY_MOD_ADD_METHOD(VertexPointer);
- }
-
/* GL_VERSION_1_2 */
{
@@ -2073,7 +1416,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(TexSubImage3D);
}
-
/* GL_VERSION_1_3 */
{
PY_MOD_ADD_METHOD(ActiveTexture);
@@ -2086,47 +1428,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(GetCompressedTexImage);
PY_MOD_ADD_METHOD(SampleCoverage);
}
- /* adding in GL_VERSION_1_3 removed from core profile */
- if (use_deprecated == true) {
- PY_MOD_ADD_METHOD(ClientActiveTexture);
- PY_MOD_ADD_METHOD(LoadTransposeMatrixd);
- PY_MOD_ADD_METHOD(LoadTransposeMatrixf);
- PY_MOD_ADD_METHOD(MultTransposeMatrixd);
- PY_MOD_ADD_METHOD(MultTransposeMatrixf);
- PY_MOD_ADD_METHOD(MultiTexCoord1d);
- PY_MOD_ADD_METHOD(MultiTexCoord1dv);
- PY_MOD_ADD_METHOD(MultiTexCoord1f);
- PY_MOD_ADD_METHOD(MultiTexCoord1fv);
- PY_MOD_ADD_METHOD(MultiTexCoord1i);
- PY_MOD_ADD_METHOD(MultiTexCoord1iv);
- PY_MOD_ADD_METHOD(MultiTexCoord1s);
- PY_MOD_ADD_METHOD(MultiTexCoord1sv);
- PY_MOD_ADD_METHOD(MultiTexCoord2d);
- PY_MOD_ADD_METHOD(MultiTexCoord2dv);
- PY_MOD_ADD_METHOD(MultiTexCoord2f);
- PY_MOD_ADD_METHOD(MultiTexCoord2fv);
- PY_MOD_ADD_METHOD(MultiTexCoord2i);
- PY_MOD_ADD_METHOD(MultiTexCoord2iv);
- PY_MOD_ADD_METHOD(MultiTexCoord2s);
- PY_MOD_ADD_METHOD(MultiTexCoord2sv);
- PY_MOD_ADD_METHOD(MultiTexCoord3d);
- PY_MOD_ADD_METHOD(MultiTexCoord3dv);
- PY_MOD_ADD_METHOD(MultiTexCoord3f);
- PY_MOD_ADD_METHOD(MultiTexCoord3fv);
- PY_MOD_ADD_METHOD(MultiTexCoord3i);
- PY_MOD_ADD_METHOD(MultiTexCoord3iv);
- PY_MOD_ADD_METHOD(MultiTexCoord3s);
- PY_MOD_ADD_METHOD(MultiTexCoord3sv);
- PY_MOD_ADD_METHOD(MultiTexCoord4d);
- PY_MOD_ADD_METHOD(MultiTexCoord4dv);
- PY_MOD_ADD_METHOD(MultiTexCoord4f);
- PY_MOD_ADD_METHOD(MultiTexCoord4fv);
- PY_MOD_ADD_METHOD(MultiTexCoord4i);
- PY_MOD_ADD_METHOD(MultiTexCoord4iv);
- PY_MOD_ADD_METHOD(MultiTexCoord4s);
- PY_MOD_ADD_METHOD(MultiTexCoord4sv);
- }
-
/* GL_VERSION_1_4 */
{
@@ -2134,7 +1435,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(BlendEquation);
}
-
/* GL_VERSION_1_5 */
{
PY_MOD_ADD_METHOD(BeginQuery);
@@ -2158,7 +1458,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(UnmapBuffer);
}
-
/* GL_VERSION_2_0 */
{
PY_MOD_ADD_METHOD(AttachShader);
@@ -2256,7 +1555,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(VertexAttribPointer);
}
-
/* GL_VERSION_2_1 */
{
PY_MOD_ADD_METHOD(UniformMatrix2x3fv);
@@ -2267,7 +1565,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(UniformMatrix4x3fv);
}
-
/* GL_VERSION_3_0 */
{
PY_MOD_ADD_METHOD(BindVertexArray);
@@ -2276,7 +1573,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(IsVertexArray);
}
-
/* GL_VERSION_3_1 */
{
PY_MOD_ADD_METHOD(BindBufferBase);
@@ -2291,7 +1587,6 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(UniformBlockBinding);
}
-
/* GL_VERSION_3_2 */
{
PY_MOD_ADD_METHOD(FramebufferTexture);
@@ -2303,39 +1598,8 @@ PyObject *BPyInit_bgl(void)
PY_MOD_ADD_METHOD(TexImage3DMultisample);
}
-
/* GL_VERSION_3_3 */
{
- PY_MOD_ADD_METHOD(ColorP3ui);
- PY_MOD_ADD_METHOD(ColorP3uiv);
- PY_MOD_ADD_METHOD(ColorP4ui);
- PY_MOD_ADD_METHOD(ColorP4uiv);
- PY_MOD_ADD_METHOD(MultiTexCoordP1ui);
- PY_MOD_ADD_METHOD(MultiTexCoordP1uiv);
- PY_MOD_ADD_METHOD(MultiTexCoordP2ui);
- PY_MOD_ADD_METHOD(MultiTexCoordP2uiv);
- PY_MOD_ADD_METHOD(MultiTexCoordP3ui);
- PY_MOD_ADD_METHOD(MultiTexCoordP3uiv);
- PY_MOD_ADD_METHOD(MultiTexCoordP4ui);
- PY_MOD_ADD_METHOD(MultiTexCoordP4uiv);
- PY_MOD_ADD_METHOD(NormalP3ui);
- PY_MOD_ADD_METHOD(NormalP3uiv);
- PY_MOD_ADD_METHOD(SecondaryColorP3ui);
- PY_MOD_ADD_METHOD(SecondaryColorP3uiv);
- PY_MOD_ADD_METHOD(TexCoordP1ui);
- PY_MOD_ADD_METHOD(TexCoordP1uiv);
- PY_MOD_ADD_METHOD(TexCoordP2ui);
- PY_MOD_ADD_METHOD(TexCoordP2uiv);
- PY_MOD_ADD_METHOD(TexCoordP3ui);
- PY_MOD_ADD_METHOD(TexCoordP3uiv);
- PY_MOD_ADD_METHOD(TexCoordP4ui);
- PY_MOD_ADD_METHOD(TexCoordP4uiv);
- PY_MOD_ADD_METHOD(VertexP2ui);
- PY_MOD_ADD_METHOD(VertexP2uiv);
- PY_MOD_ADD_METHOD(VertexP3ui);
- PY_MOD_ADD_METHOD(VertexP3uiv);
- PY_MOD_ADD_METHOD(VertexP4ui);
- PY_MOD_ADD_METHOD(VertexP4uiv);
}
#define PY_DICT_ADD_INT(x) py_module_dict_add_int(dict, #x, x)
@@ -2453,8 +1717,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_POINT);
PY_DICT_ADD_INT(GL_POINTS);
PY_DICT_ADD_INT(GL_POINT_SIZE);
- PY_DICT_ADD_INT(GL_POINT_SIZE_GRANULARITY);
- PY_DICT_ADD_INT(GL_POINT_SIZE_RANGE);
PY_DICT_ADD_INT(GL_POLYGON_MODE);
PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FACTOR);
PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FILL);
@@ -2544,338 +1806,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_XOR);
PY_DICT_ADD_INT(GL_ZERO);
}
- /* adding in GL_VERSION_1_1 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_2D);
- PY_DICT_ADD_INT(GL_2_BYTES);
- PY_DICT_ADD_INT(GL_3D);
- PY_DICT_ADD_INT(GL_3D_COLOR);
- PY_DICT_ADD_INT(GL_3D_COLOR_TEXTURE);
- PY_DICT_ADD_INT(GL_3_BYTES);
- PY_DICT_ADD_INT(GL_4D_COLOR_TEXTURE);
- PY_DICT_ADD_INT(GL_4_BYTES);
- PY_DICT_ADD_INT(GL_ACCUM);
- PY_DICT_ADD_INT(GL_ACCUM_ALPHA_BITS);
- PY_DICT_ADD_INT(GL_ACCUM_BLUE_BITS);
- PY_DICT_ADD_INT(GL_ACCUM_BUFFER_BIT);
- PY_DICT_ADD_INT(GL_ACCUM_CLEAR_VALUE);
- PY_DICT_ADD_INT(GL_ACCUM_GREEN_BITS);
- PY_DICT_ADD_INT(GL_ACCUM_RED_BITS);
- PY_DICT_ADD_INT(GL_ADD);
- PY_DICT_ADD_INT(GL_ALL_ATTRIB_BITS);
- PY_DICT_ADD_INT(GL_ALPHA12);
- PY_DICT_ADD_INT(GL_ALPHA16);
- PY_DICT_ADD_INT(GL_ALPHA4);
- PY_DICT_ADD_INT(GL_ALPHA8);
- PY_DICT_ADD_INT(GL_ALPHA_BIAS);
- PY_DICT_ADD_INT(GL_ALPHA_BITS);
- PY_DICT_ADD_INT(GL_ALPHA_SCALE);
- PY_DICT_ADD_INT(GL_ALPHA_TEST);
- PY_DICT_ADD_INT(GL_ALPHA_TEST_FUNC);
- PY_DICT_ADD_INT(GL_ALPHA_TEST_REF);
- PY_DICT_ADD_INT(GL_AMBIENT);
- PY_DICT_ADD_INT(GL_AMBIENT_AND_DIFFUSE);
- PY_DICT_ADD_INT(GL_ATTRIB_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_AUTO_NORMAL);
- PY_DICT_ADD_INT(GL_AUX0);
- PY_DICT_ADD_INT(GL_AUX1);
- PY_DICT_ADD_INT(GL_AUX2);
- PY_DICT_ADD_INT(GL_AUX3);
- PY_DICT_ADD_INT(GL_AUX_BUFFERS);
- PY_DICT_ADD_INT(GL_BITMAP);
- PY_DICT_ADD_INT(GL_BITMAP_TOKEN);
- PY_DICT_ADD_INT(GL_BLUE_BIAS);
- PY_DICT_ADD_INT(GL_BLUE_BITS);
- PY_DICT_ADD_INT(GL_BLUE_SCALE);
- PY_DICT_ADD_INT(GL_C3F_V3F);
- PY_DICT_ADD_INT(GL_C4F_N3F_V3F);
- PY_DICT_ADD_INT(GL_C4UB_V2F);
- PY_DICT_ADD_INT(GL_C4UB_V3F);
- PY_DICT_ADD_INT(GL_CLAMP);
- PY_DICT_ADD_INT(GL_CLIENT_ALL_ATTRIB_BITS);
- PY_DICT_ADD_INT(GL_CLIENT_ATTRIB_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_CLIENT_PIXEL_STORE_BIT);
- PY_DICT_ADD_INT(GL_CLIENT_VERTEX_ARRAY_BIT);
- PY_DICT_ADD_INT(GL_CLIP_PLANE0);
- PY_DICT_ADD_INT(GL_CLIP_PLANE1);
- PY_DICT_ADD_INT(GL_CLIP_PLANE2);
- PY_DICT_ADD_INT(GL_CLIP_PLANE3);
- PY_DICT_ADD_INT(GL_CLIP_PLANE4);
- PY_DICT_ADD_INT(GL_CLIP_PLANE5);
- PY_DICT_ADD_INT(GL_COEFF);
- PY_DICT_ADD_INT(GL_COLOR_ARRAY);
- PY_DICT_ADD_INT(GL_COLOR_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_COLOR_ARRAY_SIZE);
- PY_DICT_ADD_INT(GL_COLOR_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_COLOR_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_COLOR_INDEX);
- PY_DICT_ADD_INT(GL_COLOR_INDEXES);
- PY_DICT_ADD_INT(GL_COLOR_MATERIAL);
- PY_DICT_ADD_INT(GL_COLOR_MATERIAL_FACE);
- PY_DICT_ADD_INT(GL_COLOR_MATERIAL_PARAMETER);
- PY_DICT_ADD_INT(GL_COMPILE);
- PY_DICT_ADD_INT(GL_COMPILE_AND_EXECUTE);
- PY_DICT_ADD_INT(GL_CONSTANT_ATTENUATION);
- PY_DICT_ADD_INT(GL_COPY_PIXEL_TOKEN);
- PY_DICT_ADD_INT(GL_CURRENT_BIT);
- PY_DICT_ADD_INT(GL_CURRENT_COLOR);
- PY_DICT_ADD_INT(GL_CURRENT_INDEX);
- PY_DICT_ADD_INT(GL_CURRENT_NORMAL);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_COLOR);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_DISTANCE);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_INDEX);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_POSITION);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_POSITION_VALID);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_TEXTURE_COORDS);
- PY_DICT_ADD_INT(GL_CURRENT_TEXTURE_COORDS);
- PY_DICT_ADD_INT(GL_DECAL);
- PY_DICT_ADD_INT(GL_DEPTH_BIAS);
- PY_DICT_ADD_INT(GL_DEPTH_BITS);
- PY_DICT_ADD_INT(GL_DEPTH_SCALE);
- PY_DICT_ADD_INT(GL_DIFFUSE);
- PY_DICT_ADD_INT(GL_DOMAIN);
- PY_DICT_ADD_INT(GL_DRAW_PIXEL_TOKEN);
- PY_DICT_ADD_INT(GL_EDGE_FLAG);
- PY_DICT_ADD_INT(GL_EDGE_FLAG_ARRAY);
- PY_DICT_ADD_INT(GL_EDGE_FLAG_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_EDGE_FLAG_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_EMISSION);
- PY_DICT_ADD_INT(GL_ENABLE_BIT);
- PY_DICT_ADD_INT(GL_EVAL_BIT);
- PY_DICT_ADD_INT(GL_EXP);
- PY_DICT_ADD_INT(GL_EXP2);
- PY_DICT_ADD_INT(GL_EYE_LINEAR);
- PY_DICT_ADD_INT(GL_EYE_PLANE);
- PY_DICT_ADD_INT(GL_FEEDBACK);
- PY_DICT_ADD_INT(GL_FEEDBACK_BUFFER_POINTER);
- PY_DICT_ADD_INT(GL_FEEDBACK_BUFFER_SIZE);
- PY_DICT_ADD_INT(GL_FEEDBACK_BUFFER_TYPE);
- PY_DICT_ADD_INT(GL_FLAT);
- PY_DICT_ADD_INT(GL_FOG);
- PY_DICT_ADD_INT(GL_FOG_BIT);
- PY_DICT_ADD_INT(GL_FOG_COLOR);
- PY_DICT_ADD_INT(GL_FOG_DENSITY);
- PY_DICT_ADD_INT(GL_FOG_END);
- PY_DICT_ADD_INT(GL_FOG_HINT);
- PY_DICT_ADD_INT(GL_FOG_INDEX);
- PY_DICT_ADD_INT(GL_FOG_MODE);
- PY_DICT_ADD_INT(GL_FOG_START);
- PY_DICT_ADD_INT(GL_GREEN_BIAS);
- PY_DICT_ADD_INT(GL_GREEN_BITS);
- PY_DICT_ADD_INT(GL_GREEN_SCALE);
- PY_DICT_ADD_INT(GL_HINT_BIT);
- PY_DICT_ADD_INT(GL_INDEX_ARRAY);
- PY_DICT_ADD_INT(GL_INDEX_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_INDEX_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_INDEX_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_INDEX_BITS);
- PY_DICT_ADD_INT(GL_INDEX_CLEAR_VALUE);
- PY_DICT_ADD_INT(GL_INDEX_LOGIC_OP);
- PY_DICT_ADD_INT(GL_INDEX_MODE);
- PY_DICT_ADD_INT(GL_INDEX_OFFSET);
- PY_DICT_ADD_INT(GL_INDEX_SHIFT);
- PY_DICT_ADD_INT(GL_INDEX_WRITEMASK);
- PY_DICT_ADD_INT(GL_INTENSITY);
- PY_DICT_ADD_INT(GL_INTENSITY12);
- PY_DICT_ADD_INT(GL_INTENSITY16);
- PY_DICT_ADD_INT(GL_INTENSITY4);
- PY_DICT_ADD_INT(GL_INTENSITY8);
- PY_DICT_ADD_INT(GL_LIGHT0);
- PY_DICT_ADD_INT(GL_LIGHT1);
- PY_DICT_ADD_INT(GL_LIGHT2);
- PY_DICT_ADD_INT(GL_LIGHT3);
- PY_DICT_ADD_INT(GL_LIGHT4);
- PY_DICT_ADD_INT(GL_LIGHT5);
- PY_DICT_ADD_INT(GL_LIGHT6);
- PY_DICT_ADD_INT(GL_LIGHT7);
- PY_DICT_ADD_INT(GL_LIGHTING);
- PY_DICT_ADD_INT(GL_LIGHTING_BIT);
- PY_DICT_ADD_INT(GL_LIGHT_MODEL_AMBIENT);
- PY_DICT_ADD_INT(GL_LIGHT_MODEL_LOCAL_VIEWER);
- PY_DICT_ADD_INT(GL_LIGHT_MODEL_TWO_SIDE);
- PY_DICT_ADD_INT(GL_LINEAR_ATTENUATION);
- PY_DICT_ADD_INT(GL_LINE_BIT);
- PY_DICT_ADD_INT(GL_LINE_RESET_TOKEN);
- PY_DICT_ADD_INT(GL_LINE_STIPPLE);
- PY_DICT_ADD_INT(GL_LINE_STIPPLE_PATTERN);
- PY_DICT_ADD_INT(GL_LINE_STIPPLE_REPEAT);
- PY_DICT_ADD_INT(GL_LINE_TOKEN);
- PY_DICT_ADD_INT(GL_LIST_BASE);
- PY_DICT_ADD_INT(GL_LIST_BIT);
- PY_DICT_ADD_INT(GL_LIST_INDEX);
- PY_DICT_ADD_INT(GL_LIST_MODE);
- PY_DICT_ADD_INT(GL_LOAD);
- PY_DICT_ADD_INT(GL_LOGIC_OP);
- PY_DICT_ADD_INT(GL_LUMINANCE);
- PY_DICT_ADD_INT(GL_LUMINANCE12);
- PY_DICT_ADD_INT(GL_LUMINANCE12_ALPHA12);
- PY_DICT_ADD_INT(GL_LUMINANCE12_ALPHA4);
- PY_DICT_ADD_INT(GL_LUMINANCE16);
- PY_DICT_ADD_INT(GL_LUMINANCE16_ALPHA16);
- PY_DICT_ADD_INT(GL_LUMINANCE4);
- PY_DICT_ADD_INT(GL_LUMINANCE4_ALPHA4);
- PY_DICT_ADD_INT(GL_LUMINANCE6_ALPHA2);
- PY_DICT_ADD_INT(GL_LUMINANCE8);
- PY_DICT_ADD_INT(GL_LUMINANCE8_ALPHA8);
- PY_DICT_ADD_INT(GL_LUMINANCE_ALPHA);
- PY_DICT_ADD_INT(GL_MAP1_COLOR_4);
- PY_DICT_ADD_INT(GL_MAP1_GRID_DOMAIN);
- PY_DICT_ADD_INT(GL_MAP1_GRID_SEGMENTS);
- PY_DICT_ADD_INT(GL_MAP1_INDEX);
- PY_DICT_ADD_INT(GL_MAP1_NORMAL);
- PY_DICT_ADD_INT(GL_MAP1_TEXTURE_COORD_1);
- PY_DICT_ADD_INT(GL_MAP1_TEXTURE_COORD_2);
- PY_DICT_ADD_INT(GL_MAP1_TEXTURE_COORD_3);
- PY_DICT_ADD_INT(GL_MAP1_TEXTURE_COORD_4);
- PY_DICT_ADD_INT(GL_MAP1_VERTEX_3);
- PY_DICT_ADD_INT(GL_MAP1_VERTEX_4);
- PY_DICT_ADD_INT(GL_MAP2_COLOR_4);
- PY_DICT_ADD_INT(GL_MAP2_GRID_DOMAIN);
- PY_DICT_ADD_INT(GL_MAP2_GRID_SEGMENTS);
- PY_DICT_ADD_INT(GL_MAP2_INDEX);
- PY_DICT_ADD_INT(GL_MAP2_NORMAL);
- PY_DICT_ADD_INT(GL_MAP2_TEXTURE_COORD_1);
- PY_DICT_ADD_INT(GL_MAP2_TEXTURE_COORD_2);
- PY_DICT_ADD_INT(GL_MAP2_TEXTURE_COORD_3);
- PY_DICT_ADD_INT(GL_MAP2_TEXTURE_COORD_4);
- PY_DICT_ADD_INT(GL_MAP2_VERTEX_3);
- PY_DICT_ADD_INT(GL_MAP2_VERTEX_4);
- PY_DICT_ADD_INT(GL_MAP_COLOR);
- PY_DICT_ADD_INT(GL_MAP_STENCIL);
- PY_DICT_ADD_INT(GL_MATRIX_MODE);
- PY_DICT_ADD_INT(GL_MAX_ATTRIB_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MAX_CLIP_PLANES);
- PY_DICT_ADD_INT(GL_MAX_EVAL_ORDER);
- PY_DICT_ADD_INT(GL_MAX_LIGHTS);
- PY_DICT_ADD_INT(GL_MAX_LIST_NESTING);
- PY_DICT_ADD_INT(GL_MAX_MODELVIEW_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MAX_NAME_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MAX_PIXEL_MAP_TABLE);
- PY_DICT_ADD_INT(GL_MAX_PROJECTION_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MODELVIEW);
- PY_DICT_ADD_INT(GL_MODELVIEW_MATRIX);
- PY_DICT_ADD_INT(GL_MODELVIEW_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_MODULATE);
- PY_DICT_ADD_INT(GL_MULT);
- PY_DICT_ADD_INT(GL_N3F_V3F);
- PY_DICT_ADD_INT(GL_NAME_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_NORMALIZE);
- PY_DICT_ADD_INT(GL_NORMAL_ARRAY);
- PY_DICT_ADD_INT(GL_NORMAL_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_NORMAL_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_NORMAL_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_OBJECT_LINEAR);
- PY_DICT_ADD_INT(GL_OBJECT_PLANE);
- PY_DICT_ADD_INT(GL_ORDER);
- PY_DICT_ADD_INT(GL_PASS_THROUGH_TOKEN);
- PY_DICT_ADD_INT(GL_PERSPECTIVE_CORRECTION_HINT);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_A_TO_A);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_A_TO_A_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_B_TO_B);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_B_TO_B_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_G_TO_G);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_G_TO_G_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_A);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_A_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_B);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_B_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_G);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_G_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_I);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_I_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_R);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_I_TO_R_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_R_TO_R);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_R_TO_R_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_S_TO_S);
- PY_DICT_ADD_INT(GL_PIXEL_MAP_S_TO_S_SIZE);
- PY_DICT_ADD_INT(GL_PIXEL_MODE_BIT);
- PY_DICT_ADD_INT(GL_POINT_BIT);
- PY_DICT_ADD_INT(GL_POINT_SMOOTH);
- PY_DICT_ADD_INT(GL_POINT_SMOOTH_HINT);
- PY_DICT_ADD_INT(GL_POINT_TOKEN);
- PY_DICT_ADD_INT(GL_POLYGON);
- PY_DICT_ADD_INT(GL_POLYGON_BIT);
- PY_DICT_ADD_INT(GL_POLYGON_STIPPLE);
- PY_DICT_ADD_INT(GL_POLYGON_STIPPLE_BIT);
- PY_DICT_ADD_INT(GL_POLYGON_TOKEN);
- PY_DICT_ADD_INT(GL_POSITION);
- PY_DICT_ADD_INT(GL_PROJECTION);
- PY_DICT_ADD_INT(GL_PROJECTION_MATRIX);
- PY_DICT_ADD_INT(GL_PROJECTION_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_Q);
- PY_DICT_ADD_INT(GL_QUADRATIC_ATTENUATION);
- PY_DICT_ADD_INT(GL_QUADS);
- PY_DICT_ADD_INT(GL_QUAD_STRIP);
- PY_DICT_ADD_INT(GL_R);
- PY_DICT_ADD_INT(GL_RED_BIAS);
- PY_DICT_ADD_INT(GL_RED_BITS);
- PY_DICT_ADD_INT(GL_RED_SCALE);
- PY_DICT_ADD_INT(GL_RENDER);
- PY_DICT_ADD_INT(GL_RENDER_MODE);
- PY_DICT_ADD_INT(GL_RETURN);
- PY_DICT_ADD_INT(GL_RGBA_MODE);
- PY_DICT_ADD_INT(GL_S);
- PY_DICT_ADD_INT(GL_SCISSOR_BIT);
- PY_DICT_ADD_INT(GL_SELECT);
- PY_DICT_ADD_INT(GL_SELECTION_BUFFER_POINTER);
- PY_DICT_ADD_INT(GL_SELECTION_BUFFER_SIZE);
- PY_DICT_ADD_INT(GL_SHADE_MODEL);
- PY_DICT_ADD_INT(GL_SHININESS);
- PY_DICT_ADD_INT(GL_SMOOTH);
- PY_DICT_ADD_INT(GL_SPECULAR);
- PY_DICT_ADD_INT(GL_SPHERE_MAP);
- PY_DICT_ADD_INT(GL_SPOT_CUTOFF);
- PY_DICT_ADD_INT(GL_SPOT_DIRECTION);
- PY_DICT_ADD_INT(GL_SPOT_EXPONENT);
- PY_DICT_ADD_INT(GL_STACK_OVERFLOW);
- PY_DICT_ADD_INT(GL_STACK_UNDERFLOW);
- PY_DICT_ADD_INT(GL_STENCIL_BITS);
- PY_DICT_ADD_INT(GL_T);
- PY_DICT_ADD_INT(GL_T2F_C3F_V3F);
- PY_DICT_ADD_INT(GL_T2F_C4F_N3F_V3F);
- PY_DICT_ADD_INT(GL_T2F_C4UB_V3F);
- PY_DICT_ADD_INT(GL_T2F_N3F_V3F);
- PY_DICT_ADD_INT(GL_T2F_V3F);
- PY_DICT_ADD_INT(GL_T4F_C4F_N3F_V4F);
- PY_DICT_ADD_INT(GL_T4F_V4F);
- PY_DICT_ADD_INT(GL_TEXTURE_BIT);
- PY_DICT_ADD_INT(GL_TEXTURE_BORDER);
- PY_DICT_ADD_INT(GL_TEXTURE_COMPONENTS);
- PY_DICT_ADD_INT(GL_TEXTURE_COORD_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_COORD_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_TEXTURE_COORD_ARRAY_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_COORD_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_TEXTURE_COORD_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_ENV);
- PY_DICT_ADD_INT(GL_TEXTURE_ENV_COLOR);
- PY_DICT_ADD_INT(GL_TEXTURE_ENV_MODE);
- PY_DICT_ADD_INT(GL_TEXTURE_GEN_MODE);
- PY_DICT_ADD_INT(GL_TEXTURE_GEN_Q);
- PY_DICT_ADD_INT(GL_TEXTURE_GEN_R);
- PY_DICT_ADD_INT(GL_TEXTURE_GEN_S);
- PY_DICT_ADD_INT(GL_TEXTURE_GEN_T);
- PY_DICT_ADD_INT(GL_TEXTURE_INTENSITY_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_LUMINANCE_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_MATRIX);
- PY_DICT_ADD_INT(GL_TEXTURE_PRIORITY);
- PY_DICT_ADD_INT(GL_TEXTURE_RESIDENT);
- PY_DICT_ADD_INT(GL_TEXTURE_STACK_DEPTH);
- PY_DICT_ADD_INT(GL_TRANSFORM_BIT);
- PY_DICT_ADD_INT(GL_V2F);
- PY_DICT_ADD_INT(GL_V3F);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY_SIZE);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_VIEWPORT_BIT);
- PY_DICT_ADD_INT(GL_ZOOM_X);
- PY_DICT_ADD_INT(GL_ZOOM_Y);
- }
-
/* GL_VERSION_1_2 */
{
@@ -2916,15 +1846,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5);
PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5_REV);
}
- /* adding in GL_VERSION_1_2 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_ALIASED_POINT_SIZE_RANGE);
- PY_DICT_ADD_INT(GL_LIGHT_MODEL_COLOR_CONTROL);
- PY_DICT_ADD_INT(GL_RESCALE_NORMAL);
- PY_DICT_ADD_INT(GL_SEPARATE_SPECULAR_COLOR);
- PY_DICT_ADD_INT(GL_SINGLE_COLOR);
- }
-
/* GL_VERSION_1_3 */
{
@@ -2988,47 +1909,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
}
- /* adding in GL_VERSION_1_3 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_ADD_SIGNED);
- PY_DICT_ADD_INT(GL_CLIENT_ACTIVE_TEXTURE);
- PY_DICT_ADD_INT(GL_COMBINE);
- PY_DICT_ADD_INT(GL_COMBINE_ALPHA);
- PY_DICT_ADD_INT(GL_COMBINE_RGB);
- PY_DICT_ADD_INT(GL_COMPRESSED_ALPHA);
- PY_DICT_ADD_INT(GL_COMPRESSED_INTENSITY);
- PY_DICT_ADD_INT(GL_COMPRESSED_LUMINANCE);
- PY_DICT_ADD_INT(GL_COMPRESSED_LUMINANCE_ALPHA);
- PY_DICT_ADD_INT(GL_CONSTANT);
- PY_DICT_ADD_INT(GL_DOT3_RGB);
- PY_DICT_ADD_INT(GL_DOT3_RGBA);
- PY_DICT_ADD_INT(GL_INTERPOLATE);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_UNITS);
- PY_DICT_ADD_INT(GL_MULTISAMPLE_BIT);
- PY_DICT_ADD_INT(GL_NORMAL_MAP);
- PY_DICT_ADD_INT(GL_OPERAND0_ALPHA);
- PY_DICT_ADD_INT(GL_OPERAND0_RGB);
- PY_DICT_ADD_INT(GL_OPERAND1_ALPHA);
- PY_DICT_ADD_INT(GL_OPERAND1_RGB);
- PY_DICT_ADD_INT(GL_OPERAND2_ALPHA);
- PY_DICT_ADD_INT(GL_OPERAND2_RGB);
- PY_DICT_ADD_INT(GL_PREVIOUS);
- PY_DICT_ADD_INT(GL_PRIMARY_COLOR);
- PY_DICT_ADD_INT(GL_REFLECTION_MAP);
- PY_DICT_ADD_INT(GL_RGB_SCALE);
- PY_DICT_ADD_INT(GL_SOURCE0_ALPHA);
- PY_DICT_ADD_INT(GL_SOURCE0_RGB);
- PY_DICT_ADD_INT(GL_SOURCE1_ALPHA);
- PY_DICT_ADD_INT(GL_SOURCE1_RGB);
- PY_DICT_ADD_INT(GL_SOURCE2_ALPHA);
- PY_DICT_ADD_INT(GL_SOURCE2_RGB);
- PY_DICT_ADD_INT(GL_SUBTRACT);
- PY_DICT_ADD_INT(GL_TRANSPOSE_COLOR_MATRIX);
- PY_DICT_ADD_INT(GL_TRANSPOSE_MODELVIEW_MATRIX);
- PY_DICT_ADD_INT(GL_TRANSPOSE_PROJECTION_MATRIX);
- PY_DICT_ADD_INT(GL_TRANSPOSE_TEXTURE_MATRIX);
- }
-
/* GL_VERSION_1_4 */
{
@@ -3058,33 +1938,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_SIZE);
PY_DICT_ADD_INT(GL_TEXTURE_LOD_BIAS);
}
- /* adding in GL_VERSION_1_4 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_COLOR_SUM);
- PY_DICT_ADD_INT(GL_COMPARE_R_TO_TEXTURE);
- PY_DICT_ADD_INT(GL_CURRENT_FOG_COORDINATE);
- PY_DICT_ADD_INT(GL_CURRENT_SECONDARY_COLOR);
- PY_DICT_ADD_INT(GL_DEPTH_TEXTURE_MODE);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE_ARRAY);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE_SOURCE);
- PY_DICT_ADD_INT(GL_FRAGMENT_DEPTH);
- PY_DICT_ADD_INT(GL_GENERATE_MIPMAP);
- PY_DICT_ADD_INT(GL_GENERATE_MIPMAP_HINT);
- PY_DICT_ADD_INT(GL_POINT_DISTANCE_ATTENUATION);
- PY_DICT_ADD_INT(GL_POINT_SIZE_MAX);
- PY_DICT_ADD_INT(GL_POINT_SIZE_MIN);
- PY_DICT_ADD_INT(GL_SECONDARY_COLOR_ARRAY);
- PY_DICT_ADD_INT(GL_SECONDARY_COLOR_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_SECONDARY_COLOR_ARRAY_SIZE);
- PY_DICT_ADD_INT(GL_SECONDARY_COLOR_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_SECONDARY_COLOR_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_FILTER_CONTROL);
- }
-
/* GL_VERSION_1_5 */
{
@@ -3107,7 +1960,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_READ_ONLY);
PY_DICT_ADD_INT(GL_READ_WRITE);
PY_DICT_ADD_INT(GL_SAMPLES_PASSED);
- PY_DICT_ADD_INT(GL_SRC1_ALPHA);
PY_DICT_ADD_INT(GL_STATIC_COPY);
PY_DICT_ADD_INT(GL_STATIC_DRAW);
PY_DICT_ADD_INT(GL_STATIC_READ);
@@ -3117,32 +1969,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
PY_DICT_ADD_INT(GL_WRITE_ONLY);
}
- /* adding in GL_VERSION_1_5 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_COLOR_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_CURRENT_FOG_COORD);
- PY_DICT_ADD_INT(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_FOG_COORD);
- PY_DICT_ADD_INT(GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_FOG_COORD_ARRAY);
- PY_DICT_ADD_INT(GL_FOG_COORD_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_FOG_COORD_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_FOG_COORD_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_FOG_COORD_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_FOG_COORD_SRC);
- PY_DICT_ADD_INT(GL_INDEX_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_NORMAL_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_SRC0_ALPHA);
- PY_DICT_ADD_INT(GL_SRC0_RGB);
- PY_DICT_ADD_INT(GL_SRC1_RGB);
- PY_DICT_ADD_INT(GL_SRC2_ALPHA);
- PY_DICT_ADD_INT(GL_SRC2_RGB);
- PY_DICT_ADD_INT(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_WEIGHT_ARRAY_BUFFER_BINDING);
- }
-
/* GL_VERSION_2_0 */
{
@@ -3227,14 +2053,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_VERTEX_PROGRAM_POINT_SIZE);
PY_DICT_ADD_INT(GL_VERTEX_SHADER);
}
- /* adding in GL_VERSION_2_0 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_COORD_REPLACE);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_COORDS);
- PY_DICT_ADD_INT(GL_POINT_SPRITE);
- PY_DICT_ADD_INT(GL_VERTEX_PROGRAM_TWO_SIDE);
- }
-
/* GL_VERSION_2_1 */
{
@@ -3255,16 +2073,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_SRGB8_ALPHA8);
PY_DICT_ADD_INT(GL_SRGB_ALPHA);
}
- /* adding in GL_VERSION_2_1 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_COMPRESSED_SLUMINANCE);
- PY_DICT_ADD_INT(GL_COMPRESSED_SLUMINANCE_ALPHA);
- PY_DICT_ADD_INT(GL_CURRENT_RASTER_SECONDARY_COLOR);
- PY_DICT_ADD_INT(GL_SLUMINANCE);
- PY_DICT_ADD_INT(GL_SLUMINANCE8);
- PY_DICT_ADD_INT(GL_SLUMINANCE8_ALPHA8);
- PY_DICT_ADD_INT(GL_SLUMINANCE_ALPHA);
- }
/* GL_VERSION_3_0 */
{
@@ -3505,14 +2313,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_VERTEX_ARRAY_BINDING);
PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_INTEGER);
}
- /* adding in GL_VERSION_3_0 removed from core profile */
- if (use_deprecated == true) {
- PY_DICT_ADD_INT(GL_ALPHA_INTEGER);
- PY_DICT_ADD_INT(GL_CLAMP_FRAGMENT_COLOR);
- PY_DICT_ADD_INT(GL_CLAMP_VERTEX_COLOR);
- PY_DICT_ADD_INT(GL_TEXTURE_INTENSITY_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_LUMINANCE_TYPE);
- }
/* GL_VERSION_3_1 */
{
@@ -3579,7 +2379,6 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_BUFFER);
}
-
/* GL_VERSION_3_2 */
{
PY_DICT_ADD_INT(GL_ALREADY_SIGNALED);
@@ -3685,4 +2484,4 @@ static PyObject *Method_ShaderSource(PyObject *UNUSED(self), PyObject *args)
}
-/** \} */ \ No newline at end of file
+/** \} */
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 69f1e297b43..02bd1fdbe39 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -114,6 +114,7 @@ static PyObject *py_blf_aspect(PyObject *UNUSED(self), PyObject *args)
}
+#if BLF_BLUR_ENABLE
PyDoc_STRVAR(py_blf_blur_doc,
".. function:: blur(fontid, radius)\n"
"\n"
@@ -135,6 +136,7 @@ static PyObject *py_blf_blur(PyObject *UNUSED(self), PyObject *args)
Py_RETURN_NONE;
}
+#endif
PyDoc_STRVAR(py_blf_draw_doc,
@@ -418,7 +420,9 @@ static PyObject *py_blf_unload(PyObject *UNUSED(self), PyObject *args)
/*----------------------------MODULE INIT-------------------------*/
static PyMethodDef BLF_methods[] = {
{"aspect", (PyCFunction) py_blf_aspect, METH_VARARGS, py_blf_aspect_doc},
+#if BLF_BLUR_ENABLE
{"blur", (PyCFunction) py_blf_blur, METH_VARARGS, py_blf_blur_doc},
+#endif
{"clipping", (PyCFunction) py_blf_clipping, METH_VARARGS, py_blf_clipping_doc},
{"word_wrap", (PyCFunction) py_blf_word_wrap, METH_VARARGS, py_blf_word_wrap_doc},
{"disable", (PyCFunction) py_blf_disable, METH_VARARGS, py_blf_disable_doc},
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index fdc2371c259..5a309339e17 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -59,8 +59,6 @@ static PyStructSequence_Field app_cb_info_fields[] = {
{(char *)"load_post", (char *)"on loading a new blend file (after)"},
{(char *)"save_pre", (char *)"on saving a blend file (before)"},
{(char *)"save_post", (char *)"on saving a blend file (after)"},
- {(char *)"scene_update_pre", (char *)"on updating the scenes data (before)"},
- {(char *)"scene_update_post", (char *)"on updating the scenes data (after)"},
{(char *)"game_pre", (char *)"on starting the game engine"},
{(char *)"game_post", (char *)"on ending the game engine"},
{(char *)"version_update", (char *)"on ending the versioning code"},
diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c
index 7711ce18bd0..da8e5d69f02 100644
--- a/source/blender/python/intern/gpu_offscreen.c
+++ b/source/blender/python/intern/gpu_offscreen.c
@@ -192,12 +192,13 @@ PyDoc_STRVAR(pygpu_offscreen_draw_view3d_doc,
);
static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *args, PyObject *kwds)
{
- static const char *kwlist[] = {"scene", "view3d", "region", "projection_matrix", "modelview_matrix", NULL};
+ static const char *kwlist[] = {"scene", "render_layer", "view3d", "region", "projection_matrix", "modelview_matrix", NULL};
MatrixObject *py_mat_modelview, *py_mat_projection;
- PyObject *py_scene, *py_region, *py_view3d;
+ PyObject *py_scene, *py_scene_layer, *py_region, *py_view3d;
Scene *scene;
+ SceneLayer *sl;
View3D *v3d;
ARegion *ar;
GPUFX *fx;
@@ -207,11 +208,12 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "OOOO&O&:draw_view3d", (char **)(kwlist),
- &py_scene, &py_view3d, &py_region,
+ args, kwds, "OOOOO&O&:draw_view3d", (char **)(kwlist),
+ &py_scene, &py_scene_layer, &py_view3d, &py_region,
pygpu_offscreen_check_matrix, &py_mat_projection,
pygpu_offscreen_check_matrix, &py_mat_modelview) ||
(!(scene = PyC_RNA_AsPointer(py_scene, "Scene")) ||
+ !(sl = PyC_RNA_AsPointer(py_scene_layer, "SceneLayer")) ||
!(v3d = PyC_RNA_AsPointer(py_view3d, "SpaceView3D")) ||
!(ar = PyC_RNA_AsPointer(py_region, "Region"))))
{
@@ -222,7 +224,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a
fx_settings = v3d->fx_settings; /* full copy */
- ED_view3d_draw_offscreen_init(scene, v3d);
+ ED_view3d_draw_offscreen_init(scene, sl, v3d);
rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata);
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index a12bdd910c3..282942709f0 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -36,6 +36,7 @@ set(INC
../makesrna
../nodes
../physics
+ ../draw
../../../intern/atomic
../../../intern/guardedalloc
../../../intern/mikktspace
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 52491673612..3086c9d4fad 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -39,6 +39,9 @@
struct bNode;
struct bNodeTree;
+struct Depsgraph;
+struct IDProperty;
+struct Main;
struct Object;
struct Render;
struct RenderData;
@@ -63,6 +66,7 @@ struct BakePixel;
#define RE_USE_TEXTURE_PREVIEW 128
#define RE_USE_SHADING_NODES_CUSTOM 256
#define RE_USE_SPHERICAL_STEREO 512
+#define RE_USE_LEGACY_PIPELINE 1024 /* XXX Temporary flag, to be removed once draw manager is finished. */
/* RenderEngine.flag */
#define RE_ENGINE_ANIMATION 1
@@ -88,16 +92,23 @@ typedef struct RenderEngineType {
char name[64];
int flag;
- void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
- void (*render)(struct RenderEngine *engine, struct Scene *scene);
- void (*bake)(struct RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type, const int pass_filter, const int object_id, const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result);
+ void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene);
+ void (*render_to_image)(struct RenderEngine *engine, struct Depsgraph *depsgraph);
+ void (*bake)(struct RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type,
+ const int pass_filter, const int object_id, const struct BakePixel *pixel_array, const int num_pixels,
+ const int depth, void *result);
void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
- void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
+ void (*render_to_view)(struct RenderEngine *engine, const struct bContext *context);
void (*update_script_node)(struct RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node);
void (*update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl);
+ void (*collection_settings_create)(struct RenderEngine *engine, struct IDProperty *props);
+ void (*render_settings_create)(struct RenderEngine *engine, struct IDProperty *props);
+
+ struct DrawEngineType *draw_engine;
+
/* RNA integration */
ExtensionRNA ext;
} RenderEngineType;
@@ -169,12 +180,14 @@ void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, s
void RE_engines_init(void);
void RE_engines_exit(void);
+void RE_engines_register(struct Main *bmain, RenderEngineType *render_type);
RenderEngineType *RE_engines_find(const char *idname);
rcti* RE_engine_get_current_tiles(struct Render *re, int *r_total_tiles, bool *r_needs_free);
struct RenderData *RE_engine_get_render_data(struct Render *re);
-void RE_bake_engine_set_engine_parameters(struct Render *re, struct Main *bmain, struct Scene *scene);
+void RE_bake_engine_set_engine_parameters(
+ struct Render *re, struct Main *bmain, struct Depsgraph *graph, struct Scene *scene);
#endif /* __RE_ENGINE_H__ */
diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h
index c1c5fc4a04d..901c1c1d05d 100644
--- a/source/blender/render/extern/include/RE_multires_bake.h
+++ b/source/blender/render/extern/include/RE_multires_bake.h
@@ -43,6 +43,12 @@ typedef struct MultiresBakeRender {
short mode;
bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */
+ /* material aligned image array (for per-face bake image) */
+ struct {
+ Image **array;
+ int len;
+ } ob_image;
+
int number_of_rays; /* Number of rays to be cast when doing AO baking */
float bias; /* Bias between object and start ray point when doing AO baking */
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 0d2e29ba4c8..145186548e6 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -37,6 +37,7 @@
struct bMovieHandle;
struct bNodeTree;
+struct Depsgraph;
struct Image;
struct ImageFormatData;
struct Main;
@@ -246,6 +247,7 @@ void RE_ChangeModeFlag(struct Render *re, int flag, bool clear);
struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */
void RE_SetOverrideCamera(struct Render *re, struct Object *camera);
void RE_SetCamera(struct Render *re, struct Object *camera);
+void RE_SetDepsgraph(struct Render *re, struct Depsgraph *graph);
void RE_SetEnvmapCamera(struct Render *re, struct Object *cam_ob, float viewscale, float clipsta, float clipend);
void RE_SetWindow(struct Render *re, const rctf *viewplane, float clipsta, float clipend);
void RE_SetOrtho(struct Render *re, const rctf *viewplane, float clipsta, float clipend);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index f0323340899..b1b95933584 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -185,6 +185,8 @@ struct Render {
/* shadow counter, detect shadow-reuse for shaders */
int shadowsamplenr[BLENDER_MAX_THREADS];
+ struct Depsgraph *depsgraph;
+
/* main, scene, and its full copy of renderdata and world */
struct Main *main;
Scene *scene;
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 31e461b4536..71a595d6a8b 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -669,11 +669,12 @@ static int get_next_bake_face(BakeShade *bs)
const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+ /* should use 'BKE_object_material_edit_image_get' but in this case simpler not to */
+ ima = vlr->mat ? vlr->mat->edit_image : NULL;
- if (!tface || !tface->tpage)
+ if (!tface || !ima)
continue;
- ima = tface->tpage;
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf == NULL)
@@ -814,7 +815,7 @@ static void shade_tface(BakeShade *bs)
ObjectInstanceRen *obi = bs->obi;
ObjectRen *obr = obi->obr;
MTFace *tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
- Image *ima = tface->tpage;
+ Image *ima = vlr->mat->edit_image;
float vec[4][2];
int a, i1, i2, i3;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 41ff8e046e7..803244cdd63 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -66,7 +66,6 @@
#include "BKE_customdata.h"
#include "BKE_colortools.h"
#include "BKE_displist.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_key.h"
@@ -82,6 +81,8 @@
#include "BKE_particle.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
+
#include "PIL_time.h"
#include "envmap.h"
@@ -3153,11 +3154,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
/* normalmaps, test if tangents needed, separated from shading */
if (ma->mode_l & MA_TANGENT_V) {
need_tangent= 1;
- if (me->mtpoly==NULL)
+ if (me->mloopuv==NULL)
need_orco= 1;
}
if (ma->mode_l & MA_NORMAP_TANG) {
- if (me->mtpoly==NULL) {
+ if (me->mloopuv==NULL) {
need_orco= 1;
}
need_tangent= 1;
@@ -3170,7 +3171,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (re->flag & R_NEED_TANGENT) {
/* exception for tangent space baking */
- if (me->mtpoly==NULL) {
+ if (me->mloopuv==NULL) {
need_orco= 1;
}
need_tangent= 1;
@@ -4982,14 +4983,13 @@ static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, in
}
}
-static void database_init_objects(Render *re, unsigned int renderlay, int nolamps, int onlyselected, Object *actob, int timeoffset)
+static void database_init_objects(Render *re, unsigned int UNUSED(renderlay), int nolamps, int onlyselected, Object *actob, int timeoffset)
{
Base *base;
Object *ob;
Group *group;
ObjectInstanceRen *obi;
Scene *sce_iter;
- int lay, vectorlay;
/* for duplis we need the Object texture mapping to work as if
* untransformed, set_dupli_tex_mat sets the matrix to allow that
@@ -5017,14 +5017,18 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
for (SETLOOPER(re->scene, sce_iter, base)) {
ob= base->object;
+#if 0
+ TODO_LAYER; /* investigate if this is an issue*/
/* in the prev/next pass for making speed vectors, avoid creating
* objects that are not on a renderlayer with a vector pass, can
* save a lot of time in complex scenes */
vectorlay= get_vector_renderlayers(re->scene);
- lay= (timeoffset)? renderlay & vectorlay: renderlay;
+#endif
- /* if the object has been restricted from rendering in the outliner, ignore it */
- if (is_object_restricted(re, ob)) continue;
+ /* if the object is not visible, ignore it */
+ if ((base->flag & BASE_VISIBLED) == 0) {
+ continue;
+ }
/* OB_DONE means the object itself got duplicated, so was already converted */
if (ob->flag & OB_DONE) {
@@ -5037,7 +5041,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
}
}
}
- else if ((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->lay)) ) {
+ else if (((base->flag & BASE_VISIBLED) != 0) || (ob->type==OB_LAMP)) {
if ((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
DupliObject *dob;
ListBase *duplilist;
@@ -5210,7 +5214,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
/* applies changes fully */
if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
- BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay);
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
render_update_anim_renderdata(re, &re->scene->r);
}
@@ -5225,7 +5229,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
RE_SetView(re, mat);
/* force correct matrix for scaled cameras */
- DAG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB);
+ DEG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB);
}
/* store for incremental render, viewmat rotates dbase */
@@ -5380,13 +5384,9 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0;
re->lights.first= re->lights.last= NULL;
- /* in localview, lamps are using normal layers, objects only local bits */
- if (re->lay & 0xFF000000)
- lay &= 0xFF000000;
-
/* applies changes fully */
scene->r.cfra += timeoffset;
- BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay);
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
/* if no camera, viewmat should have been set! */
if (camera) {
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 156b4215992..7bd8c6decf0 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -51,6 +51,7 @@
#include "BKE_main.h"
#include "BKE_image.h" /* BKE_imbuf_write */
+#include "BKE_layer.h"
#include "BKE_texture.h"
#include "BKE_scene.h"
@@ -248,17 +249,14 @@ static void envmap_transmatrix(float mat[4][4], int part)
static void env_set_imats(Render *re)
{
- Base *base;
float mat[4][4];
-
- base = re->scene->base.first;
- while (base) {
- mul_m4_m4m4(mat, re->viewmat, base->object->obmat);
- invert_m4_m4(base->object->imat, mat);
-
- base = base->next;
+
+ FOREACH_SCENE_OBJECT(re->scene, ob)
+ {
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
}
-
+ FOREACH_SCENE_OBJECT_END
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index a581f7bd198..be6d6459b2f 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -45,9 +45,12 @@
#include "BKE_camera.h"
#include "BKE_global.h"
#include "BKE_colortools.h"
+#include "BKE_layer.h"
#include "BKE_report.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#ifdef WITH_PYTHON
@@ -58,6 +61,8 @@
#include "RE_pipeline.h"
#include "RE_bake.h"
+#include "DRW_engine.h"
+
#include "initrender.h"
#include "renderpipeline.h"
#include "render_types.h"
@@ -68,8 +73,8 @@
static RenderEngineType internal_render_type = {
NULL, NULL,
- "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL,
- NULL, NULL, NULL, NULL, NULL, NULL, render_internal_update_passes,
+ "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL | RE_USE_LEGACY_PIPELINE,
+ NULL, NULL, NULL, NULL, NULL, NULL, render_internal_update_passes, NULL, NULL, NULL,
{NULL, NULL, NULL}
};
@@ -77,8 +82,8 @@ static RenderEngineType internal_render_type = {
static RenderEngineType internal_game_type = {
NULL, NULL,
- "BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME | RE_USE_LEGACY_PIPELINE,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
{NULL, NULL, NULL}
};
@@ -88,16 +93,22 @@ ListBase R_engines = {NULL, NULL};
void RE_engines_init(void)
{
- BLI_addtail(&R_engines, &internal_render_type);
+ RE_engines_register(NULL, &internal_render_type);
#ifdef WITH_GAMEENGINE
- BLI_addtail(&R_engines, &internal_game_type);
+ RE_engines_register(NULL, &internal_game_type);
#endif
+ DRW_engines_register();
}
void RE_engines_exit(void)
{
RenderEngineType *type, *next;
+ DRW_engines_free();
+
+ BKE_layer_collection_engine_settings_callback_free();
+ BKE_scene_layer_engine_settings_callback_free();
+
for (type = R_engines.first; type; type = next) {
next = type->next;
@@ -112,6 +123,22 @@ void RE_engines_exit(void)
}
}
+void RE_engines_register(Main *bmain, RenderEngineType *render_type)
+{
+ if (render_type->draw_engine) {
+ DRW_engine_register(render_type->draw_engine);
+ }
+ if (render_type->collection_settings_create) {
+ BKE_layer_collection_engine_settings_callback_register(
+ bmain, render_type->idname, render_type->collection_settings_create);
+ }
+ if (render_type->render_settings_create) {
+ BKE_scene_layer_engine_settings_callback_register(
+ bmain, render_type->idname, render_type->render_settings_create);
+ }
+ BLI_addtail(&R_engines, render_type);
+}
+
RenderEngineType *RE_engines_find(const char *idname)
{
RenderEngineType *type;
@@ -126,7 +153,7 @@ RenderEngineType *RE_engines_find(const char *idname)
bool RE_engine_is_external(Render *re)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
- return (type && type->render);
+ return (type && type->render_to_image);
}
/* Create, Free */
@@ -184,7 +211,8 @@ static RenderPart *get_part_from_result(Render *re, RenderResult *result)
return NULL;
}
-RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
+RenderResult *RE_engine_begin_result(
+ RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
{
Render *re = engine->re;
RenderResult *result;
@@ -409,7 +437,8 @@ float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, int use
return BKE_camera_multiview_shift_x(re ? &re->r : NULL, camera, re->viewname);
}
-void RE_engine_get_camera_model_matrix(RenderEngine *engine, Object *camera, int use_spherical_stereo, float *r_modelmat)
+void RE_engine_get_camera_model_matrix(
+ RenderEngine *engine, Object *camera, int use_spherical_stereo, float *r_modelmat)
{
Render *re = engine->re;
@@ -486,8 +515,9 @@ RenderData *RE_engine_get_render_data(Render *re)
}
/* Bake */
-void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene)
+void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Depsgraph *graph, Scene *scene)
{
+ re->depsgraph = graph;
re->scene = scene;
re->main = bmain;
render_copy_renderdata(&re->r, &scene->r);
@@ -537,10 +567,21 @@ bool RE_bake_engine(
/* update is only called so we create the engine.session */
if (type->update)
- type->update(engine, re->main, re->scene);
-
- if (type->bake)
- type->bake(engine, re->scene, object, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result);
+ type->update(engine, re->main, re->depsgraph, re->scene);
+
+ if (type->bake) {
+ type->bake(
+ engine,
+ re->scene,
+ object,
+ pass_type,
+ pass_filter,
+ object_id,
+ pixel_array,
+ num_pixels,
+ depth,
+ result);
+ }
engine->tile_x = 0;
engine->tile_y = 0;
@@ -576,8 +617,7 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
BPy_BEGIN_ALLOW_THREADS;
#endif
- /* It's possible that here we're including layers which were never visible before. */
- BKE_scene_update_for_newframe_ex(re->eval_ctx, re->main, scene, (1 << 20) - 1, true);
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, scene);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
@@ -588,17 +628,6 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
/* Render */
-static bool render_layer_exclude_animated(Scene *scene, SceneRenderLayer *srl)
-{
- PointerRNA ptr;
- PropertyRNA *prop;
-
- RNA_pointer_create(&scene->id, &RNA_SceneRenderLayer, srl, &ptr);
- prop = RNA_struct_find_property(&ptr, "layers_exclude");
-
- return RNA_property_animated(&ptr, prop);
-}
-
int RE_engine_render(Render *re, int do_all)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
@@ -606,7 +635,7 @@ int RE_engine_render(Render *re, int do_all)
bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0;
/* verify if we can render */
- if (!type->render)
+ if (!type->render_to_image)
return 0;
if ((re->r.scemode & R_BUTS_PREVIEW) && !(type->flag & RE_USE_PREVIEW))
return 0;
@@ -623,40 +652,7 @@ int RE_engine_render(Render *re, int do_all)
/* update animation here so any render layer animation is applied before
* creating the render result */
if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_BUTS_PREVIEW)) == 0) {
- unsigned int lay = re->lay;
-
- /* don't update layers excluded on all render layers */
- if (type->flag & RE_USE_EXCLUDE_LAYERS) {
- SceneRenderLayer *srl;
- unsigned int non_excluded_lay = 0;
-
- if (re->r.scemode & R_SINGLE_LAYER) {
- srl = BLI_findlink(&re->r.layers, re->r.actlay);
- if (srl) {
- non_excluded_lay |= ~(srl->lay_exclude & ~srl->lay_zmask);
-
- /* in this case we must update all because animation for
- * the scene has not been updated yet, and so may not be
- * up to date until after BKE_scene_update_for_newframe */
- if (render_layer_exclude_animated(re->scene, srl))
- non_excluded_lay |= ~0;
- }
- }
- else {
- for (srl = re->r.layers.first; srl; srl = srl->next) {
- if (!(srl->layflag & SCE_LAY_DISABLE)) {
- non_excluded_lay |= ~(srl->lay_exclude & ~srl->lay_zmask);
-
- if (render_layer_exclude_animated(re->scene, srl))
- non_excluded_lay |= ~0;
- }
- }
- }
-
- lay &= non_excluded_lay;
- }
-
- BKE_scene_update_for_newframe_ex(re->eval_ctx, re->main, re->scene, lay, true);
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
render_update_anim_renderdata(re, &re->scene->r);
}
@@ -722,16 +718,18 @@ int RE_engine_render(Render *re, int do_all)
if (re->result->do_exr_tile)
render_result_exr_file_begin(re);
- if (type->update)
- type->update(engine, re->main, re->scene);
+ if (type->update) {
+ type->update(engine, re->main, re->depsgraph, re->scene);
+ }
/* Clear UI drawing locks. */
if (re->draw_lock) {
re->draw_lock(re->dlh, 0);
}
- if (type->render)
- type->render(engine, re->scene);
+ if (type->render_to_image) {
+ type->render_to_image(engine, re->depsgraph);
+ }
engine->tile_x = 0;
engine->tile_y = 0;
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 970a3937657..4ac44671871 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -48,6 +48,8 @@
#include "BKE_camera.h"
+#include "DEG_depsgraph.h"
+
#ifdef WITH_QUICKTIME
#include "quicktime_export.h"
#endif
@@ -503,6 +505,11 @@ void RE_SetCamera(Render *re, Object *cam_ob)
re_camera_params_get(re, &params, cam_ob);
}
+void RE_SetDepsgraph(Render *re, Depsgraph *graph)
+{
+ re->depsgraph = graph;
+}
+
void RE_SetPixelSize(Render *re, float pixsize)
{
re->viewdx = pixsize;
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index fba5836ac32..4c0355ef604 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -42,14 +42,16 @@
#include "BLI_threads.h"
#include "BKE_ccg.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_modifier.h"
#include "BKE_subsurf.h"
+#include "DEG_depsgraph.h"
+
#include "RE_multires_bake.h"
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
@@ -78,7 +80,6 @@ typedef struct {
MLoop *mloop;
MLoopUV *mloopuv;
const MLoopTri *mlooptri;
- MTexPoly *mtpoly;
float *pvtangent;
const float *precomputed_normals;
int w, h;
@@ -89,6 +90,8 @@ typedef struct {
void *bake_data;
ImBuf *ibuf;
MPassKnownData pass_data;
+ /* material aligned UV array */
+ Image **image_array;
} MResolvePixelData;
typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
@@ -373,13 +376,15 @@ static void *do_multires_bake_thread(void *data_v)
while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) {
const MLoopTri *lt = &data->mlooptri[tri_index];
- MTexPoly *mtpoly = &data->mtpoly[lt->poly];
- MLoopUV *mloopuv = data->mloopuv;
+ const MPoly *mp = &data->mpoly[lt->poly];
+ const short mat_nr = mp->mat_nr;
+ const MLoopUV *mloopuv = data->mloopuv;
if (multiresbake_test_break(bkr))
break;
- if (mtpoly->tpage != handle->image)
+ Image *tri_image = mat_nr < bkr->ob_image.len ? bkr->ob_image.array[mat_nr] : NULL;
+ if (tri_image != handle->image)
continue;
data->tri_index = tri_index;
@@ -445,7 +450,6 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t
MPoly *mpoly = dm->getPolyArray(dm);
MLoop *mloop = dm->getLoopArray(dm);
MLoopUV *mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
- MTexPoly *mtpoly = dm->getPolyDataArray(dm, CD_MTEXPOLY);
const float *precomputed_normals = dm->getPolyDataArray(dm, CD_NORMAL);
float *pvtangent = NULL;
@@ -489,7 +493,6 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t
handle->data.mvert = mvert;
handle->data.mloopuv = mloopuv;
handle->data.mlooptri = mlooptri;
- handle->data.mtpoly = mtpoly;
handle->data.mloop = mloop;
handle->data.pvtangent = pvtangent;
handle->data.precomputed_normals = precomputed_normals; /* don't strictly need this */
@@ -1178,30 +1181,34 @@ static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void
static void count_images(MultiresBakeRender *bkr)
{
- int a, totpoly;
- DerivedMesh *dm = bkr->lores_dm;
- MTexPoly *mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY);
-
BLI_listbase_clear(&bkr->image);
bkr->tot_image = 0;
- totpoly = dm->getNumPolys(dm);
-
- for (a = 0; a < totpoly; a++)
- mtexpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
+ for (int i = 0; i < bkr->ob_image.len; i++) {
+ Image *ima = bkr->ob_image.array[i];
+ if (ima) {
+ ima->id.tag &= ~LIB_TAG_DOIT;
+ }
+ }
- for (a = 0; a < totpoly; a++) {
- Image *ima = mtexpoly[a].tpage;
- if ((ima->id.tag & LIB_TAG_DOIT) == 0) {
- LinkData *data = BLI_genericNodeN(ima);
- BLI_addtail(&bkr->image, data);
- bkr->tot_image++;
- ima->id.tag |= LIB_TAG_DOIT;
+ for (int i = 0; i < bkr->ob_image.len; i++) {
+ Image *ima = bkr->ob_image.array[i];
+ if (ima) {
+ if ((ima->id.tag & LIB_TAG_DOIT) == 0) {
+ LinkData *data = BLI_genericNodeN(ima);
+ BLI_addtail(&bkr->image, data);
+ bkr->tot_image++;
+ ima->id.tag |= LIB_TAG_DOIT;
+ }
}
}
- for (a = 0; a < totpoly; a++)
- mtexpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
+ for (int i = 0; i < bkr->ob_image.len; i++) {
+ Image *ima = bkr->ob_image.array[i];
+ if (ima) {
+ ima->id.tag &= ~LIB_TAG_DOIT;
+ }
+ }
}
static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
@@ -1283,7 +1290,7 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
}
BKE_image_release_ibuf(ima, ibuf, NULL);
- DAG_id_tag_update(&ima->id, 0);
+ DEG_id_tag_update(&ima->id, 0);
}
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 929eae495cf..ecbb9fbee0b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -62,7 +62,6 @@
#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "BKE_camera.h"
#include "BKE_colortools.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
@@ -78,6 +77,8 @@
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
#include "BKE_object.h"
+#include "DEG_depsgraph.h"
+
#include "PIL_time.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -550,6 +551,7 @@ void RE_FreeRender(Render *re)
/* main dbase can already be invalid now, some database-free code checks it */
re->main = NULL;
re->scene = NULL;
+ re->depsgraph = NULL;
RE_Database_Free(re); /* view render can still have full database */
free_sample_tables(re);
@@ -1698,7 +1700,7 @@ static void do_render_blur_3d(Render *re)
/* make sure motion blur changes get reset to current frame */
if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
- BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay);
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
}
/* weak... the display callback wants an active renderlayer pointer... */
@@ -1934,6 +1936,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
/* still unsure entity this... */
resc->main = re->main;
+ resc->depsgraph = re->depsgraph;
resc->scene = sce;
resc->lay = sce->lay;
resc->scene_color_manage = BKE_scene_check_color_management_enabled(sce);
@@ -2014,14 +2017,14 @@ bool RE_allow_render_generic_object(Object *ob)
#define DEPSGRAPH_WORKAROUND_HACK
#ifdef DEPSGRAPH_WORKAROUND_HACK
-static void tag_dependend_objects_for_render(Scene *scene, int renderlay)
+static void tag_dependend_objects_for_render(Scene *scene, int UNUSED(renderlay))
{
Scene *sce_iter;
Base *base;
for (SETLOOPER(scene, sce_iter, base)) {
Object *object = base->object;
- if ((base->lay & renderlay) == 0) {
+ if ((base->flag & BASE_VISIBLED) == 0) {
continue;
}
@@ -2041,22 +2044,22 @@ static void tag_dependend_objects_for_render(Scene *scene, int renderlay)
if (md->type == eModifierType_Boolean) {
BooleanModifierData *bmd = (BooleanModifierData *)md;
if (bmd->object && bmd->object->type == OB_MESH) {
- DAG_id_tag_update(&bmd->object->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&bmd->object->id, OB_RECALC_DATA);
}
}
else if (md->type == eModifierType_Array) {
ArrayModifierData *amd = (ArrayModifierData *)md;
if (amd->start_cap && amd->start_cap->type == OB_MESH) {
- DAG_id_tag_update(&amd->start_cap->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&amd->start_cap->id, OB_RECALC_DATA);
}
if (amd->end_cap && amd->end_cap->type == OB_MESH) {
- DAG_id_tag_update(&amd->end_cap->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&amd->end_cap->id, OB_RECALC_DATA);
}
}
else if (md->type == eModifierType_Shrinkwrap) {
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
if (smd->target && smd->target->type == OB_MESH) {
- DAG_id_tag_update(&smd->target->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&smd->target->id, OB_RECALC_DATA);
}
}
}
@@ -2590,7 +2593,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
R.i.cfra = re->i.cfra;
if (update_newframe)
- BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay);
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
if (re->r.scemode & R_FULL_SAMPLE)
do_merge_fullsample(re, ntree);
@@ -3642,19 +3645,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 1, 0);
if (nfra != scene->r.cfra) {
- /*
- * Skip this frame, but update for physics and particles system.
- * From convertblender.c:
- * in localview, lamps are using normal layers, objects only local bits.
- */
- unsigned int updatelay;
-
- if (re->lay & 0xFF000000)
- updatelay = re->lay & 0xFF000000;
- else
- updatelay = re->lay;
-
- BKE_scene_update_for_newframe(re->eval_ctx, bmain, scene, updatelay);
+ /* Skip this frame, but update for physics and particles system. */
+ BKE_scene_update_for_newframe(re->eval_ctx, bmain, scene);
continue;
}
else
@@ -3816,6 +3808,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
re->scene = sce;
re->scene_color_manage = BKE_scene_check_color_management_enabled(sce);
re->lay = sce->lay;
+ re->depsgraph = sce->depsgraph;
camera = RE_GetCamera(re);
RE_SetCamera(re, camera);
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 20602314526..597a2338fe7 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -442,7 +442,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
}
- if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE))) {
+ if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP))) {
MCol *mcol;
const float *uv;
char *name;
@@ -504,15 +504,6 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
suv->dyuv[0] = 0.0f;
suv->dyuv[1] = 0.0f;
}
-
- if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
- if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) {
- shi->vcol[0] = 1.0f;
- shi->vcol[1] = 1.0f;
- shi->vcol[2] = 1.0f;
- shi->vcol[3] = 1.0f;
- }
- }
}
if (shi->totuv == 0) {
@@ -521,14 +512,6 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
suv->uv[0] = 0.0f;
suv->uv[1] = spoint->strandco;
suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
-
- if (mode & MA_FACETEXTURE) {
- /* no tface? set at 1.0f */
- shi->vcol[0] = 1.0f;
- shi->vcol[1] = 1.0f;
- shi->vcol[2] = 1.0f;
- shi->vcol[3] = 1.0f;
- }
}
}
@@ -570,7 +553,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
if (shi->do_manage) {
- if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
+ if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}
@@ -1076,7 +1059,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
}
- if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
+ if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
VlakRen *vlr = shi->vlr;
MTFace *tface;
MCol *mcol;
@@ -1231,18 +1214,6 @@ void shade_input_set_shade_texco(ShadeInput *shi)
suv->dyuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
suv->dyuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
}
-
- if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
- if (((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) && ((R.flag & R_NEED_VCOL) == 0)) {
- shi->vcol[0] = 1.0f;
- shi->vcol[1] = 1.0f;
- shi->vcol[2] = 1.0f;
- shi->vcol[3] = 1.0f;
- }
- if (tface->tpage) {
- render_realtime_texture(shi, tface->tpage);
- }
- }
}
}
@@ -1256,14 +1227,6 @@ void shade_input_set_shade_texco(ShadeInput *shi)
suv->uv[0] = 2.0f * (u + .5f);
suv->uv[1] = 2.0f * (v + .5f);
suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
-
- if (mode & MA_FACETEXTURE) {
- /* no tface? set at 1.0f */
- shi->vcol[0] = 1.0f;
- shi->vcol[1] = 1.0f;
- shi->vcol[2] = 1.0f;
- shi->vcol[3] = 1.0f;
- }
}
}
@@ -1319,7 +1282,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
* else un-initialized values are used
*/
if (shi->do_manage) {
- if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 8dea0930b9e..c5a666d52c9 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -899,14 +899,7 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
{
Material *ma= shi->mat;
- if (ma->mode & (MA_FACETEXTURE)) {
- shi->r= shi->vcol[0];
- shi->g= shi->vcol[1];
- shi->b= shi->vcol[2];
- if (ma->mode & (MA_FACETEXTURE_ALPHA))
- shi->alpha= shi->vcol[3];
- }
- else if (ma->mode & (MA_VERTEXCOLP)) {
+ if (ma->mode & (MA_VERTEXCOLP)) {
float neg_alpha = 1.0f - shi->vcol[3];
shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];
shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3];
@@ -1764,12 +1757,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* material color itself */
if (passflag & color_passes) {
- if (ma->mode & (MA_FACETEXTURE)) {
- shi->r= shi->vcol[0];
- shi->g= shi->vcol[1];
- shi->b= shi->vcol[2];
- if (ma->mode & (MA_FACETEXTURE_ALPHA))
- shi->alpha= shi->vcol[3];
+ if (false) {
+ /* pass */
}
#ifdef WITH_FREESTYLE
else if (ma->vcol_alpha) {
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 925563a0777..ffdc0a59dee 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -25,12 +25,15 @@
set(INC
.
+ manipulators
+ manipulators/intern
../blenfont
../blenkernel
../blenlib
../blenloader
../blentranslation
../compositor
+ ../depsgraph
../editors/include
../gpu
../imbuf
@@ -68,6 +71,17 @@ set(SRC
intern/wm_subwindow.c
intern/wm_window.c
intern/wm_stereo.c
+ manipulators/intern/wm_manipulator.c
+ manipulators/intern/wm_manipulatorgroup.c
+ manipulators/intern/wm_manipulatormap.c
+ manipulators/intern/manipulator_library/arrow_manipulator.c
+ manipulators/intern/manipulator_library/arrow2d_manipulator.c
+ manipulators/intern/manipulator_library/cage_manipulator.c
+ manipulators/intern/manipulator_library/dial_manipulator.c
+ manipulators/intern/manipulator_library/primitive_manipulator.c
+ manipulators/intern/manipulator_library/geom_arrow_manipulator.c
+ manipulators/intern/manipulator_library/geom_cube_manipulator.c
+ manipulators/intern/manipulator_library/manipulator_library_utils.c
WM_api.h
WM_keymap.h
@@ -80,6 +94,13 @@ set(SRC
wm_files.h
wm_subwindow.h
wm_window.h
+ manipulators/WM_manipulator_api.h
+ manipulators/WM_manipulator_types.h
+ manipulators/WM_manipulator_library.h
+ manipulators/wm_manipulator_wmapi.h
+ manipulators/intern/wm_manipulator_intern.h
+ manipulators/intern/manipulator_library/manipulator_geometry.h
+ manipulators/intern/manipulator_library/manipulator_library_intern.h
)
if(WITH_AUDASPACE)
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 492dec2cc10..80170d70dbd 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -42,6 +42,10 @@
#include "WM_keymap.h"
#include "BLI_compiler_attrs.h"
+/* Include external manipulator API's */
+#include "manipulators/WM_manipulator_api.h"
+#include "manipulators/WM_manipulator_library.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -64,12 +68,16 @@ struct wmDrag;
struct ImBuf;
struct ImageFormatData;
struct ARegion;
+struct ScrArea;
#ifdef WITH_INPUT_NDOF
struct wmNDOFMotionData;
#endif
typedef struct wmJob wmJob;
+typedef struct wmManipulator wmManipulator;
+typedef struct wmManipulatorMap wmManipulatorMap;
+typedef struct wmManipulatorMapType wmManipulatorMapType;
/* general API */
void WM_init_state_size_set (int stax, int stay, int sizx, int sizy);
@@ -171,6 +179,9 @@ void WM_event_free_ui_handler_all(
wmUIHandlerFunc ui_handle, wmUIHandlerRemoveFunc ui_remove);
struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
+void WM_event_modal_handler_area_replace(wmWindow *win, const struct ScrArea *old_area, struct ScrArea *new_area);
+void WM_event_modal_handler_region_replace(wmWindow *win, const struct ARegion *old_region, struct ARegion *new_region);
+
void WM_event_remove_handlers(struct bContext *C, ListBase *handlers);
/* handler flag */
@@ -228,6 +239,7 @@ void WM_operator_view3d_unit_defaults(struct bContext *C, struct wmOperator *op
int WM_operator_smooth_viewtx_get(const struct wmOperator *op);
int WM_menu_invoke_ex(struct bContext *C, struct wmOperator *op, int opcontext);
int WM_menu_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_enum_search_invoke_previews(struct bContext *C, struct wmOperator *op, short prv_cols, short prv_rows);
int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, confirm menu + exec */
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
@@ -411,9 +423,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
void wmSubWindowSet (struct wmWindow *win, int swinid);
void wmSubWindowScissorSet (struct wmWindow *win, int swinid, const struct rcti *srct, bool srct_pad);
- /* OpenGL utilities with safety check + working in modelview matrix mode */
-void wmFrustum (float x1, float x2, float y1, float y2, float n, float f);
-void wmOrtho (float x1, float x2, float y1, float y2, float n, float f);
+ /* OpenGL utilities with safety check */
void wmOrtho2 (float x1, float x2, float y1, float y2);
/* use for conventions (avoid hard-coded offsets all over) */
void wmOrtho2_region_pixelspace(const struct ARegion *ar);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 97f9257b4cb..84209a0e3c8 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -119,6 +119,7 @@ struct ImBuf;
/* exported types for WM */
#include "wm_cursors.h"
#include "wm_event_types.h"
+#include "manipulators/WM_manipulator_types.h"
/* ************** wmOperatorType ************************ */
@@ -576,6 +577,9 @@ typedef struct wmOperatorType {
/* pointer to modal keymap, do not free! */
struct wmKeyMap *modalkeymap;
+ /* manipulator-group that is accessible while operator runs */
+ wmManipulatorGroupType *mgrouptype;
+
/* python needs the operator type as well */
int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 3a53906a8e8..40a2bf42a28 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -46,6 +46,8 @@
#include "BKE_context.h"
+#include "GPU_shader.h"
+
#include "IMB_imbuf_types.h"
#include "UI_interface.h"
@@ -268,10 +270,10 @@ void wm_drags_check_ops(bContext *C, wmEvent *event)
static void wm_drop_operator_draw(const char *name, int x, int y)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- const unsigned char fg[4] = {255, 255, 255, 255};
- const unsigned char bg[4] = {0, 0, 0, 50};
+ const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
- UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, fg, bg);
+ UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
}
static const char *wm_drag_name(wmDrag *drag)
@@ -332,8 +334,10 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
if (rect)
drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
else {
- glColor4f(1.0, 1.0, 1.0, 0.65); /* this blends texture */
- glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, drag->imb->rect, drag->scale, drag->scale);
+ float col[4] = {1.0f, 1.0f, 1.0f, 0.65f}; /* this blends texture */
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTexScaled(&state, x, y, drag->imb->x, drag->imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST,
+ drag->imb->rect, drag->scale, drag->scale, 1.0f, 1.0f, col);
}
}
else {
@@ -361,8 +365,8 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else {
- glColor4ub(255, 255, 255, 255);
- UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag));
+ const unsigned char col[] = {255, 255, 255, 255};
+ UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag), col);
}
/* operator name with roundbox */
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 77ffa46b990..3c176912409 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -57,8 +57,7 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
-#include "GPU_glew.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
#include "RE_engine.h"
@@ -128,7 +127,7 @@ static bool wm_area_test_invalid_backbuf(ScrArea *sa)
if (sa->spacetype == SPACE_VIEW3D)
return (((View3D *)sa->spacedata.first)->flag & V3D_INVALID_BACKBUF) != 0;
else
- return 1;
+ return true;
}
static void wm_region_test_render_do_draw(bScreen *screen, ScrArea *sa, ARegion *ar)
@@ -372,118 +371,116 @@ static void wm_draw_triple_fail(bContext *C, wmWindow *win)
{
wm_draw_window_clear(win);
- win->drawfail = 1;
+ win->drawfail = true;
wm_method_draw_overlap_all(C, win, 0);
}
-static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
+static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
{
- const int winsize_x = WM_window_pixels_x(win);
- const int winsize_y = WM_window_pixels_y(win);
-
- GLint maxsize;
-
/* compute texture sizes */
- if (GLEW_ARB_texture_rectangle || GLEW_NV_texture_rectangle || GLEW_EXT_texture_rectangle) {
- triple->target = GL_TEXTURE_RECTANGLE_ARB;
- }
- else {
- triple->target = GL_TEXTURE_2D;
- }
-
- triple->x = winsize_x;
- triple->y = winsize_y;
+ triple->x = WM_window_pixels_x(win);
+ triple->y = WM_window_pixels_y(win);
+
+#if USE_TEXTURE_RECTANGLE
+ /* GL_TEXTURE_RECTANGLE is part of GL 3.1 so we can use it soon without runtime checks */
+ triple->target = GL_TEXTURE_RECTANGLE;
+#else
+ triple->target = GL_TEXTURE_2D;
+#endif
/* generate texture names */
glGenTextures(1, &triple->bind);
- if (!triple->bind) {
- /* not the typical failure case but we handle it anyway */
- printf("WM: failed to allocate texture for triple buffer drawing (glGenTextures).\n");
- return 0;
- }
-
/* proxy texture is only guaranteed to test for the cases that
* there is only one texture in use, which may not be the case */
- maxsize = GPU_max_texture_size();
+ const GLint maxsize = GPU_max_texture_size();
if (triple->x > maxsize || triple->y > maxsize) {
- glBindTexture(triple->target, 0);
printf("WM: failed to allocate texture for triple buffer drawing "
- "(texture too large for graphics card).\n");
- return 0;
+ "(texture too large for graphics card).\n");
+ return false;
}
/* setup actual texture */
glBindTexture(triple->target, triple->bind);
- glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+ /* no mipmaps */
+#if USE_TEXTURE_RECTANGLE
+ /* already has no mipmaps */
+#else
+ glTexParameteri(triple->target, GL_TEXTURE_MAX_LEVEL, 0);
+ /* GL_TEXTURE_BASE_LEVEL = 0 by default */
+#endif
+
glTexParameteri(triple->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glBindTexture(triple->target, 0);
- /* not sure if this works everywhere .. */
- if (glGetError() == GL_OUT_OF_MEMORY) {
- printf("WM: failed to allocate texture for triple buffer drawing (out of memory).\n");
- return 0;
- }
+ glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(triple->target, 0);
- return 1;
+ return true;
}
-void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha, bool is_interlace)
+void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
{
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
- float halfx, halfy, ratiox, ratioy;
-
/* wmOrtho for the screen has this same offset */
- ratiox = sizex;
- ratioy = sizey;
- halfx = GLA_PIXEL_OFS;
- halfy = GLA_PIXEL_OFS;
+ float ratiox = sizex;
+ float ratioy = sizey;
+ float halfx = GLA_PIXEL_OFS;
+ float halfy = GLA_PIXEL_OFS;
+#if USE_TEXTURE_RECTANGLE
/* texture rectangle has unnormalized coordinates */
- if (triple->target == GL_TEXTURE_2D) {
- ratiox /= triple->x;
- ratioy /= triple->y;
- halfx /= triple->x;
- halfy /= triple->y;
- }
+#else
+ ratiox /= triple->x;
+ ratioy /= triple->y;
+ halfx /= triple->x;
+ halfy /= triple->y;
+#endif
- /* interlace stereo buffer bind the shader before calling wm_triple_draw_textures */
- if (is_interlace) {
- glEnable(triple->target);
- }
- else {
- GPU_basic_shader_bind((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_TEXTURE_2D : GPU_SHADER_TEXTURE_RECT);
- }
+ VertexFormat *format = immVertexFormat();
+ unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ const int activeTex = 7; /* arbitrary */
+ glActiveTexture(GL_TEXTURE0 + activeTex);
glBindTexture(triple->target, triple->bind);
- glColor4f(1.0f, 1.0f, 1.0f, alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(halfx, halfy);
- glVertex2f(0, 0);
+#if USE_TEXTURE_RECTANGLE
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA);
+#else
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+ /* TODO: make pure 2D version
+ * and a 2D_IMAGE (replace, not modulate) version for when alpha = 1.0
+ */
+#endif
+ immUniform1f("alpha", alpha);
+ immUniform1i("image", activeTex);
- glTexCoord2f(ratiox + halfx, halfy);
- glVertex2f(sizex, 0);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
- glTexCoord2f(ratiox + halfx, ratioy + halfy);
- glVertex2f(sizex, sizey);
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, 0.0f, 0.0f);
- glTexCoord2f(halfx, ratioy + halfy);
- glVertex2f(0, sizey);
- glEnd();
+ immAttrib2f(texcoord, ratiox + halfx, halfy);
+ immVertex2f(pos, sizex, 0.0f);
- glBindTexture(triple->target, 0);
+ immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
+ immVertex2f(pos, sizex, sizey);
- if (is_interlace) {
- glDisable(triple->target);
- }
- else {
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- }
+ immAttrib2f(texcoord, halfx, ratioy + halfy);
+ immVertex2f(pos, 0.0f, sizey);
+
+ immEnd();
+ immUnbindProgram();
+
+ glBindTexture(triple->target, 0);
+ if (activeTex != 0)
+ glActiveTexture(GL_TEXTURE0);
}
static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
@@ -492,8 +489,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
const int sizey = WM_window_pixels_y(win);
glBindTexture(triple->target, triple->bind);
+ /* what is GL_READ_BUFFER right now? */
glCopyTexSubImage2D(triple->target, 0, 0, 0, 0, 0, sizex, sizey);
-
glBindTexture(triple->target, 0);
}
@@ -506,7 +503,7 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *tripl
wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct, true);
glEnable(GL_BLEND);
- wm_triple_draw_textures(win, triple, 1.0f - fac, false);
+ wm_triple_draw_textures(win, triple, 1.0f - fac);
glDisable(GL_BLEND);
}
}
@@ -514,20 +511,21 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *tripl
static void wm_method_draw_triple(bContext *C, wmWindow *win)
{
wmWindowManager *wm = CTX_wm_manager(C);
- wmDrawTriple *triple;
wmDrawData *dd, *dd_next, *drawdata = win->drawdata.first;
bScreen *screen = win->screen;
ScrArea *sa;
ARegion *ar;
- int copytex = false;
+ bool copytex = false;
if (drawdata && drawdata->triple) {
- glClearColor(0, 0, 0, 0);
+#if 0 /* why do we need to clear before overwriting? */
+ glClearColor(1, 1, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+#endif
wmSubWindowSet(win, screen->mainwin);
- wm_triple_draw_textures(win, drawdata->triple, 1.0f, false);
+ wm_triple_draw_textures(win, drawdata->triple, 1.0f);
}
else {
/* we run it when we start OR when we turn stereo on */
@@ -554,7 +552,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
MEM_freeN(dd);
}
- triple = drawdata->triple;
+ wmDrawTriple *triple = drawdata->triple;
/* draw marked area regions */
for (sa = screen->areabase.first; sa; sa = sa->next) {
@@ -562,7 +560,6 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->swinid && ar->do_draw) {
-
if (ar->overlap == false) {
CTX_wm_region_set(C, ar);
ED_region_do_draw(C, ar);
@@ -662,12 +659,14 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, StereoVi
if (drawdata && drawdata->triple) {
if (id == 0) {
+#if 0 /* why do we need to clear before overwriting? */
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+#endif
wmSubWindowSet(win, screen->mainwin);
- wm_triple_draw_textures(win, drawdata->triple, 1.0f, false);
+ wm_triple_draw_textures(win, drawdata->triple, 1.0f);
}
}
else {
@@ -849,20 +848,20 @@ static bool wm_draw_update_test_window(wmWindow *win)
}
if (do_draw)
- return 1;
+ return true;
if (win->screen->do_refresh)
- return 1;
+ return true;
if (win->screen->do_draw)
- return 1;
+ return true;
if (win->screen->do_draw_gesture)
- return 1;
+ return true;
if (win->screen->do_draw_paintcursor)
- return 1;
+ return true;
if (win->screen->do_draw_drag)
- return 1;
+ return true;
- return 0;
+ return false;
}
static int wm_automatic_draw_method(wmWindow *win)
@@ -916,7 +915,6 @@ void wm_draw_update(bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
- int drawmethod;
#ifdef WITH_OPENSUBDIV
BKE_subsurf_free_unused_buffers();
@@ -952,7 +950,7 @@ void wm_draw_update(bContext *C)
if (win->screen->do_refresh)
ED_screen_refresh(wm, win);
- drawmethod = wm_automatic_draw_method(win);
+ int drawmethod = wm_automatic_draw_method(win);
if (win->drawfail)
wm_method_draw_overlap_all(C, win, 0);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index f26ee0e73ec..5d4b7a68d42 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -36,6 +36,7 @@
#include <string.h>
#include "DNA_listBase.h"
+#include "DNA_manipulator_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
@@ -53,6 +54,7 @@
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -68,8 +70,6 @@
#include "RNA_access.h"
-#include "GPU_debug.h"
-
#include "UI_interface.h"
#include "PIL_time.h"
@@ -319,7 +319,8 @@ void wm_event_do_notifiers(bContext *C)
}
}
if (ELEM(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_WM)) {
- ED_info_stats_clear(win->screen->scene);
+ SceneLayer *sl = BKE_scene_layer_context_active(win->screen->scene);
+ ED_info_stats_clear(sl);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL);
}
}
@@ -339,12 +340,13 @@ void wm_event_do_notifiers(bContext *C)
/* the notifiers are sent without context, to keep it clean */
while ((note = BLI_pophead(&wm->queue))) {
for (win = wm->windows.first; win; win = win->next) {
+ Scene *scene = win->screen->scene;
/* filter out notifiers */
if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) {
/* pass */
}
- else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) {
+ else if (note->category == NC_SCENE && note->reference && note->reference != scene) {
/* pass */
}
else {
@@ -358,13 +360,13 @@ void wm_event_do_notifiers(bContext *C)
ED_screen_do_listen(C, note);
for (ar = win->screen->regionbase.first; ar; ar = ar->next) {
- ED_region_do_listen(win->screen, NULL, ar, note);
+ ED_region_do_listen(win->screen, NULL, ar, note, scene);
}
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
- ED_area_do_listen(win->screen, sa, note);
+ ED_area_do_listen(win->screen, sa, note, scene);
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- ED_region_do_listen(win->screen, sa, ar, note);
+ ED_region_do_listen(win->screen, sa, ar, note, scene);
}
}
}
@@ -1693,7 +1695,12 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
wm_handler_op_context(C, handler, event);
wm_region_mouse_co(C, event);
wm_event_modalkeymap(C, op, event, &dbl_click_disabled);
-
+
+ /* attach manipulator-map to handler if not there yet */
+ if (ot->mgrouptype && !handler->manipulator_map) {
+ wm_manipulatorgroup_attach_to_modal_handler(C, handler, ot->mgrouptype, op);
+ }
+
if (ot->flag & OPTYPE_UNDO)
wm->op_undo_depth++;
@@ -1742,6 +1749,9 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
CTX_wm_region_set(C, NULL);
}
+ /* update manipulators during modal handlers */
+ wm_manipulatormaps_handled_modal_update(C, event, handler, ot);
+
/* remove modal handler, operator itself should have been canceled and freed */
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
WM_cursor_grab_disable(CTX_wm_window(C), NULL);
@@ -2114,6 +2124,71 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
}
+ else if (handler->manipulator_map) {
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+ wmManipulatorMap *mmap = handler->manipulator_map;
+ wmManipulator *manipulator = wm_manipulatormap_get_highlighted_manipulator(mmap);
+ unsigned char part;
+
+ wm_manipulatormap_handler_context(C, handler);
+ wm_region_mouse_co(C, event);
+
+ /* handle manipulator highlighting */
+ if (event->type == MOUSEMOVE && !wm_manipulatormap_get_active_manipulator(mmap)) {
+ manipulator = wm_manipulatormap_find_highlighted_manipulator(mmap, C, event, &part);
+ wm_manipulatormap_set_highlighted_manipulator(mmap, C, manipulator, part);
+ }
+ /* handle user configurable manipulator-map keymap */
+ else if (manipulator) {
+ /* get user customized keymap from default one */
+ const wmManipulatorGroup *highlightgroup = wm_manipulator_get_parent_group(manipulator);
+ const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap);
+ wmKeyMapItem *kmi;
+
+ PRINT("%s: checking '%s' ...", __func__, keymap->idname);
+
+ if (!keymap->poll || keymap->poll(C)) {
+ PRINT("pass\n");
+ for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ if (wm_eventmatch(event, kmi)) {
+ wmOperator *op = handler->op;
+
+ PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
+
+ /* weak, but allows interactive callback to not use rawkey */
+ event->keymap_idname = kmi->idname;
+
+ /* handler->op is called later, we want keymap op to be triggered here */
+ handler->op = NULL;
+ action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
+ handler->op = op;
+
+ if (action & WM_HANDLER_BREAK) {
+ if (action & WM_HANDLER_HANDLED) {
+ if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS))
+ printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname);
+ }
+ else {
+ PRINT("%s: un-handled '%s'\n", __func__, kmi->idname);
+ }
+ }
+ }
+ }
+ }
+ else {
+ PRINT("fail\n");
+ }
+ }
+
+ /* restore the area */
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+
+ if (handler->op) {
+ action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
+ }
+ }
else {
/* modal, swallows all */
action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
@@ -2556,8 +2631,6 @@ void wm_event_do_handlers(bContext *C)
/* update key configuration after handling events */
WM_keyconfig_update(wm);
-
- GPU_ASSERT_NO_GL_ERRORS("wm_event_do_handlers");
}
/* ********** filesector handling ************ */
@@ -2594,7 +2667,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
wmWindow *win = CTX_wm_window(C);
/* only allow 1 file selector open per window */
- for (handler = win->modalhandlers.first; handler; handler = handlernext) {
+ for (handler = win->handlers.first; handler; handler = handlernext) {
handlernext = handler->next;
if (handler->type == WM_HANDLER_FILESELECT) {
@@ -2608,7 +2681,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
if (sfile->op == handler->op) {
CTX_wm_area_set(C, sa);
- wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL);
+ wm_handler_fileselect_do(C, &win->handlers, handler, EVT_FILESELECT_CANCEL);
break;
}
}
@@ -2616,7 +2689,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
/* if not found we stop the handler without changing the screen */
if (!sa)
- wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL);
+ wm_handler_fileselect_do(C, &win->handlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL);
}
}
@@ -2627,7 +2700,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
handler->op_area = CTX_wm_area(C);
handler->op_region = CTX_wm_region(C);
- BLI_addhead(&win->modalhandlers, handler);
+ BLI_addhead(&win->handlers, handler);
/* check props once before invoking if check is available
* ensures initial properties are valid */
@@ -2670,6 +2743,33 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
return handler;
}
+/**
+ * Modal handlers store a pointer to an area which might be freed while the handler runs.
+ * Use this function to NULL all handler pointers to \a old_area.
+ */
+void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area)
+{
+ for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
+ if (handler->op_area == old_area) {
+ handler->op_area = new_area;
+ }
+ }
+}
+
+/**
+ * Modal handlers store a pointer to a region which might be freed while the handler runs.
+ * Use this function to NULL all handler pointers to \a old_region.
+ */
+void WM_event_modal_handler_region_replace(wmWindow *win, const ARegion *old_region, ARegion *new_region)
+{
+ for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
+ if (handler->op_region == old_region) {
+ handler->op_region = new_region;
+ handler->op_region_type = new_region ? new_region->regiontype : RGN_TYPE_WINDOW;
+ }
+ }
+}
+
wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
{
wmEventHandler *handler;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 187c1193ec6..99e0e28ab1b 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -77,7 +77,6 @@
#include "BKE_blendfile.h"
#include "BKE_blender_undo.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -119,6 +118,8 @@
#include "BPY_extern.h"
#endif
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
@@ -464,7 +465,7 @@ static void wm_file_read_post(bContext *C, bool is_startup_file)
CTX_wm_window_set(C, wm->windows.first);
ED_editors_init(C);
- DAG_on_visible_update(CTX_data_main(C), true);
+ DEG_on_visible_update(CTX_data_main(C), true);
#ifdef WITH_PYTHON
if (is_startup_file) {
@@ -974,7 +975,7 @@ static void wm_history_file_update(void)
/* screen can be NULL */
-static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **thumb_pt)
+static ImBuf *blend_file_thumb(Scene *scene, SceneLayer *sl, bScreen *screen, BlendThumbnail **thumb_pt)
{
/* will be scaled down, but gives some nice oversampling */
ImBuf *ibuf;
@@ -1011,14 +1012,14 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **t
/* gets scaled to BLEN_THUMB_SIZE */
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(
- scene, scene->camera,
+ scene, sl, scene->camera,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, 0, false, NULL,
NULL, NULL, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(
- scene, v3d, ar,
+ scene, sl, v3d, ar,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
IB_rect, false, R_ALPHAPREMUL, 0, false, NULL,
NULL, NULL, err_out);
@@ -1114,7 +1115,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
/* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */
main_thumb = thumb = CTX_data_main(C)->blen_thumb;
if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) {
- ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb);
+ ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_data_scene_layer(C), CTX_wm_screen(C), &thumb);
}
/* operator now handles overwrite checks */
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 3b733f9558c..82e9be3970f 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -59,7 +59,7 @@
#include "BLO_readfile.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_global.h"
@@ -69,6 +69,8 @@
#include "BKE_idcode.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
#include "IMB_colormanagement.h"
@@ -131,8 +133,8 @@ static short wm_link_append_flag(wmOperator *op)
if (RNA_boolean_get(op->ptr, "autoselect"))
flag |= FILE_AUTOSELECT;
- if (RNA_boolean_get(op->ptr, "active_layer"))
- flag |= FILE_ACTIVELAY;
+ if (RNA_boolean_get(op->ptr, "active_collection"))
+ flag |= FILE_ACTIVE_COLLECTION;
if ((prop = RNA_struct_find_property(op->ptr, "relative_path")) && RNA_property_boolean_get(op->ptr, prop))
flag |= FILE_RELPATH;
if (RNA_boolean_get(op->ptr, "link"))
@@ -212,7 +214,7 @@ static WMLinkAppendDataItem *wm_link_append_data_item_add(
}
static void wm_link_do(
- WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d,
+ WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, SceneLayer *sl,
const bool use_placeholders, const bool force_indirect)
{
Main *mainl;
@@ -261,7 +263,7 @@ static void wm_link_do(
}
new_id = BLO_library_link_named_part_ex(
- mainl, &bh, item->idcode, item->name, flag, scene, v3d, use_placeholders, force_indirect);
+ mainl, &bh, item->idcode, item->name, flag, scene, sl, use_placeholders, force_indirect);
if (new_id) {
/* If the link is successful, clear item's libs 'todo' flags.
@@ -271,7 +273,7 @@ static void wm_link_do(
}
}
- BLO_library_link_end(mainl, &bh, flag, scene, v3d);
+ BLO_library_link_end(mainl, &bh, flag, scene, sl);
BLO_blendhandle_close(bh);
}
}
@@ -280,6 +282,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
PropertyRNA *prop;
WMLinkAppendData *lapp_data;
char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX];
@@ -334,8 +337,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* from here down, no error returns */
- if (scene && RNA_boolean_get(op->ptr, "autoselect")) {
- BKE_scene_base_deselect_all(scene);
+ if (sl && RNA_boolean_get(op->ptr, "autoselect")) {
+ BKE_scene_layer_base_deselect_all(sl);
}
/* tag everything, all untagged data can be made local
@@ -405,7 +408,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* XXX We'd need re-entrant locking on Main for this to work... */
/* BKE_main_lock(bmain); */
- wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C), false, false);
+ wm_link_do(lapp_data, op->reports, bmain, scene, sl, false, false);
/* BKE_main_unlock(bmain); */
@@ -445,8 +448,17 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
* link into other scenes from this blend file */
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
+ /* TODO(sergey): Use proper flag for tagging here. */
+
+ /* TODO (dalai): Temporary solution!
+ * Ideally we only need to tag the new objects themselves, not the scene. This way we'll avoid flush of
+ * collection properties to all objects and limit update to the particular object only.
+ * But afraid first we need to change collection evaluation in DEG according to depsgraph manifesto.
+ */
+ DEG_id_tag_update(&scene->id, 0);
+
/* recreate dependency graph to include new objects */
- DAG_scene_relations_rebuild(bmain, scene);
+ DEG_scene_relations_rebuild(bmain, scene);
/* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
GPU_materials_free();
@@ -471,8 +483,8 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
prop = RNA_def_boolean(ot->srna, "autoselect", true,
"Select", "Select new objects");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "active_layer", true,
- "Active Layer", "Put new objects on the active layer");
+ prop = RNA_def_boolean(ot->srna, "active_collection", true,
+ "Active Collection", "Put new objects on the active collection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "instance_groups", is_link,
"Instance Groups", "Create Dupli-Group instances for each group");
@@ -736,7 +748,7 @@ static void lib_relocate_do(
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
/* recreate dependency graph to include new objects */
- DAG_scene_relations_rebuild(bmain, scene);
+ DEG_scene_relations_rebuild(bmain, scene);
/* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
GPU_materials_free();
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 46203333eb5..92215757d88 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -45,15 +45,15 @@
#include "BKE_context.h"
-
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
#include "wm_subwindow.h"
#include "wm_draw.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "BIF_glutil.h"
@@ -168,69 +168,99 @@ int wm_gesture_evaluate(wmGesture *gesture)
/* ******************* gesture draw ******************* */
-static void wm_gesture_draw_rect(wmGesture *gt)
+static void wm_gesture_draw_line(wmGesture *gt)
{
rcti *rect = (rcti *)gt->customdata;
-
- glEnable(GL_BLEND);
- glColor4f(1.0, 1.0, 1.0, 0.05);
- glBegin(GL_QUADS);
- glVertex2s(rect->xmax, rect->ymin);
- glVertex2s(rect->xmax, rect->ymax);
- glVertex2s(rect->xmin, rect->ymax);
- glVertex2s(rect->xmin, rect->ymin);
- glEnd();
- glDisable(GL_BLEND);
-
- GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- glColor3ub(96, 96, 96);
- GPU_basic_shader_line_stipple(1, 0xCCCC);
- sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- glColor3ub(255, 255, 255);
- GPU_basic_shader_line_stipple(1, 0x3333);
- sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+
+ uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 8.0f);
+
+ float xmin = (float)rect->xmin;
+ float ymin = (float)rect->ymin;
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(shdr_pos, xmin, ymin);
+ immVertex2f(shdr_pos, (float)rect->xmax, (float)rect->ymax);
+ immEnd();
+
+ immUnbindProgram();
}
-static void wm_gesture_draw_line(wmGesture *gt)
+static void wm_gesture_draw_rect(wmGesture *gt)
{
rcti *rect = (rcti *)gt->customdata;
-
- GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
- glColor3ub(96, 96, 96);
- GPU_basic_shader_line_stipple(1, 0xAAAA);
- sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- glColor3ub(255, 255, 255);
- GPU_basic_shader_line_stipple(1, 0x5555);
- sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
-
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
+
+ uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
+
+ glEnable(GL_BLEND);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.05f);
+
+ immRecti(shdr_pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ immUnbindProgram();
+
+ glDisable(GL_BLEND);
+
+ shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 8.0f);
+
+ imm_draw_line_box(shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, (float)rect->ymax);
+
+ immUnbindProgram();
+
+ // wm_gesture_draw_line(gt); // draws a diagonal line in the lined box to test wm_gesture_draw_line
}
static void wm_gesture_draw_circle(wmGesture *gt)
{
rcti *rect = (rcti *)gt->customdata;
- glTranslatef((float)rect->xmin, (float)rect->ymin, 0.0f);
-
glEnable(GL_BLEND);
- glColor4f(1.0, 1.0, 1.0, 0.05);
- glutil_draw_filled_arc(0.0, M_PI * 2.0, rect->xmax, 40);
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.05f);
+ imm_draw_circle_fill(shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, 40);
+
+ immUnbindProgram();
+
glDisable(GL_BLEND);
-
- // for USE_GLSL works bad because of no relation between lines
- GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- glColor3ub(96, 96, 96);
- GPU_basic_shader_line_stipple(1, 0xAAAA);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, rect->xmax, 40);
- glColor3ub(255, 255, 255);
- GPU_basic_shader_line_stipple(1, 0x5555);
- glutil_draw_lined_arc(0.0, M_PI * 2.0, rect->xmax, 40);
-
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- glTranslatef(-rect->xmin, -rect->ymin, 0.0f);
-
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 4.0f);
+
+ imm_draw_circle_wire(shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, 40);
+
+ immUnbindProgram();
}
struct LassoFillData {
@@ -253,6 +283,7 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
int i;
rcti rect;
rcti rect_win;
+ float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
for (i = 0; i < tot; i++, lasso += 2) {
moves[i][0] = lasso[0];
@@ -278,28 +309,28 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
(const int (*)[2])moves, tot,
draw_filled_lasso_px_cb, &lasso_fill_data);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ /* Additive Blending */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
- glColor4f(1, 1, 1, 1);
- glPixelTransferf(GL_RED_BIAS, 1);
- glPixelTransferf(GL_GREEN_BIAS, 1);
- glPixelTransferf(GL_BLUE_BIAS, 1);
+ GLint unpack_alignment;
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment);
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glEnable(GL_BLEND);
- glaDrawPixelsTex(rect.xmin, rect.ymin, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, GL_NEAREST, pixel_buf);
- glDisable(GL_BLEND);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_bind(state.shader);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immDrawPixelsTex(&state, rect.xmin, rect.ymin, w, h, GL_RED, GL_UNSIGNED_BYTE, GL_NEAREST, pixel_buf, 1.0f, 1.0f, NULL);
- glPixelTransferf(GL_RED_BIAS, 0);
- glPixelTransferf(GL_GREEN_BIAS, 0);
- glPixelTransferf(GL_BLUE_BIAS, 0);
+ GPU_shader_unbind();
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment);
MEM_freeN(pixel_buf);
+
+ glDisable(GL_BLEND);
}
MEM_freeN(moves);
@@ -315,29 +346,34 @@ static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled)
draw_filled_lasso(win, gt);
}
- // for USE_GLSL can't check this yet
- GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- glColor3ub(96, 96, 96);
- GPU_basic_shader_line_stipple(1, 0xAAAA);
- glBegin(GL_LINE_STRIP);
- for (i = 0; i < gt->points; i++, lasso += 2)
- glVertex2sv(lasso);
- if (gt->type == WM_GESTURE_LASSO)
- glVertex2sv((short *)gt->customdata);
- glEnd();
-
- glColor3ub(255, 255, 255);
- GPU_basic_shader_line_stipple(1, 0x5555);
- glBegin(GL_LINE_STRIP);
- lasso = (short *)gt->customdata;
- for (i = 0; i < gt->points; i++, lasso += 2)
- glVertex2sv(lasso);
- if (gt->type == WM_GESTURE_LASSO)
- glVertex2sv((short *)gt->customdata);
- glEnd();
-
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
+ const int numverts = gt->points;
+
+ /* Nothing to draw, do early output. */
+ if (numverts < 2) {
+ return;
+ }
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 2.0f);
+
+ immBegin((gt->type == WM_GESTURE_LASSO) ? PRIM_LINE_LOOP : PRIM_LINE_STRIP, numverts);
+
+ for (i = 0; i < gt->points; i++, lasso += 2) {
+ immVertex2f(shdr_pos, (float)lasso[0], (float)lasso[1]);
+ }
+
+ immEnd();
+
+ immUnbindProgram();
}
static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
@@ -346,25 +382,49 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
const int winsize_x = WM_window_pixels_x(win);
const int winsize_y = WM_window_pixels_y(win);
- GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- glColor3ub(96, 96, 96);
- GPU_basic_shader_line_stipple(1, 0xCCCC);
- sdrawline(rect->xmin - winsize_x, rect->ymin, rect->xmin + winsize_x, rect->ymin);
- sdrawline(rect->xmin, rect->ymin - winsize_y, rect->xmin, rect->ymin + winsize_y);
-
- glColor3ub(255, 255, 255);
- GPU_basic_shader_line_stipple(1, 0x3333);
- sdrawline(rect->xmin - winsize_x, rect->ymin, rect->xmin + winsize_x, rect->ymin);
- sdrawline(rect->xmin, rect->ymin - winsize_y, rect->xmin, rect->ymin + winsize_y);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ float x1, x2, y1, y2;
+
+ const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniform1i("num_colors", 2); /* "advanced" mode */
+ immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", 8.0f);
+
+ immBegin(PRIM_LINES, 4);
+
+ x1 = (float)(rect->xmin - winsize_x);
+ y1 = (float)rect->ymin;
+ x2 = (float)(rect->xmin + winsize_x);
+ y2 = y1;
+
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
+
+ x1 = (float)rect->xmin;
+ y1 = (float)(rect->ymin - winsize_y);
+ x2 = x1;
+ y2 = (float)(rect->ymin + winsize_y);
+
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
+
+ immEnd();
+
+ immUnbindProgram();
}
/* called in wm_draw.c */
void wm_gesture_draw(wmWindow *win)
{
wmGesture *gt = (wmGesture *)win->gesture.first;
-
- GPU_basic_shader_line_width(1);
+
+ glLineWidth(1.0f);
for (; gt; gt = gt->next) {
/* all in subwindow space */
wmSubWindowSet(win, gt->swinid);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 9bafe72d805..ce4a65b854a 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -119,10 +119,11 @@
#include "GPU_draw.h"
#include "GPU_init_exit.h"
-#include "BKE_depsgraph.h"
#include "BKE_sound.h"
#include "COM_compositor.h"
+#include "DEG_depsgraph.h"
+
#ifdef WITH_OPENSUBDIV
# include "BKE_subsurf.h"
#endif
@@ -169,12 +170,13 @@ void WM_init(bContext *C, int argc, const char **argv)
BKE_library_callback_free_window_manager_set(wm_close_and_free); /* library.c */
BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference); /* library.c */
+ BKE_region_callback_free_manipulatormap_set(wm_manipulatormap_delete); /* screen.c */
BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference); /* library.c */
BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */
BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */
- DAG_editors_update_cb(ED_render_id_flush_update,
- ED_render_scene_update,
- ED_render_scene_update_pre); /* depsgraph.c */
+ DEG_editors_set_update_cb(ED_render_id_flush_update,
+ ED_render_scene_update,
+ ED_render_scene_update_pre);
ED_spacetypes_init(); /* editors/space_api/spacetype.c */
@@ -527,6 +529,9 @@ void WM_exit_ext(bContext *C, const bool do_python)
ED_gpencil_strokes_copybuf_free();
BKE_node_clipboard_clear();
+ /* free manipulator-maps after freeing blender, so no deleted data get accessed during cleaning up of areas */
+ wm_manipulatormaptypes_free();
+
BLF_exit();
#ifdef WITH_INTERNATIONAL
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index d3ebd3e4d2c..00fc75eb282 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -70,7 +70,6 @@
#include "BKE_blender_version.h"
#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
@@ -86,9 +85,12 @@
#include "BKE_idcode.h"
-#include "BIF_glutil.h" /* for paint cursor */
#include "BLF_api.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -97,8 +99,6 @@
#include "ED_util.h"
#include "ED_view3d.h"
-#include "GPU_basic_shader.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -175,6 +175,10 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
ot->name = N_("Dummy Name");
}
+ if (ot->mgrouptype) {
+ ot->mgrouptype->flag |= WM_MANIPULATORGROUPTYPE_OP;
+ }
+
/* XXX All ops should have a description but for now allow them not to. */
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
RNA_def_struct_identifier(ot->srna, ot->idname);
@@ -491,6 +495,9 @@ void WM_operatortype_remove_ptr(wmOperatorType *ot)
BLI_ghash_remove(global_ops_hash, ot->idname, NULL, NULL);
WM_keyconfig_update_operatortype();
+ if (ot->mgrouptype) {
+ WM_manipulatorgrouptype_unregister(NULL, G.main, ot->mgrouptype);
+ }
MEM_freeN(ot);
}
@@ -1104,46 +1111,70 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_REGION_WIN);
}
+struct EnumSearchMenu {
+ wmOperator *op; /* the operator that will be executed when selecting an item */
+
+ bool use_previews;
+ short prv_cols, prv_rows;
+};
/* generic enum search invoke popup */
-static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
+static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg)
{
- static char search[256] = "";
- wmEvent event;
+ struct EnumSearchMenu *search_menu = arg;
wmWindow *win = CTX_wm_window(C);
+ wmOperator *op = search_menu->op;
+ /* template_ID uses 4 * widget_unit for width, we use a bit more, some items may have a suffix to show */
+ const int width = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_cols : UI_searchbox_size_x();
+ const int height = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_rows : UI_searchbox_size_y();
+ static char search[256] = "";
uiBlock *block;
uiBut *but;
- wmOperator *op = (wmOperator *)arg_op;
block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
search[0] = '\0';
+ BLI_assert(search_menu->use_previews || (search_menu->prv_cols == 0 && search_menu->prv_rows == 0));
#if 0 /* ok, this isn't so easy... */
uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
#endif
but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
- 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, "");
+ 10, 10, width, UI_UNIT_Y, search_menu->prv_rows, search_menu->prv_cols, "");
/* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), width, height, NULL, 0, 0, 0, 0, NULL);
UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
-
- wm_event_init_from_window(win, &event);
- event.type = EVT_BUT_OPEN;
- event.val = KM_PRESS;
- event.customdata = but;
- event.customdatafree = false;
- wm_event_add(win, &event);
+ UI_but_focus_on_enter_event(win, but);
return block;
}
+/**
+ * Similar to #WM_enum_search_invoke, but draws previews. Also, this can't
+ * be used as invoke callback directly since it needs additional info.
+ */
+int WM_enum_search_invoke_previews(
+ bContext *C, wmOperator *op, short prv_cols, short prv_rows)
+{
+ static struct EnumSearchMenu search_menu;
+
+ search_menu.op = op;
+ search_menu.use_previews = true;
+ search_menu.prv_cols = prv_cols;
+ search_menu.prv_rows = prv_rows;
+
+ UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
+
+ return OPERATOR_INTERFACE;
+}
int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- UI_popup_block_invoke(C, wm_enum_search_menu, op);
+ static struct EnumSearchMenu search_menu;
+ search_menu.op = op;
+ UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
return OPERATOR_INTERFACE;
}
@@ -2088,14 +2119,22 @@ static void WM_OT_window_close(wmOperatorType *ot)
ot->poll = WM_operator_winactive;
}
-static void WM_OT_window_duplicate(wmOperatorType *ot)
+static void WM_OT_window_new(wmOperatorType *ot)
{
- ot->name = "Duplicate Window";
- ot->idname = "WM_OT_window_duplicate";
- ot->description = "Duplicate the current Blender window";
-
- ot->exec = wm_window_duplicate_exec;
+ PropertyRNA *prop;
+
+ ot->name = "New Window";
+ ot->idname = "WM_OT_window_new";
+ ot->description = "Create a new Blender window";
+
+ ot->exec = wm_window_new_exec;
+ ot->invoke = wm_window_new_invoke;
ot->poll = wm_operator_winactive_normal;
+
+ prop = RNA_def_enum(ot->srna, "screen", DummyRNA_NULL_items, 0, "Screen", "");
+ RNA_def_enum_funcs(prop, wm_window_new_screen_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
@@ -2998,8 +3037,8 @@ static void radial_control_set_tex(RadialControl *rc)
if ((ibuf = BKE_brush_gen_radial_control_imbuf(rc->image_id_ptr.data, rc->use_secondary_tex))) {
glGenTextures(1, &rc->gltex);
glBindTexture(GL_TEXTURE_2D, rc->gltex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, ibuf->x, ibuf->y, 0,
- GL_ALPHA, GL_FLOAT, ibuf->rect_float);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, ibuf->x, ibuf->y, 0,
+ GL_RED, GL_FLOAT, ibuf->rect_float);
MEM_freeN(ibuf->rect_float);
MEM_freeN(ibuf);
}
@@ -3032,43 +3071,63 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
RNA_property_float_get_array(fill_ptr, fill_prop, col);
}
- glColor4f(col[0], col[1], col[2], alpha);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
if (rc->gltex) {
+
+ unsigned int texCoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+
glBindTexture(GL_TEXTURE_2D, rc->gltex);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ GLint swizzleMask[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR);
+
+ immUniformColor3fvAlpha(col, alpha);
+ immUniform1i("image", GL_TEXTURE0);
/* set up rotation if available */
if (rc->rot_prop) {
rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop);
- glPushMatrix();
- glRotatef(RAD2DEGF(rot), 0, 0, 1);
+ gpuPushMatrix();
+ gpuRotate2D(RAD2DEGF(rot));
}
/* draw textured quad */
- GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(-radius, -radius);
- glTexCoord2f(1, 0);
- glVertex2f(radius, -radius);
- glTexCoord2f(1, 1);
- glVertex2f(radius, radius);
- glTexCoord2f(0, 1);
- glVertex2f(-radius, radius);
- glEnd();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+
+ immAttrib2f(texCoord, 0, 0);
+ immVertex2f(pos, -radius, -radius);
+
+ immAttrib2f(texCoord, 1, 0);
+ immVertex2f(pos, radius, -radius);
+
+ immAttrib2f(texCoord, 1, 1);
+ immVertex2f(pos, radius, radius);
+
+ immAttrib2f(texCoord, 0, 1);
+ immVertex2f(pos, -radius, radius);
+
+ immEnd();
/* undo rotation */
if (rc->rot_prop)
- glPopMatrix();
+ gpuPopMatrix();
}
else {
/* flat color if no texture available */
- glutil_draw_filled_arc(0, M_PI * 2, radius, 40);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fvAlpha(col, alpha);
+ imm_draw_circle_fill(pos, 0.0f, 0.0f, radius, 40);
}
+
+ immUnbindProgram();
}
static void radial_control_paint_cursor(bContext *C, int x, int y, void *customdata)
@@ -3127,7 +3186,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
/* Keep cursor in the original place */
x = rc->initial_mouse[0] - ar->winrct.xmin;
y = rc->initial_mouse[1] - ar->winrct.ymin;
- glTranslatef((float)x, (float)y, 0.0f);
+ gpuTranslate2f((float)x, (float)y);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
@@ -3135,7 +3194,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
/* apply zoom if available */
if (rc->zoom_prop) {
RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
- glScalef(zoom[0], zoom[1], 1);
+ gpuScale2fv(zoom);
}
/* draw rotated texture */
@@ -3144,24 +3203,39 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
/* set line color */
if (rc->col_prop)
RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col);
- glColor4f(col[0], col[1], col[2], 0.5);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fvAlpha(col, 0.5f);
if (rc->subtype == PROP_ANGLE) {
- glPushMatrix();
+ gpuPushMatrix();
+
/* draw original angle line */
- glRotatef(RAD2DEGF(rc->initial_value), 0, 0, 1);
- fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
+ gpuRotate2D(RAD2DEGF(rc->initial_value));
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f);
+ immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
+ immEnd();
+
/* draw new angle line */
- glRotatef(RAD2DEGF(rc->current_value - rc->initial_value), 0, 0, 1);
- fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
- glPopMatrix();
+ gpuRotate2D(RAD2DEGF(rc->current_value - rc->initial_value));
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f);
+ immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
+ immEnd();
+
+ gpuPopMatrix();
}
/* draw circles on top */
- glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r1, 40);
- glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r2, 40);
+ imm_draw_circle_wire(pos, 0.0f, 0.0f, r1, 40);
+ imm_draw_circle_wire(pos, 0.0f, 0.0f, r2, 40);
if (rmin > 0.0f)
- glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), rmin, 40);
+ imm_draw_circle_wire(pos, 0.0, 0.0f, rmin, 40);
+ immUnbindProgram();
BLF_size(fontid, 1.5 * fstyle_points * U.pixelsize, U.dpi);
BLF_enable(fontid, BLF_SHADOW);
@@ -3177,6 +3251,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
+
}
typedef enum {
@@ -3782,7 +3857,7 @@ static void redraw_timer_step(
}
else if (type == eRTAnimationStep) {
scene->r.cfra += (cfra == scene->r.cfra) ? 1 : -1;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
}
else if (type == eRTAnimationPlay) {
/* play anim, return on same frame as started with */
@@ -3794,7 +3869,7 @@ static void redraw_timer_step(
if (scene->r.cfra > scene->r.efra)
scene->r.cfra = scene->r.sfra;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
redraw_timer_window_swap(C);
}
}
@@ -3882,28 +3957,6 @@ static void WM_OT_memory_statistics(wmOperatorType *ot)
ot->exec = memory_statistics_exec;
}
-/* ************************** memory statistics for testing ***************** */
-
-static int dependency_relations_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
-
- DAG_print_dependencies(bmain, scene, ob);
-
- return OPERATOR_FINISHED;
-}
-
-static void WM_OT_dependency_relations(wmOperatorType *ot)
-{
- ot->name = "Dependency Relations";
- ot->idname = "WM_OT_dependency_relations";
- ot->description = "Print dependency graph relations to the console";
-
- ot->exec = dependency_relations_exec;
-}
-
/* *************************** Mat/tex/etc. previews generation ************* */
typedef struct PreviewsIDEnsureData {
@@ -4150,7 +4203,7 @@ void wm_operatortype_init(void)
global_ops_hash = BLI_ghash_str_new_ex("wm_operatortype_init gh", 2048);
WM_operatortype_append(WM_OT_window_close);
- WM_operatortype_append(WM_OT_window_duplicate);
+ WM_operatortype_append(WM_OT_window_new);
WM_operatortype_append(WM_OT_read_history);
WM_operatortype_append(WM_OT_read_homefile);
WM_operatortype_append(WM_OT_read_factory_settings);
@@ -4172,7 +4225,6 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_save_mainfile);
WM_operatortype_append(WM_OT_redraw_timer);
WM_operatortype_append(WM_OT_memory_statistics);
- WM_operatortype_append(WM_OT_dependency_relations);
WM_operatortype_append(WM_OT_debug_menu);
WM_operatortype_append(WM_OT_operator_defaults);
WM_operatortype_append(WM_OT_splash);
@@ -4187,6 +4239,10 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_previews_ensure);
WM_operatortype_append(WM_OT_previews_clear);
WM_operatortype_append(WM_OT_doc_view_manual_ui_context);
+
+ /* manipulators */
+ WM_operatortype_append(MANIPULATORGROUP_OT_manipulator_select);
+ WM_operatortype_append(MANIPULATORGROUP_OT_manipulator_tweak);
}
/* circleselect-like modal operators */
@@ -4388,7 +4444,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
wmKeyMapItem *kmi;
/* note, this doesn't replace existing keymap items */
- WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "WM_OT_window_new", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
#ifdef __APPLE__
WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_menu(keymap, "INFO_MT_file_open_recent", OKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
@@ -4492,6 +4548,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
RNA_float_set(kmi->ptr, "value", 1.0f / 1.5f);
#endif /* WITH_INPUT_NDOF */
+ wm_manipulators_keymap(keyconf);
gesture_circle_modal_keymap(keyconf);
gesture_border_modal_keymap(keyconf);
gesture_zoom_border_modal_keymap(keyconf);
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 6bf7bcc2934..434c6414c01 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -58,17 +58,22 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "BKE_depsgraph.h"
#include "BKE_image.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_matrix.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
#include "DNA_scene_types.h"
#include "ED_datafiles.h" /* for fonts */
#include "GHOST_C-api.h"
#include "BLF_api.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h" /* only for WM_main_playanim */
#ifdef WITH_AUDASPACE
@@ -190,10 +195,7 @@ static void playanim_window_get_size(int *r_width, int *r_height)
static void playanim_gl_matrix(void)
{
/* unified matrix, note it affects offset for drawing */
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
+ gpuOrtho2D(0.0f, 1.0f, 0.0f, 1.0f);
}
/* implementation */
@@ -308,42 +310,45 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
CLAMP(offs_x, 0.0f, 1.0f);
CLAMP(offs_y, 0.0f, 1.0f);
- glRasterPos2f(offs_x, offs_y);
glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
-
+
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- fdrawcheckerboard(offs_x, offs_y, offs_x + span_x, offs_y + span_y);
+ imm_draw_checker_box(offs_x, offs_y, offs_x + span_x, offs_y + span_y);
}
- glRasterPos2f(offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
- offs_y + (ps->draw_flip[1] ? span_y : 0.0f));
-
- glPixelZoom(ps->zoom * (ps->draw_flip[0] ? -1.0f : 1.0f),
- ps->zoom * (ps->draw_flip[1] ? -1.0f : 1.0f));
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ immDrawPixelsTex(
+ &state,
+ offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
+ offs_y + (ps->draw_flip[1] ? span_y : 0.0f),
+ ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST,
+ ibuf->rect,
+ ((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x),
+ ((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y),
+ NULL);
glDisable(GL_BLEND);
-
+
pupdate_time();
if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) {
int sizex, sizey;
float fsizex_inv, fsizey_inv;
char str[32 + FILE_MAX];
- cpack(-1);
BLI_snprintf(str, sizeof(str), "%s | %.2f frames/s", picture->name, fstep / swaptime);
playanim_window_get_size(&sizex, &sizey);
fsizex_inv = 1.0f / sizex;
fsizey_inv = 1.0f / sizey;
+ BLF_color4f(fontid, 1.0, 1.0, 1.0, 1.0);
BLF_enable(fontid, BLF_ASPECT);
BLF_aspect(fontid, fsizex_inv, fsizey_inv, 1.0f);
BLF_position(fontid, 10.0f * fsizex_inv, 10.0f * fsizey_inv, 0.0f);
@@ -354,24 +359,25 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
float fac = ps->picture->frame / (double)(((PlayAnimPict *)picsbase.last)->frame - ((PlayAnimPict *)picsbase.first)->frame);
fac = 2.0f * fac - 1.0f;
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
-
- glBegin(GL_LINES);
- glVertex2f(fac, -1.0f);
- glVertex2f(fac, 1.0f);
- glEnd();
-
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
+ gpuPushProjectionMatrix();
+ gpuLoadIdentityProjectionMatrix();
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ub(0, 255, 0);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, fac, -1.0f);
+ immVertex2f(pos, fac, 1.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
+ gpuPopProjectionMatrix();
}
GHOST_SwapWindowBuffers(g_WS.ghost_window);
@@ -1255,6 +1261,9 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
//GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
+ /* initialize OpenGL immediate mode */
+ immInit();
+
/* initialize the font */
BLF_init(11, 72);
ps.fontid = BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
@@ -1525,7 +1534,11 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
#endif
/* we still miss freeing a lot!,
* but many areas could skip initialization too for anim play */
-
+
+ GPU_shader_free_builtin_shaders();
+
+ immDestroy();
+
BLF_exit();
GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);
@@ -1538,7 +1551,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
IMB_exit();
BKE_images_exit();
- DAG_exit();
+ DEG_free_node_types();
totblock = MEM_get_memory_blocks_in_use();
if (totblock != 0) {
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 66ebf18c9e1..94e4e85026f 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -52,8 +52,7 @@
#include "ED_screen.h"
-#include "GPU_glew.h"
-#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -77,54 +76,82 @@ static void wm_method_draw_stereo3d_pageflip(wmWindow *win)
else //STEREO_RIGHT_ID
glDrawBuffer(GL_BACK_RIGHT);
- wm_triple_draw_textures(win, drawdata->triple, 1.0f, false);
+ wm_triple_draw_textures(win, drawdata->triple, 1.0f);
}
glDrawBuffer(GL_BACK);
}
-static enum eStereo3dInterlaceType interlace_prev_type = -1;
-static char interlace_prev_swap = -1;
+static GPUInterlaceShader interlace_gpu_id_from_type(eStereo3dInterlaceType interlace_type)
+{
+ switch (interlace_type) {
+ case S3D_INTERLACE_ROW:
+ return GPU_SHADER_INTERLACE_ROW;
+ case S3D_INTERLACE_COLUMN:
+ return GPU_SHADER_INTERLACE_COLUMN;
+ case S3D_INTERLACE_CHECKERBOARD:
+ default:
+ return GPU_SHADER_INTERLACE_CHECKER;
+ }
+}
static void wm_method_draw_stereo3d_interlace(wmWindow *win)
{
- wmDrawData *drawdata;
- int view;
- bool flag;
bool swap = (win->stereo3d_format->flag & S3D_INTERLACE_SWAP) != 0;
enum eStereo3dInterlaceType interlace_type = win->stereo3d_format->interlace_type;
- for (view = 0; view < 2; view ++) {
- flag = swap ? !view : view;
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE);
- switch (interlace_type) {
- case S3D_INTERLACE_ROW:
- if (flag)
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW_SWAP);
- else
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW);
- break;
- case S3D_INTERLACE_COLUMN:
- if (flag)
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN_SWAP);
- else
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN);
- break;
- case S3D_INTERLACE_CHECKERBOARD:
- default:
- if (flag)
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER_SWAP);
- else
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER);
- break;
- }
+ wmDrawData *drawdata[2];
+ for (int eye = 0; eye < 2; eye++) {
+ int view = swap ? !eye : eye;
+ drawdata[eye] = BLI_findlink(&win->drawdata, (view * 2) + 1);
+ }
+
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
+
+ /* wmOrtho for the screen has this same offset */
+ float ratiox = sizex;
+ float ratioy = sizey;
+ float halfx = GLA_PIXEL_OFS;
+ float halfy = GLA_PIXEL_OFS;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_INTERLACE);
+
+ /* leave GL_TEXTURE0 as the latest bind texture */
+ for (int eye = 1; eye >= 0; eye--) {
+ glActiveTexture(GL_TEXTURE0 + eye);
+ glBindTexture(drawdata[eye]->triple->target, drawdata[eye]->triple->bind);
+ }
- wm_triple_draw_textures(win, drawdata->triple, 1.0f, true);
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ immUniform1i("image_a", 0);
+ immUniform1i("image_b", 1);
+
+ immUniform1i("interlace_id", interlace_gpu_id_from_type(interlace_type));
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ immAttrib2f(texcoord, ratiox + halfx, halfy);
+ immVertex2f(pos, sizex, 0.0f);
+
+ immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
+ immVertex2f(pos, sizex, sizey);
+
+ immAttrib2f(texcoord, halfx, ratioy + halfy);
+ immVertex2f(pos, 0.0f, sizey);
+
+ immEnd();
+ immUnbindProgram();
+
+ for (int eye = 0; eye < 2; eye++) {
+ glBindTexture(drawdata[eye]->triple->target, 0);
}
- interlace_prev_type = interlace_type;
- interlace_prev_swap = swap;
}
static void wm_method_draw_stereo3d_anaglyph(wmWindow *win)
@@ -157,7 +184,7 @@ static void wm_method_draw_stereo3d_anaglyph(wmWindow *win)
break;
}
- wm_triple_draw_textures(win, drawdata->triple, 1.0f, false);
+ wm_triple_draw_textures(win, drawdata->triple, 1.0f);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
@@ -172,6 +199,10 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
int soffx;
bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0;
+ VertexFormat *format = immVertexFormat();
+ unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
for (view = 0; view < 2; view ++) {
drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
triple = drawdata->triple;
@@ -203,26 +234,33 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
halfy /= triple->y;
}
- glEnable(triple->target);
+ /* TODO: if target is always same for both eyes, bind program & set uniform before loop */
+ immBindBuiltinProgram((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_3D_IMAGE_MODULATE_ALPHA : GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA);
+
glBindTexture(triple->target, triple->bind);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBegin(GL_QUADS);
- glTexCoord2f(halfx, halfy);
- glVertex2f(soffx, 0);
+ immUniform1f("alpha", 1.0f);
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, soffx, 0.0f);
- glTexCoord2f(ratiox + halfx, halfy);
- glVertex2f(soffx + (sizex * 0.5f), 0);
+ immAttrib2f(texcoord, ratiox + halfx, halfy);
+ immVertex2f(pos, soffx + (sizex * 0.5f), 0.0f);
- glTexCoord2f(ratiox + halfx, ratioy + halfy);
- glVertex2f(soffx + (sizex * 0.5f), sizey);
+ immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
+ immVertex2f(pos, soffx + (sizex * 0.5f), sizey);
- glTexCoord2f(halfx, ratioy + halfy);
- glVertex2f(soffx, sizey);
- glEnd();
+ immAttrib2f(texcoord, halfx, ratioy + halfy);
+ immVertex2f(pos, soffx, sizey);
+ immEnd();
+
+ /* TODO: if target is always same for both eyes, unbind program & texture target after loop */
glBindTexture(triple->target, 0);
- glDisable(triple->target);
+ immUnbindProgram();
}
}
@@ -234,6 +272,10 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
int view;
int soffy;
+ VertexFormat *format = immVertexFormat();
+ unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
for (view = 0; view < 2; view ++) {
drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
triple = drawdata->triple;
@@ -262,26 +304,33 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
halfy /= triple->y;
}
- glEnable(triple->target);
+ /* TODO: if target is always same for both eyes, bind program & set uniforms before loop */
+ immBindBuiltinProgram((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_3D_IMAGE_MODULATE_ALPHA : GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA);
+
glBindTexture(triple->target, triple->bind);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBegin(GL_QUADS);
- glTexCoord2f(halfx, halfy);
- glVertex2f(0, soffy);
+ immUniform1f("alpha", 1.0f);
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+
+ immBegin(PRIM_TRIANGLE_FAN, 4);
+
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, 0.0f, soffy);
+
+ immAttrib2f(texcoord, ratiox + halfx, halfy);
+ immVertex2f(pos, sizex, soffy);
- glTexCoord2f(ratiox + halfx, halfy);
- glVertex2f(sizex, soffy);
+ immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
+ immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
- glTexCoord2f(ratiox + halfx, ratioy + halfy);
- glVertex2f(sizex, soffy + (sizey * 0.5f));
+ immAttrib2f(texcoord, halfx, ratioy + halfy);
+ immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
- glTexCoord2f(halfx, ratioy + halfy);
- glVertex2f(0, soffy + (sizey * 0.5f));
- glEnd();
+ immEnd();
+ /* TODO: if target is always same for both eyes, unbind program & texture target after loop */
+ immUnbindProgram();
glBindTexture(triple->target, 0);
- glDisable(triple->target);
}
}
@@ -310,9 +359,9 @@ void wm_method_draw_stereo3d(const bContext *UNUSED(C), wmWindow *win)
static bool wm_stereo3d_quadbuffer_supported(void)
{
- int gl_stereo = 0;
- glGetBooleanv(GL_STEREO, (GLboolean *)&gl_stereo);
- return gl_stereo != 0;
+ GLboolean stereo = GL_FALSE;
+ glGetBooleanv(GL_STEREO, &stereo);
+ return stereo == GL_TRUE;
}
static bool wm_stereo3d_is_fullscreen_required(eStereoDisplayMode stereo_display)
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 458ac4a121a..7613479aacd 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -47,8 +47,7 @@
#include "BIF_gl.h"
-#include "GPU_extensions.h"
-#include "GPU_basic_shader.h"
+#include "GPU_matrix.h"
#include "WM_api.h"
#include "wm_subwindow.h"
@@ -150,7 +149,7 @@ static void wm_swin_matrix_get(wmWindow *win, wmSubWindow *swin, float mat[4][4]
orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100);
}
else {
- glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat);
+ gpuGetProjectionMatrix(mat);
}
}
void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4])
@@ -216,7 +215,7 @@ int wm_subwindow_open(wmWindow *win, const rcti *winrct, bool activate)
/* extra service */
wm_swin_size_get(swin, &width, &height);
wmOrtho2_pixelspace(width, height);
- glLoadIdentity();
+ gpuLoadIdentity();
}
return swin->swinid;
@@ -322,7 +321,7 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, const rcti *srct, bool src
glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
wmOrtho2_pixelspace(width, height);
- glLoadIdentity();
+ gpuLoadIdentity();
glFlush();
}
@@ -333,31 +332,13 @@ void wmSubWindowSet(wmWindow *win, int swinid)
wmSubWindowScissorSet(win, swinid, NULL, true);
}
-void wmFrustum(float x1, float x2, float y1, float y2, float n, float f)
-{
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(x1, x2, y1, y2, n, f);
- glMatrixMode(GL_MODELVIEW);
-}
-
-void wmOrtho(float x1, float x2, float y1, float y2, float n, float f)
-{
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glOrtho(x1, x2, y1, y2, n, f);
-
- glMatrixMode(GL_MODELVIEW);
-}
-
void wmOrtho2(float x1, float x2, float y1, float y2)
{
/* prevent opengl from generating errors */
if (x1 == x2) x2 += 1.0f;
if (y1 == y2) y2 += 1.0f;
- wmOrtho(x1, x2, y1, y2, -100, 100);
+ gpuOrtho(x1, x2, y1, y2, -100, 100);
}
static void wmOrtho2_offset(const float x, const float y, const float ofs)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index de169881bc4..3ff323862b3 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -51,12 +51,14 @@
#include "BKE_blender.h"
#include "BKE_context.h"
+#include "BKE_icons.h"
#include "BKE_library.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -70,15 +72,18 @@
#include "ED_fileselect.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "PIL_time.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_init_exit.h"
-#include "GPU_glew.h"
+#include "GPU_immediate.h"
#include "BLF_api.h"
+#include "UI_resources.h"
+
/* for assert */
#ifndef NDEBUG
# include "BLI_threads.h"
@@ -244,6 +249,25 @@ wmWindow *wm_window_new(bContext *C)
return win;
}
+/**
+ * A higher level version of copy that tests the new window can be added.
+ */
+static wmWindow *wm_window_new_test(bContext *C)
+{
+ wmWindow *win = wm_window_new(C);
+
+ WM_check(C);
+
+ if (win->ghostwin) {
+ WM_event_add_notifier(C, NC_WINDOW | NA_ADDED, NULL);
+ return win;
+ }
+ else {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wm_window_close(C, wm, win);
+ return NULL;
+ }
+}
/* part of wm_window.c api */
wmWindow *wm_window_copy(bContext *C, wmWindow *win_src)
@@ -757,17 +781,79 @@ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-/* operator callback */
-int wm_window_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
+/* new window operator callback */
+int wm_window_new_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win_src = CTX_wm_window(C);
- bool ok;
+ const int screen_id = RNA_enum_get(op->ptr, "screen");
+ bScreen *screen = BLI_findlink(&bmain->screen, screen_id);
+ wmWindow *win_dst;
- ok = (wm_window_copy_test(C, win_src) != NULL);
+ if (screen->winid) {
+ /* Screen is already used, duplicate window and screen */
+ win_dst = wm_window_copy_test(C, win_src);
+ }
+ else if ((win_dst = wm_window_new_test(C))) {
+ /* New window with a different screen */
+ win_dst->screen = screen;
+ screen->winid = win_dst->winid;
+ CTX_wm_window_set(C, win_dst);
+ ED_screen_refresh(CTX_wm_manager(C), win_dst);
+ }
- return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return (win_dst != NULL) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+int wm_window_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Main *bmain = CTX_data_main(C);
+
+ if (BLI_listbase_count_ex(&bmain->screen, 2) == 1) {
+ RNA_enum_set(op->ptr, "screen", 0);
+ return wm_window_new_exec(C, op);
+ }
+ else {
+ return WM_enum_search_invoke_previews(C, op, 6, 2);
+ }
+}
+
+struct EnumPropertyItem *wm_window_new_screen_itemf(
+ bContext *C, struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ Main *bmain = CTX_data_main(C);
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ int value = 0, totitem = 0;
+ int count_act_screens = 0;
+ /* XXX setting max number of windows to 20. We'd need support
+ * for dynamic strings in EnumPropertyItem.name to avoid this. */
+ static char active_screens[20][MAX_NAME + 12];
+
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ if (screen->winid) {
+ BLI_snprintf(active_screens[count_act_screens], sizeof(*active_screens), "%s (Duplicate)",
+ screen->id.name + 2);
+ tmp.name = active_screens[count_act_screens++];
+ }
+ else {
+ tmp.name = screen->id.name + 2;
+ }
+
+ tmp.value = value;
+ tmp.identifier = screen->id.name;
+ UI_id_icon_render(C, CTX_data_scene(C), &screen->id, true, false);
+ tmp.icon = BKE_icon_id_ensure(&screen->id);
+
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ value++;
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
/* fullscreen operator callback */
int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
@@ -867,8 +953,11 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
if (G.debug & G_DEBUG_EVENTS) {
printf("%s: set drawable %d\n", __func__, win->winid);
}
+
+ immDeactivate();
GHOST_ActivateWindowDrawingContext(win->ghostwin);
-
+ immActivate();
+
/* this can change per window */
wm_window_set_dpi(win);
}
@@ -1138,6 +1227,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
wm_window_make_drawable(wm, win);
wm_draw_window_clear(win);
+ BKE_icon_changed(win->screen->id.icon_id);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
@@ -1250,6 +1340,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
wm_window_set_dpi(win);
if (U.pixelsize != prev_pixelsize) {
+ BKE_icon_changed(win->screen->id.icon_id);
+
// close all popups since they are positioned with the pixel
// size baked in and it's difficult to correct them
wmWindow *oldWindow = CTX_wm_window(C);
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
new file mode 100644
index 00000000000..c2d194c7c03
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
@@ -0,0 +1,113 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/WM_manipulator_api.h
+ * \ingroup wm
+ *
+ * \name Manipulator API
+ * \brief API for external use of wmManipulator types.
+ *
+ * Only included in WM_api.h
+ */
+
+
+#ifndef __WM_MANIPULATOR_API_H__
+#define __WM_MANIPULATOR_API_H__
+
+struct ARegion;
+struct Main;
+struct wmKeyConfig;
+struct wmManipulatorGroupType;
+struct wmManipulatorMap;
+struct wmManipulatorMapType;
+struct wmManipulatorMapType_Params;
+
+/* -------------------------------------------------------------------- */
+/* wmManipulator */
+
+struct wmManipulator *WM_manipulator_new(
+ void (*draw)(const struct bContext *, struct wmManipulator *),
+ void (*render_3d_intersection)(const struct bContext *, struct wmManipulator *, int),
+ int (*intersect)(struct bContext *, const struct wmEvent *, struct wmManipulator *),
+ int (*handler)(struct bContext *, const struct wmEvent *, struct wmManipulator *, const int));
+void WM_manipulator_delete(
+ ListBase *manipulatorlist, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator,
+ struct bContext *C);
+
+void WM_manipulator_set_property(struct wmManipulator *, int slot, struct PointerRNA *ptr, const char *propname);
+struct PointerRNA *WM_manipulator_set_operator(struct wmManipulator *, const char *opname);
+void WM_manipulator_set_custom_handler(
+ struct wmManipulator *manipulator,
+ int (*handler)(struct bContext *, const struct wmEvent *, struct wmManipulator *, const int));
+void WM_manipulator_set_func_select(
+ struct wmManipulator *manipulator,
+ void (*select)(struct bContext *, struct wmManipulator *, const int action)); /* wmManipulatorSelectFunc */
+void WM_manipulator_set_origin(struct wmManipulator *manipulator, const float origin[3]);
+void WM_manipulator_set_offset(struct wmManipulator *manipulator, const float offset[3]);
+void WM_manipulator_set_flag(struct wmManipulator *manipulator, const int flag, const bool enable);
+void WM_manipulator_set_scale(struct wmManipulator *manipulator, float scale);
+void WM_manipulator_set_line_width(struct wmManipulator *manipulator, const float line_width);
+void WM_manipulator_set_colors(struct wmManipulator *manipulator, const float col[4], const float col_hi[4]);
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorGroup */
+
+struct wmManipulatorGroupType *WM_manipulatorgrouptype_append(
+ struct wmManipulatorMapType *mmaptype,
+ void (*mgrouptype_func)(struct wmManipulatorGroupType *));
+struct wmManipulatorGroupType *WM_manipulatorgrouptype_append_runtime(
+ const struct Main *main, struct wmManipulatorMapType *mmaptype,
+ void (*mgrouptype_func)(struct wmManipulatorGroupType *));
+void WM_manipulatorgrouptype_init_runtime(
+ const struct Main *bmain, struct wmManipulatorMapType *mmaptype,
+ struct wmManipulatorGroupType *mgrouptype);
+void WM_manipulatorgrouptype_unregister(
+ struct bContext *C, struct Main *bmain, struct wmManipulatorGroupType *mgroup);
+
+struct wmKeyMap *WM_manipulatorgroup_keymap_common(
+ const struct wmManipulatorGroupType *mgrouptype, struct wmKeyConfig *config);
+struct wmKeyMap *WM_manipulatorgroup_keymap_common_sel(
+ const struct wmManipulatorGroupType *mgrouptype, struct wmKeyConfig *config);
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorMap */
+
+struct wmManipulatorMapType *WM_manipulatormaptype_find(
+ const struct wmManipulatorMapType_Params *mmap_params);
+struct wmManipulatorMapType *WM_manipulatormaptype_ensure(
+ const struct wmManipulatorMapType_Params *mmap_params);
+
+struct wmManipulatorMap *WM_manipulatormap_new_from_type(
+ const struct wmManipulatorMapType_Params *mmap_params);
+void WM_manipulatormap_tag_refresh(struct wmManipulatorMap *mmap);
+void WM_manipulatormap_draw(struct wmManipulatorMap *mmap, const struct bContext *C, const int drawstep);
+void WM_manipulatormap_add_handlers(struct ARegion *ar, struct wmManipulatorMap *mmap);
+bool WM_manipulatormap_select_all(struct bContext *C, struct wmManipulatorMap *mmap, const int action);
+bool WM_manipulatormap_cursor_set(const struct wmManipulatorMap *mmap, struct wmWindow *win);
+
+#endif /* __WM_MANIPULATOR_API_H__ */
+
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_library.h b/source/blender/windowmanager/manipulators/WM_manipulator_library.h
new file mode 100644
index 00000000000..1e7106905e3
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_library.h
@@ -0,0 +1,128 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/WM_manipulator_library.h
+ * \ingroup wm
+ *
+ * \name Generic Manipulator Library
+ *
+ * Only included in WM_api.h and lower level files.
+ */
+
+
+#ifndef __WM_MANIPULATOR_LIBRARY_H__
+#define __WM_MANIPULATOR_LIBRARY_H__
+
+struct wmManipulatorGroup;
+
+
+/* -------------------------------------------------------------------- */
+/* 3D Arrow Manipulator */
+
+enum {
+ MANIPULATOR_ARROW_STYLE_NORMAL = 1,
+ MANIPULATOR_ARROW_STYLE_NO_AXIS = (1 << 1),
+ MANIPULATOR_ARROW_STYLE_CROSS = (1 << 2),
+ MANIPULATOR_ARROW_STYLE_INVERTED = (1 << 3), /* inverted offset during interaction - if set it also sets constrained below */
+ MANIPULATOR_ARROW_STYLE_CONSTRAINED = (1 << 4), /* clamp arrow interaction to property width */
+ MANIPULATOR_ARROW_STYLE_BOX = (1 << 5), /* use a box for the arrowhead */
+ MANIPULATOR_ARROW_STYLE_CONE = (1 << 6),
+};
+
+/* slots for properties */
+enum {
+ ARROW_SLOT_OFFSET_WORLD_SPACE = 0
+};
+
+struct wmManipulator *MANIPULATOR_arrow_new(struct wmManipulatorGroup *mgroup, const char *name, const int style);
+void MANIPULATOR_arrow_set_direction(struct wmManipulator *manipulator, const float direction[3]);
+void MANIPULATOR_arrow_set_up_vector(struct wmManipulator *manipulator, const float direction[3]);
+void MANIPULATOR_arrow_set_line_len(struct wmManipulator *manipulator, const float len);
+void MANIPULATOR_arrow_set_ui_range(struct wmManipulator *manipulator, const float min, const float max);
+void MANIPULATOR_arrow_set_range_fac(struct wmManipulator *manipulator, const float range_fac);
+void MANIPULATOR_arrow_cone_set_aspect(struct wmManipulator *manipulator, const float aspect[2]);
+
+
+/* -------------------------------------------------------------------- */
+/* 2D Arrow Manipulator */
+
+struct wmManipulator *MANIPULATOR_arrow2d_new(struct wmManipulatorGroup *mgroup, const char *name);
+void MANIPULATOR_arrow2d_set_angle(struct wmManipulator *manipulator, const float rot_fac);
+void MANIPULATOR_arrow2d_set_line_len(struct wmManipulator *manipulator, const float len);
+
+
+/* -------------------------------------------------------------------- */
+/* Cage Manipulator */
+
+enum {
+ MANIPULATOR_RECT_TRANSFORM_STYLE_TRANSLATE = 1, /* Manipulator translates */
+ MANIPULATOR_RECT_TRANSFORM_STYLE_ROTATE = (1 << 1), /* Manipulator rotates */
+ MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE = (1 << 2), /* Manipulator scales */
+ MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM = (1 << 3), /* Manipulator scales uniformly */
+};
+
+enum {
+ RECT_TRANSFORM_SLOT_OFFSET = 0,
+ RECT_TRANSFORM_SLOT_SCALE = 1
+};
+
+struct wmManipulator *MANIPULATOR_rect_transform_new(
+ struct wmManipulatorGroup *mgroup, const char *name, const int style);
+void MANIPULATOR_rect_transform_set_dimensions(
+ struct wmManipulator *manipulator, const float width, const float height);
+
+
+/* -------------------------------------------------------------------- */
+/* Dial Manipulator */
+
+enum {
+ MANIPULATOR_DIAL_STYLE_RING = 0,
+ MANIPULATOR_DIAL_STYLE_RING_CLIPPED = 1,
+ MANIPULATOR_DIAL_STYLE_RING_FILLED = 2,
+};
+
+struct wmManipulator *MANIPULATOR_dial_new(struct wmManipulatorGroup *mgroup, const char *name, const int style);
+void MANIPULATOR_dial_set_up_vector(struct wmManipulator *manipulator, const float direction[3]);
+
+
+/* -------------------------------------------------------------------- */
+/* Facemap Manipulator */
+
+struct wmManipulator *MANIPULATOR_facemap_new(
+ struct wmManipulatorGroup *mgroup, const char *name, const int style,
+ struct Object *ob, const int facemap);
+struct bFaceMap *MANIPULATOR_facemap_get_fmap(struct wmManipulator *manipulator);
+
+
+/* -------------------------------------------------------------------- */
+/* Primitive Manipulator */
+
+enum {
+ MANIPULATOR_PRIMITIVE_STYLE_PLANE = 0,
+};
+
+struct wmManipulator *MANIPULATOR_primitive_new(struct wmManipulatorGroup *mgroup, const char *name, const int style);
+void MANIPULATOR_primitive_set_direction(struct wmManipulator *manipulator, const float direction[3]);
+void MANIPULATOR_primitive_set_up_vector(struct wmManipulator *manipulator, const float direction[3]);
+
+#endif /* __WM_MANIPULATOR_LIBRARY_H__ */
+
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
new file mode 100644
index 00000000000..8de33ca923e
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
@@ -0,0 +1,152 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/WM_manipulator_types.h
+ * \ingroup wm
+ *
+ * \name Manipulator Types
+ * \brief Manipulator defines for external use.
+ *
+ * Only included in WM_types.h and lower level files.
+ */
+
+
+#ifndef __WM_MANIPULATOR_TYPES_H__
+#define __WM_MANIPULATOR_TYPES_H__
+
+#include "BLI_compiler_attrs.h"
+
+struct wmManipulatorGroupType;
+struct wmManipulatorGroup;
+struct wmKeyConfig;
+
+typedef bool (*wmManipulatorGroupPollFunc)(const struct bContext *, struct wmManipulatorGroupType *) ATTR_WARN_UNUSED_RESULT;
+typedef void (*wmManipulatorGroupInitFunc)(const struct bContext *, struct wmManipulatorGroup *);
+typedef void (*wmManipulatorGroupRefreshFunc)(const struct bContext *, struct wmManipulatorGroup *);
+typedef void (*wmManipulatorGroupDrawPrepareFunc)(const struct bContext *, struct wmManipulatorGroup *);
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulator */
+
+/**
+ * Simple utility wrapper for storing a single manipulator as wmManipulatorGroup.customdata (which gets freed).
+ */
+typedef struct wmManipulatorWrapper {
+ struct wmManipulator *manipulator;
+} wmManipulatorWrapper;
+
+/* wmManipulator.flag
+ * Flags for individual manipulators. */
+enum {
+ WM_MANIPULATOR_DRAW_HOVER = (1 << 0), /* draw *only* while hovering */
+ WM_MANIPULATOR_DRAW_ACTIVE = (1 << 1), /* draw while dragging */
+ WM_MANIPULATOR_DRAW_VALUE = (1 << 2), /* draw an indicator for the current value while dragging */
+ WM_MANIPULATOR_HIDDEN = (1 << 3),
+};
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorGroup */
+
+/* factory class for a manipulator-group type, gets called every time a new area is spawned */
+typedef struct wmManipulatorGroupType {
+ struct wmManipulatorGroupType *next, *prev;
+
+ char idname[64]; /* MAX_NAME */
+ const char *name; /* manipulator-group name - displayed in UI (keymap editor) */
+
+ /* poll if manipulator-map should be visible */
+ wmManipulatorGroupPollFunc poll;
+ /* initially create manipulators and set permanent data - stuff you only need to do once */
+ wmManipulatorGroupInitFunc init;
+ /* refresh data, only called if recreate flag is set (WM_manipulatormap_tag_refresh) */
+ wmManipulatorGroupRefreshFunc refresh;
+ /* refresh data for drawing, called before each redraw */
+ wmManipulatorGroupDrawPrepareFunc draw_prepare;
+
+ /* keymap init callback for this manipulator-group */
+ struct wmKeyMap *(*keymap_init)(const struct wmManipulatorGroupType *, struct wmKeyConfig *);
+ /* keymap created with callback from above */
+ struct wmKeyMap *keymap;
+
+ /* rna for properties */
+ struct StructRNA *srna;
+
+ /* RNA integration */
+ ExtensionRNA ext;
+
+ int flag;
+
+ /* if type is spawned from operator this is set here */
+ void *op;
+
+ /* same as manipulator-maps, so registering/unregistering goes to the correct region */
+ short spaceid, regionid;
+ char mapidname[64];
+} wmManipulatorGroupType;
+
+/**
+ * wmManipulatorGroupType.flag
+ * Flags that influence the behavior of all manipulators in the group.
+ */
+enum {
+ /* Mark manipulator-group as being 3D */
+ WM_MANIPULATORGROUPTYPE_IS_3D = (1 << 0),
+ /* Scale manipulators as 3D object that respects zoom (otherwise zoom independent draw size) */
+ WM_MANIPULATORGROUPTYPE_SCALE_3D = (1 << 1),
+ /* Manipulators can be depth culled with scene objects (covered by other geometry - TODO) */
+ WM_MANIPULATORGROUPTYPE_SCENE_DEPTH = (1 << 2),
+ /* Manipulators can be selected */
+ WM_MANIPULATORGROUPTYPE_SELECTABLE = (1 << 3),
+ /* manipulator group is attached to operator, and is only accessible as long as this runs */
+ WM_MANIPULATORGROUPTYPE_OP = (1 << 4),
+};
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorMap */
+
+struct wmManipulatorMapType_Params {
+ const char *idname;
+ const int spaceid;
+ const int regionid;
+};
+
+/**
+ * Pass a value of this enum to #WM_manipulatormap_draw to tell it what to draw.
+ */
+enum {
+ /* Draw 2D manipulator-groups (ManipulatorGroupType.is_3d == false) */
+ WM_MANIPULATORMAP_DRAWSTEP_2D = 0,
+ /* Draw 3D manipulator-groups (ManipulatorGroupType.is_3d == true) */
+ WM_MANIPULATORMAP_DRAWSTEP_3D,
+ /* Draw only depth culled manipulators (WM_MANIPULATOR_SCENE_DEPTH flag).
+ * Note that these are expected to be 3D manipulators too. */
+ WM_MANIPULATORMAP_DRAWSTEP_IN_SCENE,
+};
+
+#endif /* __WM_MANIPULATOR_TYPES_H__ */
+
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c
new file mode 100644
index 00000000000..ad5f2f6251b
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c
@@ -0,0 +1,231 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c
+ * \ingroup wm
+ *
+ * \name 2D Arrow Manipulator
+ *
+ * \brief Simple arrow manipulator which is dragged into a certain direction.
+ */
+
+#include "BIF_gl.h"
+
+#include "BKE_context.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
+
+#include "DNA_manipulator_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "ED_screen.h"
+
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_types.h"
+
+/* own includes */
+#include "WM_manipulator_types.h"
+#include "wm_manipulator_wmapi.h"
+#include "WM_manipulator_library.h"
+#include "wm_manipulator_intern.h"
+#include "manipulator_library_intern.h"
+
+
+typedef struct ArrowManipulator2D {
+ struct wmManipulator manipulator;
+
+ float angle;
+ float line_len;
+} ArrowManipulator2D;
+
+
+static void arrow2d_draw_geom(ArrowManipulator2D *arrow, const float origin[2], const float color[4])
+{
+ const float size = 0.11f;
+ const float size_h = size / 2.0f;
+ const float len = arrow->line_len;
+ const float draw_line_ofs = (arrow->manipulator.line_width * 0.5f) / arrow->manipulator.scale;
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ gpuPushMatrix();
+ gpuTranslate2fv(origin);
+ gpuScaleUniform(arrow->manipulator.scale);
+ gpuRotate2D(RAD2DEGF(arrow->angle));
+ /* local offset */
+ gpuTranslate2f(arrow->manipulator.offset[0] + draw_line_ofs, arrow->manipulator.offset[1]);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4fv(color);
+
+ immBegin(PRIM_LINES, 2);
+ immVertex2f(pos, 0.0f, 0.0f);
+ immVertex2f(pos, 0.0f, len);
+ immEnd();
+
+ immBegin(PRIM_TRIANGLES, 3);
+ immVertex2f(pos, size_h, len);
+ immVertex2f(pos, -size_h, len);
+ immVertex2f(pos, 0.0f, len + size * 1.7f);
+ immEnd();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
+}
+
+static void manipulator_arrow2d_draw(const bContext *UNUSED(C), struct wmManipulator *manipulator)
+{
+ ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator;
+ float col[4];
+
+ manipulator_color_get(manipulator, manipulator->state & WM_MANIPULATOR_HIGHLIGHT, col);
+
+ glLineWidth(manipulator->line_width);
+ glEnable(GL_BLEND);
+ arrow2d_draw_geom(arrow, manipulator->origin, col);
+ glDisable(GL_BLEND);
+
+ if (arrow->manipulator.interaction_data) {
+ ManipulatorInteraction *inter = arrow->manipulator.interaction_data;
+
+ glEnable(GL_BLEND);
+ arrow2d_draw_geom(arrow, inter->init_origin, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
+ glDisable(GL_BLEND);
+ }
+}
+
+static int manipulator_arrow2d_invoke(bContext *UNUSED(C), const wmEvent *UNUSED(event), struct wmManipulator *manipulator)
+{
+ ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
+
+ copy_v2_v2(inter->init_origin, manipulator->origin);
+ manipulator->interaction_data = inter;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int manipulator_arrow2d_intersect(bContext *UNUSED(C), const wmEvent *event, struct wmManipulator *manipulator)
+{
+ ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator;
+ const float mval[2] = {event->mval[0], event->mval[1]};
+ const float line_len = arrow->line_len * manipulator->scale;
+ float mval_local[2];
+
+ copy_v2_v2(mval_local, mval);
+ sub_v2_v2(mval_local, manipulator->origin);
+
+ float line[2][2];
+ line[0][0] = line[0][1] = line[1][0] = 0.0f;
+ line[1][1] = line_len;
+
+ /* rotate only if needed */
+ if (arrow->angle != 0.0f) {
+ float rot_point[2];
+ copy_v2_v2(rot_point, line[1]);
+ rotate_v2_v2fl(line[1], rot_point, arrow->angle);
+ }
+
+ /* arrow line intersection check */
+ float isect_1[2], isect_2[2];
+ const int isect = isect_line_sphere_v2(
+ line[0], line[1], mval_local, MANIPULATOR_HOTSPOT + manipulator->line_width * 0.5f,
+ isect_1, isect_2);
+
+ if (isect > 0) {
+ float line_ext[2][2]; /* extended line for segment check including hotspot */
+ copy_v2_v2(line_ext[0], line[0]);
+ line_ext[1][0] = line[1][0] + MANIPULATOR_HOTSPOT * ((line[1][0] - line[0][0]) / line_len);
+ line_ext[1][1] = line[1][1] + MANIPULATOR_HOTSPOT * ((line[1][1] - line[0][1]) / line_len);
+
+ const float lambda_1 = line_point_factor_v2(isect_1, line_ext[0], line_ext[1]);
+ if (isect == 1) {
+ return IN_RANGE_INCL(lambda_1, 0.0f, 1.0f);
+ }
+ else {
+ BLI_assert(isect == 2);
+ const float lambda_2 = line_point_factor_v2(isect_2, line_ext[0], line_ext[1]);
+ return IN_RANGE_INCL(lambda_1, 0.0f, 1.0f) && IN_RANGE_INCL(lambda_2, 0.0f, 1.0f);
+ }
+ }
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------- */
+/** \name 2D Arrow Manipulator API
+ *
+ * \{ */
+
+struct wmManipulator *MANIPULATOR_arrow2d_new(wmManipulatorGroup *mgroup, const char *name)
+{
+ ArrowManipulator2D *arrow = MEM_callocN(sizeof(ArrowManipulator2D), __func__);
+
+ arrow->manipulator.draw = manipulator_arrow2d_draw;
+ arrow->manipulator.invoke = manipulator_arrow2d_invoke;
+// arrow->manipulator.bind_to_prop = manipulator_arrow2d_bind_to_prop;
+// arrow->manipulator.handler = manipulator_arrow2d_handler;
+ arrow->manipulator.intersect = manipulator_arrow2d_intersect;
+// arrow->manipulator.exit = manipulator_arrow2d_exit;
+ arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
+
+ arrow->line_len = 1.0f;
+
+ wm_manipulator_register(mgroup, &arrow->manipulator, name);
+
+ return (struct wmManipulator *)arrow;
+}
+
+void MANIPULATOR_arrow2d_set_angle(struct wmManipulator *manipulator, const float angle)
+{
+ ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator;
+ arrow->angle = angle;
+}
+
+void MANIPULATOR_arrow2d_set_line_len(struct wmManipulator *manipulator, const float len)
+{
+ ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator;
+ arrow->line_len = len;
+}
+
+/** \} */ /* Arrow Manipulator API */
+
+
+/* -------------------------------------------------------------------- */
+
+void fix_linking_manipulator_arrow2d(void)
+{
+ (void)0;
+}
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
new file mode 100644
index 00000000000..b2e04849c34
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
@@ -0,0 +1,548 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
+ * \ingroup wm
+ *
+ * \name Arrow Manipulator
+ *
+ * 3D Manipulator
+ *
+ * \brief Simple arrow manipulator which is dragged into a certain direction.
+ * The arrow head can have varying shapes, e.g. cone, box, etc.
+ */
+
+#include "BIF_gl.h"
+
+#include "BKE_context.h"
+
+#include "BLI_math.h"
+
+#include "DNA_manipulator_types.h"
+#include "DNA_view3d_types.h"
+
+#include "ED_view3d.h"
+#include "ED_screen.h"
+
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_select.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+#include "manipulator_geometry.h"
+#include "manipulator_library_intern.h"
+
+/* to use custom arrows exported to geom_arrow_manipulator.c */
+//#define USE_MANIPULATOR_CUSTOM_ARROWS
+
+/* ArrowManipulator->flag */
+enum {
+ ARROW_UP_VECTOR_SET = (1 << 0),
+ ARROW_CUSTOM_RANGE_SET = (1 << 1),
+};
+
+typedef struct ArrowManipulator {
+ wmManipulator manipulator;
+
+ ManipulatorCommonData data;
+
+ int style;
+ int flag;
+
+ float len; /* arrow line length */
+ float direction[3];
+ float up[3];
+ float aspect[2]; /* cone style only */
+} ArrowManipulator;
+
+
+/* -------------------------------------------------------------------- */
+
+static void manipulator_arrow_get_final_pos(wmManipulator *manipulator, float r_pos[3])
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+
+ mul_v3_v3fl(r_pos, arrow->direction, arrow->data.offset);
+ add_v3_v3(r_pos, arrow->manipulator.origin);
+}
+
+static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, const float color[4])
+{
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ bool unbind_shader = true;
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (arrow->style & MANIPULATOR_ARROW_STYLE_CROSS) {
+ immUniformColor4fv(color);
+
+ immBegin(PRIM_LINES, 4);
+ immVertex3f(pos, -1.0, 0.f, 0.0);
+ immVertex3f(pos, 1.0, 0.f, 0.0);
+ immVertex3f(pos, 0.f, -1.0, 0.0);
+ immVertex3f(pos, 0.f, 1.0, 0.0);
+ immEnd();
+ }
+ else if (arrow->style & MANIPULATOR_ARROW_STYLE_CONE) {
+ const float unitx = arrow->aspect[0];
+ const float unity = arrow->aspect[1];
+ const float vec[4][3] = {
+ {-unitx, -unity, 0},
+ { unitx, -unity, 0},
+ { unitx, unity, 0},
+ {-unitx, unity, 0},
+ };
+
+ glLineWidth(arrow->manipulator.line_width);
+ wm_manipulator_vec_draw(color, vec, ARRAY_SIZE(vec), pos, PRIM_LINE_STRIP);
+ }
+ else {
+#ifdef USE_MANIPULATOR_CUSTOM_ARROWS
+ wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_arrow, select, color);
+#else
+
+ const float vec[2][3] = {
+ {0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, arrow->len},
+ };
+
+ glLineWidth(arrow->manipulator.line_width);
+ wm_manipulator_vec_draw(color, vec, ARRAY_SIZE(vec), pos, PRIM_LINE_STRIP);
+
+
+ /* *** draw arrow head *** */
+
+ gpuPushMatrix();
+
+ if (arrow->style & MANIPULATOR_ARROW_STYLE_BOX) {
+ const float size = 0.05f;
+
+ /* translate to line end with some extra offset so box starts exactly where line ends */
+ gpuTranslate3f(0.0f, 0.0f, arrow->len + size);
+ /* scale down to box size */
+ gpuScale3f(size, size, size);
+
+ /* draw cube */
+ immUnbindProgram();
+ unbind_shader = false;
+ wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_cube, select, color);
+ }
+ else {
+ const float len = 0.25f;
+ const float width = 0.06f;
+ const bool use_lighting = select == false && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0);
+
+ /* translate to line end */
+ gpuTranslate3f(0.0f, 0.0f, arrow->len);
+
+ if (use_lighting) {
+ immUnbindProgram();
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+
+ imm_draw_circle_fill_3d(pos, 0.0, 0.0, width, 8);
+ imm_draw_cylinder_fill_3d(pos, width, 0.0, len, 8, 1);
+ }
+
+ gpuPopMatrix();
+#endif /* USE_MANIPULATOR_CUSTOM_ARROWS */
+ }
+
+ if (unbind_shader) {
+ immUnbindProgram();
+ }
+}
+
+static void arrow_draw_intern(ArrowManipulator *arrow, const bool select, const bool highlight)
+{
+ const float up[3] = {0.0f, 0.0f, 1.0f};
+ float col[4];
+ float rot[3][3];
+ float mat[4][4];
+ float final_pos[3];
+
+ manipulator_color_get(&arrow->manipulator, highlight, col);
+ manipulator_arrow_get_final_pos(&arrow->manipulator, final_pos);
+
+ if (arrow->flag & ARROW_UP_VECTOR_SET) {
+ copy_v3_v3(rot[2], arrow->direction);
+ copy_v3_v3(rot[1], arrow->up);
+ cross_v3_v3v3(rot[0], arrow->up, arrow->direction);
+ }
+ else {
+ rotation_between_vecs_to_mat3(rot, up, arrow->direction);
+ }
+ copy_m4_m3(mat, rot);
+ copy_v3_v3(mat[3], final_pos);
+ mul_mat3_m4_fl(mat, arrow->manipulator.scale);
+
+ gpuPushMatrix();
+ gpuMultMatrix(mat);
+
+ gpuTranslate3fv(arrow->manipulator.offset);
+
+ glEnable(GL_BLEND);
+ arrow_draw_geom(arrow, select, col);
+ glDisable(GL_BLEND);
+
+ gpuPopMatrix();
+
+ if (arrow->manipulator.interaction_data) {
+ ManipulatorInteraction *inter = arrow->manipulator.interaction_data;
+
+ copy_m4_m3(mat, rot);
+ copy_v3_v3(mat[3], inter->init_origin);
+ mul_mat3_m4_fl(mat, inter->init_scale);
+
+ gpuPushMatrix();
+ gpuMultMatrix(mat);
+ gpuTranslate3fv(arrow->manipulator.offset);
+
+ glEnable(GL_BLEND);
+ arrow_draw_geom(arrow, select, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f});
+ glDisable(GL_BLEND);
+
+ gpuPopMatrix();
+ }
+}
+
+static void manipulator_arrow_render_3d_intersect(
+ const bContext *UNUSED(C), wmManipulator *manipulator,
+ int selectionbase)
+{
+ GPU_select_load_id(selectionbase);
+ arrow_draw_intern((ArrowManipulator *)manipulator, true, false);
+}
+
+static void manipulator_arrow_draw(const bContext *UNUSED(C), wmManipulator *manipulator)
+{
+ arrow_draw_intern((ArrowManipulator *)manipulator, false, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
+}
+
+/**
+ * Calculate arrow offset independent from prop min value,
+ * meaning the range will not be offset by min value first.
+ */
+static int manipulator_arrow_handler(bContext *C, const wmEvent *event, wmManipulator *manipulator, const int flag)
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+ ManipulatorInteraction *inter = manipulator->interaction_data;
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ float orig_origin[4];
+ float viewvec[3], tangent[3], plane[3];
+ float offset[4];
+ float m_diff[2];
+ float dir_2d[2], dir2d_final[2];
+ float facdir = 1.0f;
+ bool use_vertical = false;
+
+
+ copy_v3_v3(orig_origin, inter->init_origin);
+ orig_origin[3] = 1.0f;
+ add_v3_v3v3(offset, orig_origin, arrow->direction);
+ offset[3] = 1.0f;
+
+ /* calculate view vector */
+ if (rv3d->is_persp) {
+ sub_v3_v3v3(viewvec, orig_origin, rv3d->viewinv[3]);
+ }
+ else {
+ copy_v3_v3(viewvec, rv3d->viewinv[2]);
+ }
+ normalize_v3(viewvec);
+
+ /* first determine if view vector is really close to the direction. If it is, we use
+ * vertical movement to determine offset, just like transform system does */
+ if (RAD2DEG(acos(dot_v3v3(viewvec, arrow->direction))) > 5.0f) {
+ /* multiply to projection space */
+ mul_m4_v4(rv3d->persmat, orig_origin);
+ mul_v4_fl(orig_origin, 1.0f / orig_origin[3]);
+ mul_m4_v4(rv3d->persmat, offset);
+ mul_v4_fl(offset, 1.0f / offset[3]);
+
+ sub_v2_v2v2(dir_2d, offset, orig_origin);
+ dir_2d[0] *= ar->winx;
+ dir_2d[1] *= ar->winy;
+ normalize_v2(dir_2d);
+ }
+ else {
+ dir_2d[0] = 0.0f;
+ dir_2d[1] = 1.0f;
+ use_vertical = true;
+ }
+
+ /* find mouse difference */
+ m_diff[0] = event->mval[0] - inter->init_mval[0];
+ m_diff[1] = event->mval[1] - inter->init_mval[1];
+
+ /* project the displacement on the screen space arrow direction */
+ project_v2_v2v2(dir2d_final, m_diff, dir_2d);
+
+ float zfac = ED_view3d_calc_zfac(rv3d, orig_origin, NULL);
+ ED_view3d_win_to_delta(ar, dir2d_final, offset, zfac);
+
+ add_v3_v3v3(orig_origin, offset, inter->init_origin);
+
+ /* calculate view vector for the new position */
+ if (rv3d->is_persp) {
+ sub_v3_v3v3(viewvec, orig_origin, rv3d->viewinv[3]);
+ }
+ else {
+ copy_v3_v3(viewvec, rv3d->viewinv[2]);
+ }
+
+ normalize_v3(viewvec);
+ if (!use_vertical) {
+ float fac;
+ /* now find a plane parallel to the view vector so we can intersect with the arrow direction */
+ cross_v3_v3v3(tangent, viewvec, offset);
+ cross_v3_v3v3(plane, tangent, viewvec);
+ fac = dot_v3v3(plane, offset) / dot_v3v3(arrow->direction, plane);
+
+ facdir = (fac < 0.0) ? -1.0 : 1.0;
+ mul_v3_v3fl(offset, arrow->direction, fac);
+ }
+ else {
+ facdir = (m_diff[1] < 0.0) ? -1.0 : 1.0;
+ }
+
+
+ ManipulatorCommonData *data = &arrow->data;
+ const float ofs_new = facdir * len_v3(offset);
+ const int slot = ARROW_SLOT_OFFSET_WORLD_SPACE;
+
+ /* set the property for the operator and call its modal function */
+ if (manipulator->props[slot]) {
+ const bool constrained = arrow->style & MANIPULATOR_ARROW_STYLE_CONSTRAINED;
+ const bool inverted = arrow->style & MANIPULATOR_ARROW_STYLE_INVERTED;
+ const bool use_precision = flag & WM_MANIPULATOR_TWEAK_PRECISE;
+ float value = manipulator_value_from_offset(data, inter, ofs_new, constrained, inverted, use_precision);
+
+ manipulator_property_value_set(C, manipulator, slot, value);
+ /* get clamped value */
+ value = manipulator_property_value_get(manipulator, slot);
+
+ data->offset = manipulator_offset_from_value(data, value, constrained, inverted);
+ }
+ else {
+ data->offset = ofs_new;
+ }
+
+ /* tag the region for redraw */
+ ED_region_tag_redraw(ar);
+ WM_event_add_mousemove(C);
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+
+static int manipulator_arrow_invoke(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator)
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+ ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
+ PointerRNA ptr = manipulator->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
+ PropertyRNA *prop = manipulator->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
+
+ if (prop) {
+ inter->init_value = RNA_property_float_get(&ptr, prop);
+ }
+
+ inter->init_offset = arrow->data.offset;
+
+ inter->init_mval[0] = event->mval[0];
+ inter->init_mval[1] = event->mval[1];
+
+ inter->init_scale = manipulator->scale;
+
+ manipulator_arrow_get_final_pos(manipulator, inter->init_origin);
+
+ manipulator->interaction_data = inter;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void manipulator_arrow_prop_data_update(wmManipulator *manipulator, const int slot)
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+ manipulator_property_data_update(
+ manipulator, &arrow->data, slot,
+ arrow->style & MANIPULATOR_ARROW_STYLE_CONSTRAINED,
+ arrow->style & MANIPULATOR_ARROW_STYLE_INVERTED);
+}
+
+static void manipulator_arrow_exit(bContext *C, wmManipulator *manipulator, const bool cancel)
+{
+ if (!cancel)
+ return;
+
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+ ManipulatorCommonData *data = &arrow->data;
+ ManipulatorInteraction *inter = manipulator->interaction_data;
+
+ manipulator_property_value_reset(C, manipulator, inter, ARROW_SLOT_OFFSET_WORLD_SPACE);
+ data->offset = inter->init_offset;
+}
+
+
+/* -------------------------------------------------------------------- */
+/** \name Arrow Manipulator API
+ *
+ * \{ */
+
+wmManipulator *MANIPULATOR_arrow_new(wmManipulatorGroup *mgroup, const char *name, const int style)
+{
+ int real_style = style;
+
+ /* inverted only makes sense in a constrained arrow */
+ if (real_style & MANIPULATOR_ARROW_STYLE_INVERTED) {
+ real_style |= MANIPULATOR_ARROW_STYLE_CONSTRAINED;
+ }
+
+
+ ArrowManipulator *arrow = MEM_callocN(sizeof(ArrowManipulator), name);
+ const float dir_default[3] = {0.0f, 0.0f, 1.0f};
+
+ arrow->manipulator.draw = manipulator_arrow_draw;
+ arrow->manipulator.get_final_position = manipulator_arrow_get_final_pos;
+ arrow->manipulator.intersect = NULL;
+ arrow->manipulator.handler = manipulator_arrow_handler;
+ arrow->manipulator.invoke = manipulator_arrow_invoke;
+ arrow->manipulator.render_3d_intersection = manipulator_arrow_render_3d_intersect;
+ arrow->manipulator.prop_data_update = manipulator_arrow_prop_data_update;
+ arrow->manipulator.exit = manipulator_arrow_exit;
+ arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
+
+ arrow->style = real_style;
+ arrow->len = 1.0f;
+ arrow->data.range_fac = 1.0f;
+ copy_v3_v3(arrow->direction, dir_default);
+
+ wm_manipulator_register(mgroup, &arrow->manipulator, name);
+
+ return (wmManipulator *)arrow;
+}
+
+/**
+ * Define direction the arrow will point towards
+ */
+void MANIPULATOR_arrow_set_direction(wmManipulator *manipulator, const float direction[3])
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+
+ copy_v3_v3(arrow->direction, direction);
+ normalize_v3(arrow->direction);
+}
+
+/**
+ * Define up-direction of the arrow manipulator
+ */
+void MANIPULATOR_arrow_set_up_vector(wmManipulator *manipulator, const float direction[3])
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+
+ if (direction) {
+ copy_v3_v3(arrow->up, direction);
+ normalize_v3(arrow->up);
+ arrow->flag |= ARROW_UP_VECTOR_SET;
+ }
+ else {
+ arrow->flag &= ~ARROW_UP_VECTOR_SET;
+ }
+}
+
+/**
+ * Define a custom arrow line length
+ */
+void MANIPULATOR_arrow_set_line_len(wmManipulator *manipulator, const float len)
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+ arrow->len = len;
+}
+
+/**
+ * Define a custom property UI range
+ *
+ * \note Needs to be called before WM_manipulator_set_property!
+ */
+void MANIPULATOR_arrow_set_ui_range(wmManipulator *manipulator, const float min, const float max)
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+
+ BLI_assert(min < max);
+ BLI_assert(!(arrow->manipulator.props[0] && "Make sure this function "
+ "is called before WM_manipulator_set_property"));
+
+ arrow->data.range = max - min;
+ arrow->data.min = min;
+ arrow->data.flag |= MANIPULATOR_CUSTOM_RANGE_SET;
+}
+
+/**
+ * Define a custom factor for arrow min/max distance
+ *
+ * \note Needs to be called before WM_manipulator_set_property!
+ */
+void MANIPULATOR_arrow_set_range_fac(wmManipulator *manipulator, const float range_fac)
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+
+ BLI_assert(!(arrow->manipulator.props[0] && "Make sure this function "
+ "is called before WM_manipulator_set_property"));
+
+ arrow->data.range_fac = range_fac;
+}
+
+/**
+ * Define xy-aspect for arrow cone
+ */
+void MANIPULATOR_arrow_cone_set_aspect(wmManipulator *manipulator, const float aspect[2])
+{
+ ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
+
+ copy_v2_v2(arrow->aspect, aspect);
+}
+
+/** \} */ /* Arrow Manipulator API */
+
+
+/* -------------------------------------------------------------------- */
+
+void fix_linking_manipulator_arrow(void)
+{
+ (void)0;
+}
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c
new file mode 100644
index 00000000000..45973fbf2fe
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c
@@ -0,0 +1,592 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c
+ * \ingroup wm
+ *
+ * \name Cage Manipulator
+ *
+ * 2D Manipulator
+ *
+ * \brief Rectangular manipulator acting as a 'cage' around its content.
+ * Interacting scales or translates the manipulator.
+ */
+
+#include "BIF_gl.h"
+
+#include "BKE_context.h"
+
+#include "BLI_math.h"
+#include "BLI_rect.h"
+
+#include "DNA_manipulator_types.h"
+
+#include "ED_screen.h"
+
+#include "GPU_matrix.h"
+#include "GPU_shader.h"
+#include "GPU_immediate.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+
+/* wmManipulator->highlighted_part */
+enum {
+ MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE = 1,
+ MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT = 2,
+ MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT = 3,
+ MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP = 4,
+ MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN = 5
+};
+
+#define MANIPULATOR_RECT_MIN_WIDTH 15.0f
+#define MANIPULATOR_RESIZER_WIDTH 20.0f
+
+typedef struct RectTransformManipulator {
+ wmManipulator manipulator;
+ float w, h; /* dimensions of manipulator */
+ float rotation; /* rotation of the rectangle */
+ float scale[2]; /* scaling for the manipulator for non-destructive editing. */
+ int style;
+} RectTransformManipulator;
+
+
+/* -------------------------------------------------------------------- */
+
+static void rect_transform_draw_corners(
+ const rctf *r, const float offsetx, const float offsety, const float color[3])
+{
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fv(color);
+
+ immBegin(PRIM_LINES, 16);
+
+ immVertex2f(pos, r->xmin, r->ymin + offsety);
+ immVertex2f(pos, r->xmin, r->ymin);
+ immVertex2f(pos, r->xmin, r->ymin);
+ immVertex2f(pos, r->xmin + offsetx, r->ymin);
+
+ immVertex2f(pos, r->xmax, r->ymin + offsety);
+ immVertex2f(pos, r->xmax, r->ymin);
+ immVertex2f(pos, r->xmax, r->ymin);
+ immVertex2f(pos, r->xmax - offsetx, r->ymin);
+
+ immVertex2f(pos, r->xmax, r->ymax - offsety);
+ immVertex2f(pos, r->xmax, r->ymax);
+ immVertex2f(pos, r->xmax, r->ymax);
+ immVertex2f(pos, r->xmax - offsetx, r->ymax);
+
+ immVertex2f(pos, r->xmin, r->ymax - offsety);
+ immVertex2f(pos, r->xmin, r->ymax);
+ immVertex2f(pos, r->xmin, r->ymax);
+ immVertex2f(pos, r->xmin + offsetx, r->ymax);
+
+ immEnd();
+
+ immUnbindProgram();
+}
+
+static void rect_transform_draw_interaction(
+ const float col[4], const int highlighted,
+ const float half_w, const float half_h,
+ const float w, const float h, const float line_width)
+{
+ /* Why generate coordinates for 4 vertices, when we only use three? */
+ float verts[4][2];
+
+ switch (highlighted) {
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT:
+ verts[0][0] = -half_w + w;
+ verts[0][1] = -half_h;
+ verts[1][0] = -half_w;
+ verts[1][1] = -half_h;
+ verts[2][0] = -half_w;
+ verts[2][1] = half_h;
+ verts[3][0] = -half_w + w;
+ verts[3][1] = half_h;
+ break;
+
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT:
+ verts[0][0] = half_w - w;
+ verts[0][1] = -half_h;
+ verts[1][0] = half_w;
+ verts[1][1] = -half_h;
+ verts[2][0] = half_w;
+ verts[2][1] = half_h;
+ verts[3][0] = half_w - w;
+ verts[3][1] = half_h;
+ break;
+
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN:
+ verts[0][0] = -half_w;
+ verts[0][1] = -half_h + h;
+ verts[1][0] = -half_w;
+ verts[1][1] = -half_h;
+ verts[2][0] = half_w;
+ verts[2][1] = -half_h;
+ verts[3][0] = half_w;
+ verts[3][1] = -half_h + h;
+ break;
+
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP:
+ verts[0][0] = -half_w;
+ verts[0][1] = half_h - h;
+ verts[1][0] = -half_w;
+ verts[1][1] = half_h;
+ verts[2][0] = half_w;
+ verts[2][1] = half_h;
+ verts[3][0] = half_w;
+ verts[3][1] = half_h - h;
+ break;
+
+ default:
+ return;
+ }
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ unsigned int color = VertexFormat_add_attrib(format, "color", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ glLineWidth(line_width + 3.0);
+
+ immBegin(PRIM_LINE_STRIP, 3);
+ immAttrib3f(color, 0.0f, 0.0f, 0.0f);
+ immVertex2fv(pos, verts[0]);
+ immVertex2fv(pos, verts[1]);
+ immVertex2fv(pos, verts[2]);
+ immEnd();
+
+ glLineWidth(line_width);
+
+ immBegin(PRIM_LINE_STRIP, 3);
+ immAttrib3fv(color, col);
+ immVertex2fv(pos, verts[0]);
+ immVertex2fv(pos, verts[1]);
+ immVertex2fv(pos, verts[2]);
+ immEnd();
+
+ immUnbindProgram();
+}
+
+static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipulator *manipulator)
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ rctf r;
+ float w = cage->w;
+ float h = cage->h;
+ float aspx = 1.0f, aspy = 1.0f;
+ const float half_w = w / 2.0f;
+ const float half_h = h / 2.0f;
+
+ r.xmin = -half_w;
+ r.ymin = -half_h;
+ r.xmax = half_w;
+ r.ymax = half_h;
+
+ gpuPushMatrix();
+ gpuTranslate2f(manipulator->origin[0] + manipulator->offset[0],
+ manipulator->origin[1] + manipulator->offset[1]);
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
+ gpuScaleUniform(cage->scale[0]);
+ else
+ gpuScale2fv(cage->scale);
+
+ if (w > h)
+ aspx = h / w;
+ else
+ aspy = w / h;
+ w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / cage->scale[0]);
+ h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH /
+ ((cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) ? cage->scale[0] : cage->scale[1]));
+
+ /* corner manipulators */
+ glLineWidth(cage->manipulator.line_width + 3.0f);
+
+ rect_transform_draw_corners(&r, w, h, (const float[3]){0, 0, 0});
+
+ /* corner manipulators */
+ glLineWidth(cage->manipulator.line_width);
+ rect_transform_draw_corners(&r, w, h, manipulator->col);
+
+ rect_transform_draw_interaction(manipulator->col, manipulator->highlighted_part, half_w, half_h,
+ w, h, cage->manipulator.line_width);
+
+ glLineWidth(1.0);
+ gpuPopMatrix();
+}
+
+static int manipulator_rect_transform_get_cursor(wmManipulator *manipulator)
+{
+ switch (manipulator->highlighted_part) {
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE:
+ return BC_HANDCURSOR;
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT:
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT:
+ return CURSOR_X_MOVE;
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN:
+ case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP:
+ return CURSOR_Y_MOVE;
+ default:
+ return CURSOR_STD;
+ }
+}
+
+static int manipulator_rect_transform_intersect(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator)
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ const float mouse[2] = {event->mval[0], event->mval[1]};
+ //float matrot[2][2];
+ float point_local[2];
+ float w = cage->w;
+ float h = cage->h;
+ float half_w = w / 2.0f;
+ float half_h = h / 2.0f;
+ float aspx = 1.0f, aspy = 1.0f;
+
+ /* rotate mouse in relation to the center and relocate it */
+ sub_v2_v2v2(point_local, mouse, manipulator->origin);
+ point_local[0] -= manipulator->offset[0];
+ point_local[1] -= manipulator->offset[1];
+ //rotate_m2(matrot, -cage->transform.rotation);
+
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
+ mul_v2_fl(point_local, 1.0f / cage->scale[0]);
+ else {
+ point_local[0] /= cage->scale[0];
+ point_local[1] /= cage->scale[0];
+ }
+
+ if (cage->w > cage->h)
+ aspx = h / w;
+ else
+ aspy = w / h;
+ w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / cage->scale[0]);
+ h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH /
+ ((cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) ? cage->scale[0] : cage->scale[1]));
+
+
+ rctf r;
+
+ r.xmin = -half_w + w;
+ r.ymin = -half_h + h;
+ r.xmax = half_w - w;
+ r.ymax = half_h - h;
+
+ bool isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+ if (isect)
+ return MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE;
+
+ /* if manipulator does not have a scale intersection, don't do it */
+ if (cage->style & (MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE | MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)) {
+ r.xmin = -half_w;
+ r.ymin = -half_h;
+ r.xmax = -half_w + w;
+ r.ymax = half_h;
+
+ isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+ if (isect)
+ return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT;
+
+ r.xmin = half_w - w;
+ r.ymin = -half_h;
+ r.xmax = half_w;
+ r.ymax = half_h;
+
+ isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+ if (isect)
+ return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT;
+
+ r.xmin = -half_w;
+ r.ymin = -half_h;
+ r.xmax = half_w;
+ r.ymax = -half_h + h;
+
+ isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+ if (isect)
+ return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN;
+
+ r.xmin = -half_w;
+ r.ymin = half_h - h;
+ r.xmax = half_w;
+ r.ymax = half_h;
+
+ isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+ if (isect)
+ return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP;
+ }
+
+ return 0;
+}
+
+typedef struct RectTransformInteraction {
+ float orig_mouse[2];
+ float orig_offset[2];
+ float orig_scale[2];
+} RectTransformInteraction;
+
+static bool manipulator_rect_transform_get_prop_value(wmManipulator *manipulator, const int slot, float *value)
+{
+ PropertyType type = RNA_property_type(manipulator->props[slot]);
+
+ if (type != PROP_FLOAT) {
+ fprintf(stderr, "Rect Transform manipulator can only be bound to float properties");
+ return false;
+ }
+ else {
+ if (slot == RECT_TRANSFORM_SLOT_OFFSET) {
+ if (RNA_property_array_length(&manipulator->ptr[slot], manipulator->props[slot]) != 2) {
+ fprintf(stderr, "Rect Transform manipulator offset not only be bound to array float property");
+ return false;
+ }
+ RNA_property_float_get_array(&manipulator->ptr[slot], manipulator->props[slot], value);
+ }
+ else if (slot == RECT_TRANSFORM_SLOT_SCALE) {
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+ *value = RNA_property_float_get(&manipulator->ptr[slot], manipulator->props[slot]);
+ }
+ else {
+ if (RNA_property_array_length(&manipulator->ptr[slot], manipulator->props[slot]) != 2) {
+ fprintf(stderr, "Rect Transform manipulator scale not only be bound to array float property");
+ return false;
+ }
+ RNA_property_float_get_array(&manipulator->ptr[slot], manipulator->props[slot], value);
+ }
+ }
+ }
+
+ return true;
+}
+
+static int manipulator_rect_transform_invoke(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator)
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction");
+
+ copy_v2_v2(data->orig_offset, manipulator->offset);
+ copy_v2_v2(data->orig_scale, cage->scale);
+
+ data->orig_mouse[0] = event->mval[0];
+ data->orig_mouse[1] = event->mval[1];
+
+ manipulator->interaction_data = data;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int manipulator_rect_transform_handler(
+ bContext *C, const wmEvent *event, wmManipulator *manipulator,
+ const int UNUSED(flag))
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ RectTransformInteraction *data = manipulator->interaction_data;
+ /* needed here as well in case clamping occurs */
+ const float orig_ofx = manipulator->offset[0], orig_ofy = manipulator->offset[1];
+
+ const float valuex = (event->mval[0] - data->orig_mouse[0]);
+ const float valuey = (event->mval[1] - data->orig_mouse[1]);
+
+
+ if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE) {
+ manipulator->offset[0] = data->orig_offset[0] + valuex;
+ manipulator->offset[1] = data->orig_offset[1] + valuey;
+ }
+ else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT) {
+ manipulator->offset[0] = data->orig_offset[0] + valuex / 2.0;
+ cage->scale[0] = (cage->w * data->orig_scale[0] - valuex) / cage->w;
+ }
+ else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT) {
+ manipulator->offset[0] = data->orig_offset[0] + valuex / 2.0;
+ cage->scale[0] = (cage->w * data->orig_scale[0] + valuex) / cage->w;
+ }
+ else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN) {
+ manipulator->offset[1] = data->orig_offset[1] + valuey / 2.0;
+
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+ cage->scale[0] = (cage->h * data->orig_scale[0] - valuey) / cage->h;
+ }
+ else {
+ cage->scale[1] = (cage->h * data->orig_scale[1] - valuey) / cage->h;
+ }
+ }
+ else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP) {
+ manipulator->offset[1] = data->orig_offset[1] + valuey / 2.0;
+
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+ cage->scale[0] = (cage->h * data->orig_scale[0] + valuey) / cage->h;
+ }
+ else {
+ cage->scale[1] = (cage->h * data->orig_scale[1] + valuey) / cage->h;
+ }
+ }
+
+ /* clamping - make sure manipulator is at least 5 pixels wide */
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+ if (cage->scale[0] < MANIPULATOR_RECT_MIN_WIDTH / cage->h ||
+ cage->scale[0] < MANIPULATOR_RECT_MIN_WIDTH / cage->w)
+ {
+ cage->scale[0] = max_ff(MANIPULATOR_RECT_MIN_WIDTH / cage->h, MANIPULATOR_RECT_MIN_WIDTH / cage->w);
+ manipulator->offset[0] = orig_ofx;
+ manipulator->offset[1] = orig_ofy;
+ }
+ }
+ else {
+ if (cage->scale[0] < MANIPULATOR_RECT_MIN_WIDTH / cage->w) {
+ cage->scale[0] = MANIPULATOR_RECT_MIN_WIDTH / cage->w;
+ manipulator->offset[0] = orig_ofx;
+ }
+ if (cage->scale[1] < MANIPULATOR_RECT_MIN_WIDTH / cage->h) {
+ cage->scale[1] = MANIPULATOR_RECT_MIN_WIDTH / cage->h;
+ manipulator->offset[1] = orig_ofy;
+ }
+ }
+
+ if (manipulator->props[RECT_TRANSFORM_SLOT_OFFSET]) {
+ PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_OFFSET];
+ PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_OFFSET];
+
+ RNA_property_float_set_array(&ptr, prop, manipulator->offset);
+ RNA_property_update(C, &ptr, prop);
+ }
+
+ if (manipulator->props[RECT_TRANSFORM_SLOT_SCALE]) {
+ PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_SCALE];
+ PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_SCALE];
+
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+ RNA_property_float_set(&ptr, prop, cage->scale[0]);
+ }
+ else {
+ RNA_property_float_set_array(&ptr, prop, cage->scale);
+ }
+ RNA_property_update(C, &ptr, prop);
+ }
+
+ /* tag the region for redraw */
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+static void manipulator_rect_transform_prop_data_update(wmManipulator *manipulator, const int slot)
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+
+ if (slot == RECT_TRANSFORM_SLOT_OFFSET)
+ manipulator_rect_transform_get_prop_value(manipulator, RECT_TRANSFORM_SLOT_OFFSET, manipulator->offset);
+ if (slot == RECT_TRANSFORM_SLOT_SCALE)
+ manipulator_rect_transform_get_prop_value(manipulator, RECT_TRANSFORM_SLOT_SCALE, cage->scale);
+}
+
+static void manipulator_rect_transform_exit(bContext *C, wmManipulator *manipulator, const bool cancel)
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ RectTransformInteraction *data = manipulator->interaction_data;
+
+ if (!cancel)
+ return;
+
+ /* reset properties */
+ if (manipulator->props[RECT_TRANSFORM_SLOT_OFFSET]) {
+ PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_OFFSET];
+ PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_OFFSET];
+
+ RNA_property_float_set_array(&ptr, prop, data->orig_offset);
+ RNA_property_update(C, &ptr, prop);
+ }
+ if (manipulator->props[RECT_TRANSFORM_SLOT_SCALE]) {
+ PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_SCALE];
+ PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_SCALE];
+
+ if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+ RNA_property_float_set(&ptr, prop, data->orig_scale[0]);
+ }
+ else {
+ RNA_property_float_set_array(&ptr, prop, data->orig_scale);
+ }
+ RNA_property_update(C, &ptr, prop);
+ }
+}
+
+
+/* -------------------------------------------------------------------- */
+/** \name Cage Manipulator API
+ *
+ * \{ */
+
+wmManipulator *MANIPULATOR_rect_transform_new(wmManipulatorGroup *mgroup, const char *name, const int style)
+{
+ RectTransformManipulator *cage = MEM_callocN(sizeof(RectTransformManipulator), name);
+
+ cage->manipulator.draw = manipulator_rect_transform_draw;
+ cage->manipulator.invoke = manipulator_rect_transform_invoke;
+ cage->manipulator.prop_data_update = manipulator_rect_transform_prop_data_update;
+ cage->manipulator.handler = manipulator_rect_transform_handler;
+ cage->manipulator.intersect = manipulator_rect_transform_intersect;
+ cage->manipulator.exit = manipulator_rect_transform_exit;
+ cage->manipulator.get_cursor = manipulator_rect_transform_get_cursor;
+ cage->manipulator.max_prop = 2;
+ cage->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
+ cage->scale[0] = cage->scale[1] = 1.0f;
+ cage->style = style;
+
+ wm_manipulator_register(mgroup, &cage->manipulator, name);
+
+ return (wmManipulator *)cage;
+}
+
+void MANIPULATOR_rect_transform_set_dimensions(wmManipulator *manipulator, const float width, const float height)
+{
+ RectTransformManipulator *cage = (RectTransformManipulator *)manipulator;
+ cage->w = width;
+ cage->h = height;
+}
+
+/** \} */ // Cage Manipulator API
+
+
+/* -------------------------------------------------------------------- */
+
+void fix_linking_manipulator_cage(void)
+{
+ (void)0;
+}
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
new file mode 100644
index 00000000000..0fa6cbfbb28
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
@@ -0,0 +1,375 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
+ * \ingroup wm
+ *
+ * \name Dial Manipulator
+ *
+ * 3D Manipulator
+ *
+ * \brief Circle shaped manipulator for circular interaction.
+ * Currently no own handling, use with operator only.
+ */
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "BKE_context.h"
+
+#include "BLI_math.h"
+
+#include "DNA_manipulator_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "GPU_select.h"
+
+#include "GPU_matrix.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* own includes */
+#include "WM_manipulator_types.h"
+#include "WM_manipulator_library.h"
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+#include "manipulator_geometry.h"
+#include "manipulator_library_intern.h"
+
+/* to use custom dials exported to geom_dial_manipulator.c */
+// #define USE_MANIPULATOR_CUSTOM_DIAL
+
+typedef struct DialManipulator {
+ wmManipulator manipulator;
+ int style;
+ float direction[3];
+} DialManipulator;
+
+typedef struct DialInteraction {
+ float init_mval[2];
+
+ /* cache the last angle to detect rotations bigger than -/+ PI */
+ float last_angle;
+ /* number of full rotations */
+ int rotations;
+} DialInteraction;
+
+#define DIAL_WIDTH 1.0f
+#define DIAL_RESOLUTION 32
+
+/* -------------------------------------------------------------------- */
+
+static void dial_geom_draw(
+ const DialManipulator *dial, const float col[4], const bool select,
+ float axis_modal_mat[4][4], float clip_plane[4])
+{
+#ifdef USE_MANIPULATOR_CUSTOM_DIAL
+ UNUSED_VARS(dial, col, axis_modal_mat, clip_plane);
+ wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_dial, select);
+#else
+ const bool filled = (dial->style == MANIPULATOR_DIAL_STYLE_RING_FILLED);
+
+ glLineWidth(dial->manipulator.line_width);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+
+ if (clip_plane) {
+ immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
+ float clip_plane_f[4] = {clip_plane[0], clip_plane[1], clip_plane[2], clip_plane[3]};
+ immUniform4fv("ClipPlane", clip_plane_f);
+ immUniformMatrix4fv("ModelMatrix", axis_modal_mat);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ }
+
+ immUniformColor4fv(col);
+
+ if (filled) {
+ imm_draw_circle_fill(pos, 0, 0, 1.0, DIAL_RESOLUTION);
+ }
+ else {
+ imm_draw_circle_wire(pos, 0, 0, 1.0, DIAL_RESOLUTION);
+ }
+
+ immUnbindProgram();
+
+ UNUSED_VARS(select);
+#endif
+}
+
+/**
+ * Draws a line from (0, 0, 0) to \a co_outer, at \a angle.
+ */
+static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float col[4])
+{
+ glLineWidth(1.0f);
+
+ gpuPushMatrix();
+ gpuRotate3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f);
+
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ immUniformColor4fv(col);
+
+ immBegin(PRIM_LINE_STRIP, 2);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+ immVertex3fv(pos, co_outer);
+ immEnd();
+
+ immUnbindProgram();
+
+ gpuPopMatrix();
+}
+
+static void dial_ghostarc_draw(
+ const DialManipulator *dial, const float angle_ofs, const float angle_delta, const float color[4])
+{
+ const float width_inner = DIAL_WIDTH - dial->manipulator.line_width * 0.5f / U.manipulator_scale;
+
+ VertexFormat *format = immVertexFormat();
+ unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+ imm_draw_disk_partial_fill(
+ pos, 0, 0, 0.0, width_inner, DIAL_RESOLUTION, RAD2DEGF(angle_ofs), RAD2DEGF(angle_delta));
+ immUnbindProgram();
+}
+
+static void dial_ghostarc_get_angles(
+ const DialManipulator *dial, const wmEvent *event, const ARegion *ar,
+ float mat[4][4], const float co_outer[3],
+ float *r_start, float *r_delta)
+{
+ DialInteraction *inter = dial->manipulator.interaction_data;
+ const RegionView3D *rv3d = ar->regiondata;
+ const float mval[2] = {event->x - ar->winrct.xmin, event->y - ar->winrct.ymin};
+ bool inv = false;
+
+ /* we might need to invert the direction of the angles */
+ float view_vec[3], axis_vec[3];
+ ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
+ normalize_v3_v3(axis_vec, dial->direction);
+ if (dot_v3v3(view_vec, axis_vec) < 0.0f) {
+ inv = true;
+ }
+
+ float co[3], origin2d[2], co2d[2];
+ mul_v3_project_m4_v3(co, mat, co_outer);
+ /* project 3d coordinats to 2d viewplane */
+ ED_view3d_project_float_global(ar, dial->manipulator.origin, origin2d, V3D_PROJ_TEST_NOP);
+ ED_view3d_project_float_global(ar, co, co2d, V3D_PROJ_TEST_NOP);
+
+ /* convert to manipulator relative space */
+ float rel_initmval[2], rel_mval[2], rel_co[2];
+ sub_v2_v2v2(rel_initmval, inter->init_mval, origin2d);
+ sub_v2_v2v2(rel_mval, mval, origin2d);
+ sub_v2_v2v2(rel_co, co2d, origin2d);
+
+ /* return angles */
+ const float start = angle_signed_v2v2(rel_co, rel_initmval) * (inv ? -1 : 1);
+ const float delta = angle_signed_v2v2(rel_initmval, rel_mval) * (inv ? -1 : 1);
+
+ /* Change of sign, we passed the 180 degree threshold. This means we need to add a turn
+ * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2.
+ * Logic taken from BLI_dial_angle */
+ if ((delta * inter->last_angle < 0.0f) &&
+ (fabsf(inter->last_angle) > (float)M_PI_2))
+ {
+ if (inter->last_angle < 0.0f)
+ inter->rotations--;
+ else
+ inter->rotations++;
+ }
+ inter->last_angle = delta;
+
+ *r_start = start;
+ *r_delta = fmod(delta + 2.0f * (float)M_PI * inter->rotations, 2 * (float)M_PI);
+}
+
+static void dial_draw_intern(
+ const bContext *C, DialManipulator *dial,
+ const bool select, const bool highlight, float clip_plane[4])
+{
+ float rot[3][3];
+ float mat[4][4];
+ const float up[3] = {0.0f, 0.0f, 1.0f};
+ float col[4];
+
+ BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
+
+ manipulator_color_get(&dial->manipulator, highlight, col);
+
+ rotation_between_vecs_to_mat3(rot, up, dial->direction);
+ copy_m4_m3(mat, rot);
+ copy_v3_v3(mat[3], dial->manipulator.origin);
+ mul_mat3_m4_fl(mat, dial->manipulator.scale);
+
+ gpuPushMatrix();
+ gpuMultMatrix(mat);
+ gpuTranslate3fv(dial->manipulator.offset);
+
+ /* draw rotation indicator arc first */
+ if ((dial->manipulator.flag & WM_MANIPULATOR_DRAW_VALUE) && (dial->manipulator.state & WM_MANIPULATOR_ACTIVE)) {
+ wmWindow *win = CTX_wm_window(C);
+ const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */
+ float angle_ofs, angle_delta;
+
+ dial_ghostarc_get_angles(dial, win->eventstate, CTX_wm_region(C), mat, co_outer, &angle_ofs, &angle_delta);
+ /* draw! */
+ dial_ghostarc_draw(dial, angle_ofs, angle_delta, (const float [4]){0.8f, 0.8f, 0.8f, 0.4f});
+
+ dial_ghostarc_draw_helpline(angle_ofs, co_outer, col); /* starting position */
+ dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, col); /* starting position + current value */
+ }
+
+ /* draw actual dial manipulator */
+ dial_geom_draw(dial, col, select, mat, clip_plane);
+
+ gpuPopMatrix();
+}
+
+static void manipulator_dial_render_3d_intersect(const bContext *C, wmManipulator *manipulator, int selectionbase)
+{
+ DialManipulator *dial = (DialManipulator *)manipulator;
+ float clip_plane_buf[4];
+ float *clip_plane = (dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) ? clip_plane_buf : NULL;
+
+ /* enable clipping if needed */
+ if (clip_plane) {
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ copy_v3_v3(clip_plane, rv3d->viewinv[2]);
+ clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], manipulator->origin);
+ glEnable(GL_CLIP_DISTANCE0);
+ }
+
+ GPU_select_load_id(selectionbase);
+ dial_draw_intern(C, dial, true, false, clip_plane);
+
+ if (clip_plane) {
+ glDisable(GL_CLIP_DISTANCE0);
+ }
+}
+
+static void manipulator_dial_draw(const bContext *C, wmManipulator *manipulator)
+{
+ DialManipulator *dial = (DialManipulator *)manipulator;
+ const bool active = manipulator->state & WM_MANIPULATOR_ACTIVE;
+ const bool highlight = (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0;
+ float clip_plane_buf[4];
+ float *clip_plane = (!active && dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) ? clip_plane_buf : NULL;
+
+ /* enable clipping if needed */
+ if (clip_plane) {
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ copy_v3_v3(clip_plane, rv3d->viewinv[2]);
+ clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], manipulator->origin);
+ clip_plane[3] -= 0.02 * dial->manipulator.scale;
+
+ glEnable(GL_CLIP_DISTANCE0);
+ }
+
+ glEnable(GL_BLEND);
+ dial_draw_intern(C, dial, false, highlight, clip_plane);
+ glDisable(GL_BLEND);
+
+ if (clip_plane) {
+ glDisable(GL_CLIP_DISTANCE0);
+ }
+}
+
+static int manipulator_dial_invoke(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator)
+{
+ DialInteraction *inter = MEM_callocN(sizeof(DialInteraction), __func__);
+
+ inter->init_mval[0] = event->mval[0];
+ inter->init_mval[1] = event->mval[1];
+
+ manipulator->interaction_data = inter;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+/* -------------------------------------------------------------------- */
+/** \name Dial Manipulator API
+ *
+ * \{ */
+
+wmManipulator *MANIPULATOR_dial_new(wmManipulatorGroup *mgroup, const char *name, const int style)
+{
+ DialManipulator *dial = MEM_callocN(sizeof(DialManipulator), name);
+ const float dir_default[3] = {0.0f, 0.0f, 1.0f};
+
+ dial->manipulator.draw = manipulator_dial_draw;
+ dial->manipulator.intersect = NULL;
+ dial->manipulator.render_3d_intersection = manipulator_dial_render_3d_intersect;
+ dial->manipulator.invoke = manipulator_dial_invoke;
+
+ dial->style = style;
+
+ /* defaults */
+ copy_v3_v3(dial->direction, dir_default);
+
+ wm_manipulator_register(mgroup, &dial->manipulator, name);
+
+ return (wmManipulator *)dial;
+}
+
+/**
+ * Define up-direction of the dial manipulator
+ */
+void MANIPULATOR_dial_set_up_vector(wmManipulator *manipulator, const float direction[3])
+{
+ DialManipulator *dial = (DialManipulator *)manipulator;
+
+ copy_v3_v3(dial->direction, direction);
+ normalize_v3(dial->direction);
+}
+
+/** \} */ // Dial Manipulator API
+
+
+/* -------------------------------------------------------------------- */
+
+void fix_linking_manipulator_dial(void)
+{
+ (void)0;
+}
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c
new file mode 100644
index 00000000000..0f874e588bc
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c
@@ -0,0 +1,141 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c
+ * \ingroup wm
+ */
+
+#include "manipulator_geometry.h"
+
+static float verts[][3] = {
+ {-0.000000, 0.012320, 0.000000},
+ {-0.000000, 0.012320, 0.974306},
+ {0.008711, 0.008711, 0.000000},
+ {0.008711, 0.008711, 0.974306},
+ {0.012320, -0.000000, 0.000000},
+ {0.012320, -0.000000, 0.974306},
+ {0.008711, -0.008711, 0.000000},
+ {0.008711, -0.008711, 0.974306},
+ {-0.000000, -0.012320, 0.000000},
+ {-0.000000, -0.012320, 0.974306},
+ {-0.008711, -0.008711, 0.000000},
+ {-0.008711, -0.008711, 0.974306},
+ {-0.012320, 0.000000, 0.000000},
+ {-0.012320, 0.000000, 0.974306},
+ {-0.008711, 0.008711, 0.000000},
+ {-0.008711, 0.008711, 0.974306},
+ {0.000000, 0.072555, 0.974306},
+ {0.051304, 0.051304, 0.974306},
+ {0.072555, -0.000000, 0.974306},
+ {0.051304, -0.051304, 0.974306},
+ {-0.000000, -0.072555, 0.974306},
+ {-0.051304, -0.051304, 0.974306},
+ {-0.072555, 0.000000, 0.974306},
+ {-0.051304, 0.051304, 0.974306},
+ {0.000000, -0.000000, 1.268098},
+};
+
+static float normals[][3] = {
+ {0.000000, 0.776360, -0.630238},
+ {0.000000, 0.594348, -0.804163},
+ {0.548967, 0.548967, -0.630238},
+ {0.420270, 0.420270, -0.804163},
+ {0.776360, 0.000000, -0.630238},
+ {0.594378, 0.000000, -0.804163},
+ {0.548967, -0.548967, -0.630238},
+ {0.420270, -0.420270, -0.804163},
+ {0.000000, -0.776360, -0.630238},
+ {0.000000, -0.594378, -0.804163},
+ {-0.548967, -0.548967, -0.630238},
+ {-0.420270, -0.420270, -0.804163},
+ {-0.776360, 0.000000, -0.630238},
+ {-0.594378, 0.000000, -0.804163},
+ {-0.548967, 0.548967, -0.630238},
+ {-0.420270, 0.420270, -0.804163},
+ {0.000000, 0.843226, -0.537492},
+ {0.596271, 0.596271, -0.537492},
+ {0.843226, 0.000000, -0.537492},
+ {0.596271, -0.596271, -0.537492},
+ {0.000000, -0.843226, -0.537492},
+ {-0.596271, -0.596271, -0.537492},
+ {-0.843226, 0.000000, -0.537492},
+ {-0.596271, 0.596271, -0.537492},
+ {0.000000, 0.000000, 1.000000},
+};
+
+static unsigned short indices[] = {
+ 1, 3, 2,
+ 3, 5, 4,
+ 5, 7, 6,
+ 7, 9, 8,
+ 9, 11, 10,
+ 11, 13, 12,
+ 5, 18, 19,
+ 15, 1, 0,
+ 13, 15, 14,
+ 6, 10, 14,
+ 11, 21, 22,
+ 7, 19, 20,
+ 13, 22, 23,
+ 3, 17, 18,
+ 9, 20, 21,
+ 15, 23, 16,
+ 1, 16, 17,
+ 23, 22, 24,
+ 21, 20, 24,
+ 19, 18, 24,
+ 17, 16, 24,
+ 16, 23, 24,
+ 22, 21, 24,
+ 20, 19, 24,
+ 18, 17, 24,
+ 0, 1, 2,
+ 2, 3, 4,
+ 4, 5, 6,
+ 6, 7, 8,
+ 8, 9, 10,
+ 10, 11, 12,
+ 7, 5, 19,
+ 14, 15, 0,
+ 12, 13, 14,
+ 14, 0, 2,
+ 2, 4, 6,
+ 6, 8, 10,
+ 10, 12, 14,
+ 14, 2, 6,
+ 13, 11, 22,
+ 9, 7, 20,
+ 15, 13, 23,
+ 5, 3, 18,
+ 11, 9, 21,
+ 1, 15, 16,
+ 3, 1, 17,
+};
+
+ManipulatorGeomInfo wm_manipulator_geom_data_arrow = {
+ .nverts = 25,
+ .ntris = 46,
+ .verts = verts,
+ .normals = normals,
+ .indices = indices,
+};
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c
new file mode 100644
index 00000000000..d0600705258
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c
@@ -0,0 +1,75 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c
+ * \ingroup wm
+ */
+
+#include "manipulator_geometry.h"
+
+static const float verts[][3] = {
+ {1.000000, 1.000000, -1.000000},
+ {1.000000, -1.000000, -1.000000},
+ {-1.000000, -1.000000, -1.000000},
+ {-1.000000, 1.000000, -1.000000},
+ {1.000000, 1.000000, 1.000000},
+ {0.999999, -1.000001, 1.000000},
+ {-1.000000, -1.000000, 1.000000},
+ {-1.000000, 1.000000, 1.000000},
+};
+
+static const float normals[][3] = {
+ {0.577349, 0.577349, -0.577349},
+ {0.577349, -0.577349, -0.577349},
+ {-0.577349, -0.577349, -0.577349},
+ {-0.577349, 0.577349, -0.577349},
+ {0.577349, 0.577349, 0.577349},
+ {0.577349, -0.577349, 0.577349},
+ {-0.577349, -0.577349, 0.577349},
+ {-0.577349, 0.577349, 0.577349},
+};
+
+static const unsigned short indices[] = {
+ 1, 2, 3,
+ 7, 6, 5,
+ 4, 5, 1,
+ 5, 6, 2,
+ 2, 6, 7,
+ 0, 3, 7,
+ 0, 1, 3,
+ 4, 7, 5,
+ 0, 4, 1,
+ 1, 5, 2,
+ 3, 2, 7,
+ 4, 0, 7,
+};
+
+ManipulatorGeomInfo wm_manipulator_geom_data_cube = {
+ .nverts = 8,
+ .ntris = 12,
+ .verts = verts,
+ .normals = normals,
+ .indices = indices,
+};
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c
new file mode 100644
index 00000000000..7f2edbcf60e
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c
@@ -0,0 +1,813 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c
+ * \ingroup wm
+ */
+
+#include "manipulator_geometry.h"
+
+static const float verts[][3] = {
+ {1.034000, 0.000000, 0.000000},
+ {1.017000, 0.000000, 0.029445},
+ {0.983000, 0.000000, 0.029445},
+ {0.966000, 0.000000, 0.000000},
+ {0.983000, 0.000000, -0.029445},
+ {1.017000, 0.000000, -0.029445},
+ {1.014132, 0.201723, 0.000000},
+ {0.997459, 0.198407, 0.029445},
+ {0.964112, 0.191774, 0.029445},
+ {0.947439, 0.188457, 0.000000},
+ {0.964112, 0.191774, -0.029445},
+ {0.997459, 0.198407, -0.029445},
+ {0.955292, 0.395695, 0.000000},
+ {0.939586, 0.389189, 0.029445},
+ {0.908174, 0.376178, 0.029445},
+ {0.892468, 0.369672, 0.000000},
+ {0.908174, 0.376178, -0.029445},
+ {0.939586, 0.389189, -0.029445},
+ {0.859740, 0.574460, 0.000000},
+ {0.845605, 0.565015, 0.029445},
+ {0.817335, 0.546126, 0.029445},
+ {0.803200, 0.536681, 0.000000},
+ {0.817335, 0.546126, -0.029445},
+ {0.845605, 0.565015, -0.029445},
+ {0.731148, 0.731148, 0.000000},
+ {0.719128, 0.719128, 0.029445},
+ {0.695086, 0.695086, 0.029445},
+ {0.683065, 0.683065, 0.000000},
+ {0.695086, 0.695086, -0.029445},
+ {0.719128, 0.719128, -0.029445},
+ {0.574460, 0.859740, 0.000000},
+ {0.565015, 0.845605, 0.029445},
+ {0.546125, 0.817335, 0.029445},
+ {0.536681, 0.803200, 0.000000},
+ {0.546125, 0.817335, -0.029445},
+ {0.565015, 0.845605, -0.029445},
+ {0.395695, 0.955291, 0.000000},
+ {0.389189, 0.939585, 0.029445},
+ {0.376178, 0.908173, 0.029445},
+ {0.369672, 0.892467, 0.000000},
+ {0.376178, 0.908173, -0.029445},
+ {0.389189, 0.939585, -0.029445},
+ {0.201724, 1.014132, 0.000000},
+ {0.198407, 0.997459, 0.029445},
+ {0.191774, 0.964112, 0.029445},
+ {0.188457, 0.947439, 0.000000},
+ {0.191774, 0.964112, -0.029445},
+ {0.198407, 0.997459, -0.029445},
+ {0.000000, 1.034000, 0.000000},
+ {0.000000, 1.017000, 0.029445},
+ {0.000000, 0.983000, 0.029445},
+ {0.000000, 0.966000, 0.000000},
+ {0.000000, 0.983000, -0.029445},
+ {0.000000, 1.017000, -0.029445},
+ {-0.201723, 1.014132, 0.000000},
+ {-0.198407, 0.997459, 0.029445},
+ {-0.191774, 0.964112, 0.029445},
+ {-0.188457, 0.947439, 0.000000},
+ {-0.191774, 0.964112, -0.029445},
+ {-0.198407, 0.997459, -0.029445},
+ {-0.395695, 0.955291, 0.000000},
+ {-0.389189, 0.939585, 0.029445},
+ {-0.376178, 0.908174, 0.029445},
+ {-0.369672, 0.892468, 0.000000},
+ {-0.376178, 0.908174, -0.029445},
+ {-0.389189, 0.939585, -0.029445},
+ {-0.574459, 0.859740, 0.000000},
+ {-0.565015, 0.845605, 0.029445},
+ {-0.546125, 0.817335, 0.029445},
+ {-0.536681, 0.803200, 0.000000},
+ {-0.546125, 0.817335, -0.029445},
+ {-0.565015, 0.845605, -0.029445},
+ {-0.731149, 0.731148, 0.000000},
+ {-0.719128, 0.719127, 0.029445},
+ {-0.695086, 0.695086, 0.029445},
+ {-0.683065, 0.683065, 0.000000},
+ {-0.695086, 0.695086, -0.029445},
+ {-0.719128, 0.719127, -0.029445},
+ {-0.859740, 0.574460, 0.000000},
+ {-0.845604, 0.565015, 0.029445},
+ {-0.817335, 0.546126, 0.029445},
+ {-0.803200, 0.536681, 0.000000},
+ {-0.817335, 0.546126, -0.029445},
+ {-0.845604, 0.565015, -0.029445},
+ {-0.955291, 0.395695, 0.000000},
+ {-0.939585, 0.389189, 0.029445},
+ {-0.908173, 0.376178, 0.029445},
+ {-0.892468, 0.369672, 0.000000},
+ {-0.908173, 0.376178, -0.029445},
+ {-0.939585, 0.389189, -0.029445},
+ {-1.014132, 0.201723, 0.000000},
+ {-0.997459, 0.198407, 0.029445},
+ {-0.964112, 0.191774, 0.029445},
+ {-0.947439, 0.188457, 0.000000},
+ {-0.964112, 0.191774, -0.029445},
+ {-0.997459, 0.198407, -0.029445},
+ {-1.034000, 0.000000, 0.000000},
+ {-1.017000, 0.000000, 0.029445},
+ {-0.983000, 0.000000, 0.029445},
+ {-0.966000, 0.000000, 0.000000},
+ {-0.983000, 0.000000, -0.029445},
+ {-1.017000, 0.000000, -0.029445},
+ {-1.014132, -0.201723, 0.000000},
+ {-0.997459, -0.198407, 0.029445},
+ {-0.964112, -0.191774, 0.029445},
+ {-0.947439, -0.188457, 0.000000},
+ {-0.964112, -0.191774, -0.029445},
+ {-0.997459, -0.198407, -0.029445},
+ {-0.955292, -0.395694, 0.000000},
+ {-0.939586, -0.389189, 0.029445},
+ {-0.908174, -0.376177, 0.029445},
+ {-0.892468, -0.369672, 0.000000},
+ {-0.908174, -0.376177, -0.029445},
+ {-0.939586, -0.389189, -0.029445},
+ {-0.859740, -0.574460, 0.000000},
+ {-0.845604, -0.565015, 0.029445},
+ {-0.817335, -0.546126, 0.029445},
+ {-0.803200, -0.536681, 0.000000},
+ {-0.817335, -0.546126, -0.029445},
+ {-0.845604, -0.565015, -0.029445},
+ {-0.731149, -0.731148, 0.000000},
+ {-0.719128, -0.719127, 0.029445},
+ {-0.695086, -0.695086, 0.029445},
+ {-0.683065, -0.683065, 0.000000},
+ {-0.695086, -0.695086, -0.029445},
+ {-0.719128, -0.719127, -0.029445},
+ {-0.574460, -0.859739, 0.000000},
+ {-0.565015, -0.845604, 0.029445},
+ {-0.546126, -0.817334, 0.029445},
+ {-0.536681, -0.803199, 0.000000},
+ {-0.546126, -0.817334, -0.029445},
+ {-0.565015, -0.845604, -0.029445},
+ {-0.395695, -0.955291, 0.000000},
+ {-0.389189, -0.939585, 0.029445},
+ {-0.376178, -0.908174, 0.029445},
+ {-0.369672, -0.892468, 0.000000},
+ {-0.376178, -0.908174, -0.029445},
+ {-0.389189, -0.939585, -0.029445},
+ {-0.201724, -1.014132, 0.000000},
+ {-0.198407, -0.997459, 0.029445},
+ {-0.191774, -0.964112, 0.029445},
+ {-0.188458, -0.947438, 0.000000},
+ {-0.191774, -0.964112, -0.029445},
+ {-0.198407, -0.997459, -0.029445},
+ {0.000000, -1.034000, 0.000000},
+ {0.000000, -1.017000, 0.029445},
+ {0.000000, -0.983000, 0.029445},
+ {0.000000, -0.966000, 0.000000},
+ {0.000000, -0.983000, -0.029445},
+ {0.000000, -1.017000, -0.029445},
+ {0.201723, -1.014132, 0.000000},
+ {0.198407, -0.997459, 0.029445},
+ {0.191773, -0.964112, 0.029445},
+ {0.188457, -0.947439, 0.000000},
+ {0.191773, -0.964112, -0.029445},
+ {0.198407, -0.997459, -0.029445},
+ {0.395695, -0.955291, 0.000000},
+ {0.389189, -0.939585, 0.029445},
+ {0.376178, -0.908173, 0.029445},
+ {0.369672, -0.892467, 0.000000},
+ {0.376178, -0.908173, -0.029445},
+ {0.389189, -0.939585, -0.029445},
+ {0.574460, -0.859740, 0.000000},
+ {0.565015, -0.845605, 0.029445},
+ {0.546125, -0.817335, 0.029445},
+ {0.536681, -0.803200, 0.000000},
+ {0.546125, -0.817335, -0.029445},
+ {0.565015, -0.845605, -0.029445},
+ {0.731148, -0.731149, 0.000000},
+ {0.719127, -0.719128, 0.029445},
+ {0.695086, -0.695086, 0.029445},
+ {0.683065, -0.683066, 0.000000},
+ {0.695086, -0.695086, -0.029445},
+ {0.719127, -0.719128, -0.029445},
+ {0.859740, -0.574460, 0.000000},
+ {0.845605, -0.565015, 0.029445},
+ {0.817335, -0.546126, 0.029445},
+ {0.803200, -0.536681, 0.000000},
+ {0.817335, -0.546126, -0.029445},
+ {0.845605, -0.565015, -0.029445},
+ {0.955291, -0.395695, 0.000000},
+ {0.939585, -0.389189, 0.029445},
+ {0.908173, -0.376178, 0.029445},
+ {0.892467, -0.369673, 0.000000},
+ {0.908173, -0.376178, -0.029445},
+ {0.939585, -0.389189, -0.029445},
+ {1.014132, -0.201723, 0.000000},
+ {0.997459, -0.198407, 0.029445},
+ {0.964112, -0.191774, 0.029445},
+ {0.947439, -0.188457, 0.000000},
+ {0.964112, -0.191774, -0.029445},
+ {0.997459, -0.198407, -0.029445},
+};
+
+static const float normals[][3] = {
+ {1.000000, 0.000000, 0.000000},
+ {0.522691, 0.000000, 0.852504},
+ {-0.475845, 0.000000, 0.879513},
+ {-1.000000, 0.000000, 0.000000},
+ {-0.475845, 0.000000, -0.879513},
+ {0.522691, 0.000000, -0.852504},
+ {0.980773, 0.195074, 0.000000},
+ {0.512650, 0.101962, 0.852504},
+ {-0.466689, -0.092807, 0.879513},
+ {-0.980773, -0.195074, 0.000000},
+ {-0.466689, -0.092807, -0.879513},
+ {0.512650, 0.101962, -0.852504},
+ {0.923856, 0.382672, 0.000000},
+ {0.482894, 0.200018, 0.852504},
+ {-0.439619, -0.182073, 0.879513},
+ {-0.923856, -0.382672, 0.000000},
+ {-0.439619, -0.182073, -0.879513},
+ {0.482894, 0.200018, -0.852504},
+ {0.831446, 0.555559, 0.000000},
+ {0.434614, 0.290384, 0.852504},
+ {-0.395642, -0.264351, 0.879513},
+ {-0.831446, -0.555559, 0.000000},
+ {-0.395642, -0.264351, -0.879513},
+ {0.434614, 0.290384, -0.852504},
+ {0.707083, 0.707083, 0.000000},
+ {0.369610, 0.369610, 0.852504},
+ {-0.336467, -0.336467, 0.879513},
+ {-0.707083, -0.707083, 0.000000},
+ {-0.336467, -0.336467, -0.879513},
+ {0.369610, 0.369610, -0.852504},
+ {0.555559, 0.831446, 0.000000},
+ {0.290384, 0.434614, 0.852504},
+ {-0.264351, -0.395642, 0.879513},
+ {-0.555559, -0.831446, 0.000000},
+ {-0.264351, -0.395642, -0.879513},
+ {0.290384, 0.434614, -0.852504},
+ {0.382672, 0.923856, 0.000000},
+ {0.200018, 0.482894, 0.852504},
+ {-0.182073, -0.439619, 0.879513},
+ {-0.382672, -0.923856, 0.000000},
+ {-0.182073, -0.439619, -0.879513},
+ {0.200018, 0.482894, -0.852504},
+ {0.195074, 0.980773, 0.000000},
+ {0.101962, 0.512650, 0.852504},
+ {-0.092807, -0.466689, 0.879513},
+ {-0.195074, -0.980773, 0.000000},
+ {-0.092807, -0.466689, -0.879513},
+ {0.101962, 0.512650, -0.852504},
+ {0.000000, 1.000000, 0.000000},
+ {0.000000, 0.522691, 0.852504},
+ {0.000000, -0.475845, 0.879513},
+ {0.000000, -1.000000, 0.000000},
+ {0.000000, -0.475845, -0.879513},
+ {0.000000, 0.522691, -0.852504},
+ {-0.195074, 0.980773, 0.000000},
+ {-0.101962, 0.512650, 0.852504},
+ {0.092807, -0.466689, 0.879513},
+ {0.195074, -0.980773, 0.000000},
+ {0.092807, -0.466689, -0.879513},
+ {-0.101962, 0.512650, -0.852504},
+ {-0.382672, 0.923856, 0.000000},
+ {-0.200018, 0.482894, 0.852504},
+ {0.182073, -0.439619, 0.879513},
+ {0.382672, -0.923856, 0.000000},
+ {0.182073, -0.439619, -0.879513},
+ {-0.200018, 0.482894, -0.852504},
+ {-0.555559, 0.831446, 0.000000},
+ {-0.290384, 0.434614, 0.852504},
+ {0.264351, -0.395642, 0.879513},
+ {0.555559, -0.831446, 0.000000},
+ {0.264351, -0.395642, -0.879513},
+ {-0.290384, 0.434614, -0.852504},
+ {-0.707083, 0.707083, 0.000000},
+ {-0.369610, 0.369610, 0.852504},
+ {0.336467, -0.336467, 0.879513},
+ {0.707083, -0.707083, 0.000000},
+ {0.336467, -0.336467, -0.879513},
+ {-0.369610, 0.369610, -0.852504},
+ {-0.831446, 0.555559, 0.000000},
+ {-0.434614, 0.290384, 0.852504},
+ {0.395642, -0.264351, 0.879513},
+ {0.831446, -0.555559, 0.000000},
+ {0.395642, -0.264351, -0.879513},
+ {-0.434614, 0.290384, -0.852504},
+ {-0.923856, 0.382672, 0.000000},
+ {-0.482894, 0.200018, 0.852504},
+ {0.439619, -0.182073, 0.879513},
+ {0.923856, -0.382672, 0.000000},
+ {0.439619, -0.182073, -0.879513},
+ {-0.482894, 0.200018, -0.852504},
+ {-0.980773, 0.195074, 0.000000},
+ {-0.512650, 0.101962, 0.852504},
+ {0.466689, -0.092807, 0.879513},
+ {0.980773, -0.195074, 0.000000},
+ {0.466689, -0.092807, -0.879513},
+ {-0.512650, 0.101962, -0.852504},
+ {-1.000000, 0.000000, 0.000000},
+ {-0.522691, 0.000000, 0.852504},
+ {0.475845, 0.000000, 0.879513},
+ {1.000000, 0.000000, 0.000000},
+ {0.475845, 0.000000, -0.879513},
+ {-0.522691, 0.000000, -0.852504},
+ {-0.980773, -0.195074, 0.000000},
+ {-0.512650, -0.101962, 0.852504},
+ {0.466689, 0.092807, 0.879513},
+ {0.980773, 0.195074, 0.000000},
+ {0.466689, 0.092807, -0.879513},
+ {-0.512650, -0.101962, -0.852504},
+ {-0.923856, -0.382672, 0.000000},
+ {-0.482894, -0.200018, 0.852504},
+ {0.439619, 0.182073, 0.879513},
+ {0.923856, 0.382672, 0.000000},
+ {0.439619, 0.182073, -0.879513},
+ {-0.482894, -0.200018, -0.852504},
+ {-0.831446, -0.555559, 0.000000},
+ {-0.434614, -0.290384, 0.852504},
+ {0.395642, 0.264351, 0.879513},
+ {0.831446, 0.555559, 0.000000},
+ {0.395642, 0.264351, -0.879513},
+ {-0.434614, -0.290384, -0.852504},
+ {-0.707083, -0.707083, 0.000000},
+ {-0.369610, -0.369610, 0.852504},
+ {0.336467, 0.336467, 0.879513},
+ {0.707083, 0.707083, 0.000000},
+ {0.336467, 0.336467, -0.879513},
+ {-0.369610, -0.369610, -0.852504},
+ {-0.555559, -0.831446, 0.000000},
+ {-0.290384, -0.434614, 0.852504},
+ {0.264351, 0.395642, 0.879513},
+ {0.555559, 0.831446, 0.000000},
+ {0.264351, 0.395642, -0.879513},
+ {-0.290384, -0.434614, -0.852504},
+ {-0.382672, -0.923856, 0.000000},
+ {-0.200018, -0.482894, 0.852504},
+ {0.182073, 0.439619, 0.879513},
+ {0.382672, 0.923856, 0.000000},
+ {0.182073, 0.439619, -0.879513},
+ {-0.200018, -0.482894, -0.852504},
+ {-0.195074, -0.980773, 0.000000},
+ {-0.101962, -0.512650, 0.852504},
+ {0.092807, 0.466689, 0.879513},
+ {0.195074, 0.980773, 0.000000},
+ {0.092807, 0.466689, -0.879513},
+ {-0.101962, -0.512650, -0.852504},
+ {0.000000, -1.000000, 0.000000},
+ {0.000000, -0.522691, 0.852504},
+ {0.000000, 0.475845, 0.879513},
+ {0.000000, 1.000000, 0.000000},
+ {0.000000, 0.475845, -0.879513},
+ {0.000000, -0.522691, -0.852504},
+ {0.195074, -0.980773, 0.000000},
+ {0.101962, -0.512650, 0.852504},
+ {-0.092807, 0.466689, 0.879513},
+ {-0.195074, 0.980773, 0.000000},
+ {-0.092807, 0.466689, -0.879513},
+ {0.101962, -0.512650, -0.852504},
+ {0.382672, -0.923856, 0.000000},
+ {0.200018, -0.482894, 0.852504},
+ {-0.182073, 0.439619, 0.879513},
+ {-0.382672, 0.923856, 0.000000},
+ {-0.182073, 0.439619, -0.879513},
+ {0.200018, -0.482894, -0.852504},
+ {0.555559, -0.831446, 0.000000},
+ {0.290384, -0.434614, 0.852504},
+ {-0.264351, 0.395642, 0.879513},
+ {-0.555559, 0.831446, 0.000000},
+ {-0.264351, 0.395642, -0.879513},
+ {0.290384, -0.434614, -0.852504},
+ {0.707083, -0.707083, 0.000000},
+ {0.369610, -0.369610, 0.852504},
+ {-0.336467, 0.336467, 0.879513},
+ {-0.707083, 0.707083, 0.000000},
+ {-0.336467, 0.336467, -0.879513},
+ {0.369610, -0.369610, -0.852504},
+ {0.831446, -0.555559, 0.000000},
+ {0.434614, -0.290384, 0.852504},
+ {-0.395642, 0.264351, 0.879513},
+ {-0.831446, 0.555559, 0.000000},
+ {-0.395642, 0.264351, -0.879513},
+ {0.434614, -0.290384, -0.852504},
+ {0.923856, -0.382672, 0.000000},
+ {0.482894, -0.200018, 0.852504},
+ {-0.439619, 0.182073, 0.879513},
+ {-0.923856, 0.382672, 0.000000},
+ {-0.439619, 0.182073, -0.879513},
+ {0.482894, -0.200018, -0.852504},
+ {0.980773, -0.195074, 0.000000},
+ {0.512650, -0.101962, 0.852504},
+ {-0.466689, 0.092807, 0.879513},
+ {-0.980773, 0.195074, 0.000000},
+ {-0.466689, 0.092807, -0.879513},
+ {0.512650, -0.101962, -0.852504},
+};
+
+static const unsigned short indices[] = {
+ 6, 7, 1,
+ 7, 8, 2,
+ 8, 9, 3,
+ 9, 10, 4,
+ 10, 11, 5,
+ 5, 11, 6,
+ 12, 13, 7,
+ 13, 14, 8,
+ 14, 15, 9,
+ 15, 16, 10,
+ 16, 17, 11,
+ 11, 17, 12,
+ 18, 19, 13,
+ 13, 19, 20,
+ 20, 21, 15,
+ 15, 21, 22,
+ 22, 23, 17,
+ 17, 23, 18,
+ 24, 25, 19,
+ 19, 25, 26,
+ 26, 27, 21,
+ 21, 27, 28,
+ 28, 29, 23,
+ 23, 29, 24,
+ 30, 31, 25,
+ 25, 31, 32,
+ 26, 32, 33,
+ 27, 33, 34,
+ 34, 35, 29,
+ 29, 35, 30,
+ 36, 37, 31,
+ 31, 37, 38,
+ 38, 39, 33,
+ 39, 40, 34,
+ 40, 41, 35,
+ 35, 41, 36,
+ 36, 42, 43,
+ 43, 44, 38,
+ 44, 45, 39,
+ 45, 46, 40,
+ 46, 47, 41,
+ 47, 42, 36,
+ 48, 49, 43,
+ 49, 50, 44,
+ 50, 51, 45,
+ 51, 52, 46,
+ 52, 53, 47,
+ 47, 53, 48,
+ 54, 55, 49,
+ 49, 55, 56,
+ 50, 56, 57,
+ 57, 58, 52,
+ 58, 59, 53,
+ 53, 59, 54,
+ 60, 61, 55,
+ 55, 61, 62,
+ 56, 62, 63,
+ 63, 64, 58,
+ 64, 65, 59,
+ 59, 65, 60,
+ 66, 67, 61,
+ 61, 67, 68,
+ 68, 69, 63,
+ 69, 70, 64,
+ 70, 71, 65,
+ 71, 66, 60,
+ 72, 73, 67,
+ 73, 74, 68,
+ 68, 74, 75,
+ 75, 76, 70,
+ 76, 77, 71,
+ 71, 77, 72,
+ 78, 79, 73,
+ 79, 80, 74,
+ 74, 80, 81,
+ 81, 82, 76,
+ 82, 83, 77,
+ 83, 78, 72,
+ 78, 84, 85,
+ 85, 86, 80,
+ 80, 86, 87,
+ 87, 88, 82,
+ 82, 88, 89,
+ 89, 84, 78,
+ 90, 91, 85,
+ 91, 92, 86,
+ 86, 92, 93,
+ 93, 94, 88,
+ 88, 94, 95,
+ 95, 90, 84,
+ 96, 97, 91,
+ 97, 98, 92,
+ 98, 99, 93,
+ 99, 100, 94,
+ 100, 101, 95,
+ 101, 96, 90,
+ 102, 103, 97,
+ 103, 104, 98,
+ 104, 105, 99,
+ 99, 105, 106,
+ 106, 107, 101,
+ 101, 107, 102,
+ 108, 109, 103,
+ 103, 109, 110,
+ 110, 111, 105,
+ 105, 111, 112,
+ 112, 113, 107,
+ 107, 113, 108,
+ 114, 115, 109,
+ 115, 116, 110,
+ 116, 117, 111,
+ 111, 117, 118,
+ 112, 118, 119,
+ 113, 119, 114,
+ 114, 120, 121,
+ 121, 122, 116,
+ 122, 123, 117,
+ 117, 123, 124,
+ 124, 125, 119,
+ 125, 120, 114,
+ 126, 127, 121,
+ 121, 127, 128,
+ 128, 129, 123,
+ 123, 129, 130,
+ 130, 131, 125,
+ 125, 131, 126,
+ 132, 133, 127,
+ 133, 134, 128,
+ 128, 134, 135,
+ 135, 136, 130,
+ 136, 137, 131,
+ 131, 137, 132,
+ 132, 138, 139,
+ 133, 139, 140,
+ 134, 140, 141,
+ 141, 142, 136,
+ 142, 143, 137,
+ 143, 138, 132,
+ 138, 144, 145,
+ 139, 145, 146,
+ 146, 147, 141,
+ 141, 147, 148,
+ 148, 149, 143,
+ 149, 144, 138,
+ 144, 150, 151,
+ 151, 152, 146,
+ 146, 152, 153,
+ 153, 154, 148,
+ 154, 155, 149,
+ 155, 150, 144,
+ 156, 157, 151,
+ 151, 157, 158,
+ 158, 159, 153,
+ 159, 160, 154,
+ 160, 161, 155,
+ 155, 161, 156,
+ 156, 162, 163,
+ 163, 164, 158,
+ 158, 164, 165,
+ 165, 166, 160,
+ 160, 166, 167,
+ 167, 162, 156,
+ 162, 168, 169,
+ 169, 170, 164,
+ 164, 170, 171,
+ 165, 171, 172,
+ 166, 172, 173,
+ 173, 168, 162,
+ 174, 175, 169,
+ 175, 176, 170,
+ 170, 176, 177,
+ 177, 178, 172,
+ 172, 178, 179,
+ 173, 179, 174,
+ 174, 180, 181,
+ 181, 182, 176,
+ 176, 182, 183,
+ 183, 184, 178,
+ 178, 184, 185,
+ 179, 185, 180,
+ 186, 187, 181,
+ 187, 188, 182,
+ 188, 189, 183,
+ 183, 189, 190,
+ 190, 191, 185,
+ 191, 186, 180,
+ 0, 1, 187,
+ 1, 2, 188,
+ 2, 3, 189,
+ 3, 4, 190,
+ 190, 4, 5,
+ 191, 5, 0,
+ 0, 6, 1,
+ 1, 7, 2,
+ 2, 8, 3,
+ 3, 9, 4,
+ 4, 10, 5,
+ 0, 5, 6,
+ 6, 12, 7,
+ 7, 13, 8,
+ 8, 14, 9,
+ 9, 15, 10,
+ 10, 16, 11,
+ 6, 11, 12,
+ 12, 18, 13,
+ 14, 13, 20,
+ 14, 20, 15,
+ 16, 15, 22,
+ 16, 22, 17,
+ 12, 17, 18,
+ 18, 24, 19,
+ 20, 19, 26,
+ 20, 26, 21,
+ 22, 21, 28,
+ 22, 28, 23,
+ 18, 23, 24,
+ 24, 30, 25,
+ 26, 25, 32,
+ 27, 26, 33,
+ 28, 27, 34,
+ 28, 34, 29,
+ 24, 29, 30,
+ 30, 36, 31,
+ 32, 31, 38,
+ 32, 38, 33,
+ 33, 39, 34,
+ 34, 40, 35,
+ 30, 35, 36,
+ 37, 36, 43,
+ 37, 43, 38,
+ 38, 44, 39,
+ 39, 45, 40,
+ 40, 46, 41,
+ 41, 47, 36,
+ 42, 48, 43,
+ 43, 49, 44,
+ 44, 50, 45,
+ 45, 51, 46,
+ 46, 52, 47,
+ 42, 47, 48,
+ 48, 54, 49,
+ 50, 49, 56,
+ 51, 50, 57,
+ 51, 57, 52,
+ 52, 58, 53,
+ 48, 53, 54,
+ 54, 60, 55,
+ 56, 55, 62,
+ 57, 56, 63,
+ 57, 63, 58,
+ 58, 64, 59,
+ 54, 59, 60,
+ 60, 66, 61,
+ 62, 61, 68,
+ 62, 68, 63,
+ 63, 69, 64,
+ 64, 70, 65,
+ 65, 71, 60,
+ 66, 72, 67,
+ 67, 73, 68,
+ 69, 68, 75,
+ 69, 75, 70,
+ 70, 76, 71,
+ 66, 71, 72,
+ 72, 78, 73,
+ 73, 79, 74,
+ 75, 74, 81,
+ 75, 81, 76,
+ 76, 82, 77,
+ 77, 83, 72,
+ 79, 78, 85,
+ 79, 85, 80,
+ 81, 80, 87,
+ 81, 87, 82,
+ 83, 82, 89,
+ 83, 89, 78,
+ 84, 90, 85,
+ 85, 91, 86,
+ 87, 86, 93,
+ 87, 93, 88,
+ 89, 88, 95,
+ 89, 95, 84,
+ 90, 96, 91,
+ 91, 97, 92,
+ 92, 98, 93,
+ 93, 99, 94,
+ 94, 100, 95,
+ 95, 101, 90,
+ 96, 102, 97,
+ 97, 103, 98,
+ 98, 104, 99,
+ 100, 99, 106,
+ 100, 106, 101,
+ 96, 101, 102,
+ 102, 108, 103,
+ 104, 103, 110,
+ 104, 110, 105,
+ 106, 105, 112,
+ 106, 112, 107,
+ 102, 107, 108,
+ 108, 114, 109,
+ 109, 115, 110,
+ 110, 116, 111,
+ 112, 111, 118,
+ 113, 112, 119,
+ 108, 113, 114,
+ 115, 114, 121,
+ 115, 121, 116,
+ 116, 122, 117,
+ 118, 117, 124,
+ 118, 124, 119,
+ 119, 125, 114,
+ 120, 126, 121,
+ 122, 121, 128,
+ 122, 128, 123,
+ 124, 123, 130,
+ 124, 130, 125,
+ 120, 125, 126,
+ 126, 132, 127,
+ 127, 133, 128,
+ 129, 128, 135,
+ 129, 135, 130,
+ 130, 136, 131,
+ 126, 131, 132,
+ 133, 132, 139,
+ 134, 133, 140,
+ 135, 134, 141,
+ 135, 141, 136,
+ 136, 142, 137,
+ 137, 143, 132,
+ 139, 138, 145,
+ 140, 139, 146,
+ 140, 146, 141,
+ 142, 141, 148,
+ 142, 148, 143,
+ 143, 149, 138,
+ 145, 144, 151,
+ 145, 151, 146,
+ 147, 146, 153,
+ 147, 153, 148,
+ 148, 154, 149,
+ 149, 155, 144,
+ 150, 156, 151,
+ 152, 151, 158,
+ 152, 158, 153,
+ 153, 159, 154,
+ 154, 160, 155,
+ 150, 155, 156,
+ 157, 156, 163,
+ 157, 163, 158,
+ 159, 158, 165,
+ 159, 165, 160,
+ 161, 160, 167,
+ 161, 167, 156,
+ 163, 162, 169,
+ 163, 169, 164,
+ 165, 164, 171,
+ 166, 165, 172,
+ 167, 166, 173,
+ 167, 173, 162,
+ 168, 174, 169,
+ 169, 175, 170,
+ 171, 170, 177,
+ 171, 177, 172,
+ 173, 172, 179,
+ 168, 173, 174,
+ 175, 174, 181,
+ 175, 181, 176,
+ 177, 176, 183,
+ 177, 183, 178,
+ 179, 178, 185,
+ 174, 179, 180,
+ 180, 186, 181,
+ 181, 187, 182,
+ 182, 188, 183,
+ 184, 183, 190,
+ 184, 190, 185,
+ 185, 191, 180,
+ 186, 0, 187,
+ 187, 1, 188,
+ 188, 2, 189,
+ 189, 3, 190,
+ 191, 190, 5,
+ 186, 191, 0,
+};
+
+ManipulatorGeomInfo wm_manipulator_geom_data_dial = {
+ .nverts = 192,
+ .ntris = 384,
+ .verts = verts,
+ .normals = normals,
+ .indices = indices,
+};
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h
new file mode 100644
index 00000000000..b3df79834a3
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h
@@ -0,0 +1,51 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h
+ * \ingroup wm
+ *
+ * \name Manipulator Geometry
+ *
+ * \brief Prototypes for arrays defining the manipulator geometry. The actual definitions can be found in files usually
+ * called geom_xxx_manipulator.c
+ */
+
+
+#ifndef __MANIPULATOR_GEOMETRY_H__
+#define __MANIPULATOR_GEOMETRY_H__
+
+typedef struct ManipulatorGeomInfo {
+ int nverts;
+ int ntris;
+ const float (*verts)[3];
+ const float (*normals)[3];
+ const unsigned short *indices;
+} ManipulatorGeomInfo;
+
+/* arrow manipulator */
+extern ManipulatorGeomInfo wm_manipulator_geom_data_arrow;
+
+/* cube manipulator */
+extern ManipulatorGeomInfo wm_manipulator_geom_data_cube;
+
+#endif /* __MANIPULATOR_GEOMETRY_H__ */
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h
new file mode 100644
index 00000000000..e432fa1523a
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h
@@ -0,0 +1,100 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h
+ * \ingroup wm
+ */
+
+
+#ifndef __MANIPULATOR_LIBRARY_INTERN_H__
+#define __MANIPULATOR_LIBRARY_INTERN_H__
+
+/* distance around which manipulators respond to input (and get highlighted) */
+#define MANIPULATOR_HOTSPOT 14.0f
+
+/**
+ * Data for common interactions. Used in manipulator_library_utils.c functions.
+ */
+typedef struct ManipulatorCommonData {
+ int flag;
+
+ float range_fac; /* factor for arrow min/max distance */
+ float offset;
+
+ /* property range for constrained manipulators */
+ float range;
+ /* min/max value for constrained manipulators */
+ float min, max;
+} ManipulatorCommonData;
+
+typedef struct ManipulatorInteraction {
+ float init_value; /* initial property value */
+ float init_origin[3];
+ float init_mval[2];
+ float init_offset;
+ float init_scale;
+
+ /* offset of last handling step */
+ float prev_offset;
+ /* Total offset added by precision tweaking.
+ * Needed to allow toggling precision on/off without causing jumps */
+ float precision_offset;
+} ManipulatorInteraction;
+
+/* ManipulatorCommonData->flag */
+enum {
+ MANIPULATOR_CUSTOM_RANGE_SET = (1 << 0),
+};
+
+
+float manipulator_offset_from_value(
+ ManipulatorCommonData *data, const float value,
+ const bool constrained, const bool inverted);
+float manipulator_value_from_offset(
+ ManipulatorCommonData *data, ManipulatorInteraction *inter, const float offset,
+ const bool constrained, const bool inverted, const bool use_precision);
+
+void manipulator_property_data_update(
+ struct wmManipulator *manipulator, ManipulatorCommonData *data, const int slot,
+ const bool constrained, const bool inverted);
+
+void manipulator_property_value_set(
+ bContext *C, const struct wmManipulator *manipulator,
+ const int slot, const float value);
+float manipulator_property_value_get(
+ const struct wmManipulator *manipulator, const int slot);
+void manipulator_property_value_reset(
+ bContext *C, const struct wmManipulator *manipulator, ManipulatorInteraction *inter,
+ const int slot);
+
+
+/* -------------------------------------------------------------------- */
+
+void manipulator_color_get(
+ const struct wmManipulator *manipulator, const bool highlight,
+ float r_col[]);
+
+#endif /* __MANIPULATOR_LIBRARY_INTERN_H__ */
+
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_utils.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_utils.c
new file mode 100644
index 00000000000..0617e9e873b
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_utils.c
@@ -0,0 +1,171 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2015 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_utils.c
+ * \ingroup wm
+ *
+ * \name Manipulator Library Utilities
+ *
+ * \brief This file contains functions for common behaviors of manipulators.
+ */
+
+#include "BKE_context.h"
+
+#include "BLI_math.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+
+/* own includes */
+#include "WM_manipulator_types.h"
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+#include "manipulator_library_intern.h"
+
+/* factor for precision tweaking */
+#define MANIPULATOR_PRECISION_FAC 0.05f
+
+
+BLI_INLINE float manipulator_offset_from_value_constr(
+ const float range_fac, const float min, const float range, const float value,
+ const bool inverted)
+{
+ return inverted ? (range_fac * (min + range - value) / range) : (range_fac * (value / range));
+}
+
+BLI_INLINE float manipulator_value_from_offset_constr(
+ const float range_fac, const float min, const float range, const float value,
+ const bool inverted)
+{
+ return inverted ? (min + range - (value * range / range_fac)) : (value * range / range_fac);
+}
+
+float manipulator_offset_from_value(
+ ManipulatorCommonData *data, const float value, const bool constrained, const bool inverted)
+{
+ if (constrained)
+ return manipulator_offset_from_value_constr(data->range_fac, data->min, data->range, value, inverted);
+
+ return value;
+}
+
+float manipulator_value_from_offset(
+ ManipulatorCommonData *data, ManipulatorInteraction *inter, const float offset,
+ const bool constrained, const bool inverted, const bool use_precision)
+{
+ const float max = data->min + data->range;
+
+ if (use_precision) {
+ /* add delta offset of this step to total precision_offset */
+ inter->precision_offset += offset - inter->prev_offset;
+ }
+ inter->prev_offset = offset;
+
+ float ofs_new = inter->init_offset + offset - inter->precision_offset * (1.0f - MANIPULATOR_PRECISION_FAC);
+ float value;
+
+ if (constrained) {
+ value = manipulator_value_from_offset_constr(data->range_fac, data->min, data->range, ofs_new, inverted);
+ }
+ else {
+ value = ofs_new;
+ }
+
+ /* clamp to custom range */
+ if (data->flag & MANIPULATOR_CUSTOM_RANGE_SET) {
+ CLAMP(value, data->min, max);
+ }
+
+ return value;
+}
+
+void manipulator_property_data_update(
+ wmManipulator *manipulator, ManipulatorCommonData *data, const int slot,
+ const bool constrained, const bool inverted)
+{
+ if (!manipulator->props[slot]) {
+ data->offset = 0.0f;
+ return;
+ }
+
+ PointerRNA ptr = manipulator->ptr[slot];
+ PropertyRNA *prop = manipulator->props[slot];
+ float value = manipulator_property_value_get(manipulator, slot);
+
+ if (constrained) {
+ if ((data->flag & MANIPULATOR_CUSTOM_RANGE_SET) == 0) {
+ float step, precision;
+ float min, max;
+ RNA_property_float_ui_range(&ptr, prop, &min, &max, &step, &precision);
+ data->range = max - min;
+ data->min = min;
+ }
+ data->offset = manipulator_offset_from_value_constr(data->range_fac, data->min, data->range, value, inverted);
+ }
+ else {
+ data->offset = value;
+ }
+}
+
+void manipulator_property_value_set(
+ bContext *C, const wmManipulator *manipulator,
+ const int slot, const float value)
+{
+ PointerRNA ptr = manipulator->ptr[slot];
+ PropertyRNA *prop = manipulator->props[slot];
+
+ /* reset property */
+ RNA_property_float_set(&ptr, prop, value);
+ RNA_property_update(C, &ptr, prop);
+}
+
+float manipulator_property_value_get(const wmManipulator *manipulator, const int slot)
+{
+ BLI_assert(RNA_property_type(manipulator->props[slot]) == PROP_FLOAT);
+ return RNA_property_float_get(&manipulator->ptr[slot], manipulator->props[slot]);
+}
+
+void manipulator_property_value_reset(
+ bContext *C, const wmManipulator *manipulator, ManipulatorInteraction *inter,
+ const int slot)
+{
+ manipulator_property_value_set(C, manipulator, slot, inter->init_value);
+}
+
+
+/* -------------------------------------------------------------------- */
+
+void manipulator_color_get(
+ const wmManipulator *manipulator, const bool highlight,
+ float r_col[4])
+{
+ if (highlight && !(manipulator->flag & WM_MANIPULATOR_DRAW_HOVER)) {
+ copy_v4_v4(r_col, manipulator->col_hi);
+ }
+ else {
+ copy_v4_v4(r_col, manipulator->col);
+ }
+}
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c
new file mode 100644
index 00000000000..bf53705a6e2
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c
@@ -0,0 +1,250 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c
+ * \ingroup wm
+ *
+ * \name Primitive Manipulator
+ *
+ * 3D Manipulator
+ *
+ * \brief Manipulator with primitive drawing type (plane, cube, etc.).
+ * Currently only plane primitive supported without own handling, use with operator only.
+ */
+
+#include "BIF_gl.h"
+
+#include "BKE_context.h"
+
+#include "BLI_math.h"
+
+#include "DNA_view3d_types.h"
+#include "DNA_manipulator_types.h"
+
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "GPU_select.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* own includes */
+#include "WM_manipulator_types.h"
+#include "WM_manipulator_library.h"
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+#include "manipulator_library_intern.h"
+
+
+/* PrimitiveManipulator->flag */
+enum {
+ PRIM_UP_VECTOR_SET = (1 << 0),
+};
+
+typedef struct PrimitiveManipulator {
+ wmManipulator manipulator;
+
+ float direction[3];
+ float up[3];
+ int style;
+ int flag;
+} PrimitiveManipulator;
+
+
+static float verts_plane[4][3] = {
+ {-1, -1, 0},
+ { 1, -1, 0},
+ { 1, 1, 0},
+ {-1, 1, 0},
+};
+
+
+/* -------------------------------------------------------------------- */
+
+static void manipulator_primitive_draw_geom(
+ const float col_inner[4], const float col_outer[4], const int style)
+{
+ float (*verts)[3];
+ unsigned int vert_count = 0;
+
+ if (style == MANIPULATOR_PRIMITIVE_STYLE_PLANE) {
+ verts = verts_plane;
+ vert_count = ARRAY_SIZE(verts_plane);
+ }
+
+ if (vert_count > 0) {
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ wm_manipulator_vec_draw(col_inner, verts, vert_count, pos, PRIM_TRIANGLE_FAN);
+ wm_manipulator_vec_draw(col_outer, verts, vert_count, pos, PRIM_LINE_LOOP);
+ immUnbindProgram();
+ }
+}
+
+static void manipulator_primitive_draw_intern(
+ PrimitiveManipulator *prim, const bool UNUSED(select),
+ const bool highlight)
+{
+ float col_inner[4], col_outer[4];
+ float rot[3][3];
+ float mat[4][4];
+
+ if (prim->flag & PRIM_UP_VECTOR_SET) {
+ copy_v3_v3(rot[2], prim->direction);
+ copy_v3_v3(rot[1], prim->up);
+ cross_v3_v3v3(rot[0], prim->up, prim->direction);
+ }
+ else {
+ const float up[3] = {0.0f, 0.0f, 1.0f};
+ rotation_between_vecs_to_mat3(rot, up, prim->direction);
+ }
+
+ copy_m4_m3(mat, rot);
+ copy_v3_v3(mat[3], prim->manipulator.origin);
+ mul_mat3_m4_fl(mat, prim->manipulator.scale);
+
+ gpuPushMatrix();
+ gpuMultMatrix(mat);
+
+ manipulator_color_get(&prim->manipulator, highlight, col_outer);
+ copy_v4_v4(col_inner, col_outer);
+ col_inner[3] *= 0.5f;
+
+ glEnable(GL_BLEND);
+ gpuTranslate3fv(prim->manipulator.offset);
+ manipulator_primitive_draw_geom(col_inner, col_outer, prim->style);
+ glDisable(GL_BLEND);
+
+ gpuPopMatrix();
+
+ if (prim->manipulator.interaction_data) {
+ ManipulatorInteraction *inter = prim->manipulator.interaction_data;
+
+ copy_v4_fl(col_inner, 0.5f);
+ copy_v3_fl(col_outer, 0.5f);
+ col_outer[3] = 0.8f;
+
+ copy_m4_m3(mat, rot);
+ copy_v3_v3(mat[3], inter->init_origin);
+ mul_mat3_m4_fl(mat, inter->init_scale);
+
+ gpuPushMatrix();
+ gpuMultMatrix(mat);
+
+ glEnable(GL_BLEND);
+ gpuTranslate3fv(prim->manipulator.offset);
+ manipulator_primitive_draw_geom(col_inner, col_outer, prim->style);
+ glDisable(GL_BLEND);
+
+ gpuPopMatrix();
+ }
+}
+
+static void manipulator_primitive_render_3d_intersect(
+ const bContext *UNUSED(C), wmManipulator *manipulator,
+ int selectionbase)
+{
+ GPU_select_load_id(selectionbase);
+ manipulator_primitive_draw_intern((PrimitiveManipulator *)manipulator, true, false);
+}
+
+static void manipulator_primitive_draw(const bContext *UNUSED(C), wmManipulator *manipulator)
+{
+ manipulator_primitive_draw_intern(
+ (PrimitiveManipulator *)manipulator, false,
+ (manipulator->state & WM_MANIPULATOR_HIGHLIGHT));
+}
+
+static int manipulator_primitive_invoke(
+ bContext *UNUSED(C), const wmEvent *UNUSED(event), wmManipulator *manipulator)
+{
+ ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
+
+ copy_v3_v3(inter->init_origin, manipulator->origin);
+ inter->init_scale = manipulator->scale;
+
+ manipulator->interaction_data = inter;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+/* -------------------------------------------------------------------- */
+/** \name Primitive Manipulator API
+ *
+ * \{ */
+
+wmManipulator *MANIPULATOR_primitive_new(wmManipulatorGroup *mgroup, const char *name, const int style)
+{
+ PrimitiveManipulator *prim = MEM_callocN(sizeof(PrimitiveManipulator), name);
+ const float dir_default[3] = {0.0f, 0.0f, 1.0f};
+
+ prim->manipulator.draw = manipulator_primitive_draw;
+ prim->manipulator.invoke = manipulator_primitive_invoke;
+ prim->manipulator.intersect = NULL;
+ prim->manipulator.render_3d_intersection = manipulator_primitive_render_3d_intersect;
+ prim->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
+ prim->style = style;
+
+ /* defaults */
+ copy_v3_v3(prim->direction, dir_default);
+
+ wm_manipulator_register(mgroup, &prim->manipulator, name);
+
+ return (wmManipulator *)prim;
+}
+
+/**
+ * Define direction the primitive will point towards
+ */
+void MANIPULATOR_primitive_set_direction(wmManipulator *manipulator, const float direction[3])
+{
+ PrimitiveManipulator *prim = (PrimitiveManipulator *)manipulator;
+
+ normalize_v3_v3(prim->direction, direction);
+}
+
+/**
+ * Define up-direction of the primitive manipulator
+ */
+void MANIPULATOR_primitive_set_up_vector(wmManipulator *manipulator, const float direction[3])
+{
+ PrimitiveManipulator *prim = (PrimitiveManipulator *)manipulator;
+
+ if (direction) {
+ normalize_v3_v3(prim->up, direction);
+ prim->flag |= PRIM_UP_VECTOR_SET;
+ }
+ else {
+ prim->flag &= ~PRIM_UP_VECTOR_SET;
+ }
+}
+
+/** \} */ // Primitive Manipulator API
+
+
+/* -------------------------------------------------------------------- */
+
+void fix_linking_manipulator_primitive(void)
+{
+ (void)0;
+}
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
new file mode 100644
index 00000000000..de2096dbde9
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -0,0 +1,485 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulator.c
+ * \ingroup wm
+ */
+
+#include "BKE_context.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+
+#include "DNA_manipulator_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "GPU_batch.h"
+#include "GPU_glew.h"
+#include "GPU_immediate.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+#include "manipulator_library/manipulator_geometry.h"
+
+/**
+ * Main draw call for ManipulatorGeomInfo data
+ */
+void wm_manipulator_geometryinfo_draw(const ManipulatorGeomInfo *info, const bool select, const float color[4])
+{
+ /* TODO store the Batches inside the ManipulatorGeomInfo and updated it when geom changes
+ * So we don't need to re-created and discard it every time */
+
+ const bool use_lighting = true || (!select && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0));
+ VertexBuffer *vbo;
+ ElementList *el;
+ Batch *batch;
+ ElementListBuilder elb = {0};
+
+ VertexFormat format = {0};
+ unsigned int pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int nor_id;
+
+ if (use_lighting) {
+ nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+
+ /* Elements */
+ ElementListBuilder_init(&elb, PRIM_TRIANGLES, info->ntris, info->nverts);
+ for (int i = 0; i < info->ntris; ++i) {
+ const unsigned short *idx = &info->indices[i * 3];
+ add_triangle_vertices(&elb, idx[0], idx[1], idx[2]);
+ }
+ el = ElementList_build(&elb);
+
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, info->nverts);
+
+ VertexBuffer_fill_attrib(vbo, pos_id, info->verts);
+
+ if (use_lighting) {
+ /* Normals are expected to be smooth. */
+ VertexBuffer_fill_attrib(vbo, nor_id, info->normals);
+ }
+
+ batch = Batch_create(PRIM_TRIANGLES, vbo, el);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+ Batch_Uniform4fv(batch, "color", color);
+
+ glEnable(GL_CULL_FACE);
+ // glEnable(GL_DEPTH_TEST);
+
+ Batch_draw(batch);
+
+ glDisable(GL_DEPTH_TEST);
+ // glDisable(GL_CULL_FACE);
+
+
+ Batch_discard_all(batch);
+}
+
+void wm_manipulator_vec_draw(
+ const float color[4], const float (*verts)[3], unsigned int vert_count,
+ unsigned int pos, unsigned int primitive_type)
+{
+ immUniformColor4fv(color);
+ immBegin(primitive_type, vert_count);
+ for (int i = 0; i < vert_count; i++) {
+ immVertex3fv(pos, verts[i]);
+ }
+ immEnd();
+}
+
+/* Still unused */
+wmManipulator *WM_manipulator_new(
+ void (*draw)(const bContext *C, wmManipulator *customdata),
+ void (*render_3d_intersection)(const bContext *C, wmManipulator *customdata, int selectionbase),
+ int (*intersect)(bContext *C, const wmEvent *event, wmManipulator *manipulator),
+ int (*handler)(bContext *C, const wmEvent *event, wmManipulator *manipulator, const int flag))
+{
+ wmManipulator *manipulator = MEM_callocN(sizeof(wmManipulator), "manipulator");
+
+ manipulator->draw = draw;
+ manipulator->handler = handler;
+ manipulator->intersect = intersect;
+ manipulator->render_3d_intersection = render_3d_intersection;
+
+ /* XXX */
+ fix_linking_manipulator_arrow();
+ fix_linking_manipulator_arrow2d();
+ fix_linking_manipulator_cage();
+ fix_linking_manipulator_dial();
+ fix_linking_manipulator_primitive();
+
+ return manipulator;
+}
+
+/**
+ * Assign an idname that is unique in \a mgroup to \a manipulator.
+ *
+ * \param rawname: Name used as basis to define final unique idname.
+ */
+static void manipulator_unique_idname_set(wmManipulatorGroup *mgroup, wmManipulator *manipulator, const char *rawname)
+{
+ if (mgroup->type->idname[0]) {
+ BLI_snprintf(manipulator->idname, sizeof(manipulator->idname), "%s_%s", mgroup->type->idname, rawname);
+ }
+ else {
+ BLI_strncpy(manipulator->idname, rawname, sizeof(manipulator->idname));
+ }
+
+ /* ensure name is unique, append '.001', '.002', etc if not */
+ BLI_uniquename(&mgroup->manipulators, manipulator, "Manipulator", '.',
+ offsetof(wmManipulator, idname), sizeof(manipulator->idname));
+}
+
+/**
+ * Initialize default values and allocate needed memory for members.
+ */
+static void manipulator_init(wmManipulator *manipulator)
+{
+ const float col_default[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ manipulator->user_scale = 1.0f;
+ manipulator->line_width = 1.0f;
+
+ /* defaults */
+ copy_v4_v4(manipulator->col, col_default);
+ copy_v4_v4(manipulator->col_hi, col_default);
+
+ /* create at least one property for interaction */
+ if (manipulator->max_prop == 0) {
+ manipulator->max_prop = 1;
+ }
+
+ manipulator->props = MEM_callocN(sizeof(PropertyRNA *) * manipulator->max_prop, "manipulator->props");
+ manipulator->ptr = MEM_callocN(sizeof(PointerRNA) * manipulator->max_prop, "manipulator->ptr");
+}
+
+/**
+ * Register \a manipulator.
+ *
+ * \param name: name used to create a unique idname for \a manipulator in \a mgroup
+ */
+void wm_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *manipulator, const char *name)
+{
+ manipulator_init(manipulator);
+ manipulator_unique_idname_set(mgroup, manipulator, name);
+ wm_manipulatorgroup_manipulator_register(mgroup, manipulator);
+}
+
+/**
+ * Free \a manipulator and unlink from \a manipulatorlist.
+ * \a manipulatorlist is allowed to be NULL.
+ */
+void WM_manipulator_delete(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmManipulator *manipulator, bContext *C)
+{
+ if (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) {
+ wm_manipulatormap_set_highlighted_manipulator(mmap, C, NULL, 0);
+ }
+ if (manipulator->state & WM_MANIPULATOR_ACTIVE) {
+ wm_manipulatormap_set_active_manipulator(mmap, C, NULL, NULL);
+ }
+ if (manipulator->state & WM_MANIPULATOR_SELECTED) {
+ wm_manipulator_deselect(mmap, manipulator);
+ }
+
+ if (manipulator->opptr.data) {
+ WM_operator_properties_free(&manipulator->opptr);
+ }
+ MEM_freeN(manipulator->props);
+ MEM_freeN(manipulator->ptr);
+
+ if (manipulatorlist)
+ BLI_remlink(manipulatorlist, manipulator);
+ MEM_freeN(manipulator);
+}
+
+wmManipulatorGroup *wm_manipulator_get_parent_group(const wmManipulator *manipulator)
+{
+ return manipulator->mgroup;
+}
+
+
+/* -------------------------------------------------------------------- */
+/** \name Manipulator Creation API
+ *
+ * API for defining data on manipulator creation.
+ *
+ * \{ */
+
+void WM_manipulator_set_property(wmManipulator *manipulator, const int slot, PointerRNA *ptr, const char *propname)
+{
+ if (slot < 0 || slot >= manipulator->max_prop) {
+ fprintf(stderr, "invalid index %d when binding property for manipulator type %s\n", slot, manipulator->idname);
+ return;
+ }
+
+ /* if manipulator evokes an operator we cannot use it for property manipulation */
+ manipulator->opname = NULL;
+ manipulator->ptr[slot] = *ptr;
+ manipulator->props[slot] = RNA_struct_find_property(ptr, propname);
+
+ if (manipulator->prop_data_update)
+ manipulator->prop_data_update(manipulator, slot);
+}
+
+PointerRNA *WM_manipulator_set_operator(wmManipulator *manipulator, const char *opname)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0);
+
+ if (ot) {
+ manipulator->opname = opname;
+
+ if (manipulator->opptr.data) {
+ WM_operator_properties_free(&manipulator->opptr);
+ }
+ WM_operator_properties_create_ptr(&manipulator->opptr, ot);
+
+ return &manipulator->opptr;
+ }
+ else {
+ fprintf(stderr, "Error binding operator to manipulator: operator %s not found!\n", opname);
+ }
+
+ return NULL;
+}
+
+
+void WM_manipulator_set_custom_handler(
+ struct wmManipulator *manipulator,
+ int (*handler)(struct bContext *, const wmEvent *, struct wmManipulator *, const int))
+{
+ manipulator->handler = handler;
+}
+
+/**
+ * \brief Set manipulator select callback.
+ *
+ * Callback is called when manipulator gets selected/deselected.
+ */
+void WM_manipulator_set_func_select(wmManipulator *manipulator, wmManipulatorSelectFunc select)
+{
+ BLI_assert(manipulator->mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SELECTABLE);
+ manipulator->select = select;
+}
+
+void WM_manipulator_set_origin(wmManipulator *manipulator, const float origin[3])
+{
+ copy_v3_v3(manipulator->origin, origin);
+}
+
+void WM_manipulator_set_offset(wmManipulator *manipulator, const float offset[3])
+{
+ copy_v3_v3(manipulator->offset, offset);
+}
+
+void WM_manipulator_set_flag(wmManipulator *manipulator, const int flag, const bool enable)
+{
+ if (enable) {
+ manipulator->flag |= flag;
+ }
+ else {
+ manipulator->flag &= ~flag;
+ }
+}
+
+void WM_manipulator_set_scale(wmManipulator *manipulator, const float scale)
+{
+ manipulator->user_scale = scale;
+}
+
+void WM_manipulator_set_line_width(wmManipulator *manipulator, const float line_width)
+{
+ manipulator->line_width = line_width;
+}
+
+/**
+ * Set manipulator rgba colors.
+ *
+ * \param col Normal state color.
+ * \param col_hi Highlighted state color.
+ */
+void WM_manipulator_set_colors(wmManipulator *manipulator, const float col[4], const float col_hi[4])
+{
+ copy_v4_v4(manipulator->col, col);
+ copy_v4_v4(manipulator->col_hi, col_hi);
+}
+
+/** \} */ // Manipulator Creation API
+
+
+/* -------------------------------------------------------------------- */
+
+/**
+ * Remove \a manipulator from selection.
+ * Reallocates memory for selected manipulators so better not call for selecting multiple ones.
+ *
+ * \return if the selection has changed.
+ */
+bool wm_manipulator_deselect(wmManipulatorMap *mmap, wmManipulator *manipulator)
+{
+ if (!mmap->mmap_context.selected_manipulator)
+ return false;
+
+ wmManipulator ***sel = &mmap->mmap_context.selected_manipulator;
+ int *tot_selected = &mmap->mmap_context.tot_selected;
+ bool changed = false;
+
+ /* caller should check! */
+ BLI_assert(manipulator->state & WM_MANIPULATOR_SELECTED);
+
+ /* remove manipulator from selected_manipulators array */
+ for (int i = 0; i < (*tot_selected); i++) {
+ if ((*sel)[i] == manipulator) {
+ for (int j = i; j < ((*tot_selected) - 1); j++) {
+ (*sel)[j] = (*sel)[j + 1];
+ }
+ changed = true;
+ break;
+ }
+ }
+
+ /* update array data */
+ if ((*tot_selected) <= 1) {
+ wm_manipulatormap_selected_delete(mmap);
+ }
+ else {
+ *sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_selected));
+ (*tot_selected)--;
+ }
+
+ manipulator->state &= ~WM_MANIPULATOR_SELECTED;
+ return changed;
+}
+
+/**
+ * Add \a manipulator to selection.
+ * Reallocates memory for selected manipulators so better not call for selecting multiple ones.
+ *
+ * \return if the selection has changed.
+ */
+bool wm_manipulator_select(bContext *C, wmManipulatorMap *mmap, wmManipulator *manipulator)
+{
+ wmManipulator ***sel = &mmap->mmap_context.selected_manipulator;
+ int *tot_selected = &mmap->mmap_context.tot_selected;
+
+ if (!manipulator || (manipulator->state & WM_MANIPULATOR_SELECTED))
+ return false;
+
+ (*tot_selected)++;
+
+ *sel = MEM_reallocN(*sel, sizeof(wmManipulator *) * (*tot_selected));
+ (*sel)[(*tot_selected) - 1] = manipulator;
+
+ manipulator->state |= WM_MANIPULATOR_SELECTED;
+ if (manipulator->select) {
+ manipulator->select(C, manipulator, SEL_SELECT);
+ }
+ wm_manipulatormap_set_highlighted_manipulator(mmap, C, manipulator, manipulator->highlighted_part);
+
+ return true;
+}
+
+void wm_manipulator_calculate_scale(wmManipulator *manipulator, const bContext *C)
+{
+ const RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ float scale = 1.0f;
+
+ if (manipulator->mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SCALE_3D) {
+ if (rv3d /*&& (U.manipulator_flag & V3D_DRAW_MANIPULATOR) == 0*/) { /* UserPref flag might be useful for later */
+ if (manipulator->get_final_position) {
+ float position[3];
+
+ manipulator->get_final_position(manipulator, position);
+ scale = ED_view3d_pixel_size(rv3d, position) * (float)U.manipulator_scale;
+ }
+ else {
+ scale = ED_view3d_pixel_size(rv3d, manipulator->origin) * (float)U.manipulator_scale;
+ }
+ }
+ else {
+ scale = U.manipulator_scale * 0.02f;
+ }
+ }
+
+ manipulator->scale = scale * manipulator->user_scale;
+}
+
+static void manipulator_update_prop_data(wmManipulator *manipulator)
+{
+ /* manipulator property might have been changed, so update manipulator */
+ if (manipulator->props && manipulator->prop_data_update) {
+ for (int i = 0; i < manipulator->max_prop; i++) {
+ if (manipulator->props[i]) {
+ manipulator->prop_data_update(manipulator, i);
+ }
+ }
+ }
+}
+
+void wm_manipulator_update(wmManipulator *manipulator, const bContext *C, const bool refresh_map)
+{
+ if (refresh_map) {
+ manipulator_update_prop_data(manipulator);
+ }
+ wm_manipulator_calculate_scale(manipulator, C);
+}
+
+bool wm_manipulator_is_visible(wmManipulator *manipulator)
+{
+ if (manipulator->flag & WM_MANIPULATOR_HIDDEN) {
+ return false;
+ }
+ if ((manipulator->state & WM_MANIPULATOR_ACTIVE) &&
+ !(manipulator->flag & (WM_MANIPULATOR_DRAW_ACTIVE | WM_MANIPULATOR_DRAW_VALUE)))
+ {
+ /* don't draw while active (while dragging) */
+ return false;
+ }
+ if ((manipulator->flag & WM_MANIPULATOR_DRAW_HOVER) &&
+ !(manipulator->state & WM_MANIPULATOR_HIGHLIGHT) &&
+ !(manipulator->state & WM_MANIPULATOR_SELECTED)) /* still draw selected manipulators */
+ {
+ /* only draw on mouse hover */
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
new file mode 100644
index 00000000000..595eb4034a4
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
@@ -0,0 +1,227 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
+ * \ingroup wm
+ */
+
+
+#ifndef __WM_MANIPULATOR_INTERN_H__
+#define __WM_MANIPULATOR_INTERN_H__
+
+struct wmKeyConfig;
+struct wmManipulatorMap;
+struct ManipulatorGeomInfo;
+
+/* -------------------------------------------------------------------- */
+/* wmManipulator */
+
+/* manipulators are set per region by registering them on manipulator-maps */
+struct wmManipulator {
+ struct wmManipulator *next, *prev;
+
+ char idname[MAX_NAME + 4]; /* + 4 for unique '.001', '.002', etc suffix */
+ /* pointer back to group this manipulator is in (just for quick access) */
+ struct wmManipulatorGroup *mgroup;
+
+ /* could become wmManipulatorType */
+ /* draw manipulator */
+ void (*draw)(const struct bContext *, struct wmManipulator *);
+
+ /* determine if the mouse intersects with the manipulator. The calculation should be done in the callback itself */
+ int (*intersect)(struct bContext *, const struct wmEvent *, struct wmManipulator *);
+
+ /* determines 3d intersection by rendering the manipulator in a selection routine. */
+ void (*render_3d_intersection)(const struct bContext *, struct wmManipulator *, int);
+
+ /* handler used by the manipulator. Usually handles interaction tied to a manipulator type */
+ int (*handler)(struct bContext *, const struct wmEvent *, struct wmManipulator *, const int);
+
+ /* manipulator-specific handler to update manipulator attributes based on the property value */
+ void (*prop_data_update)(struct wmManipulator *, int);
+
+ /* returns the final position which may be different from the origin, depending on the manipulator.
+ * used in calculations of scale */
+ void (*get_final_position)(struct wmManipulator *, float[]);
+
+ /* activate a manipulator state when the user clicks on it */
+ int (*invoke)(struct bContext *, const struct wmEvent *, struct wmManipulator *);
+
+ /* called when manipulator tweaking is done - used to free data and reset property when cancelling */
+ void (*exit)(struct bContext *, struct wmManipulator *, const bool );
+
+ int (*get_cursor)(struct wmManipulator *);
+
+ /* called when manipulator selection state changes */
+ wmManipulatorSelectFunc select;
+
+ int flag; /* flags that influence the behavior or how the manipulators are drawn */
+ short state; /* state flags (active, highlighted, selected) */
+
+ unsigned char highlighted_part;
+
+ /* center of manipulator in space, 2d or 3d */
+ float origin[3];
+ /* custom offset from origin */
+ float offset[3];
+ /* runtime property, set the scale while drawing on the viewport */
+ float scale;
+ /* user defined scale, in addition to the original one */
+ float user_scale;
+ /* user defined width for line drawing */
+ float line_width;
+ /* manipulator colors (uses default fallbacks if not defined) */
+ float col[4], col_hi[4];
+
+ /* data used during interaction */
+ void *interaction_data;
+
+ /* name of operator to spawn when activating the manipulator */
+ const char *opname;
+ /* operator properties if manipulator spawns and controls an operator,
+ * or owner pointer if manipulator spawns and controls a property */
+ PointerRNA opptr;
+
+ /* maximum number of properties attached to the manipulator */
+ int max_prop;
+ /* arrays of properties attached to various manipulator parameters. As
+ * the manipulator is interacted with, those properties get updated */
+ PointerRNA *ptr;
+ PropertyRNA **props;
+};
+
+/* wmManipulator.state */
+enum {
+ WM_MANIPULATOR_HIGHLIGHT = (1 << 0), /* while hovered */
+ WM_MANIPULATOR_ACTIVE = (1 << 1), /* while dragging */
+ WM_MANIPULATOR_SELECTED = (1 << 2),
+};
+
+/**
+ * \brief Manipulator tweak flag.
+ * Bitflag passed to manipulator while tweaking.
+ */
+enum {
+ /* drag with extra precision (shift)
+ * NOTE: Manipulators are responsible for handling this (manipulator->handler callback)! */
+ WM_MANIPULATOR_TWEAK_PRECISE = (1 << 0),
+};
+
+void wm_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *manipulator, const char *name);
+
+bool wm_manipulator_deselect(struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
+bool wm_manipulator_select(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
+
+void wm_manipulator_calculate_scale(struct wmManipulator *manipulator, const bContext *C);
+void wm_manipulator_update(struct wmManipulator *manipulator, const bContext *C, const bool refresh_map);
+bool wm_manipulator_is_visible(struct wmManipulator *manipulator);
+
+void fix_linking_manipulator_arrow(void);
+void fix_linking_manipulator_arrow2d(void);
+void fix_linking_manipulator_cage(void);
+void fix_linking_manipulator_dial(void);
+void fix_linking_manipulator_facemap(void);
+void fix_linking_manipulator_primitive(void);
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorGroup */
+
+enum {
+ TWEAK_MODAL_CANCEL = 1,
+ TWEAK_MODAL_CONFIRM,
+ TWEAK_MODAL_PRECISION_ON,
+ TWEAK_MODAL_PRECISION_OFF,
+};
+
+struct wmManipulatorGroup *wm_manipulatorgroup_new_from_type(struct wmManipulatorGroupType *mgrouptype);
+void wm_manipulatorgroup_free(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulatorGroup *mgroup);
+void wm_manipulatorgroup_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *manipulator);
+struct wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
+ const struct wmManipulatorGroup *mgroup, struct bContext *C, const struct wmEvent *event,
+ unsigned char *part);
+void wm_manipulatorgroup_intersectable_manipulators_to_list(
+ const struct wmManipulatorGroup *mgroup, struct ListBase *listbase);
+void wm_manipulatorgroup_ensure_initialized(struct wmManipulatorGroup *mgroup, const struct bContext *C);
+bool wm_manipulatorgroup_is_visible(const struct wmManipulatorGroup *mgroup, const struct bContext *C);
+bool wm_manipulatorgroup_is_visible_in_drawstep(const struct wmManipulatorGroup *mgroup, const int drawstep);
+
+void wm_manipulatorgrouptype_keymap_init(struct wmManipulatorGroupType *mgrouptype, struct wmKeyConfig *keyconf);
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorMap */
+
+struct wmManipulatorMap {
+ struct wmManipulatorMap *next, *prev;
+
+ struct wmManipulatorMapType *type;
+ ListBase manipulator_groups;
+
+ char update_flag; /* private, update tagging */
+
+ /**
+ * \brief Manipulator map runtime context
+ *
+ * Contains information about this manipulator-map. Currently
+ * highlighted manipulator, currently selected manipulators, ...
+ */
+ struct {
+ /* we redraw the manipulator-map when this changes */
+ struct wmManipulator *highlighted_manipulator;
+ /* user has clicked this manipulator and it gets all input */
+ struct wmManipulator *active_manipulator;
+ /* array for all selected manipulators
+ * TODO check on using BLI_array */
+ struct wmManipulator **selected_manipulator;
+ int tot_selected;
+ } mmap_context;
+};
+
+/**
+ * This is a container for all manipulator types that can be instantiated in a region.
+ * (similar to dropboxes).
+ *
+ * \note There is only ever one of these for every (area, region) combination.
+ */
+struct wmManipulatorMapType {
+ struct wmManipulatorMapType *next, *prev;
+ char idname[64];
+ short spaceid, regionid;
+ /* types of manipulator-groups for this manipulator-map type */
+ ListBase manipulator_grouptypes;
+};
+
+void wm_manipulatormap_selected_delete(struct wmManipulatorMap *mmap);
+bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, struct wmManipulator ***sel);
+
+
+/* -------------------------------------------------------------------- */
+/* Manipulator drawing */
+
+void wm_manipulator_geometryinfo_draw(const struct ManipulatorGeomInfo *info, const bool select, const float color[4]);
+void wm_manipulator_vec_draw(
+ const float color[4], const float (*verts)[3], unsigned int vert_count,
+ unsigned int pos, unsigned int primitive_type);
+
+#endif /* __WM_MANIPULATOR_INTERN_H__ */
+
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
new file mode 100644
index 00000000000..5074c6d0257
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
@@ -0,0 +1,590 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
+ * \ingroup wm
+ *
+ * \name Manipulator-Group
+ *
+ * Manipulator-groups store and manage groups of manipulators. They can be
+ * attached to modal handlers and have own keymaps.
+ */
+
+#include <stdlib.h>
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "BPY_extern.h"
+
+#include "DNA_manipulator_types.h"
+
+#include "ED_screen.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+#include "wm_event_system.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+
+/* -------------------------------------------------------------------- */
+/** \name wmManipulatorGroup
+ *
+ * \{ */
+
+/* wmManipulatorGroup.flag */
+enum {
+ WM_MANIPULATORGROUP_INITIALIZED = (1 << 2), /* mgroup has been initialized */
+};
+
+/**
+ * Create a new manipulator-group from \a mgrouptype.
+ */
+wmManipulatorGroup *wm_manipulatorgroup_new_from_type(wmManipulatorGroupType *mgrouptype)
+{
+ wmManipulatorGroup *mgroup = MEM_callocN(sizeof(*mgroup), "manipulator-group");
+ mgroup->type = mgrouptype;
+
+ return mgroup;
+}
+
+void wm_manipulatorgroup_free(bContext *C, wmManipulatorMap *mmap, wmManipulatorGroup *mgroup)
+{
+ for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator;) {
+ wmManipulator *manipulator_next = manipulator->next;
+ WM_manipulator_delete(&mgroup->manipulators, mmap, manipulator, C);
+ manipulator = manipulator_next;
+ }
+ BLI_assert(BLI_listbase_is_empty(&mgroup->manipulators));
+
+#ifdef WITH_PYTHON
+ if (mgroup->py_instance) {
+ /* do this first in case there are any __del__ functions or
+ * similar that use properties */
+ BPY_DECREF_RNA_INVALIDATE(mgroup->py_instance);
+ }
+#endif
+
+ if (mgroup->reports && (mgroup->reports->flag & RPT_FREE)) {
+ BKE_reports_clear(mgroup->reports);
+ MEM_freeN(mgroup->reports);
+ }
+
+ if (mgroup->customdata_free) {
+ mgroup->customdata_free(mgroup->customdata);
+ }
+ else {
+ MEM_SAFE_FREE(mgroup->customdata);
+ }
+
+ BLI_remlink(&mmap->manipulator_groups, mgroup);
+ MEM_freeN(mgroup);
+}
+
+/**
+ * Add \a manipulator to \a mgroup and make sure its name is unique within the group.
+ */
+void wm_manipulatorgroup_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *manipulator)
+{
+ BLI_assert(!BLI_findstring(&mgroup->manipulators, manipulator->idname, offsetof(wmManipulator, idname)));
+ BLI_addtail(&mgroup->manipulators, manipulator);
+ manipulator->mgroup = mgroup;
+}
+
+void wm_manipulatorgroup_attach_to_modal_handler(
+ bContext *C, wmEventHandler *handler,
+ wmManipulatorGroupType *mgrouptype, wmOperator *op)
+{
+ /* maybe overly careful, but manipulator-grouptype could come from a failed creation */
+ if (!mgrouptype) {
+ return;
+ }
+
+ /* now instantiate the manipulator-map */
+ mgrouptype->op = op;
+
+ /* try to find map in handler region that contains mgrouptype */
+ if (handler->op_region && handler->op_region->manipulator_map) {
+ handler->manipulator_map = handler->op_region->manipulator_map;
+ ED_region_tag_redraw(handler->op_region);
+ }
+
+ WM_event_add_mousemove(C);
+}
+
+wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
+ const wmManipulatorGroup *mgroup, bContext *C, const wmEvent *event,
+ unsigned char *part)
+{
+ for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
+ if (manipulator->intersect && (manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
+ if ((*part = manipulator->intersect(C, event, manipulator))) {
+ return manipulator;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Adds all manipulators of \a mgroup that can be selected to the head of \a listbase. Added items need freeing!
+ */
+void wm_manipulatorgroup_intersectable_manipulators_to_list(const wmManipulatorGroup *mgroup, ListBase *listbase)
+{
+ for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
+ if ((manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
+ if (((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) && manipulator->render_3d_intersection) ||
+ ((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) == 0 && manipulator->intersect))
+ {
+ BLI_addhead(listbase, BLI_genericNodeN(manipulator));
+ }
+ }
+ }
+}
+
+void wm_manipulatorgroup_ensure_initialized(wmManipulatorGroup *mgroup, const bContext *C)
+{
+ /* prepare for first draw */
+ if (UNLIKELY((mgroup->flag & WM_MANIPULATORGROUP_INITIALIZED) == 0)) {
+ mgroup->type->init(C, mgroup);
+ mgroup->flag |= WM_MANIPULATORGROUP_INITIALIZED;
+ }
+}
+
+bool wm_manipulatorgroup_is_visible(const wmManipulatorGroup *mgroup, const bContext *C)
+{
+ /* Check for poll function, if manipulator-group belongs to an operator, also check if the operator is running. */
+ return ((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_OP) == 0 || mgroup->type->op) &&
+ (!mgroup->type->poll || mgroup->type->poll(C, mgroup->type));
+}
+
+bool wm_manipulatorgroup_is_visible_in_drawstep(const wmManipulatorGroup *mgroup, const int drawstep)
+{
+ switch (drawstep) {
+ case WM_MANIPULATORMAP_DRAWSTEP_2D:
+ return (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) == 0;
+ case WM_MANIPULATORMAP_DRAWSTEP_3D:
+ return (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D);
+ case WM_MANIPULATORMAP_DRAWSTEP_IN_SCENE:
+ return (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SCENE_DEPTH);
+ default:
+ BLI_assert(0);
+ return false;
+ }
+}
+
+/** \name Manipulator operators
+ *
+ * Basic operators for manipulator interaction with user configurable keymaps.
+ *
+ * \{ */
+
+static int manipulator_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmManipulatorMap *mmap = ar->manipulator_map;
+ wmManipulator ***sel = &mmap->mmap_context.selected_manipulator;
+ wmManipulator *highlighted = mmap->mmap_context.highlighted_manipulator;
+
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool deselect = RNA_boolean_get(op->ptr, "deselect");
+ bool toggle = RNA_boolean_get(op->ptr, "toggle");
+
+ /* deselect all first */
+ if (extend == false && deselect == false && toggle == false) {
+ wm_manipulatormap_deselect_all(mmap, sel);
+ BLI_assert(*sel == NULL && mmap->mmap_context.tot_selected == 0);
+ }
+
+ if (highlighted) {
+ const bool is_selected = (highlighted->state & WM_MANIPULATOR_SELECTED);
+ bool redraw = false;
+
+ if (toggle) {
+ /* toggle: deselect if already selected, else select */
+ deselect = is_selected;
+ }
+
+ if (deselect) {
+ if (is_selected && wm_manipulator_deselect(mmap, highlighted)) {
+ redraw = true;
+ }
+ }
+ else if (wm_manipulator_select(C, mmap, highlighted)) {
+ redraw = true;
+ }
+
+ if (redraw) {
+ ED_region_tag_redraw(ar);
+ }
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+void MANIPULATORGROUP_OT_manipulator_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Manipulator Select";
+ ot->description = "Select the currently highlighted manipulator";
+ ot->idname = "MANIPULATORGROUP_OT_manipulator_select";
+
+ /* api callbacks */
+ ot->invoke = manipulator_select_invoke;
+
+ ot->flag = OPTYPE_UNDO;
+
+ WM_operator_properties_mouse_select(ot);
+}
+
+typedef struct ManipulatorTweakData {
+ wmManipulatorMap *mmap;
+ wmManipulator *active;
+
+ int init_event; /* initial event type */
+ int flag; /* tweak flags */
+} ManipulatorTweakData;
+
+static void manipulator_tweak_finish(bContext *C, wmOperator *op, const bool cancel)
+{
+ ManipulatorTweakData *mtweak = op->customdata;
+ if (mtweak->active->exit) {
+ mtweak->active->exit(C, mtweak->active, cancel);
+ }
+ wm_manipulatormap_set_active_manipulator(mtweak->mmap, C, NULL, NULL);
+ MEM_freeN(mtweak);
+}
+
+static int manipulator_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ManipulatorTweakData *mtweak = op->customdata;
+ wmManipulator *manipulator = mtweak->active;
+
+ if (!manipulator) {
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ if (event->type == mtweak->init_event && event->val == KM_RELEASE) {
+ manipulator_tweak_finish(C, op, false);
+ return OPERATOR_FINISHED;
+ }
+
+
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case TWEAK_MODAL_CANCEL:
+ manipulator_tweak_finish(C, op, true);
+ return OPERATOR_CANCELLED;
+ case TWEAK_MODAL_CONFIRM:
+ manipulator_tweak_finish(C, op, false);
+ return OPERATOR_FINISHED;
+ case TWEAK_MODAL_PRECISION_ON:
+ mtweak->flag |= WM_MANIPULATOR_TWEAK_PRECISE;
+ break;
+ case TWEAK_MODAL_PRECISION_OFF:
+ mtweak->flag &= ~WM_MANIPULATOR_TWEAK_PRECISE;
+ break;
+ }
+ }
+
+ /* handle manipulator */
+ if (manipulator->handler) {
+ manipulator->handler(C, event, manipulator, mtweak->flag);
+ }
+
+ /* Ugly hack to send manipulator events */
+ ((wmEvent *)event)->type = EVT_MANIPULATOR_UPDATE;
+
+ /* always return PASS_THROUGH so modal handlers
+ * with manipulators attached can update */
+ return OPERATOR_PASS_THROUGH;
+}
+
+static int manipulator_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmManipulatorMap *mmap = ar->manipulator_map;
+ wmManipulator *manipulator = mmap->mmap_context.highlighted_manipulator;
+
+ if (!manipulator) {
+ /* wm_handlers_do_intern shouldn't let this happen */
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+
+ /* activate highlighted manipulator */
+ wm_manipulatormap_set_active_manipulator(mmap, C, event, manipulator);
+
+ /* XXX temporary workaround for modal manipulator operator
+ * conflicting with modal operator attached to manipulator */
+ if (manipulator->opname) {
+ wmOperatorType *ot = WM_operatortype_find(manipulator->opname, true);
+ if (ot->modal) {
+ return OPERATOR_FINISHED;
+ }
+ }
+
+
+ ManipulatorTweakData *mtweak = MEM_mallocN(sizeof(ManipulatorTweakData), __func__);
+
+ mtweak->init_event = event->type;
+ mtweak->active = mmap->mmap_context.highlighted_manipulator;
+ mtweak->mmap = mmap;
+ mtweak->flag = 0;
+
+ op->customdata = mtweak;
+
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void MANIPULATORGROUP_OT_manipulator_tweak(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Manipulator Tweak";
+ ot->description = "Tweak the active manipulator";
+ ot->idname = "MANIPULATORGROUP_OT_manipulator_tweak";
+
+ /* api callbacks */
+ ot->invoke = manipulator_tweak_invoke;
+ ot->modal = manipulator_tweak_modal;
+
+ ot->flag = OPTYPE_UNDO;
+}
+
+/** \} */ // Manipulator operators
+
+
+static wmKeyMap *manipulatorgroup_tweak_modal_keymap(wmKeyConfig *keyconf, const char *mgroupname)
+{
+ wmKeyMap *keymap;
+ char name[KMAP_MAX_NAME];
+
+ static EnumPropertyItem modal_items[] = {
+ {TWEAK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {TWEAK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ {TWEAK_MODAL_PRECISION_ON, "PRECISION_ON", 0, "Enable Precision", ""},
+ {TWEAK_MODAL_PRECISION_OFF, "PRECISION_OFF", 0, "Disable Precision", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+
+ BLI_snprintf(name, sizeof(name), "%s Tweak Modal Map", mgroupname);
+ keymap = WM_modalkeymap_get(keyconf, name);
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items)
+ return NULL;
+
+ keymap = WM_modalkeymap_add(keyconf, name, modal_items);
+
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_CANCEL);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_CANCEL);
+
+ WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_CONFIRM);
+
+ WM_modalkeymap_add_item(keymap, RIGHTSHIFTKEY, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_PRECISION_ON);
+ WM_modalkeymap_add_item(keymap, RIGHTSHIFTKEY, KM_RELEASE, KM_ANY, 0, TWEAK_MODAL_PRECISION_OFF);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_PRECISION_ON);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, TWEAK_MODAL_PRECISION_OFF);
+
+
+ WM_modalkeymap_assign(keymap, "MANIPULATORGROUP_OT_manipulator_tweak");
+
+ return keymap;
+}
+
+/**
+ * Common default keymap for manipulator groups
+ */
+wmKeyMap *WM_manipulatorgroup_keymap_common(const struct wmManipulatorGroupType *mgrouptype, wmKeyConfig *config)
+{
+ /* Use area and region id since we might have multiple manipulators with the same name in different areas/regions */
+ wmKeyMap *km = WM_keymap_find(config, mgrouptype->name, mgrouptype->spaceid, mgrouptype->regionid);
+
+ WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_tweak", ACTIONMOUSE, KM_PRESS, KM_ANY, 0);
+ manipulatorgroup_tweak_modal_keymap(config, mgrouptype->name);
+
+ return km;
+}
+
+/**
+ * Variation of #WM_manipulatorgroup_keymap_common but with keymap items for selection
+ */
+wmKeyMap *WM_manipulatorgroup_keymap_common_sel(const struct wmManipulatorGroupType *mgrouptype, wmKeyConfig *config)
+{
+ /* Use area and region id since we might have multiple manipulators with the same name in different areas/regions */
+ wmKeyMap *km = WM_keymap_find(config, mgrouptype->name, mgrouptype->spaceid, mgrouptype->regionid);
+
+ WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_tweak", ACTIONMOUSE, KM_PRESS, KM_ANY, 0);
+ manipulatorgroup_tweak_modal_keymap(config, mgrouptype->name);
+
+ wmKeyMapItem *kmi = WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_select", SELECTMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", false);
+ kmi = WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+
+ return km;
+}
+
+/** \} */ /* wmManipulatorGroup */
+
+/* -------------------------------------------------------------------- */
+/** \name wmManipulatorGroupType
+ *
+ * \{ */
+
+/**
+ * Use this for registering manipulators on startup. For runtime, use #WM_manipulatorgrouptype_append_runtime.
+ */
+wmManipulatorGroupType *WM_manipulatorgrouptype_append(
+ wmManipulatorMapType *mmaptype, void (*mgrouptype_func)(wmManipulatorGroupType *))
+{
+ wmManipulatorGroupType *mgrouptype = MEM_callocN(sizeof(wmManipulatorGroupType), "manipulator-group");
+
+ mgrouptype_func(mgrouptype);
+ mgrouptype->spaceid = mmaptype->spaceid;
+ mgrouptype->regionid = mmaptype->regionid;
+ BLI_strncpy(mgrouptype->mapidname, mmaptype->idname, MAX_NAME);
+ /* if not set, use default */
+ if (!mgrouptype->keymap_init) {
+ mgrouptype->keymap_init = WM_manipulatorgroup_keymap_common;
+ }
+
+ /* add the type for future created areas of the same type */
+ BLI_addtail(&mmaptype->manipulator_grouptypes, mgrouptype);
+ return mgrouptype;
+}
+
+/**
+ * Use this for registering manipulators on runtime.
+ */
+wmManipulatorGroupType *WM_manipulatorgrouptype_append_runtime(
+ const Main *main, wmManipulatorMapType *mmaptype,
+ void (*mgrouptype_func)(wmManipulatorGroupType *))
+{
+ wmManipulatorGroupType *mgrouptype = WM_manipulatorgrouptype_append(mmaptype, mgrouptype_func);
+
+ /* Main is missing on startup when we create new areas.
+ * So this is only called for manipulators initialized on runtime */
+ WM_manipulatorgrouptype_init_runtime(main, mmaptype, mgrouptype);
+
+ return mgrouptype;
+}
+
+void WM_manipulatorgrouptype_init_runtime(
+ const Main *bmain, wmManipulatorMapType *mmaptype,
+ wmManipulatorGroupType *mgrouptype)
+{
+ /* init keymap - on startup there's an extra call to init keymaps for 'permanent' manipulator-groups */
+ wm_manipulatorgrouptype_keymap_init(mgrouptype, ((wmWindowManager *)bmain->wm.first)->defaultconf);
+
+ /* now create a manipulator for all existing areas */
+ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
+ for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
+ for (ARegion *ar = lb->first; ar; ar = ar->next) {
+ wmManipulatorMap *mmap = ar->manipulator_map;
+ if (mmap->type == mmaptype) {
+ wmManipulatorGroup *mgroup = wm_manipulatorgroup_new_from_type(mgrouptype);
+
+ /* just add here, drawing will occur on next update */
+ BLI_addtail(&mmap->manipulator_groups, mgroup);
+ wm_manipulatormap_set_highlighted_manipulator(mmap, NULL, NULL, 0);
+ ED_region_tag_redraw(ar);
+ }
+ }
+ }
+ }
+ }
+}
+
+void WM_manipulatorgrouptype_unregister(bContext *C, Main *bmain, wmManipulatorGroupType *mgrouptype)
+{
+ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
+ for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
+ for (ARegion *ar = lb->first; ar; ar = ar->next) {
+ wmManipulatorMap *mmap = ar->manipulator_map;
+ wmManipulatorGroup *mgroup, *mgroup_next;
+
+ for (mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup_next) {
+ mgroup_next = mgroup->next;
+ if (mgroup->type == mgrouptype) {
+ wm_manipulatorgroup_free(C, mmap, mgroup);
+ ED_region_tag_redraw(ar);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ wmManipulatorMapType *mmaptype = WM_manipulatormaptype_find(&(const struct wmManipulatorMapType_Params) {
+ mgrouptype->mapidname, mgrouptype->spaceid,
+ mgrouptype->regionid});
+
+ BLI_remlink(&mmaptype->manipulator_grouptypes, mgrouptype);
+ mgrouptype->prev = mgrouptype->next = NULL;
+
+ MEM_freeN(mgrouptype);
+}
+
+void wm_manipulatorgrouptype_keymap_init(wmManipulatorGroupType *mgrouptype, wmKeyConfig *keyconf)
+{
+ mgrouptype->keymap = mgrouptype->keymap_init(mgrouptype, keyconf);
+}
+
+/** \} */ /* wmManipulatorGroupType */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
new file mode 100644
index 00000000000..cfc393c30b3
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
@@ -0,0 +1,769 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulatormap.c
+ * \ingroup wm
+ */
+
+#include <string.h>
+
+#include "BKE_context.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_ghash.h"
+
+#include "DNA_manipulator_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "GPU_glew.h"
+#include "GPU_matrix.h"
+#include "GPU_select.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+#include "wm_event_system.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+/**
+ * Store all manipulator-maps here. Anyone who wants to register a manipulator for a certain
+ * area type can query the manipulator-map to do so.
+ */
+static ListBase manipulatormaptypes = {NULL, NULL};
+
+/**
+ * Manipulator-map update tagging.
+ */
+enum eManipulatorMapUpdateFlags {
+ /* Tag manipulator-map for refresh. */
+ MANIPULATORMAP_REFRESH = (1 << 0),
+};
+
+
+/* -------------------------------------------------------------------- */
+/** \name wmManipulatorMap
+ *
+ * \{ */
+
+/**
+ * Creates a manipulator-map with all registered manipulators for that type
+ */
+wmManipulatorMap *WM_manipulatormap_new_from_type(const struct wmManipulatorMapType_Params *mmap_params)
+{
+ wmManipulatorMapType *mmaptype = WM_manipulatormaptype_ensure(mmap_params);
+ wmManipulatorMap *mmap;
+
+ mmap = MEM_callocN(sizeof(wmManipulatorMap), "ManipulatorMap");
+ mmap->type = mmaptype;
+ mmap->update_flag = MANIPULATORMAP_REFRESH;
+
+ /* create all manipulator-groups for this manipulator-map. We may create an empty one
+ * too in anticipation of manipulators from operators etc */
+ for (wmManipulatorGroupType *mgrouptype = mmaptype->manipulator_grouptypes.first;
+ mgrouptype;
+ mgrouptype = mgrouptype->next)
+ {
+ wmManipulatorGroup *mgroup = wm_manipulatorgroup_new_from_type(mgrouptype);
+ BLI_addtail(&mmap->manipulator_groups, mgroup);
+ }
+
+ return mmap;
+}
+
+void wm_manipulatormap_selected_delete(wmManipulatorMap *mmap)
+{
+ MEM_SAFE_FREE(mmap->mmap_context.selected_manipulator);
+ mmap->mmap_context.tot_selected = 0;
+}
+
+void wm_manipulatormap_delete(wmManipulatorMap *mmap)
+{
+ if (!mmap)
+ return;
+
+ for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first, *mgroup_next; mgroup; mgroup = mgroup_next) {
+ mgroup_next = mgroup->next;
+ wm_manipulatorgroup_free(NULL, mmap, mgroup);
+ }
+ BLI_assert(BLI_listbase_is_empty(&mmap->manipulator_groups));
+
+ wm_manipulatormap_selected_delete(mmap);
+
+ MEM_freeN(mmap);
+}
+
+/**
+ * Creates and returns idname hash table for (visible) manipulators in \a mmap
+ *
+ * \param poll Polling function for excluding manipulators.
+ * \param data Custom data passed to \a poll
+ */
+static GHash *WM_manipulatormap_manipulator_hash_new(
+ const bContext *C, wmManipulatorMap *mmap,
+ bool (*poll)(const wmManipulator *, void *),
+ void *data, const bool include_hidden)
+{
+ GHash *hash = BLI_ghash_str_new(__func__);
+
+ /* collect manipulators */
+ for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+ if (!mgroup->type->poll || mgroup->type->poll(C, mgroup->type)) {
+ for (wmManipulator *manipulator = mgroup->manipulators.first;
+ manipulator;
+ manipulator = manipulator->next)
+ {
+ if ((include_hidden || (manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) &&
+ (!poll || poll(manipulator, data)))
+ {
+ BLI_ghash_insert(hash, manipulator->idname, manipulator);
+ }
+ }
+ }
+ }
+
+ return hash;
+}
+
+void WM_manipulatormap_tag_refresh(wmManipulatorMap *mmap)
+{
+ if (mmap) {
+ mmap->update_flag |= MANIPULATORMAP_REFRESH;
+ }
+}
+
+static void manipulatormap_tag_updated(wmManipulatorMap *mmap)
+{
+ mmap->update_flag = 0;
+}
+
+static bool manipulator_prepare_drawing(
+ wmManipulatorMap *mmap, wmManipulator *manipulator,
+ const bContext *C, ListBase *draw_manipulators)
+{
+ if (!wm_manipulator_is_visible(manipulator)) {
+ /* skip */
+ }
+ else {
+ wm_manipulator_update(manipulator, C, (mmap->update_flag & MANIPULATORMAP_REFRESH) != 0);
+ BLI_addhead(draw_manipulators, BLI_genericNodeN(manipulator));
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Update manipulators of \a mmap to prepare for drawing. Adds all manipulators that
+ * should be drawn to list \a draw_manipulators, note that added items need freeing.
+ */
+static void manipulatormap_prepare_drawing(
+ wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators, const int drawstep)
+{
+ if (!mmap || BLI_listbase_is_empty(&mmap->manipulator_groups))
+ return;
+ wmManipulator *active_manipulator = mmap->mmap_context.active_manipulator;
+
+ /* only active manipulator needs updating */
+ if (active_manipulator) {
+ if (manipulator_prepare_drawing(mmap, active_manipulator, C, draw_manipulators)) {
+ manipulatormap_tag_updated(mmap);
+ }
+ /* don't draw any other manipulators */
+ return;
+ }
+
+ for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+ /* check group visibility - drawstep first to avoid unnecessary call of group poll callback */
+ if (!wm_manipulatorgroup_is_visible_in_drawstep(mgroup, drawstep) ||
+ !wm_manipulatorgroup_is_visible(mgroup, C))
+ {
+ continue;
+ }
+
+ /* needs to be initialized on first draw */
+ wm_manipulatorgroup_ensure_initialized(mgroup, C);
+ /* update data if needed */
+ /* XXX weak: Manipulator-group may skip refreshing if it's invisible (map gets untagged nevertheless) */
+ if (mmap->update_flag & MANIPULATORMAP_REFRESH && mgroup->type->refresh) {
+ mgroup->type->refresh(C, mgroup);
+ }
+ /* prepare drawing */
+ if (mgroup->type->draw_prepare) {
+ mgroup->type->draw_prepare(C, mgroup);
+ }
+
+ for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
+ manipulator_prepare_drawing(mmap, manipulator, C, draw_manipulators);
+ }
+ }
+
+ manipulatormap_tag_updated(mmap);
+}
+
+/**
+ * Draw all visible manipulators in \a mmap.
+ * Uses global draw_manipulators listbase.
+ */
+static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators)
+{
+ if (!mmap)
+ return;
+ BLI_assert(!BLI_listbase_is_empty(&mmap->manipulator_groups));
+
+ const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE);
+
+ /* TODO this will need it own shader probably? don't think it can be handled from that point though. */
+/* const bool use_lighting = (U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0; */
+
+ /* enable multisampling */
+ if (draw_multisample) {
+ glEnable(GL_MULTISAMPLE);
+ }
+
+ /* draw_manipulators contains all visible manipulators - draw them */
+ for (LinkData *link = draw_manipulators->first, *link_next; link; link = link_next) {
+ wmManipulator *manipulator = link->data;
+ link_next = link->next;
+
+ manipulator->draw(C, manipulator);
+ /* free/remove manipulator link after drawing */
+ BLI_freelinkN(draw_manipulators, link);
+ }
+
+ if (draw_multisample) {
+ glDisable(GL_MULTISAMPLE);
+ }
+}
+
+void WM_manipulatormap_draw(wmManipulatorMap *mmap, const bContext *C, const int drawstep)
+{
+ ListBase draw_manipulators = {NULL};
+
+ manipulatormap_prepare_drawing(mmap, C, &draw_manipulators, drawstep);
+ manipulators_draw_list(mmap, C, &draw_manipulators);
+ BLI_assert(BLI_listbase_is_empty(&draw_manipulators));
+}
+
+static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible_manipulators)
+{
+ int selectionbase = 0;
+ wmManipulator *manipulator;
+
+ for (LinkData *link = visible_manipulators->first; link; link = link->next) {
+ manipulator = link->data;
+ /* pass the selection id shifted by 8 bits. Last 8 bits are used for selected manipulator part id */
+ manipulator->render_3d_intersection(C, manipulator, selectionbase << 8);
+
+ selectionbase++;
+ }
+}
+
+static int manipulator_find_intersected_3D_intern(
+ ListBase *visible_manipulators, const bContext *C, const int co[2],
+ const float hotspot)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = sa->spacedata.first;
+ rcti rect;
+ GLuint buffer[64]; // max 4 items per select, so large enuf
+ short hits;
+ const bool do_passes = GPU_select_query_check_active();
+
+ rect.xmin = co[0] - hotspot;
+ rect.xmax = co[0] + hotspot;
+ rect.ymin = co[1] - hotspot;
+ rect.ymax = co[1] + hotspot;
+
+ ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_scene(C), ar, v3d, NULL, NULL, &rect);
+
+ if (do_passes)
+ GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
+ else
+ GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_ALL, 0);
+ /* do the drawing */
+ manipulator_find_active_3D_loop(C, visible_manipulators);
+
+ hits = GPU_select_end();
+
+ if (do_passes) {
+ GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
+ manipulator_find_active_3D_loop(C, visible_manipulators);
+ GPU_select_end();
+ }
+
+ ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_scene(C), ar, v3d, NULL, NULL, NULL);
+
+ return hits > 0 ? buffer[3] : -1;
+}
+
+/**
+ * Try to find a 3D manipulator at screen-space coordinate \a co. Uses OpenGL picking.
+ */
+static wmManipulator *manipulator_find_intersected_3D(
+ bContext *C, const int co[2], ListBase *visible_manipulators,
+ unsigned char *part)
+{
+ wmManipulator *result = NULL;
+ const float hotspot = 14.0f;
+ int ret;
+
+ *part = 0;
+ /* set up view matrices */
+ view3d_operator_needs_opengl(C);
+
+ ret = manipulator_find_intersected_3D_intern(visible_manipulators, C, co, 0.5f * hotspot);
+
+ if (ret != -1) {
+ LinkData *link;
+ int retsec;
+ retsec = manipulator_find_intersected_3D_intern(visible_manipulators, C, co, 0.2f * hotspot);
+
+ if (retsec != -1)
+ ret = retsec;
+
+ link = BLI_findlink(visible_manipulators, ret >> 8);
+ *part = ret & 255;
+ result = link->data;
+ }
+
+ return result;
+}
+
+/**
+ * Try to find a manipulator under the mouse position. 2D intersections have priority over
+ * 3D ones (could check for smallest screen-space distance but not needed right now).
+ */
+wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
+ wmManipulatorMap *mmap, bContext *C, const wmEvent *event,
+ unsigned char *part)
+{
+ wmManipulator *manipulator = NULL;
+ ListBase visible_3d_manipulators = {NULL};
+
+ for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+ if (wm_manipulatorgroup_is_visible(mgroup, C)) {
+ if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) {
+ wm_manipulatorgroup_intersectable_manipulators_to_list(mgroup, &visible_3d_manipulators);
+ }
+ else if ((manipulator = wm_manipulatorgroup_find_intersected_mainpulator(mgroup, C, event, part))) {
+ break;
+ }
+ }
+ }
+
+ if (!BLI_listbase_is_empty(&visible_3d_manipulators)) {
+ manipulator = manipulator_find_intersected_3D(C, event->mval, &visible_3d_manipulators, part);
+ BLI_freelistN(&visible_3d_manipulators);
+ }
+
+ return manipulator;
+}
+
+void WM_manipulatormap_add_handlers(ARegion *ar, wmManipulatorMap *mmap)
+{
+ wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "manipulator handler");
+
+ BLI_assert(mmap == ar->manipulator_map);
+ handler->manipulator_map = mmap;
+ BLI_addtail(&ar->handlers, handler);
+}
+
+void wm_manipulatormaps_handled_modal_update(
+ bContext *C, wmEvent *event, wmEventHandler *handler,
+ const wmOperatorType *ot)
+{
+ const bool modal_running = (handler->op != NULL);
+
+ /* happens on render or when joining areas */
+ if (!handler->op_region || !handler->op_region->manipulator_map)
+ return;
+
+ /* hide operator manipulators */
+ if (!modal_running && ot->mgrouptype) {
+ ot->mgrouptype->op = NULL;
+ }
+
+ wmManipulatorMap *mmap = handler->op_region->manipulator_map;
+ wmManipulator *manipulator = wm_manipulatormap_get_active_manipulator(mmap);
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ wm_manipulatormap_handler_context(C, handler);
+
+ /* regular update for running operator */
+ if (modal_running) {
+ if (manipulator && manipulator->handler && manipulator->opname &&
+ STREQ(manipulator->opname, handler->op->idname))
+ {
+ manipulator->handler(C, event, manipulator, 0);
+ }
+ }
+ /* operator not running anymore */
+ else {
+ wm_manipulatormap_set_highlighted_manipulator(mmap, C, NULL, 0);
+ wm_manipulatormap_set_active_manipulator(mmap, C, event, NULL);
+ }
+
+ /* restore the area */
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+}
+
+/**
+ * Deselect all selected manipulators in \a mmap.
+ * \return if selection has changed.
+ */
+bool wm_manipulatormap_deselect_all(wmManipulatorMap *mmap, wmManipulator ***sel)
+{
+ if (*sel == NULL || mmap->mmap_context.tot_selected == 0)
+ return false;
+
+ for (int i = 0; i < mmap->mmap_context.tot_selected; i++) {
+ (*sel)[i]->state &= ~WM_MANIPULATOR_SELECTED;
+ (*sel)[i] = NULL;
+ }
+ wm_manipulatormap_selected_delete(mmap);
+
+ /* always return true, we already checked
+ * if there's anything to deselect */
+ return true;
+}
+
+BLI_INLINE bool manipulator_selectable_poll(const wmManipulator *manipulator, void *UNUSED(data))
+{
+ return (manipulator->mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SELECTABLE);
+}
+
+/**
+ * Select all selectable manipulators in \a mmap.
+ * \return if selection has changed.
+ */
+static bool wm_manipulatormap_select_all_intern(
+ bContext *C, wmManipulatorMap *mmap, wmManipulator ***sel,
+ const int action)
+{
+ /* GHash is used here to avoid having to loop over all manipulators twice (once to
+ * get tot_sel for allocating, once for actually selecting). Instead we collect
+ * selectable manipulators in hash table and use this to get tot_sel and do selection */
+
+ GHash *hash = WM_manipulatormap_manipulator_hash_new(C, mmap, manipulator_selectable_poll, NULL, true);
+ GHashIterator gh_iter;
+ int i, *tot_sel = &mmap->mmap_context.tot_selected;
+ bool changed = false;
+
+ *tot_sel = BLI_ghash_size(hash);
+ *sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_sel));
+
+ GHASH_ITER_INDEX (gh_iter, hash, i) {
+ wmManipulator *manipulator_iter = BLI_ghashIterator_getValue(&gh_iter);
+
+ if ((manipulator_iter->state & WM_MANIPULATOR_SELECTED) == 0) {
+ changed = true;
+ }
+ manipulator_iter->state |= WM_MANIPULATOR_SELECTED;
+ if (manipulator_iter->select) {
+ manipulator_iter->select(C, manipulator_iter, action);
+ }
+ (*sel)[i] = manipulator_iter;
+ BLI_assert(i < (*tot_sel));
+ }
+ /* highlight first manipulator */
+ wm_manipulatormap_set_highlighted_manipulator(mmap, C, (*sel)[0], (*sel)[0]->highlighted_part);
+
+ BLI_ghash_free(hash, NULL, NULL);
+ return changed;
+}
+
+/**
+ * Select/Deselect all selectable manipulators in \a mmap.
+ * \return if selection has changed.
+ *
+ * TODO select all by type
+ */
+bool WM_manipulatormap_select_all(bContext *C, wmManipulatorMap *mmap, const int action)
+{
+ wmManipulator ***sel = &mmap->mmap_context.selected_manipulator;
+ bool changed = false;
+
+ switch (action) {
+ case SEL_SELECT:
+ changed = wm_manipulatormap_select_all_intern(C, mmap, sel, action);
+ break;
+ case SEL_DESELECT:
+ changed = wm_manipulatormap_deselect_all(mmap, sel);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ if (changed)
+ WM_event_add_mousemove(C);
+
+ return changed;
+}
+
+/**
+ * Prepare context for manipulator handling (but only if area/region is
+ * part of screen). Version of #wm_handler_op_context for manipulators.
+ */
+void wm_manipulatormap_handler_context(bContext *C, wmEventHandler *handler)
+{
+ bScreen *screen = CTX_wm_screen(C);
+
+ if (screen) {
+ if (handler->op_area == NULL) {
+ /* do nothing in this context */
+ }
+ else {
+ ScrArea *sa;
+
+ for (sa = screen->areabase.first; sa; sa = sa->next)
+ if (sa == handler->op_area)
+ break;
+ if (sa == NULL) {
+ /* when changing screen layouts with running modal handlers (like render display), this
+ * is not an error to print */
+ if (handler->manipulator_map == NULL)
+ printf("internal error: modal manipulator-map handler has invalid area\n");
+ }
+ else {
+ ARegion *ar;
+ CTX_wm_area_set(C, sa);
+ for (ar = sa->regionbase.first; ar; ar = ar->next)
+ if (ar == handler->op_region)
+ break;
+ /* XXX no warning print here, after full-area and back regions are remade */
+ if (ar)
+ CTX_wm_region_set(C, ar);
+ }
+ }
+ }
+}
+
+bool WM_manipulatormap_cursor_set(const wmManipulatorMap *mmap, wmWindow *win)
+{
+ for (; mmap; mmap = mmap->next) {
+ wmManipulator *manipulator = mmap->mmap_context.highlighted_manipulator;
+ if (manipulator && manipulator->get_cursor) {
+ WM_cursor_set(win, manipulator->get_cursor(manipulator));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void wm_manipulatormap_set_highlighted_manipulator(
+ wmManipulatorMap *mmap, const bContext *C, wmManipulator *manipulator,
+ unsigned char part)
+{
+ if ((manipulator != mmap->mmap_context.highlighted_manipulator) ||
+ (manipulator && part != manipulator->highlighted_part))
+ {
+ if (mmap->mmap_context.highlighted_manipulator) {
+ mmap->mmap_context.highlighted_manipulator->state &= ~WM_MANIPULATOR_HIGHLIGHT;
+ mmap->mmap_context.highlighted_manipulator->highlighted_part = 0;
+ }
+
+ mmap->mmap_context.highlighted_manipulator = manipulator;
+
+ if (manipulator) {
+ manipulator->state |= WM_MANIPULATOR_HIGHLIGHT;
+ manipulator->highlighted_part = part;
+
+ if (C && manipulator->get_cursor) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_cursor_set(win, manipulator->get_cursor(manipulator));
+ }
+ }
+ else {
+ if (C) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_cursor_set(win, CURSOR_STD);
+ }
+ }
+
+ /* tag the region for redraw */
+ if (C) {
+ ARegion *ar = CTX_wm_region(C);
+ ED_region_tag_redraw(ar);
+ }
+ }
+}
+
+wmManipulator *wm_manipulatormap_get_highlighted_manipulator(wmManipulatorMap *mmap)
+{
+ return mmap->mmap_context.highlighted_manipulator;
+}
+
+void wm_manipulatormap_set_active_manipulator(
+ wmManipulatorMap *mmap, bContext *C, const wmEvent *event, wmManipulator *manipulator)
+{
+ if (manipulator && C) {
+ manipulator->state |= WM_MANIPULATOR_ACTIVE;
+ mmap->mmap_context.active_manipulator = manipulator;
+
+ if (manipulator->opname) {
+ wmOperatorType *ot = WM_operatortype_find(manipulator->opname, 0);
+
+ if (ot) {
+ /* first activate the manipulator itself */
+ if (manipulator->invoke && manipulator->handler) {
+ manipulator->invoke(C, event, manipulator);
+ }
+
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &manipulator->opptr);
+
+ /* we failed to hook the manipulator to the operator handler or operator was cancelled, return */
+ if (!mmap->mmap_context.active_manipulator) {
+ manipulator->state &= ~WM_MANIPULATOR_ACTIVE;
+ /* first activate the manipulator itself */
+ if (manipulator->interaction_data) {
+ MEM_freeN(manipulator->interaction_data);
+ manipulator->interaction_data = NULL;
+ }
+ }
+ return;
+ }
+ else {
+ printf("Manipulator error: operator not found");
+ mmap->mmap_context.active_manipulator = NULL;
+ return;
+ }
+ }
+ else {
+ if (manipulator->invoke && manipulator->handler) {
+ manipulator->invoke(C, event, manipulator);
+ }
+ }
+ WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);
+ }
+ else {
+ manipulator = mmap->mmap_context.active_manipulator;
+
+
+ /* deactivate, manipulator but first take care of some stuff */
+ if (manipulator) {
+ manipulator->state &= ~WM_MANIPULATOR_ACTIVE;
+ /* first activate the manipulator itself */
+ if (manipulator->interaction_data) {
+ MEM_freeN(manipulator->interaction_data);
+ manipulator->interaction_data = NULL;
+ }
+ }
+ mmap->mmap_context.active_manipulator = NULL;
+
+ if (C) {
+ WM_cursor_grab_disable(CTX_wm_window(C), NULL);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ WM_event_add_mousemove(C);
+ }
+ }
+}
+
+wmManipulator *wm_manipulatormap_get_active_manipulator(wmManipulatorMap *mmap)
+{
+ return mmap->mmap_context.active_manipulator;
+}
+
+/** \} */ /* wmManipulatorMap */
+
+
+/* -------------------------------------------------------------------- */
+/** \name wmManipulatorMapType
+ *
+ * \{ */
+
+wmManipulatorMapType *WM_manipulatormaptype_find(
+ const struct wmManipulatorMapType_Params *mmap_params)
+{
+ for (wmManipulatorMapType *mmaptype = manipulatormaptypes.first; mmaptype; mmaptype = mmaptype->next) {
+ if (mmaptype->spaceid == mmap_params->spaceid &&
+ mmaptype->regionid == mmap_params->regionid &&
+ STREQ(mmaptype->idname, mmap_params->idname))
+ {
+ return mmaptype;
+ }
+ }
+
+ return NULL;
+}
+
+wmManipulatorMapType *WM_manipulatormaptype_ensure(
+ const struct wmManipulatorMapType_Params *mmap_params)
+{
+ wmManipulatorMapType *mmaptype = WM_manipulatormaptype_find(mmap_params);
+
+ if (mmaptype) {
+ return mmaptype;
+ }
+
+ mmaptype = MEM_callocN(sizeof(wmManipulatorMapType), "manipulatortype list");
+ mmaptype->spaceid = mmap_params->spaceid;
+ mmaptype->regionid = mmap_params->regionid;
+ BLI_strncpy(mmaptype->idname, mmap_params->idname, sizeof(mmaptype->idname));
+ BLI_addhead(&manipulatormaptypes, mmaptype);
+
+ return mmaptype;
+}
+
+void wm_manipulatormaptypes_free(void)
+{
+ for (wmManipulatorMapType *mmaptype = manipulatormaptypes.first; mmaptype; mmaptype = mmaptype->next) {
+ BLI_freelistN(&mmaptype->manipulator_grouptypes);
+ }
+ BLI_freelistN(&manipulatormaptypes);
+}
+
+/**
+ * Initialize keymaps for all existing manipulator-groups
+ */
+void wm_manipulators_keymap(wmKeyConfig *keyconf)
+{
+ wmManipulatorMapType *mmaptype;
+ wmManipulatorGroupType *mgrouptype;
+
+ /* we add this item-less keymap once and use it to group manipulator-group keymaps into it */
+ WM_keymap_find(keyconf, "Manipulators", 0, 0);
+
+ for (mmaptype = manipulatormaptypes.first; mmaptype; mmaptype = mmaptype->next) {
+ for (mgrouptype = mmaptype->manipulator_grouptypes.first; mgrouptype; mgrouptype = mgrouptype->next) {
+ wm_manipulatorgrouptype_keymap_init(mgrouptype, keyconf);
+ }
+ }
+}
+
+/** \} */ /* wmManipulatorMapType */
+
diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
new file mode 100644
index 00000000000..c5008cef896
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
@@ -0,0 +1,90 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/wm_manipulator_wmapi.h
+ * \ingroup wm
+ *
+ * \name Manipulators Window Manager API
+ * API for usage in window manager code only. It should contain all functionality
+ * needed to hook up the manipulator system with Blender's window manager. It's
+ * mostly the event system that needs to communicate with manipulator code.
+ *
+ * Only included in wm.h and lower level files.
+ */
+
+
+#ifndef __WM_MANIPULATOR_WMAPI_H__
+#define __WM_MANIPULATOR_WMAPI_H__
+
+struct wmEventHandler;
+struct wmManipulatorMap;
+struct wmOperatorType;
+struct wmOperator;
+
+
+/* -------------------------------------------------------------------- */
+/* wmManipulator */
+
+typedef void (*wmManipulatorSelectFunc)(struct bContext *, struct wmManipulator *, const int);
+
+struct wmManipulatorGroup *wm_manipulator_get_parent_group(const struct wmManipulator *manipulator);
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorGroup */
+
+void MANIPULATORGROUP_OT_manipulator_select(struct wmOperatorType *ot);
+void MANIPULATORGROUP_OT_manipulator_tweak(struct wmOperatorType *ot);
+
+void wm_manipulatorgroup_attach_to_modal_handler(
+ struct bContext *C, struct wmEventHandler *handler,
+ struct wmManipulatorGroupType *mgrouptype, struct wmOperator *op);
+
+/* -------------------------------------------------------------------- */
+/* wmManipulatorMap */
+
+void wm_manipulatormap_delete(struct wmManipulatorMap *mmap);
+void wm_manipulatormaptypes_free(void);
+
+void wm_manipulators_keymap(struct wmKeyConfig *keyconf);
+
+void wm_manipulatormaps_handled_modal_update(
+ bContext *C, struct wmEvent *event, struct wmEventHandler *handler,
+ const struct wmOperatorType *ot);
+void wm_manipulatormap_handler_context(bContext *C, struct wmEventHandler *handler);
+
+struct wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
+ struct wmManipulatorMap *mmap, bContext *C,
+ const struct wmEvent *event, unsigned char *part);
+void wm_manipulatormap_set_highlighted_manipulator(
+ struct wmManipulatorMap *mmap, const bContext *C,
+ struct wmManipulator *manipulator, unsigned char part);
+struct wmManipulator *wm_manipulatormap_get_highlighted_manipulator(struct wmManipulatorMap *mmap);
+void wm_manipulatormap_set_active_manipulator(
+ struct wmManipulatorMap *mmap, bContext *C,
+ const struct wmEvent *event, struct wmManipulator *manipulator);
+struct wmManipulator *wm_manipulatormap_get_active_manipulator(struct wmManipulatorMap *mmap);
+
+#endif /* __WM_MANIPULATOR_WMAPI_H__ */
+
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index e8485359490..f63246580ea 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -34,6 +34,8 @@
struct wmWindow;
struct ReportList;
+#include "manipulators/wm_manipulator_wmapi.h"
+
typedef struct wmPaintCursor {
struct wmPaintCursor *next, *prev;
diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h
index 5257bba45ff..56dff304719 100644
--- a/source/blender/windowmanager/wm_draw.h
+++ b/source/blender/windowmanager/wm_draw.h
@@ -34,6 +34,8 @@
#include "GPU_glew.h"
+#define USE_TEXTURE_RECTANGLE 1
+
typedef struct wmDrawTriple {
GLuint bind;
int x, y;
@@ -56,7 +58,7 @@ void wm_draw_region_clear (struct wmWindow *win, struct ARegion *ar);
void wm_tag_redraw_overlay (struct wmWindow *win, struct ARegion *ar);
-void wm_triple_draw_textures (struct wmWindow *win, struct wmDrawTriple *triple, float alpha, bool is_interlace);
+void wm_triple_draw_textures (struct wmWindow *win, struct wmDrawTriple *triple, float alpha);
void wm_draw_data_free (struct wmWindow *win);
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index efc01b1f8a8..2f7ebbc1def 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -52,7 +52,7 @@ typedef struct wmEventHandler {
wmKeyMap *keymap; /* pointer to builtin/custom keymaps */
const rcti *bblocal, *bbwin; /* optional local and windowspace bb */
- /* modal operator handler */
+ /* modal operator handler and WM_HANDLER_FILESELECT */
wmOperator *op; /* for derived/modal handlers */
struct ScrArea *op_area; /* for derived/modal handlers */
struct ARegion *op_region; /* for derived/modal handlers */
@@ -68,7 +68,8 @@ typedef struct wmEventHandler {
/* drop box handler */
ListBase *dropboxes;
-
+ /* manipulator handler */
+ struct wmManipulatorMap *manipulator_map;
} wmEventHandler;
/* custom types for handlers, for signalling, freeing */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 3085f138846..9d34bc24e6c 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -339,6 +339,8 @@ enum {
EVT_DROP = 0x5023,
EVT_BUT_CANCEL = 0x5024,
+ /* could become manipulator callback */
+ EVT_MANIPULATOR_UPDATE = 0x5025,
/* ********** End of Blender internal events. ********** */
};
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index f70ec6b47f6..089e2994d3d 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -32,7 +32,11 @@
#ifndef __WM_WINDOW_H__
#define __WM_WINDOW_H__
+struct EnumPropertyItem;
+struct wmEvent;
struct wmOperator;
+struct PointerRNA;
+struct PropertyRNA;
/* *************** internal api ************** */
void wm_ghost_init (bContext *C);
@@ -76,9 +80,12 @@ void wm_window_IME_end (wmWindow *win);
/* *************** window operators ************** */
int wm_window_close_exec(bContext *C, struct wmOperator *op);
-int wm_window_duplicate_exec(bContext *C, struct wmOperator *op);
int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
+struct EnumPropertyItem *wm_window_new_screen_itemf(bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free);
+int wm_window_new_exec(bContext *C, struct wmOperator *op);
+int wm_window_new_invoke(bContext *C, struct wmOperator *op, const struct wmEvent *event);
+
/* Initial (unmaximized) size to start with for
* systems that can't find it for themselves (X11).
* Clamped by real desktop limits */
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 66c72be3d5d..4f0e64b0955 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -127,6 +127,7 @@ endif()
bf_intern_moto
bf_nodes
bf_gpu
+ bf_intern_gawain
bf_imbuf
bf_avi
ge_logic_network
diff --git a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
index 0e570e19258..d2c2129532a 100644
--- a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
+++ b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
@@ -35,11 +35,12 @@ set(INC
../../blender/blenloader
../../blender/makesdna
../../blender/makesrna
+ ../../../intern/glew-mx
../../../intern/guardedalloc
)
set(INC_SYS
-
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 82a3527a655..d06777e792c 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -43,8 +43,10 @@
struct ARegion;
struct ARegionType;
+struct bFaceMap;
struct BMEditMesh;
struct Base;
+struct BaseLegacy;
struct bContext;
struct BoundBox;
struct Brush;
@@ -178,11 +180,14 @@ struct wmWindowManager;
#include "../blender/editors/include/UI_resources.h"
#include "../blender/editors/include/UI_view2d.h"
#include "../blender/freestyle/FRS_freestyle.h"
+#include "../blender/gpu/GPU_immediate.h"
+#include "../blender/gpu/GPU_matrix.h"
#include "../blender/python/BPY_extern.h"
#include "../blender/render/extern/include/RE_engine.h"
#include "../blender/render/extern/include/RE_pipeline.h"
#include "../blender/render/extern/include/RE_render_ext.h"
#include "../blender/render/extern/include/RE_shader_ext.h"
+#include "../blender/draw/DRW_engine.h"
#include "../blender/windowmanager/WM_api.h"
@@ -228,7 +233,7 @@ void EDBM_mesh_load(struct Object *ob) RET_NONE
void EDBM_mesh_make(struct ToolSettings *ts, struct Object *ob, const bool use_key_index) RET_NONE
void EDBM_mesh_normals_update(struct BMEditMesh *em) RET_NONE
void *g_system;
-bool EDBM_mtexpoly_check(struct BMEditMesh *em) RET_ZERO
+bool EDBM_uv_check(struct BMEditMesh *em) RET_ZERO
float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, const char *name, const char *viewname) RET_NULL
float RE_filter_value(int type, float x) RET_ZERO
@@ -260,7 +265,7 @@ bool ED_texture_context_check_linestyle(const struct bContext *C) RET_ZERO
void FRS_free_view_map_cache(void) RET_NONE
/* texture.c */
-int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, short thread, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) RET_ZERO
+int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, const short thread, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) RET_ZERO
int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) RET_ZERO
int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool) RET_ZERO
@@ -365,8 +370,10 @@ void ED_armature_edit_bone_remove(struct bArmature *arm, struct EditBone *exBone
void object_test_constraints(struct Object *owner) RET_NONE
void ED_armature_ebone_to_mat4(struct EditBone *ebone, float mat[4][4]) RET_NONE
void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]) RET_NONE
-void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr) RET_NONE
+void ED_object_parent(struct Object *ob, struct Object *par, const int type, const char *substr) RET_NONE
void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con) RET_NONE
+void ED_object_facemap_face_add(struct Object *ob, struct bFaceMap *fmap, int facenum) RET_NONE
+void ED_object_facemap_face_remove(struct Object *ob, struct bFaceMap *fmap, int facenum) RET_NONE
void ED_node_composit_default(const struct bContext *C, struct Scene *scene) RET_NONE
void *ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *custumdata, int type) RET_ZERO /* XXX this one looks weird */
void *ED_region_draw_cb_customdata(void *handle) RET_ZERO /* XXX This one looks wrong also */
@@ -414,7 +421,7 @@ void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *name) RET
char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) RET_NULL
void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) RET_NONE
-struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob) RET_NULL
+struct PTCacheEdit *PE_get_current(struct Scene *scene, struct SceneLayer *sl, struct Object *ob) RET_NULL
void PE_current_changed(struct Scene *scene, struct Object *ob) RET_NONE
/* rna keymap */
@@ -454,7 +461,7 @@ bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rn
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock) RET_NONE
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **r_lock) RET_NULL
void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy) RET_NONE
-const char *ED_info_stats_string(struct Scene *scene) RET_NULL
+const char *ED_info_stats_string(struct Scene *scene, struct SceneLayer *sl) RET_NULL
void ED_area_tag_redraw(struct ScrArea *sa) RET_NONE
void ED_area_tag_refresh(struct ScrArea *sa) RET_NONE
void ED_area_newspace(struct bContext *C, struct ScrArea *sa, int type, const bool skip_ar_exit) RET_NONE
@@ -488,7 +495,8 @@ void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View
void ED_node_shader_default(const struct bContext *C, struct ID *id) RET_NONE
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh) RET_NONE
struct bScreen *ED_screen_animation_playing(const struct wmWindowManager *wm) RET_NULL
-void ED_base_object_select(struct Base *base, short mode) RET_NONE
+void ED_base_object_select(struct BaseLegacy *base, short mode) RET_NONE
+void ED_object_base_select(struct Base *base, short mode) RET_NONE
bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Object *ob, struct ModifierData *md) RET_ZERO
struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, const char *name, int type) RET_ZERO
void ED_object_modifier_clear(struct Main *bmain, struct Object *ob) RET_NONE
@@ -509,7 +517,7 @@ void uiLayoutSetAlignment(uiLayout *layout, char alignment) RET_NONE
void uiLayoutSetScaleX(struct uiLayout *layout, float scale) RET_NONE
void uiLayoutSetScaleY(struct uiLayout *layout, float scale) RET_NONE
void uiTemplateIconView(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, int show_labels, float icon_scale) RET_NONE
-void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Base *base) RET_NONE
+void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Object *base) RET_NONE
void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int calc_tessface) RET_NONE
void ED_mesh_vertices_add(struct Mesh *mesh, struct ReportList *reports, int count) RET_NONE
void ED_mesh_edges_add(struct Mesh *mesh, struct ReportList *reports, int count) RET_NONE
@@ -535,7 +543,7 @@ int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, struc
float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only) RET_ZERO
void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height) RET_NONE
-bool ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima) RET_ZERO
+bool ED_space_image_check_show_maskedit(struct SceneLayer *sl, struct SpaceImage *sima) RET_ZERO
bool ED_texture_context_check_world(const struct bContext *C) RET_ZERO
bool ED_texture_context_check_material(const struct bContext *C) RET_ZERO
@@ -546,9 +554,9 @@ bool ED_texture_context_check_others(const struct bContext *C) RET_ZERO
bool ED_text_region_location_from_cursor(SpaceText *st, ARegion *ar, const int cursor_co[2], int r_pixel_co[2]) RET_ZERO
SnapObjectContext *ED_transform_snap_object_context_create(
- struct Main *bmain, struct Scene *scene, int flag) RET_NULL
+ struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, int flag) RET_NULL
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- struct Main *bmain, struct Scene *scene, int flag,
+ struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, int flag,
const struct ARegion *ar, const struct View3D *v3d) RET_NULL
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) RET_NONE
bool ED_transform_snap_object_project_ray_ex(
@@ -599,6 +607,14 @@ const char *uiLayoutIntrospect(uiLayout *layout) RET_NULL
void UI_reinit_font(void) RET_NONE
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big) RET_ZERO
struct bTheme *UI_GetTheme(void) RET_NULL
+void UI_GetThemeColor3fv(int colorid, float col[4]) RET_NONE
+void UI_GetThemeColor4fv(int colorid, float col[4]) RET_NONE
+void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4]) RET_NONE
+void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4]) RET_NONE
+void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int offset, float col[3]) RET_NONE
+void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4]) RET_NONE
+void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned char col[3]) RET_NONE
+void UI_GetThemeColorShadeAlpha4ubv(int colorid, int coloffset, int alphaoffset, unsigned char col[4]) RET_NONE
/* rna template */
void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *proptypename, const char *text) RET_NONE
@@ -610,6 +626,17 @@ struct uiLayout *uiTemplateConstraint(struct uiLayout *layout, struct PointerRNA
void uiTemplatePreview(struct uiLayout *layout, struct bContext *C, struct ID *id, int show_buttons, struct ID *parent,
struct MTex *slot, const char *preview_id) RET_NONE
void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int rows, int cols) RET_NONE
+void uiTemplateSearch(
+ uiLayout *layout, struct bContext *C,
+ PointerRNA *ptr, const char *propname,
+ PointerRNA *searchptr, const char *searchpropname,
+ const char *newop, const char *unlinkop) RET_NONE
+void uiTemplateSearchPreview(
+ uiLayout *layout, struct bContext *C,
+ PointerRNA *ptr, const char *propname,
+ PointerRNA *searchptr, const char *searchpropname,
+ const char *newop, const char *unlinkop,
+ const int rows, const int cols) RET_NONE
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type, int levels, int brush, int neg_slope) RET_NONE
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int expand) RET_NONE
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, const char *propname, PointerRNA *used_ptr, const char *used_propname, int active_layer) RET_NONE
@@ -632,6 +659,7 @@ void uiTemplateNodeView(struct uiLayout *layout, struct bContext *C, struct bNod
void uiTemplateTextureUser(struct uiLayout *layout, struct bContext *C) RET_NONE
void uiTemplateTextureShow(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop) RET_NONE
void uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr) RET_NONE
+void uiTemplateOverrideProperty(struct uiLayout *layout, struct PointerRNA *collection_props_ptr, struct PointerRNA *scene_props_ptr, const char *name, const char *custom_template) RET_NONE
void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact) RET_NONE
void uiTemplateMovieclipInformation(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *userptr) RET_NONE
void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname) RET_NONE
@@ -665,6 +693,7 @@ void RE_ReleaseResultImage(struct Render *re) RET_NONE
int RE_engine_test_break(struct RenderEngine *engine) RET_ZERO
void RE_engines_init() RET_NONE
void RE_engines_exit() RET_NONE
+void RE_engines_register(struct Main *bmain, RenderEngineType *render_type) RET_NONE
void RE_engine_report(struct RenderEngine *engine, int type, const char *msg) RET_NONE
ListBase R_engines = {NULL, NULL};
void RE_engine_free(struct RenderEngine *engine) RET_NONE
@@ -675,13 +704,20 @@ void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe)
void RE_FreePersistentData(void) RET_NONE
void RE_point_density_cache(struct Scene *scene, struct PointDensity *pd, const bool use_render_params) RET_NONE
void RE_point_density_minmax(struct Scene *scene, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]) RET_NONE
-void RE_point_density_sample(struct Scene *scene, struct PointDensity *pd, int resolution, const bool use_render_params, float *values) RET_NONE
+void RE_point_density_sample(struct Scene *scene, struct PointDensity *pd, const int resolution, const bool use_render_params, float *values) RET_NONE
void RE_point_density_free(struct PointDensity *pd) RET_NONE
void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE
void RE_FreeAllPersistentData(void) RET_NONE
float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta) RET_ZERO
void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int channels, const char *chanid, int type) RET_NONE
+/* Draw */
+void OBJECT_collection_settings_create(struct IDProperty *properties) RET_NONE
+void EDIT_MESH_collection_settings_create(struct IDProperty *properties) RET_NONE
+void EDIT_ARMATURE_collection_settings_create(struct IDProperty *properties) RET_NONE
+void PAINT_WEIGHT_collection_settings_create(struct IDProperty *properties) RET_NONE
+void PAINT_VERTEX_collection_settings_create(struct IDProperty *properties) RET_NONE
+
/* python */
struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet) RET_NULL
void WM_operatortype_iter(struct GHashIterator *ghi) RET_NONE
@@ -723,6 +759,7 @@ int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title,
/* RNA COLLADA dependency */
int collada_export(struct Scene *sce,
+ struct SceneLayer *scene_layer,
const char *filepath,
int apply_modifiers,
BC_export_mesh_type export_mesh_type,
@@ -734,7 +771,6 @@ int collada_export(struct Scene *sce,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
int include_material_textures,
int use_texture_copies,
diff --git a/source/creator/creator.c b/source/creator/creator.c
index a59a45f885c..4e090b0b19f 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -56,7 +56,6 @@
#include "BKE_brush.h"
#include "BKE_cachefile.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h" /* for DAG_init */
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_material.h"
@@ -66,6 +65,7 @@
#include "BKE_image.h"
#include "BKE_particle.h"
+#include "DEG_depsgraph.h"
#include "IMB_imbuf.h" /* for IMB_init */
@@ -231,8 +231,7 @@ int main(
/* --- end declarations --- */
- /* ensure we free data on early-exit */
- struct CreatorAtExitData app_init_data = {NULL};
+ /* ensure we free data on early-exit */ struct CreatorAtExitData app_init_data = {NULL};
BKE_blender_atexit_register(callback_main_atexit, &app_init_data);
#ifdef WIN32
@@ -361,7 +360,7 @@ int main(
BKE_cachefiles_init();
BKE_images_init();
BKE_modifier_init();
- DAG_init();
+ DEG_register_node_types();
BKE_brush_system_init();
RE_texture_rng_init();
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 658a0b2db08..f25efbf72e9 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -55,8 +55,6 @@
#include "BKE_sound.h"
#include "BKE_image.h"
-#include "DEG_depsgraph.h"
-
#ifdef WITH_FFMPEG
#include "IMB_imbuf.h"
#endif
@@ -72,9 +70,7 @@
#include "WM_api.h"
-#include "GPU_basic_shader.h"
#include "GPU_draw.h"
-#include "GPU_extensions.h"
/* for passing information between creator and gameengine */
#ifdef WITH_GAMEENGINE
@@ -569,7 +565,6 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
BLI_argsPrintArgDoc(ba, "--env-system-python");
printf("\n");
BLI_argsPrintArgDoc(ba, "-nojoystick");
- BLI_argsPrintArgDoc(ba, "-noglsl");
BLI_argsPrintArgDoc(ba, "-noaudio");
BLI_argsPrintArgDoc(ba, "-setaudio");
@@ -587,8 +582,6 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
printf("\n");
printf("Experimental Features:\n");
- BLI_argsPrintArgDoc(ba, "--enable-new-depsgraph");
- BLI_argsPrintArgDoc(ba, "--enable-new-basic-shader-glsl");
/* Other options _must_ be last (anything not handled will show here) */
printf("\n");
@@ -1013,15 +1006,6 @@ static int arg_handle_joystick_disable(int UNUSED(argc), const char **UNUSED(arg
return 0;
}
-static const char arg_handle_glsl_disable_doc[] =
-"\n\tDisable GLSL shading"
-;
-static int arg_handle_glsl_disable(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
-{
- GPU_extensions_disable();
- return 0;
-}
-
static const char arg_handle_audio_disable_doc[] =
"\n\tForce sound system to None"
;
@@ -1185,26 +1169,6 @@ static int arg_handle_threads_set(int argc, const char **argv, void *UNUSED(data
}
}
-static const char arg_handle_depsgraph_use_new_doc[] =
-"\n\tUse new dependency graph"
-;
-static int arg_handle_depsgraph_use_new(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
-{
- printf("Using new dependency graph.\n");
- DEG_depsgraph_switch_to_new();
- return 0;
-}
-
-static const char arg_handle_basic_shader_glsl_use_new_doc[] =
-"\n\tUse new GLSL basic shader"
-;
-static int arg_handle_basic_shader_glsl_use_new(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
-{
- printf("Using new GLSL basic shader.\n");
- GPU_basic_shader_use_glsl_set(true);
- return 0;
-}
-
static const char arg_handle_verbosity_set_doc[] =
"<verbose>\n"
"\tSet logging verbosity level."
@@ -1842,9 +1806,6 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 1, NULL, "--debug-gpumem",
CB_EX(arg_handle_debug_mode_generic_set, gpumem), (void *)G_DEBUG_GPU_MEM);
- BLI_argsAdd(ba, 1, NULL, "--enable-new-depsgraph", CB(arg_handle_depsgraph_use_new), NULL);
- BLI_argsAdd(ba, 1, NULL, "--enable-new-basic-shader-glsl", CB(arg_handle_basic_shader_glsl_use_new), NULL);
-
BLI_argsAdd(ba, 1, NULL, "--verbose", CB(arg_handle_verbosity_set), NULL);
BLI_argsAdd(ba, 1, NULL, "--factory-startup", CB(arg_handle_factory_startup_set), NULL);
@@ -1865,7 +1826,6 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
/* third pass: disabling things and forcing settings */
BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, CB(arg_handle_joystick_disable), syshandle);
- BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, CB(arg_handle_glsl_disable), NULL);
BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, CB(arg_handle_audio_disable), NULL);
BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, CB(arg_handle_audio_set), NULL);
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 6e698166fd9..99f3d0639f3 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -267,7 +267,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0);
- bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support();
+ bool displaylists = false; // (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support();
#ifdef WITH_PYTHON
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
#endif
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index a5af525e13a..1f6687c2b67 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -138,7 +138,8 @@ static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
if (pchan->prop)
pchan->prop= IDP_CopyProperty(pchan->prop);
#endif
- pchan->prop= NULL;
+ pchan->prop = NULL;
+ pchan->draw_data = NULL;
}
BLI_ghash_free(ghash, NULL, NULL);
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 4751e60996d..6667e6a44c2 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -589,17 +589,17 @@ static bool ConvertMaterial(
/* In Multitexture use the face texture if and only if
* it is set in the buttons
* In GLSL is not working yet :/ 3.2011 */
- bool facetex = false;
- if (validface && mat->mode & MA_FACETEXTURE) {
- facetex = true;
- }
// foreach MTex
for (int i = 0; i < MAXTEX; i++) {
// use face tex
- if (i == 0 && facetex ) {
- facetex = false;
+ if (i == 0) {
+#if 0
Image *tmp = (Image *)(tface->tpage);
+#else
+ /* weak but better then nothing */
+ Image *tmp = mat ? mat->edit_image : NULL;
+#endif
if (tmp) {
material->img[i] = tmp;
@@ -789,7 +789,11 @@ static bool ConvertMaterial(
// check for tface tex to fallback on
if (validface) {
+#if 0
material->img[0] = (Image *)(tface->tpage);
+#else
+ material->img[0] = mat ? mat->edit_image : NULL;
+#endif
// ------------------------
if (material->img[0]) {
material->texname[0] = material->img[0]->id.name;
@@ -830,7 +834,7 @@ static bool ConvertMaterial(
/* No material, what to do? let's see what is in the UV and set the material accordingly
* light and visible is always on */
if (validface) {
- material->tile = tface->tile;
+ /* nop */
}
else {
// nothing at all
@@ -869,13 +873,6 @@ static bool ConvertMaterial(
if (validmat) {
material->matname =(mat->id.name);
}
-
- if (tface) {
- ME_MTEXFACE_CPY(&material->mtexpoly, tface);
- }
- else {
- memset(&material->mtexpoly, 0, sizeof(material->mtexpoly));
- }
material->material = mat;
return true;
}
@@ -894,7 +891,7 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
converter->GetGLSLMaterials());
- if (ma && (ma->mode & MA_FACETEXTURE) == 0)
+ if (ma)
converter->CacheBlenderMaterial(scene, ma, bl_mat);
}
@@ -910,7 +907,7 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer);
polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
- if (ma && (ma->mode & MA_FACETEXTURE) == 0)
+ if (ma)
converter->CachePolyMaterial(scene, ma, polymat);
}
@@ -1740,7 +1737,7 @@ static void blenderSceneSetBackground(Scene *blenderscene)
for (SETLOOPER(blenderscene, it, base)) {
base->object->lay = base->lay;
- base->object->flag = base->flag;
+ BKE_scene_base_flag_sync_from_base(base);
}
}
diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
index 577e25d6198..6d6d53b1e17 100644
--- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
@@ -43,6 +43,7 @@ set(INC
../../../blender/blenlib
../../../blender/blenloader
../../../blender/blentranslation
+ ../../../blender/depsgraph
../../../blender/gpu
../../../blender/imbuf
../../../blender/makesdna
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 50c34bbadaf..ddb04e9f84d 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -586,7 +586,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
bool fixed_framerate= (SYS_GetCommandLineInt(syshandle, "fixedtime", (gm->flag & GAME_ENABLE_ALL_FRAMES)) != 0);
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
- bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0) && GPU_display_list_support();
+ bool useLists = false; // (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0) && GPU_display_list_support();
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 1) != 0);
bool restrictAnimFPS = (gm->flag & GAME_RESTRICT_ANIM_UPDATES) != 0;
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 0c206dfce3d..72ab06009b6 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -68,7 +68,6 @@ extern "C"
#include "BKE_appdir.h"
#include "BKE_blender.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_icons.h"
#include "BKE_image.h"
@@ -81,6 +80,8 @@ extern "C"
#include "BKE_text.h"
#include "BKE_sound.h"
+#include "DEG_depsgraph.h"
+
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
@@ -509,7 +510,7 @@ int main(
IMB_init();
BKE_images_init();
BKE_modifier_init();
- DAG_init();
+ DEG_register_node_types();
#ifdef WITH_FFMPEG
IMB_ffmpeg_init();
@@ -1201,7 +1202,7 @@ int main(
IMB_exit();
BKE_images_exit();
- DAG_exit();
+ DEG_free_node_types();
IMB_moviecache_destruct();
SYS_DeleteSystem(syshandle);
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 4f707e6267f..40384b43054 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -69,7 +69,6 @@ void BL_Material::Initialize()
alpha = 1.f;
emit = 0.f;
material = 0;
- memset(&mtexpoly, 0, sizeof(mtexpoly));
materialindex = 0;
amb=0.5f;
num_enabled = 0;
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index 9207a41f56d..710c02f4871 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -84,7 +84,6 @@ public:
Material* material;
- MTexPoly mtexpoly; /* copy of the derived meshes tface */
Image* img[MAXTEX];
EnvMap* cubemap[MAXTEX];
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index d26e35f8138..98d27ef3685 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -160,12 +160,6 @@ KX_BlenderMaterial::~KX_BlenderMaterial()
OnExit();
}
-MTexPoly *KX_BlenderMaterial::GetMTexPoly() const
-{
- // fonts on polys
- return &mMaterial->mtexpoly;
-}
-
unsigned int* KX_BlenderMaterial::GetMCol() const
{
// fonts on polys
@@ -190,7 +184,7 @@ Material *KX_BlenderMaterial::GetBlenderMaterial() const
Image *KX_BlenderMaterial::GetBlenderImage() const
{
- return mMaterial->mtexpoly.tpage;
+ return mMaterial->material ? mMaterial->material->edit_image : NULL;
}
Scene* KX_BlenderMaterial::GetBlenderScene() const
@@ -290,11 +284,6 @@ void KX_BlenderMaterial::OnExit()
mTextures[i].DeleteTex();
mTextures[i].DisableUnit();
}
-
- /* used to call with 'mMaterial->tface' but this can be a freed array,
- * see: [#30493], so just call with NULL, this is best since it clears
- * the 'lastface' pointer in GPU too - campbell */
- GPU_set_tpage(NULL, 1, mMaterial->alphablend);
}
@@ -310,7 +299,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
mLastShader = NULL;
}
- ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(GPU_BLEND_SOLID);
BL_Texture::DisableAllTextures();
return;
}
@@ -334,7 +323,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
ras->SetAlphaBlend(mMaterial->alphablend);
}
else {
- ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(GPU_BLEND_SOLID);
ras->SetAlphaBlend(-1); // indicates custom mode
// tested to be valid enums
@@ -346,7 +335,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras)
{
if ( !enable || !mBlenderShader->Ok() ) {
- ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(GPU_BLEND_SOLID);
// frame cleanup.
if (mLastBlenderShader) {
@@ -377,7 +366,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
BL_Texture::DisableAllTextures();
if ( !enable ) {
- ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(GPU_BLEND_SOLID);
return;
}
@@ -420,7 +409,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
ras->SetAlphaBlend(mMaterial->alphablend);
}
else {
- ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(GPU_BLEND_SOLID);
ras->SetAlphaBlend(-1); // indicates custom mode
glEnable(GL_BLEND);
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index a3d10c0a89d..c562ee0c583 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -84,7 +84,6 @@ public:
Material* GetBlenderMaterial() const;
Image* GetBlenderImage() const;
- MTexPoly *GetMTexPoly() const;
unsigned int* GetMCol() const;
BL_Texture * getTex (unsigned int idx) {
return (idx < MAXTEX) ? mTextures + idx : NULL;
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 89aea80bb67..4a97dc09f62 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -31,7 +31,7 @@
*/
-#include "glew-mx.h"
+#include "GPU_matrix.h"
#include "KX_Camera.h"
#include "KX_Scene.h"
#include "KX_PythonInit.h"
@@ -1048,19 +1048,21 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition,
}
const GLint *viewport;
- GLdouble win[3];
- GLdouble modelmatrix[16];
- GLdouble projmatrix[16];
+ GLfloat vec[3];
+ GLfloat win[3];
+ GLfloat modelmatrix[4][4];
+ GLfloat projmatrix[4][4];
MT_Matrix4x4 m_modelmatrix = this->GetWorldToCamera();
MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
- m_modelmatrix.getValue(modelmatrix);
- m_projmatrix.getValue(projmatrix);
+ vect.getValue(vec);
+ m_modelmatrix.getValue((float*) modelmatrix);
+ m_projmatrix.getValue((float*) projmatrix);
viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort();
- gluProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]);
+ gpuProject(vec, modelmatrix, projmatrix, viewport, win);
vect[0] = (win[0] - viewport[0]) / viewport[2];
vect[1] = (win[1] - viewport[1]) / viewport[3];
@@ -1087,36 +1089,33 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect,
y = 1.0 - y; //to follow Blender window coordinate system (Top-Down)
- MT_Vector3 vect;
- MT_Point3 campos, screenpos;
-
const GLint *viewport;
- GLdouble win[3];
- GLdouble modelmatrix[16];
- GLdouble projmatrix[16];
+ GLfloat vec[3];
+ GLfloat win[3];
+ GLfloat modelmatrix[4][4];
+ GLfloat projmatrix[4][4];
MT_Matrix4x4 m_modelmatrix = this->GetWorldToCamera();
MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
- m_modelmatrix.getValue(modelmatrix);
- m_projmatrix.getValue(projmatrix);
+ m_modelmatrix.getValue((float*) modelmatrix);
+ m_projmatrix.getValue((float*) projmatrix);
viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort();
- vect[0] = x * viewport[2];
- vect[1] = y * viewport[3];
-
- vect[0] += viewport[0];
- vect[1] += viewport[1];
+ vec[0] = x * viewport[2];
+ vec[1] = y * viewport[3];
- vect[2] = 0.f;
+ vec[0] += viewport[0];
+ vec[1] += viewport[1];
- gluUnProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]);
+ vec[2] = 0.f;
- campos = this->GetCameraLocation();
- screenpos = MT_Point3(win[0], win[1], win[2]);
- vect = campos-screenpos;
+ gpuUnProject(vec, modelmatrix, projmatrix, viewport, win);
+ MT_Point3 campos = this->GetCameraLocation();
+ MT_Point3 screenpos(win[0], win[1], win[2]);
+ MT_Vector3 vect = campos - screenpos;
vect.normalize();
return PyObjectFrom(vect);
}
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
index d08372e47d4..7abff85d39c 100644
--- a/source/gameengine/Ketsji/KX_Dome.cpp
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -41,7 +41,7 @@
#include "RAS_CameraData.h"
#include "BLI_math.h"
-#include "glew-mx.h"
+#include "GPU_matrix.h"
// constructor
KX_Dome::KX_Dome (
@@ -1685,7 +1685,7 @@ void KX_Dome::DrawEnvMap(void)
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- gluLookAt(0.0f,0.0f,1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
+ gpuLookAt(0.0f,0.0f,1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
glPolygonMode(GL_FRONT, GL_FILL);
glShadeModel(GL_SMOOTH);
@@ -1830,7 +1830,7 @@ void KX_Dome::DrawDomeFisheye(void)
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- gluLookAt(0.0f,-1.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,1.0f);
+ gpuLookAt(0.0f,-1.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,1.0f);
if (m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
glPolygonMode(GL_FRONT, GL_LINE);
@@ -1913,7 +1913,7 @@ void KX_Dome::DrawPanorama(void)
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- gluLookAt(0.0f,-1.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,1.0f);
+ gpuLookAt(0.0f,-1.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,1.0f);
if (m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
glPolygonMode(GL_FRONT, GL_LINE);
@@ -1981,7 +1981,7 @@ void KX_Dome::DrawDomeWarped(void)
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- gluLookAt(0.0f, 0.0f, 1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
+ gpuLookAt(0.0f, 0.0f, 1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
if (m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
glPolygonMode(GL_FRONT, GL_LINE);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 5f490747c2b..b2a480e99ca 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -34,6 +34,7 @@
#endif
#include <stdio.h>
+#include "DNA_scene_types.h"
#include "KX_Light.h"
#include "KX_Camera.h"
@@ -44,7 +45,6 @@
#include "KX_PyMath.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "DNA_lamp_types.h"
#include "BKE_scene.h"
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index b446acd6e63..469f2d62b76 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -38,7 +38,7 @@
struct GPULamp;
struct Scene;
-struct Base;
+struct BaseLegacy;
class KX_Camera;
class RAS_IRasterizer;
class RAS_ILightObject;
@@ -51,7 +51,7 @@ protected:
RAS_ILightObject* m_lightobj;
class RAS_IRasterizer* m_rasterizer; //needed for registering and replication of lightobj
Scene* m_blenderscene;
- Base* m_base;
+ BaseLegacy* m_base;
public:
KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,RAS_IRasterizer* rasterizer,RAS_ILightObject* lightobj, bool glsl);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index c79e1c23ef6..b3cee944880 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -2234,7 +2234,9 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject *gameobj, class RA
std::vector<int> vert_remap_array(numverts, 0);
for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) {
- if (tf->mode & TF_DYNAMIC) {
+ // 2.8x TODO: use GEMAT_NOPHYSICS.
+ // if (tf->mode & TF_DYNAMIC)
+ {
int flen;
if (mf->v4) {
@@ -2271,7 +2273,9 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject *gameobj, class RA
int *poly_index_pt = &m_polygonIndexArray[0];
for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) {
- if (tf->mode & TF_DYNAMIC) {
+ // 2.8x TODO: use GEMAT_NOPHYSICS.
+ // if (tf->mode & TF_DYNAMIC)
+ {
int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
if (mf->v4) {
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index 2a736aa7deb..1d22d2debf9 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -233,10 +233,6 @@ Image *RAS_IPolyMaterial::GetBlenderImage() const
{
return NULL;
}
-MTexPoly *RAS_IPolyMaterial::GetMTexPoly() const
-{
- return NULL;
-}
unsigned int *RAS_IPolyMaterial::GetMCol() const
{
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index a34f7a9b390..7023d305510 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -41,7 +41,6 @@
#endif
class RAS_IRasterizer;
-struct MTexPoly;
struct Material;
struct Image;
struct Scene;
@@ -167,7 +166,6 @@ public:
virtual Material* GetBlenderMaterial() const;
virtual Image* GetBlenderImage() const;
- virtual MTexPoly* GetMTexPoly() const;
virtual unsigned int* GetMCol() const;
virtual Scene* GetBlenderScene() const;
virtual void ReleaseMaterial();
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
index 69e859f06d9..18254357f85 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
@@ -43,6 +43,7 @@
#include "DNA_lamp_types.h"
#include "DNA_scene_types.h"
+#include "GPU_lamp.h"
#include "GPU_material.h"
RAS_OpenGLLight::RAS_OpenGLLight(RAS_OpenGLRasterizer *ras)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 5eed9b3b8f8..80c399fb256 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -60,6 +60,7 @@
extern "C"{
#include "BLF_api.h"
#include "BKE_DerivedMesh.h"
+ #include "DNA_material_types.h"
}
@@ -710,7 +711,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
glattrib = unit;
GPU_render_text(
- polymat->GetMTexPoly(), polymat->GetDrawingMode(), mytext, mytext.Length(), polymat->GetMCol(),
+ polymat->GetDrawingMode(), mytext, mytext.Length(), polymat->GetMCol(),
v_ptr, uv_ptr, glattrib);
ClearCachingInfo();
@@ -781,33 +782,6 @@ static int CheckMaterialDM(int matnr, void *attribs)
return 1;
}
-static DMDrawOption CheckTexDM(MTexPoly *mtexpoly, const bool has_mcol, int matnr)
-{
-
- // index is the original face index, retrieve the polygon
- if (matnr == current_blmat_nr &&
- (mtexpoly == NULL || mtexpoly->tpage == current_image)) {
- // must handle color.
- if (current_wireframe)
- return DM_DRAW_OPTION_NO_MCOL;
- if (current_ms->m_bObjectColor) {
- MT_Vector4& rgba = current_ms->m_RGBAcolor;
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- // don't use mcol
- return DM_DRAW_OPTION_NO_MCOL;
- }
- if (!has_mcol) {
- // we have to set the color from the material
- unsigned char rgba[4];
- current_polymat->GetMaterialRGBAColor(rgba);
- glColor4ubv((const GLubyte *)rgba);
- return DM_DRAW_OPTION_NORMAL;
- }
- return DM_DRAW_OPTION_NORMAL;
- }
- return DM_DRAW_OPTION_SKIP;
-}
-
void RAS_OpenGLRasterizer::DrawDerivedMesh(class RAS_MeshSlot &ms)
{
// mesh data is in derived mesh
@@ -824,7 +798,10 @@ void RAS_OpenGLRasterizer::DrawDerivedMesh(class RAS_MeshSlot &ms)
else
this->SetCullFace(false);
- if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
+#if 0
+ if (current_polymat->GetFlag() & RAS_BLENDERGLSL)
+#endif
+ {
// GetMaterialIndex return the original mface material index,
// increment by 1 to match what derived mesh is doing
current_blmat_nr = current_polymat->GetMaterialIndex()+1;
@@ -839,11 +816,6 @@ void RAS_OpenGLRasterizer::DrawDerivedMesh(class RAS_MeshSlot &ms)
int current_blend_mode = GPU_get_material_alpha_blend();
ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
GPU_set_material_alpha_blend(current_blend_mode);
- } else {
- //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
- current_blmat_nr = current_polymat->GetMaterialIndex();
- current_image = current_polymat->GetBlenderImage();
- ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL, DM_DRAW_USE_ACTIVE_UV);
}
}
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index ac480f4d58c..65e348336b4 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -482,3 +482,5 @@ if(WITH_ALEMBIC)
)
endif()
endif()
+
+add_subdirectory(render_layer)
diff --git a/tests/python/bl_alembic_import_test.py b/tests/python/bl_alembic_import_test.py
index 358b8a3c758..1322a883b72 100644
--- a/tests/python/bl_alembic_import_test.py
+++ b/tests/python/bl_alembic_import_test.py
@@ -63,7 +63,7 @@ class SimpleImportTest(AbstractAlembicTest):
# The objects should be linked to scene_collection in Blender 2.8,
# and to scene in Blender 2.7x.
- objects = bpy.context.scene.objects
+ objects = bpy.context.scene_collection.objects
self.assertEqual(13, len(objects))
# Test the hierarchy.
@@ -95,7 +95,7 @@ class SimpleImportTest(AbstractAlembicTest):
# All cubes should be selected, but the sphere shouldn't be.
for ob in bpy.data.objects:
- self.assertEqual('Cube' in ob.name, ob.select)
+ self.assertEqual('Cube' in ob.name, ob.select_get())
def test_change_path_constraint(self):
import math
diff --git a/tests/python/bl_mesh_modifiers.py b/tests/python/bl_mesh_modifiers.py
index bff2c31984c..f202e5b6611 100644
--- a/tests/python/bl_mesh_modifiers.py
+++ b/tests/python/bl_mesh_modifiers.py
@@ -248,7 +248,7 @@ def mesh_uv_add(obj):
(1.0, 1.0),
(1.0, 0.0))
- uv_lay = obj.data.uv_textures.new()
+ uv_lay = obj.data.uv_layers.new()
# XXX, odd that we need to do this. until UV's and texface
# are separated we will need to keep it
diff --git a/tests/python/render_layer/CMakeLists.txt b/tests/python/render_layer/CMakeLists.txt
new file mode 100644
index 00000000000..9d19985000d
--- /dev/null
+++ b/tests/python/render_layer/CMakeLists.txt
@@ -0,0 +1,172 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# 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.
+#
+# Contributor(s): Jacques Beaurain, Dalai Felinto.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# --env-system-scripts allows to run without the install target.
+
+# Use '--write-blend=/tmp/test.blend' to view output
+
+set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/../lib/tests)
+set(TEST_OUT_DIR ${CMAKE_BINARY_DIR}/tests)
+
+# ugh, any better way to do this on testing only?
+execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR})
+
+#~ if(NOT IS_DIRECTORY ${TEST_SRC_DIR})
+#~ message(FATAL_ERROR "CMake test directory not found!")
+#~ endif()
+
+# all calls to blender use this
+if(APPLE)
+ if(${CMAKE_GENERATOR} MATCHES "Xcode")
+ set(TEST_BLENDER_EXE ${EXECUTABLE_OUTPUT_PATH}/Debug/blender.app/Contents/MacOS/blender)
+ else()
+ set(TEST_BLENDER_EXE ${EXECUTABLE_OUTPUT_PATH}/blender.app/Contents/MacOS/blender)
+ endif()
+else()
+ set(TEST_BLENDER_EXE ${EXECUTABLE_OUTPUT_PATH}/blender)
+endif()
+
+# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
+set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
+
+
+# ------------------------------------------------------------------------------
+
+macro(RENDER_LAYER_TEST test_name)
+ # Adds ${CMAKE_CURRENT_LIST_DIR} to sys.path so that the tests can import
+ # things from render_layer_common.py
+ add_test(render_layer_${test_name} ${TEST_BLENDER_EXE}
+ --python-expr "import sys; sys.path.append('${CMAKE_CURRENT_LIST_DIR}')"
+ --python-exit-code 1
+ --python ${CMAKE_CURRENT_LIST_DIR}/test_${test_name}.py --
+ --testdir="${TEST_SRC_DIR}/layers"
+ )
+endmacro()
+
+RENDER_LAYER_TEST(active_collection)
+RENDER_LAYER_TEST(collection_rename)
+RENDER_LAYER_TEST(evaluation_render_settings_a)
+RENDER_LAYER_TEST(evaluation_render_settings_b)
+RENDER_LAYER_TEST(evaluation_render_settings_c)
+RENDER_LAYER_TEST(evaluation_render_settings_d)
+RENDER_LAYER_TEST(evaluation_render_settings_e)
+RENDER_LAYER_TEST(evaluation_render_settings_f)
+RENDER_LAYER_TEST(evaluation_render_settings_g)
+RENDER_LAYER_TEST(evaluation_render_settings_h)
+RENDER_LAYER_TEST(evaluation_render_settings_i)
+RENDER_LAYER_TEST(evaluation_visibility_a)
+RENDER_LAYER_TEST(evaluation_visibility_b)
+RENDER_LAYER_TEST(evaluation_visibility_c)
+RENDER_LAYER_TEST(evaluation_visibility_d)
+RENDER_LAYER_TEST(evaluation_visibility_e)
+RENDER_LAYER_TEST(evaluation_visibility_f)
+RENDER_LAYER_TEST(evaluation_visibility_g)
+RENDER_LAYER_TEST(evaluation_visibility_h)
+RENDER_LAYER_TEST(evaluation_visibility_i)
+RENDER_LAYER_TEST(evaluation_selectability_a)
+RENDER_LAYER_TEST(evaluation_selectability_b)
+RENDER_LAYER_TEST(evaluation_selectability_c)
+RENDER_LAYER_TEST(evaluation_selectability_d)
+RENDER_LAYER_TEST(evaluation_selectability_e)
+RENDER_LAYER_TEST(evaluation_selectability_f)
+RENDER_LAYER_TEST(object_add_cylinder)
+RENDER_LAYER_TEST(object_add_empty)
+RENDER_LAYER_TEST(object_add_torus)
+RENDER_LAYER_TEST(object_add_no_collection_cylinder)
+RENDER_LAYER_TEST(object_add_no_collection_empty)
+RENDER_LAYER_TEST(object_add_no_collection_torus)
+RENDER_LAYER_TEST(object_copy)
+RENDER_LAYER_TEST(object_delete_a)
+RENDER_LAYER_TEST(object_delete_b)
+RENDER_LAYER_TEST(object_link_a)
+RENDER_LAYER_TEST(object_link_b)
+RENDER_LAYER_TEST(object_link_c)
+RENDER_LAYER_TEST(operator_context)
+RENDER_LAYER_TEST(move_above_below_scene_collection_a)
+RENDER_LAYER_TEST(move_above_below_scene_collection_b)
+RENDER_LAYER_TEST(move_above_below_scene_collection_c)
+RENDER_LAYER_TEST(move_above_below_scene_collection_d)
+RENDER_LAYER_TEST(move_above_below_scene_collection_e)
+RENDER_LAYER_TEST(move_above_below_scene_collection_f)
+RENDER_LAYER_TEST(move_above_below_scene_collection_g)
+RENDER_LAYER_TEST(move_above_below_scene_collection_h)
+RENDER_LAYER_TEST(move_above_below_scene_collection_i)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_a)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_b)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_c)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_d)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_e)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_f)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_g)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_h)
+RENDER_LAYER_TEST(move_above_below_scene_collection_sync_i)
+RENDER_LAYER_TEST(move_into_scene_collection_a)
+RENDER_LAYER_TEST(move_into_scene_collection_b)
+RENDER_LAYER_TEST(move_into_scene_collection_c)
+RENDER_LAYER_TEST(move_into_scene_collection_d)
+RENDER_LAYER_TEST(move_into_scene_collection_e)
+RENDER_LAYER_TEST(move_into_scene_collection_f)
+RENDER_LAYER_TEST(move_into_scene_collection_g)
+RENDER_LAYER_TEST(move_into_scene_collection_h)
+RENDER_LAYER_TEST(move_into_scene_collection_i)
+RENDER_LAYER_TEST(move_into_scene_collection_j)
+RENDER_LAYER_TEST(move_into_scene_collection_k)
+RENDER_LAYER_TEST(move_into_scene_collection_l)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_a)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_b)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_c)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_d)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_e)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_f)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_g)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_h)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_i)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_j)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_k)
+RENDER_LAYER_TEST(move_into_scene_collection_sync_l)
+RENDER_LAYER_TEST(move_above_below_layer_collection_a)
+RENDER_LAYER_TEST(move_above_below_layer_collection_b)
+RENDER_LAYER_TEST(move_above_below_layer_collection_c)
+RENDER_LAYER_TEST(move_above_below_layer_collection_d)
+RENDER_LAYER_TEST(move_above_below_layer_collection_e)
+RENDER_LAYER_TEST(move_above_below_layer_collection_f)
+RENDER_LAYER_TEST(move_above_below_layer_collection_g)
+RENDER_LAYER_TEST(move_above_below_layer_collection_h)
+RENDER_LAYER_TEST(move_above_below_layer_collection_i)
+RENDER_LAYER_TEST(move_above_below_layer_collection_j)
+RENDER_LAYER_TEST(move_above_below_layer_collection_k)
+RENDER_LAYER_TEST(move_above_below_layer_collection_l)
+RENDER_LAYER_TEST(move_into_layer_collection_a)
+RENDER_LAYER_TEST(move_into_layer_collection_b)
+RENDER_LAYER_TEST(move_into_layer_collection_c)
+RENDER_LAYER_TEST(move_into_layer_collection_d)
+RENDER_LAYER_TEST(move_into_layer_collection_e)
+RENDER_LAYER_TEST(move_into_layer_collection_f)
+RENDER_LAYER_TEST(move_into_layer_collection_g)
+RENDER_LAYER_TEST(move_into_layer_collection_h)
+RENDER_LAYER_TEST(move_into_layer_collection_i)
+RENDER_LAYER_TEST(move_into_layer_collection_j)
+RENDER_LAYER_TEST(layer_linking)
+RENDER_LAYER_TEST(layer_syncing)
+RENDER_LAYER_TEST(scene_copy_a)
+RENDER_LAYER_TEST(scene_copy_b)
+RENDER_LAYER_TEST(scene_copy_c)
+RENDER_LAYER_TEST(scene_copy_d)
+RENDER_LAYER_TEST(scene_write_read)
diff --git a/tests/python/render_layer/render_layer_common.py b/tests/python/render_layer/render_layer_common.py
new file mode 100644
index 00000000000..ec417a829d6
--- /dev/null
+++ b/tests/python/render_layer/render_layer_common.py
@@ -0,0 +1,785 @@
+import unittest
+
+# ############################################################
+# Layer Collection Crawler
+# ############################################################
+
+
+def listbase_iter(data, struct, listbase):
+ element = data.get_pointer((struct, listbase, b'first'))
+ while element is not None:
+ yield element
+ element = element.get_pointer(b'next')
+
+
+def linkdata_iter(collection, data):
+ element = collection.get_pointer((data, b'first'))
+ while element is not None:
+ yield element
+ element = element.get_pointer(b'next')
+
+
+def get_layer_collection(layer_collection):
+ data = {}
+ flag = layer_collection.get(b'flag')
+
+ data['is_visible'] = (flag & (1 << 0)) != 0
+ data['is_selectable'] = (flag & (1 << 1)) != 0
+ data['is_folded'] = True
+
+ scene_collection = layer_collection.get_pointer(b'scene_collection')
+ if scene_collection is None:
+ name = 'Fail!'
+ else:
+ name = scene_collection.get(b'name')
+ data['name'] = name
+
+ objects = []
+ for link in linkdata_iter(layer_collection, b'object_bases'):
+ ob_base = link.get_pointer(b'data')
+ ob = ob_base.get_pointer(b'object')
+ objects.append(ob.get((b'id', b'name'))[2:])
+ data['objects'] = objects
+
+ collections = {}
+ for nested_layer_collection in linkdata_iter(layer_collection, b'layer_collections'):
+ subname, subdata = get_layer_collection(nested_layer_collection)
+ collections[subname] = subdata
+ data['collections'] = collections
+
+ return name, data
+
+
+def get_layer(layer):
+ data = {}
+ name = layer.get(b'name')
+
+ data['name'] = name
+ data['active_object'] = layer.get((b'basact', b'object', b'id', b'name'))[2:]
+ data['engine'] = layer.get(b'engine')
+
+ objects = []
+ for link in linkdata_iter(layer, b'object_bases'):
+ ob = link.get_pointer(b'object')
+ objects.append(ob.get((b'id', b'name'))[2:])
+ data['objects'] = objects
+
+ collections = {}
+ for layer_collection in linkdata_iter(layer, b'layer_collections'):
+ subname, subdata = get_layer_collection(layer_collection)
+ collections[subname] = subdata
+ data['collections'] = collections
+
+ return name, data
+
+
+def get_layers(scene):
+ """Return all the render layers and their data"""
+ layers = {}
+ for layer in linkdata_iter(scene, b'render_layers'):
+ name, data = get_layer(layer)
+ layers[name] = data
+ return layers
+
+
+def get_scene_collection_objects(collection, listbase):
+ objects = []
+ for link in linkdata_iter(collection, listbase):
+ ob = link.get_pointer(b'data')
+ if ob is None:
+ name = 'Fail!'
+ else:
+ name = ob.get((b'id', b'name'))[2:]
+ objects.append(name)
+ return objects
+
+
+def get_scene_collection(collection):
+ """"""
+ data = {}
+ name = collection.get(b'name')
+
+ data['name'] = name
+ data['filter'] = collection.get(b'filter')
+
+ data['objects'] = get_scene_collection_objects(collection, b'objects')
+ data['filter_objects'] = get_scene_collection_objects(collection, b'filter_objects')
+
+ collections = {}
+ for nested_collection in linkdata_iter(collection, b'scene_collections'):
+ subname, subdata = get_scene_collection(nested_collection)
+ collections[subname] = subdata
+ data['collections'] = collections
+
+ return name, data
+
+
+def get_scene_collections(scene):
+ """Return all the scene collections ahd their data"""
+ master_collection = scene.get_pointer(b'collection')
+ return get_scene_collection(master_collection)
+
+
+def query_scene(filepath, name, callbacks):
+ """Return the equivalent to bpy.context.scene"""
+ from io_blend_utils.blend import blendfile
+
+ with blendfile.open_blend(filepath) as blend:
+ scenes = [block for block in blend.blocks if block.code == b'SC']
+ for scene in scenes:
+ if scene.get((b'id', b'name'))[2:] != name:
+ continue
+
+ return [callback(scene) for callback in callbacks]
+
+
+# ############################################################
+# Utils
+# ############################################################
+
+def dump(data):
+ import json
+ return json.dumps(
+ data,
+ sort_keys=True,
+ indent=4,
+ separators=(',', ': '),
+ )
+
+
+# ############################################################
+# Tests
+# ############################################################
+
+PDB = False
+DUMP_DIFF = True
+
+
+def compare_files(file_a, file_b):
+ import filecmp
+
+ if not filecmp.cmp(
+ file_a,
+ file_b):
+
+ if DUMP_DIFF:
+ import subprocess
+ subprocess.call(["diff", "-u", file_a, file_b])
+
+ if PDB:
+ import pdb
+ print("Files differ:", file_a, file_b)
+ pdb.set_trace()
+
+ return False
+
+ return True
+
+
+class RenderLayerTesting(unittest.TestCase):
+ _test_simple = False
+ _extra_arguments = []
+
+ @classmethod
+ def setUpClass(cls):
+ """Runs once"""
+ cls.pretest_parsing()
+
+ @classmethod
+ def get_root(cls):
+ """
+ return the folder with the test files
+ """
+ arguments = {}
+ for argument in cls._extra_arguments:
+ name, value = argument.split('=')
+ cls.assertTrue(name and name.startswith("--"), "Invalid argument \"{0}\"".format(argument))
+ cls.assertTrue(value, "Invalid argument \"{0}\"".format(argument))
+ arguments[name[2:]] = value.strip('"')
+
+ return arguments.get('testdir')
+
+ @classmethod
+ def pretest_parsing(cls):
+ """
+ Test if the arguments are properly set, and store ROOT
+ name has extra _ because we need this test to run first
+ """
+ root = cls.get_root()
+ cls.assertTrue(root, "Testdir not set")
+
+ def setUp(self):
+ """Runs once per test"""
+ import bpy
+ bpy.ops.wm.read_factory_settings()
+
+ def path_exists(self, filepath):
+ import os
+ self.assertTrue(
+ os.path.exists(filepath),
+ "Test file \"{0}\" not found".format(filepath))
+
+ def do_object_add(self, filepath_json, add_mode):
+ """
+ Testing for adding objects and see if they
+ go to the right collection
+ """
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ ROOT = self.get_root()
+ with tempfile.TemporaryDirectory() as dirpath:
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+
+ # open file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # create sub-collections
+ three_b = bpy.data.objects.get('T.3b')
+ three_c = bpy.data.objects.get('T.3c')
+
+ scene = bpy.context.scene
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = subzero.collections.new('scorpion')
+ subzero.objects.link(three_b)
+ scorpion.objects.link(three_c)
+ layer = scene.render_layers.new('Fresh new Layer')
+ layer.collections.link(subzero)
+
+ # change active collection
+ layer.collections.active_index = 3
+ self.assertEqual(layer.collections.active.name, 'scorpion', "Run: test_syncing_object_add")
+
+ # change active layer
+ override = bpy.context.copy()
+ override["render_layer"] = layer
+ override["scene_collection"] = layer.collections.active.collection
+
+ # add new objects
+ if add_mode == 'EMPTY':
+ bpy.ops.object.add(override) # 'Empty'
+
+ elif add_mode == 'CYLINDER':
+ bpy.ops.mesh.primitive_cylinder_add(override) # 'Cylinder'
+
+ elif add_mode == 'TORUS':
+ bpy.ops.mesh.primitive_torus_add(override) # 'Torus'
+
+ # save file
+ filepath_objects = os.path.join(dirpath, 'objects.blend')
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_objects)
+
+ # get the generated json
+ datas = query_scene(filepath_objects, 'Main', (get_scene_collections, get_layers))
+ self.assertTrue(datas, "Data is not valid")
+
+ filepath_objects_json = os.path.join(dirpath, "objects.json")
+ with open(filepath_objects_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_objects_json,
+ filepath_json,
+ ),
+ "Scene dump files differ")
+
+ def do_object_add_no_collection(self, add_mode):
+ """
+ Test for adding objects when no collection
+ exists in render layer
+ """
+ import bpy
+
+ # empty layer of collections
+
+ layer = bpy.context.render_layer
+ while layer.collections:
+ layer.collections.unlink(layer.collections[0])
+
+ # add new objects
+ if add_mode == 'EMPTY':
+ bpy.ops.object.add() # 'Empty'
+
+ elif add_mode == 'CYLINDER':
+ bpy.ops.mesh.primitive_cylinder_add() # 'Cylinder'
+
+ elif add_mode == 'TORUS':
+ bpy.ops.mesh.primitive_torus_add() # 'Torus'
+
+ self.assertEqual(len(layer.collections), 1, "New collection not created")
+ collection = layer.collections[0]
+ self.assertEqual(len(collection.objects), 1, "New collection is empty")
+
+ def do_object_link(self, master_collection):
+ import bpy
+ self.assertEqual(master_collection.name, "Master Collection")
+ self.assertEqual(master_collection, bpy.context.scene.master_collection)
+ master_collection.objects.link(bpy.data.objects.new('object', None))
+
+ def do_scene_copy(self, filepath_json_reference, copy_mode, data_callbacks):
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ ROOT = self.get_root()
+ with tempfile.TemporaryDirectory() as dirpath:
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+
+ (self.path_exists(f) for f in (
+ filepath_layers,
+ filepath_json_reference,
+ ))
+
+ filepath_saved = os.path.join(dirpath, '{0}.blend'.format(copy_mode))
+ filepath_json = os.path.join(dirpath, "{0}.json".format(copy_mode))
+
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+ bpy.ops.scene.new(type=copy_mode)
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_saved)
+
+ datas = query_scene(filepath_saved, 'Main.001', data_callbacks)
+ self.assertTrue(datas, "Data is not valid")
+
+ with open(filepath_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_json,
+ filepath_json_reference,
+ ),
+ "Scene copy \"{0}\" test failed".format(copy_mode.title()))
+
+ def do_object_delete(self, del_mode):
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ ROOT = self.get_root()
+ with tempfile.TemporaryDirectory() as dirpath:
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ filepath_reference_json = os.path.join(ROOT, 'layers_object_delete.json')
+
+ # open file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # create sub-collections
+ three_b = bpy.data.objects.get('T.3b')
+ three_d = bpy.data.objects.get('T.3d')
+
+ scene = bpy.context.scene
+
+ # mangle the file a bit with some objects linked across collections
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = subzero.collections.new('scorpion')
+ subzero.objects.link(three_d)
+ scorpion.objects.link(three_b)
+ scorpion.objects.link(three_d)
+
+ # object to delete
+ ob = three_d
+
+ # delete object
+ if del_mode == 'DATA':
+ bpy.data.objects.remove(ob, do_unlink=True)
+
+ elif del_mode == 'OPERATOR':
+ bpy.context.scene.update() # update depsgraph
+ bpy.ops.object.select_all(action='DESELECT')
+ ob.select_set(action='SELECT')
+ self.assertTrue(ob.select_get())
+ bpy.ops.object.delete()
+
+ # save file
+ filepath_generated = os.path.join(dirpath, 'generated.blend')
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_generated)
+
+ # get the generated json
+ datas = query_scene(filepath_generated, 'Main', (get_scene_collections, get_layers))
+ self.assertTrue(datas, "Data is not valid")
+
+ filepath_generated_json = os.path.join(dirpath, "generated.json")
+ with open(filepath_generated_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_generated_json,
+ filepath_reference_json,
+ ),
+ "Scene dump files differ")
+
+ def do_visibility_object_add(self, add_mode):
+ import bpy
+
+ scene = bpy.context.scene
+
+ # delete all objects of the file
+ for ob in bpy.data.objects:
+ bpy.data.objects.remove(ob, do_unlink=True)
+
+ # real test
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection = scene.master_collection.collections.new("Collection")
+ layer.collections.link(scene_collection)
+
+ bpy.context.scene.update() # update depsgraph
+
+ self.assertEqual(len(bpy.data.objects), 0)
+
+ # add new objects
+ if add_mode == 'EMPTY':
+ bpy.ops.object.add() # 'Empty'
+
+ elif add_mode == 'CYLINDER':
+ bpy.ops.mesh.primitive_cylinder_add() # 'Cylinder'
+
+ elif add_mode == 'TORUS':
+ bpy.ops.mesh.primitive_torus_add() # 'Torus'
+
+ self.assertEqual(len(bpy.data.objects), 1)
+
+ new_ob = bpy.data.objects[0]
+ self.assertTrue(new_ob.visible_get(), "Object should be visible")
+
+ def cleanup_tree(self):
+ """
+ Remove any existent layer and collections,
+ leaving only the one render_layer we can't remove
+ """
+ import bpy
+ scene = bpy.context.scene
+ while len(scene.render_layers) > 1:
+ scene.render_layers.remove(scene.render_layers[1])
+
+ layer = scene.render_layers[0]
+ while layer.collections:
+ layer.collections.unlink(layer.collections[0])
+
+ master_collection = scene.master_collection
+ while master_collection.collections:
+ master_collection.collections.remove(master_collection.collections[0])
+
+ def rename_collections(self, collection=None):
+ """
+ Rename 'Collection 1' to '1'
+ """
+ def strip_name(collection):
+ import re
+ if collection.name.startswith("Default Collection"):
+ collection.name = '1'
+ else:
+ collection.name = re.findall(r'\d+', collection.name)[0]
+
+ if collection is None:
+ import bpy
+ collection = bpy.context.scene.master_collection
+
+ for nested_collection in collection.collections:
+ strip_name(nested_collection)
+ self.rename_collections(nested_collection)
+
+
+class MoveSceneCollectionTesting(RenderLayerTesting):
+ """
+ To be used by tests of render_layer_move_into_scene_collection
+ """
+ def get_initial_scene_tree_map(self):
+ collections_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return collections_map
+
+ def build_scene_tree(self, tree_map, collection=None, ret_dict=None):
+ """
+ Returns a flat dictionary with new scene collections
+ created from a nested tuple of nested tuples (name, tuple)
+ """
+ import bpy
+
+ if collection is None:
+ collection = bpy.context.scene.master_collection
+
+ if ret_dict is None:
+ ret_dict = {collection.name: collection}
+ self.assertEqual(collection.name, "Master Collection")
+
+ for name, nested_collections in tree_map:
+ new_collection = collection.collections.new(name)
+ ret_dict[name] = new_collection
+
+ if nested_collections:
+ self.build_scene_tree(nested_collections, new_collection, ret_dict)
+
+ return ret_dict
+
+ def setup_tree(self):
+ """
+ Cleanup file, and populate it with class scene tree map
+ """
+ self.cleanup_tree()
+ self.assertTrue(
+ hasattr(self, "get_initial_scene_tree_map"),
+ "Test class has no get_initial_scene_tree_map method implemented")
+
+ return self.build_scene_tree(self.get_initial_scene_tree_map())
+
+ def get_scene_tree_map(self, collection=None, ret_list=None):
+ """
+ Extract the scene collection tree from scene
+ Return as a nested list of nested lists (name, list)
+ """
+ import bpy
+
+ if collection is None:
+ scene = bpy.context.scene
+ collection = scene.master_collection
+
+ if ret_list is None:
+ ret_list = []
+
+ for nested_collection in collection.collections:
+ new_collection = [nested_collection.name, None]
+ ret_list.append(new_collection)
+
+ if nested_collection.collections:
+ new_collection[1] = list()
+ self.get_scene_tree_map(nested_collection, new_collection[1])
+
+ return ret_list
+
+ def compare_tree_maps(self):
+ """
+ Compare scene with expected (class defined) data
+ """
+ self.assertEqual(self.get_scene_tree_map(), self.get_reference_scene_tree_map())
+
+
+class MoveSceneCollectionSyncTesting(MoveSceneCollectionTesting):
+ """
+ To be used by tests of render_layer_move_into_scene_collection_sync
+ """
+ def get_initial_layers_tree_map(self):
+ layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ '3',
+ ]],
+ ['Layer 2', [
+ 'C',
+ '3',
+ 'dog',
+ 'cat',
+ ]],
+ ]
+ return layers_map
+
+ def get_reference_layers_tree_map(self):
+ """
+ For those classes we don't expect any changes in the layer tree
+ """
+ return self.get_initial_layers_tree_map()
+
+ def setup_tree(self):
+ tree = super(MoveSceneCollectionSyncTesting, self).setup_tree()
+
+ import bpy
+ scene = bpy.context.scene
+
+ self.assertTrue(
+ hasattr(self, "get_initial_layers_tree_map"),
+ "Test class has no get_initial_layers_tree_map method implemented")
+
+ layers_map = self.get_initial_layers_tree_map()
+
+ for layer_name, collections_names in layers_map:
+ layer = scene.render_layers.new(layer_name)
+ layer.collections.unlink(layer.collections[0])
+
+ for collection_name in collections_names:
+ layer.collections.link(tree[collection_name])
+
+ return tree
+
+ def compare_tree_maps(self):
+ """
+ Compare scene with expected (class defined) data
+ """
+ super(MoveSceneCollectionSyncTesting, self).compare_tree_maps()
+
+ import bpy
+ scene = bpy.context.scene
+ layers_map = self.get_reference_layers_tree_map()
+
+ for layer_name, collections_names in layers_map:
+ layer = scene.render_layers.get(layer_name)
+ self.assertTrue(layer)
+ self.assertEqual(len(collections_names), len(layer.collections))
+
+ for i, collection_name in enumerate(collections_names):
+ self.assertEqual(collection_name, layer.collections[i].name)
+ self.verify_collection_tree(layer.collections[i])
+
+ def verify_collection_tree(self, layer_collection):
+ """
+ Check if the LayerCollection mimics the SceneLayer tree
+ """
+ scene_collection = layer_collection.collection
+ self.assertEqual(len(layer_collection.collections), len(scene_collection.collections))
+
+ for i, nested_collection in enumerate(layer_collection.collections):
+ self.assertEqual(nested_collection.collection.name, scene_collection.collections[i].name)
+ self.assertEqual(nested_collection.collection, scene_collection.collections[i])
+ self.verify_collection_tree(nested_collection)
+
+
+class MoveLayerCollectionTesting(MoveSceneCollectionSyncTesting):
+ """
+ To be used by tests of render_layer_move_into_layer_collection
+ """
+ def parse_move(self, path, sep='.'):
+ """
+ convert 'Layer 1.C.2' into:
+ bpy.context.scene.render_layers['Layer 1'].collections['C'].collections['2']
+ """
+ import bpy
+
+ paths = path.split(sep)
+ layer = bpy.context.scene.render_layers[paths[0]]
+ collections = layer.collections
+
+ for subpath in paths[1:]:
+ collection = collections[subpath]
+ collections = collection.collections
+
+ return collection
+
+ def move_into(self, src, dst):
+ layer_collection_src = self.parse_move(src)
+ layer_collection_dst = self.parse_move(dst)
+ return layer_collection_src.move_into(layer_collection_dst)
+
+ def move_above(self, src, dst):
+ layer_collection_src = self.parse_move(src)
+ layer_collection_dst = self.parse_move(dst)
+ return layer_collection_src.move_above(layer_collection_dst)
+
+ def move_below(self, src, dst):
+ layer_collection_src = self.parse_move(src)
+ layer_collection_dst = self.parse_move(dst)
+ return layer_collection_src.move_below(layer_collection_dst)
+
+
+class Clay:
+ def __init__(self, extra_kid_layer=False):
+ import bpy
+
+ self._scene = bpy.context.scene
+ self._layer = self._fresh_layer()
+ self._object = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ # update depsgraph
+ self._scene.update()
+
+ scene_collection_grandma = self._scene.master_collection.collections.new("Grandma")
+ scene_collection_mom = scene_collection_grandma.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+ scene_collection_kid.objects.link(self._object)
+
+ layer_collection_grandma = self._layer.collections.link(scene_collection_grandma)
+ layer_collection_mom = layer_collection_grandma.collections[0]
+ layer_collection_kid = layer_collection_mom.collections[0]
+
+ # store the variables
+ self._scene_collections = {
+ 'grandma': scene_collection_grandma,
+ 'mom': scene_collection_mom,
+ 'kid': scene_collection_kid,
+ }
+ self._layer_collections = {
+ 'grandma': layer_collection_grandma,
+ 'mom': layer_collection_mom,
+ 'kid': layer_collection_kid,
+ }
+
+ if extra_kid_layer:
+ layer_collection_extra = self._layer.collections.link(scene_collection_kid)
+ self._layer_collections['extra'] = layer_collection_extra
+
+ self._update()
+
+ def _fresh_layer(self):
+ import bpy
+
+ # remove all other objects
+ while bpy.data.objects:
+ bpy.data.objects.remove(bpy.data.objects[0])
+
+ # remove all the other collections
+ while self._scene.master_collection.collections:
+ self._scene.master_collection.collections.remove(
+ self._scene.master_collection.collections[0])
+
+ layer = self._scene.render_layers.new('Evaluation Test')
+ layer.collections.unlink(layer.collections[0])
+ self._scene.render_layers.active = layer
+
+ # remove all other layers
+ for layer_iter in self._scene.render_layers:
+ if layer_iter != layer:
+ self._scene.render_layers.remove(layer_iter)
+
+ return layer
+
+ def _update(self):
+ """
+ Force depsgrpah evaluation
+ and update pointers to IDProperty collections
+ """
+ ENGINE = 'BLENDER_CLAY'
+
+ self._scene.update() # update depsgraph
+ self._layer.update() # flush depsgraph evaluation
+
+ # change scene settings
+ self._properties = {
+ 'scene': self._scene.collection_properties[ENGINE],
+ 'object': self._object.collection_properties[ENGINE],
+ }
+
+ for key, value in self._layer_collections.items():
+ self._properties[key] = self._layer_collections[key].engine_overrides[ENGINE]
+
+ def get(self, name, data_path):
+ self._update()
+ return getattr(self._properties[name], data_path)
+
+ def set(self, name, data_path, value):
+ self._update()
+ self._properties[name].use(data_path)
+ setattr(self._properties[name], data_path, value)
diff --git a/tests/python/render_layer/test_active_collection.py b/tests/python/render_layer/test_active_collection.py
new file mode 100644
index 00000000000..6e1438ab594
--- /dev/null
+++ b/tests/python/render_layer/test_active_collection.py
@@ -0,0 +1,75 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_active_collection(self):
+ """
+ See if active collection index is working
+ layer.collections.active_index works recursively
+ """
+ import bpy
+ import os
+
+ ROOT = self.get_root()
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+
+ # open file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # create sub-collections
+ three_b = bpy.data.objects.get('T.3b')
+ three_c = bpy.data.objects.get('T.3c')
+
+ scene = bpy.context.scene
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = subzero.collections.new('scorpion')
+ subzero.objects.link(three_b)
+ scorpion.objects.link(three_c)
+ layer = scene.render_layers.new('Fresh new Layer')
+ layer.collections.link(subzero)
+
+ lookup = [
+ 'Master Collection',
+ '1',
+ 'sub-zero',
+ 'scorpion',
+ '2',
+ '3',
+ '4',
+ '5',
+ 'sub-zero',
+ 'scorpion']
+
+ for i, name in enumerate(lookup):
+ layer.collections.active_index = i
+ self.assertEqual(
+ name, layer.collections.active.name,
+ "Collection index mismatch: [{0}] : {1} != {2}".format(
+ i, name, layer.collections.active.name))
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_collection_rename.py b/tests/python/render_layer/test_collection_rename.py
new file mode 100644
index 00000000000..596eea7135d
--- /dev/null
+++ b/tests/python/render_layer/test_collection_rename.py
@@ -0,0 +1,81 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def setup_family(self):
+ import bpy
+ scene = bpy.context.scene
+
+ # Just add a bunch of collections on which we can do various tests.
+ grandma = scene.master_collection.collections.new('grandma')
+ grandpa = scene.master_collection.collections.new('grandpa')
+ mom = grandma.collections.new('mom')
+ son = mom.collections.new('son')
+ daughter = mom.collections.new('daughter')
+ uncle = grandma.collections.new('uncle')
+ cousin = uncle.collections.new('cousin')
+
+ lookup = {c.name: c for c in (grandma, grandpa, mom, son, daughter, uncle, cousin)}
+ return lookup
+
+ def test_rename_a(self):
+ family = self.setup_family()
+
+ family['mom'].name = family['daughter'].name
+ self.assertNotEqual(family['mom'].name, family['daughter'].name)
+
+ def test_rename_b(self):
+ family = self.setup_family()
+
+ family['grandma'].name = family['grandpa'].name
+ self.assertNotEqual(family['grandma'].name, family['grandpa'].name)
+
+ def test_rename_c(self):
+ family = self.setup_family()
+
+ family['cousin'].name = family['daughter'].name
+ self.assertNotEqual(family['cousin'].name, family['daughter'].name)
+
+ def test_rename_d(self):
+ family = self.setup_family()
+
+ family['son'].name = family['daughter'].name
+ self.assertNotEqual(family['son'].name, family['daughter'].name)
+
+ def test_add_equal_name_a(self):
+ family = self.setup_family()
+
+ other_daughter = family['mom'].collections.new(family['daughter'].name)
+ self.assertNotEqual(other_daughter.name, family['daughter'].name)
+
+ def test_add_equal_name_b(self):
+ family = self.setup_family()
+
+ other_aunt = family['grandma'].collections.new(family['daughter'].name)
+ self.assertNotEqual(other_aunt.name, family['daughter'].name)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_a.py b/tests/python/render_layer/test_evaluation_render_settings_a.py
new file mode 100644
index 00000000000..62565adaff1
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_a.py
@@ -0,0 +1,38 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay()
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+ clay.set('scene', 'matcap_icon', '05')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '05')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_b.py b/tests/python/render_layer/test_evaluation_render_settings_b.py
new file mode 100644
index 00000000000..64475dabfc3
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_b.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay()
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+ clay.set('scene', 'matcap_icon', '05')
+ clay.set('grandma', 'matcap_icon', '03')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '03')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_c.py b/tests/python/render_layer/test_evaluation_render_settings_c.py
new file mode 100644
index 00000000000..325a4efdfc0
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_c.py
@@ -0,0 +1,38 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay()
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+ clay.set('mom', 'matcap_icon', '02')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '02')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_d.py b/tests/python/render_layer/test_evaluation_render_settings_d.py
new file mode 100644
index 00000000000..faa3d437aca
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_d.py
@@ -0,0 +1,38 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay()
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+ clay.set('kid', 'matcap_icon', '05')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '05')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_e.py b/tests/python/render_layer/test_evaluation_render_settings_e.py
new file mode 100644
index 00000000000..4e3fe221923
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_e.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay()
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+ clay.set('grandma', 'matcap_icon', '04')
+ clay.set('kid', 'matcap_icon', '05')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '05')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_f.py b/tests/python/render_layer/test_evaluation_render_settings_f.py
new file mode 100644
index 00000000000..1c69c1588af
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_f.py
@@ -0,0 +1,40 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay(extra_kid_layer=True)
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+
+ clay.set('scene', 'matcap_icon', '05')
+ clay.set('extra', 'matcap_icon', '07')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '07')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_g.py b/tests/python/render_layer/test_evaluation_render_settings_g.py
new file mode 100644
index 00000000000..99c4c0e34e0
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_g.py
@@ -0,0 +1,40 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay(extra_kid_layer=True)
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+
+ clay.set('mom', 'matcap_icon', '02')
+ clay.set('extra', 'matcap_icon', '06')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '06')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_h.py b/tests/python/render_layer/test_evaluation_render_settings_h.py
new file mode 100644
index 00000000000..a21e14a4624
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_h.py
@@ -0,0 +1,40 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay(extra_kid_layer=True)
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+
+ clay.set('kid', 'matcap_icon', '02')
+ clay.set('extra', 'matcap_icon', '04')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '04')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_render_settings_i.py b/tests/python/render_layer/test_evaluation_render_settings_i.py
new file mode 100644
index 00000000000..256ae76aa92
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_render_settings_i.py
@@ -0,0 +1,40 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_render_settings(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ clay = Clay(extra_kid_layer=True)
+ self.assertEqual(clay.get('object', 'matcap_icon'), '01')
+
+ clay.set('mom', 'matcap_icon', '02')
+ self.assertEqual(clay.get('extra', 'matcap_icon'), '01')
+ self.assertEqual(clay.get('object', 'matcap_icon'), '02')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_selectability_a.py b/tests/python/render_layer/test_evaluation_selectability_a.py
new file mode 100644
index 00000000000..c27e1509a2f
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_selectability_a.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_selectability(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Selectability Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = True
+ bpy.context.scene.update() # update depsgraph
+ cube.select_set('SELECT')
+
+ self.assertTrue(cube.visible_get(), "Cube should be visible")
+ self.assertTrue(cube.select_get(), "Cube should be selected")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_selectability_b.py b/tests/python/render_layer/test_evaluation_selectability_b.py
new file mode 100644
index 00000000000..eb78717ef41
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_selectability_b.py
@@ -0,0 +1,59 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_selectability(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Selectability Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+ bpy.context.scene.update() # update depsgraph
+ cube.select_set('SELECT')
+
+ layer_collection_mom.collections[layer_collection_kid.name].hide = True
+ layer_collection_kid.hide = True
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertFalse(cube.visible_get(), "Cube should be invisible")
+ self.assertFalse(cube.select_get(), "Cube should be unselected")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_selectability_c.py b/tests/python/render_layer/test_evaluation_selectability_c.py
new file mode 100644
index 00000000000..9860b9ab048
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_selectability_c.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_selectability(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Selectability Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ bpy.context.scene.update() # update depsgraph
+ cube.select_set('SELECT')
+
+ self.assertTrue(cube.visible_get(), "Cube should be visible")
+ self.assertTrue(cube.select_get(), "Cube should be selected")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_selectability_d.py b/tests/python/render_layer/test_evaluation_selectability_d.py
new file mode 100644
index 00000000000..0cb9a4278bb
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_selectability_d.py
@@ -0,0 +1,60 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_selectability(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Selectability Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ bpy.context.scene.update() # update depsgraph
+
+ cube.select_set('SELECT')
+ layer_collection_mom.collections[layer_collection_kid.name].hide_select = True
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Cube should be visible")
+ self.assertTrue(cube.select_get(), "Cube should be selected")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_selectability_e.py b/tests/python/render_layer/test_evaluation_selectability_e.py
new file mode 100644
index 00000000000..cffc540aa46
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_selectability_e.py
@@ -0,0 +1,59 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_selectability(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Selectability Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ cube.select_set('SELECT')
+ layer_collection_mom.collections[layer_collection_kid.name].hide_select = True
+ layer_collection_kid.hide = True
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Cube should be visible")
+ self.assertFalse(cube.select_get(), "Cube should be unselected")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_selectability_f.py b/tests/python/render_layer/test_evaluation_selectability_f.py
new file mode 100644
index 00000000000..c8d00164ab7
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_selectability_f.py
@@ -0,0 +1,48 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_selectability(self):
+ import bpy
+ scene = bpy.context.scene
+
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+ scene_collection = scene.master_collection.collections.new('collection')
+ layer_collection = scene.render_layers.active.collections.link(scene_collection)
+
+ bpy.context.scene.update() # update depsgraph
+
+ scene_collection.objects.link(cube)
+
+ self.assertFalse(layer_collection.hide)
+ self.assertFalse(layer_collection.hide_select)
+
+ bpy.context.scene.update() # update depsgraph
+ cube.select_set(action='SELECT')
+ self.assertTrue(cube.select_get())
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_a.py b/tests/python/render_layer/test_evaluation_visibility_a.py
new file mode 100644
index 00000000000..8a711c5f558
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_a.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene.master_collection.collections.new("Kid")
+
+ scene_collection_mom.objects.link(cube)
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = True
+ layer_collection_kid.hide = False
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Object should be visible")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_b.py b/tests/python/render_layer/test_evaluation_visibility_b.py
new file mode 100644
index 00000000000..c291277d140
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_b.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ layer_collection_mom.collections[layer_collection_kid.name].hide = True
+ layer_collection_kid.hide = True
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertFalse(cube.visible_get(), "Object should be invisible")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_c.py b/tests/python/render_layer/test_evaluation_visibility_c.py
new file mode 100644
index 00000000000..e0388ce0ab0
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_c.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ layer_collection_mom.collections[layer_collection_kid.name].hide = True
+ layer_collection_kid.hide = False
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Object should be visible")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_d.py b/tests/python/render_layer/test_evaluation_visibility_d.py
new file mode 100644
index 00000000000..97777dd8a79
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_d.py
@@ -0,0 +1,54 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Object should be visible")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_e.py b/tests/python/render_layer/test_evaluation_visibility_e.py
new file mode 100644
index 00000000000..ff86dd94857
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_e.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_mom.objects.link(cube)
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ layer_collection_kid.hide = True
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Object should be visible")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_f.py b/tests/python/render_layer/test_evaluation_visibility_f.py
new file mode 100644
index 00000000000..add74634215
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_f.py
@@ -0,0 +1,58 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ cube = bpy.data.objects.new('guinea pig', bpy.data.meshes.new('mesh'))
+
+ layer = scene.render_layers.new('Visibility Test')
+ layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
+
+ scene_collection_mom = scene.master_collection.collections.new("Mom")
+ scene_collection_kid = scene_collection_mom.collections.new("Kid")
+
+ scene_collection_mom.objects.link(cube)
+ scene_collection_kid.objects.link(cube)
+
+ layer_collection_mom = layer.collections.link(scene_collection_mom)
+ layer_collection_kid = layer.collections.link(scene_collection_kid)
+
+ layer_collection_mom.hide = False
+ layer_collection_mom.collections[layer_collection_kid.name].hide = True
+ layer_collection_kid.hide = True
+
+ bpy.context.scene.update() # update depsgraph
+ self.assertTrue(cube.visible_get(), "Object should be visible")
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_g.py b/tests/python/render_layer/test_evaluation_visibility_g.py
new file mode 100644
index 00000000000..c9faf65538e
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_g.py
@@ -0,0 +1,35 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility_empty(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ self.do_visibility_object_add('EMPTY')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_h.py b/tests/python/render_layer/test_evaluation_visibility_h.py
new file mode 100644
index 00000000000..7785cc0c1a7
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_h.py
@@ -0,0 +1,35 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility_cylinder(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ self.do_visibility_object_add('CYLINDER')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_evaluation_visibility_i.py b/tests/python/render_layer/test_evaluation_visibility_i.py
new file mode 100644
index 00000000000..da72c1f33ba
--- /dev/null
+++ b/tests/python/render_layer/test_evaluation_visibility_i.py
@@ -0,0 +1,35 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_visibility_torus(self):
+ """
+ See if the depsgraph evaluation is correct
+ """
+ self.do_visibility_object_add('TORUS')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_layer_linking.py b/tests/python/render_layer/test_layer_linking.py
new file mode 100644
index 00000000000..5b564922c45
--- /dev/null
+++ b/tests/python/render_layer/test_layer_linking.py
@@ -0,0 +1,114 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def do_layer_linking(self, filepath_json, link_mode):
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ ROOT = self.get_root()
+ with tempfile.TemporaryDirectory() as dirpath:
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+
+ # open file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # create sub-collections
+ three_b = bpy.data.objects.get('T.3b')
+ three_c = bpy.data.objects.get('T.3c')
+
+ scene = bpy.context.scene
+
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = subzero.collections.new('scorpion')
+
+ # test linking sync
+ subzero.objects.link(three_b)
+ scorpion.objects.link(three_c)
+
+ # test unlinking sync
+ layer = scene.render_layers.new('Fresh new Layer')
+
+ if link_mode in {'COLLECTION_LINK', 'COLLECTION_UNLINK'}:
+ layer.collections.link(subzero)
+
+ if link_mode == 'COLLECTION_UNLINK':
+ initial_collection = layer.collections['Master Collection']
+ layer.collections.unlink(initial_collection)
+
+ # save file
+ filepath_nested = os.path.join(dirpath, 'nested.blend')
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_nested)
+
+ # get the generated json
+ datas = query_scene(filepath_nested, 'Main', (get_scene_collections, get_layers))
+ self.assertTrue(datas, "Data is not valid")
+
+ filepath_nested_json = os.path.join(dirpath, "nested.json")
+ with open(filepath_nested_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_nested_json,
+ filepath_json,
+ ),
+ "Scene dump files differ")
+
+ def test_syncing_layer_new(self):
+ """
+ See if the creation of new layers is going well
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_new_layer.json')
+ self.do_layer_linking(filepath_json, 'LAYER_NEW')
+
+ def test_syncing_layer_collection_link(self):
+ """
+ See if the creation of new layers is going well
+ And linking a new scene collection in the layer works
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_layer_collection_link.json')
+ self.do_layer_linking(filepath_json, 'COLLECTION_LINK')
+
+ def test_syncing_layer_collection_unlink(self):
+ """
+ See if the creation of new layers is going well
+ And unlinking the origin scene collection works
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_layer_collection_unlink.json')
+ self.do_layer_linking(filepath_json, 'COLLECTION_UNLINK')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_layer_syncing.py b/tests/python/render_layer/test_layer_syncing.py
new file mode 100644
index 00000000000..e8c6f92ab09
--- /dev/null
+++ b/tests/python/render_layer/test_layer_syncing.py
@@ -0,0 +1,118 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def do_syncing(self, filepath_json, unlink_mode):
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ ROOT = self.get_root()
+ with tempfile.TemporaryDirectory() as dirpath:
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+
+ # open file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # create sub-collections
+ three_b = bpy.data.objects.get('T.3b')
+ three_c = bpy.data.objects.get('T.3c')
+ three_d = bpy.data.objects.get('T.3d')
+
+ scene = bpy.context.scene
+
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = scene.master_collection.collections['1'].collections.new('scorpion')
+
+ # test linking sync
+ subzero.objects.link(three_b)
+ scorpion.objects.link(three_c)
+
+ # test unlinking sync
+ if unlink_mode in {'OBJECT', 'COLLECTION'}:
+ scorpion.objects.link(three_d)
+ scorpion.objects.unlink(three_d)
+
+ if unlink_mode == 'COLLECTION':
+ scorpion.objects.link(three_d)
+ scene.master_collection.collections['1'].collections.remove(subzero)
+ scene.master_collection.collections['1'].collections.remove(scorpion)
+
+ # save file
+ filepath_nested = os.path.join(dirpath, 'nested.blend')
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_nested)
+
+ # get the generated json
+ datas = query_scene(filepath_nested, 'Main', (get_scene_collections, get_layers))
+ self.assertTrue(datas, "Data is not valid")
+
+ filepath_nested_json = os.path.join(dirpath, "nested.json")
+ with open(filepath_nested_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_nested_json,
+ filepath_json,
+ ),
+ "Scene dump files differ")
+
+ def test_syncing_link(self):
+ """
+ See if scene collections and layer collections are in sync
+ when we create new subcollections and link new objects
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_nested.json')
+ self.do_syncing(filepath_json, 'NONE')
+
+ def test_syncing_unlink_object(self):
+ """
+ See if scene collections and layer collections are in sync
+ when we create new subcollections, link new objects and unlink
+ some.
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_nested.json')
+ self.do_syncing(filepath_json, 'OBJECT')
+
+ def test_syncing_unlink_collection(self):
+ """
+ See if scene collections and layer collections are in sync
+ when we create new subcollections, link new objects and unlink full collections
+ some.
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers.json')
+ self.do_syncing(filepath_json, 'COLLECTION')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_a.py b/tests/python/render_layer/test_move_above_below_layer_collection_a.py
new file mode 100644
index 00000000000..16da5a651b7
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_a.py
@@ -0,0 +1,53 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_below('Layer 1.3', 'Layer 1.C'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_above('Layer 1.C', 'Layer 1.3'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_b.py b/tests/python/render_layer/test_move_above_below_layer_collection_b.py
new file mode 100644
index 00000000000..59141ab1aed
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_b.py
@@ -0,0 +1,53 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_below('Layer 1.3.cat', 'Layer 1.3.dog'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_above('Layer 1.3.dog', 'Layer 1.3.cat'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_c.py b/tests/python/render_layer/test_move_above_below_layer_collection_c.py
new file mode 100644
index 00000000000..59141ab1aed
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_c.py
@@ -0,0 +1,53 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_below('Layer 1.3.cat', 'Layer 1.3.dog'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_above('Layer 1.3.dog', 'Layer 1.3.cat'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_d.py b/tests/python/render_layer/test_move_above_below_layer_collection_d.py
new file mode 100644
index 00000000000..e0e6185fe65
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_d.py
@@ -0,0 +1,53 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_above('Layer 2.3.dog', 'Layer 1.C.2'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_below('Layer 1.C.2', 'Layer 2.3.dog'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_e.py b/tests/python/render_layer/test_move_above_below_layer_collection_e.py
new file mode 100644
index 00000000000..a3b9f29def0
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_e.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_below('Layer 1.Master Collection', 'Layer 1.C.1'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_f.py b/tests/python/render_layer/test_move_above_below_layer_collection_f.py
new file mode 100644
index 00000000000..9a0bb4873e8
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_f.py
@@ -0,0 +1,105 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def get_reference_layers_tree_map(self):
+ reference_layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ '3',
+ ]],
+ ['Layer 2', [
+ 'C',
+ 'dog',
+ 'cat',
+ ]],
+ ]
+ return reference_layers_map
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_below('Layer 2.3', 'Layer 2.C.1'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_above('Layer 2.3', 'Layer 2.C.2'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 2.3')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ # collection that will disappear
+ collection_old = self.parse_move('Layer 2.C.3')
+ collection_old.hide = True
+ collection_old.hide_select = False
+
+ # move
+ self.assertTrue(self.move_below('Layer 2.3', 'Layer 2.C.1'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 2.C.3')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_g.py b/tests/python/render_layer/test_move_above_below_layer_collection_g.py
new file mode 100644
index 00000000000..4d9b0224d5b
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_g.py
@@ -0,0 +1,86 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['cat', None],
+ ['dog', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_above('Layer 2.C.3.cat', 'Layer 2.3.dog'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 2.C.3.cat')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ # collection that will disappear
+ collection_old = self.parse_move('Layer 2.3.cat')
+ collection_old.hide = True
+ collection_old.hide_select = False
+
+ # move
+ self.assertTrue(self.move_above('Layer 2.C.3.cat', 'Layer 2.3.dog'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 2.3.cat')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_h.py b/tests/python/render_layer/test_move_above_below_layer_collection_h.py
new file mode 100644
index 00000000000..e582011fb93
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_h.py
@@ -0,0 +1,71 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_below('Layer 2.C.3.cat', 'Layer 2.3.dog'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 2.C.3.cat')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ # collection that will disappear
+ collection_old = self.parse_move('Layer 2.3.cat')
+ collection_old.hide = True
+ collection_old.hide_select = False
+
+ # move
+ self.assertTrue(self.move_below('Layer 2.C.3.cat', 'Layer 2.3.dog'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 2.3.cat')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_i.py b/tests/python/render_layer/test_move_above_below_layer_collection_i.py
new file mode 100644
index 00000000000..90814d8d621
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_i.py
@@ -0,0 +1,78 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ reference_layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ '3',
+ ]],
+ ['Layer 2', [
+ '3',
+ 'C',
+ 'dog',
+ 'cat',
+ ]],
+ ]
+ return reference_layers_map
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_below('Layer 2.C', 'Layer 2.3'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 2.C')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ # move
+ self.assertTrue(self.move_below('Layer 2.C', 'Layer 2.3'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 2.C')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_j.py b/tests/python/render_layer/test_move_above_below_layer_collection_j.py
new file mode 100644
index 00000000000..d90b017a2d7
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_j.py
@@ -0,0 +1,68 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_below('Layer 1.3.dog', 'Layer 1.3.cat'))
+ self.assertTrue(self.move_above('Layer 1.3.dog', 'Layer 1.3.cat'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 1.3.dog')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ # move
+ self.assertTrue(self.move_below('Layer 1.3.dog', 'Layer 1.3.cat'))
+ self.assertTrue(self.move_above('Layer 1.3.dog', 'Layer 1.3.cat'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 1.3.dog')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_k.py b/tests/python/render_layer/test_move_above_below_layer_collection_k.py
new file mode 100644
index 00000000000..ee74e2989e8
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_k.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_move(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_below('Layer 2.C.2', 'Layer 2.3'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_layer_collection_l.py b/tests/python/render_layer/test_move_above_below_layer_collection_l.py
new file mode 100644
index 00000000000..036886a4c47
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_layer_collection_l.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ reference_layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ '3',
+ ]],
+ ['Layer 2', [
+ 'C',
+ 'cat',
+ '3',
+ 'dog',
+ ]],
+ ]
+ return reference_layers_map
+
+ def test_layer_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_below('Layer 2.cat', 'Layer 2.C'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_above('Layer 2.cat', 'Layer 2.3'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_a.py b/tests/python/render_layer/test_move_above_below_scene_collection_a.py
new file mode 100644
index 00000000000..8c1d31afb94
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_a.py
@@ -0,0 +1,85 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_above(tree['dog']))
+ self.assertTrue(tree['dog'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['dog'].move_below(tree['cat']))
+ self.assertTrue(tree['cat'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['dog'].move_below(tree['cat']))
+ self.assertTrue(tree['dog'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_d(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_above(tree['dog']))
+ self.assertTrue(tree['cat'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_b.py b/tests/python/render_layer/test_move_above_below_scene_collection_b.py
new file mode 100644
index 00000000000..360f36328e2
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_b.py
@@ -0,0 +1,74 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_above(tree['1']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['1'].move_below(tree['3']))
+ self.assertTrue(tree['2'].move_below(tree['1']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_above(tree['2']))
+ self.assertTrue(tree['1'].move_above(tree['2']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_c.py b/tests/python/render_layer/test_move_above_below_scene_collection_c.py
new file mode 100644
index 00000000000..e80151120bc
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_c.py
@@ -0,0 +1,56 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_below(tree['ii']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_d.py b/tests/python/render_layer/test_move_above_below_scene_collection_d.py
new file mode 100644
index 00000000000..4e928ca3d7f
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_d.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['B', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_e.py b/tests/python/render_layer/test_move_above_below_scene_collection_e.py
new file mode 100644
index 00000000000..5251119feab
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_e.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['iii', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['iii'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['iii'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_f.py b/tests/python/render_layer/test_move_above_below_scene_collection_f.py
new file mode 100644
index 00000000000..6e0a04360c8
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_f.py
@@ -0,0 +1,56 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['A'].move_above(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_g.py b/tests/python/render_layer/test_move_above_below_scene_collection_g.py
new file mode 100644
index 00000000000..5a094914eb6
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_g.py
@@ -0,0 +1,49 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['dog'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['cat'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_h.py b/tests/python/render_layer/test_move_above_below_scene_collection_h.py
new file mode 100644
index 00000000000..7769df8c270
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_h.py
@@ -0,0 +1,89 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(master_collection.move_above(collection))
+
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(master_collection.move_below(collection))
+
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(collection.move_above(master_collection))
+
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_d(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(collection.move_below(master_collection))
+
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_i.py b/tests/python/render_layer/test_move_above_below_scene_collection_i.py
new file mode 100644
index 00000000000..fbffd8c0a5f
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_i.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_above(tree['2']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_below(tree['2']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_d(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_below(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_a.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_a.py
new file mode 100644
index 00000000000..56813179ee2
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_a.py
@@ -0,0 +1,85 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_above(tree['dog']))
+ self.assertTrue(tree['dog'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['dog'].move_below(tree['cat']))
+ self.assertTrue(tree['cat'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['dog'].move_below(tree['cat']))
+ self.assertTrue(tree['dog'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_d(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_above(tree['dog']))
+ self.assertTrue(tree['cat'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_b.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_b.py
new file mode 100644
index 00000000000..5418c75e04a
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_b.py
@@ -0,0 +1,74 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_above(tree['1']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['1'].move_below(tree['3']))
+ self.assertTrue(tree['2'].move_below(tree['1']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_above(tree['2']))
+ self.assertTrue(tree['1'].move_above(tree['2']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_c.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_c.py
new file mode 100644
index 00000000000..145fd0e168e
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_c.py
@@ -0,0 +1,56 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_below(tree['ii']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_d.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_d.py
new file mode 100644
index 00000000000..6e013ad32ca
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_d.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['B', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_e.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_e.py
new file mode 100644
index 00000000000..33e90ad9439
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_e.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['iii', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['iii'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['iii'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_f.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_f.py
new file mode 100644
index 00000000000..fd7a2bd1daf
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_f.py
@@ -0,0 +1,56 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_move(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['A'].move_above(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_g.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_g.py
new file mode 100644
index 00000000000..f15d3a5dfe3
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_g.py
@@ -0,0 +1,49 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['dog'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['cat'].move_below(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_h.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_h.py
new file mode 100644
index 00000000000..6caff710085
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_h.py
@@ -0,0 +1,89 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(master_collection.move_above(collection))
+
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(master_collection.move_below(collection))
+
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(collection.move_above(master_collection))
+
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_d(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(collection.move_below(master_collection))
+
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_above_below_scene_collection_sync_i.py b/tests/python/render_layer/test_move_above_below_scene_collection_sync_i.py
new file mode 100644
index 00000000000..02f304f9068
--- /dev/null
+++ b/tests/python/render_layer/test_move_above_below_scene_collection_sync_i.py
@@ -0,0 +1,65 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_move_a(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_above(tree['2']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_b(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_below(tree['2']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_c(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_above(tree['cat']))
+ self.compare_tree_maps()
+
+ def test_scene_collection_move_d(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_below(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_a.py b/tests/python/render_layer/test_move_into_layer_collection_a.py
new file mode 100644
index 00000000000..b365a81c197
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_a.py
@@ -0,0 +1,74 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ reference_layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ '3',
+ ]],
+ ['Layer 2', [
+ 'C',
+ '3',
+ 'dog',
+ 'cat',
+ ]],
+ ]
+ return reference_layers_map
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into("Layer 1.C.2", "Layer 2.3"))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_b.py b/tests/python/render_layer/test_move_into_layer_collection_b.py
new file mode 100644
index 00000000000..eeaaac7fb8b
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_b.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into('Layer 1.3', 'Layer 1.3.cat'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_c.py b/tests/python/render_layer/test_move_into_layer_collection_c.py
new file mode 100644
index 00000000000..52dc66d5a49
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_c.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into("Layer 2.C", "Layer 2.3"))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_d.py b/tests/python/render_layer/test_move_into_layer_collection_d.py
new file mode 100644
index 00000000000..96ce8703212
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_d.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into("Layer 2.3.cat", "Layer 2.3"))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_e.py b/tests/python/render_layer/test_move_into_layer_collection_e.py
new file mode 100644
index 00000000000..b46cd8cd202
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_e.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into("Layer 1.Master Collection", "Layer 1.C"))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_f.py b/tests/python/render_layer/test_move_into_layer_collection_f.py
new file mode 100644
index 00000000000..8c0f9bcebbc
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_f.py
@@ -0,0 +1,91 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def get_reference_layers_tree_map(self):
+ reference_layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ ]],
+ ['Layer 2', [
+ 'C',
+ '3',
+ 'dog',
+ 'cat',
+ ]],
+ ]
+ return reference_layers_map
+
+ def test_layer_collection_into_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_into("Layer 1.3", "Layer 1.Master Collection.A"))
+ self.compare_tree_maps()
+
+ def test_layer_collection_into_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 1.3')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ self.assertTrue(self.move_into('Layer 1.3', 'Layer 1.Master Collection.A'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 1.Master Collection.A.3')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_g.py b/tests/python/render_layer/test_move_into_layer_collection_g.py
new file mode 100644
index 00000000000..fa3264cbfc4
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_g.py
@@ -0,0 +1,82 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ reference_layers_map = [
+ ['Layer 1', [
+ 'Master Collection',
+ 'C',
+ '3',
+ ]],
+ ['Layer 2', [
+ 'C',
+ 'dog',
+ 'cat',
+ ]],
+ ]
+ return reference_layers_map
+
+ def test_layer_collection_into_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_into('Layer 2.3', 'Layer 2.C'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_into_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 2.3')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ # collection that will disappear
+ collection_old = self.parse_move('Layer 2.C.3')
+ collection_old.hide = True
+ collection_old.hide_select = False
+
+ # move collection
+ self.assertTrue(self.move_into('Layer 2.3', 'Layer 2.C'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 2.C.3')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_h.py b/tests/python/render_layer/test_move_into_layer_collection_h.py
new file mode 100644
index 00000000000..064e529cc2b
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_h.py
@@ -0,0 +1,81 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', [
+ ['dog', None],
+ ]],
+ ['2', None],
+ ['3', [
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into_a(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertTrue(self.move_into('Layer 1.3.dog', 'Layer 1.C.1'))
+ self.compare_tree_maps()
+
+ def test_layer_collection_into_b(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+
+ # collection that will be moved
+ collection_original = self.parse_move('Layer 1.3.dog')
+ collection_original.hide = False
+ collection_original.hide_select = True
+
+ self.assertTrue(self.move_into('Layer 1.3.dog', 'Layer 1.C.1'))
+ self.compare_tree_maps()
+
+ # we expect the settings to be carried along from the
+ # original layer collection
+ collection_new = self.parse_move('Layer 1.C.1.dog')
+ self.assertEqual(collection_new.hide, False)
+ self.assertEqual(collection_new.hide_select, True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_i.py b/tests/python/render_layer/test_move_into_layer_collection_i.py
new file mode 100644
index 00000000000..a42d13bb2eb
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_i.py
@@ -0,0 +1,45 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into('Layer 2.C.3', 'Layer 2.dog'))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_layer_collection_j.py b/tests/python/render_layer/test_move_into_layer_collection_j.py
new file mode 100644
index 00000000000..700d6a7fe3c
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_layer_collection_j.py
@@ -0,0 +1,46 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveLayerCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def get_reference_layers_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_layers_tree_map()
+
+ def test_layer_collection_into(self):
+ """
+ Test outliner operations
+ Prevent collection from being dragged into itself
+ """
+ self.setup_tree()
+ self.assertFalse(self.move_into("Layer 2.dog", "Layer 2.3.dog"))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_a.py b/tests/python/render_layer/test_move_into_scene_collection_a.py
new file mode 100644
index 00000000000..4467b2ebe81
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_a.py
@@ -0,0 +1,58 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_into(tree['2']))
+ self.assertTrue(tree['cat'].move_into(tree['3']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_b.py b/tests/python/render_layer/test_move_into_scene_collection_b.py
new file mode 100644
index 00000000000..258963121b0
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_b.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', [
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_into(tree['B']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_c.py b/tests/python/render_layer/test_move_into_scene_collection_c.py
new file mode 100644
index 00000000000..56b26c58956
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_c.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', [
+ ['cat', None],
+ ]],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_into(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_d.py b/tests/python/render_layer/test_move_into_scene_collection_d.py
new file mode 100644
index 00000000000..4086d892c60
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_d.py
@@ -0,0 +1,42 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ # can't move into a collection if already the last item of the collection
+ self.assertFalse(tree['cat'].move_into(tree['3']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_e.py b/tests/python/render_layer/test_move_into_scene_collection_e.py
new file mode 100644
index 00000000000..331a3cf8297
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_e.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', [
+ ['B', None],
+ ]],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_into(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_f.py b/tests/python/render_layer/test_move_into_scene_collection_f.py
new file mode 100644
index 00000000000..8ef22d82e5e
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_f.py
@@ -0,0 +1,56 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ['B', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_into(tree['3']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_g.py b/tests/python/render_layer/test_move_into_scene_collection_g.py
new file mode 100644
index 00000000000..a6c3b07d3bd
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_g.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ]],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['A'].move_into(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_h.py b/tests/python/render_layer/test_move_into_scene_collection_h.py
new file mode 100644
index 00000000000..a50ebf73881
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_h.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', [
+ ['ii', None],
+ ]],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['ii'].move_into(tree['2']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_i.py b/tests/python/render_layer/test_move_into_scene_collection_i.py
new file mode 100644
index 00000000000..8a36d252132
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_i.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', [
+ ['ii', None],
+ ]],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['ii'].move_into(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_j.py b/tests/python/render_layer/test_move_into_scene_collection_j.py
new file mode 100644
index 00000000000..7f0037f90e4
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_j.py
@@ -0,0 +1,48 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(master_collection.move_into(collection))
+
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_k.py b/tests/python/render_layer/test_move_into_scene_collection_k.py
new file mode 100644
index 00000000000..819e898c22a
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_k.py
@@ -0,0 +1,41 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_into(tree['2']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_l.py b/tests/python/render_layer/test_move_into_scene_collection_l.py
new file mode 100644
index 00000000000..71b5760ac4e
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_l.py
@@ -0,0 +1,41 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_into(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_a.py b/tests/python/render_layer/test_move_into_scene_collection_sync_a.py
new file mode 100644
index 00000000000..c601e21424f
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_a.py
@@ -0,0 +1,42 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_into(tree['2']))
+ self.assertTrue(tree['cat'].move_into(tree['3']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_b.py b/tests/python/render_layer/test_move_into_scene_collection_sync_b.py
new file mode 100644
index 00000000000..5a22eefbfb1
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_b.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', [
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['3'].move_into(tree['B']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_c.py b/tests/python/render_layer/test_move_into_scene_collection_sync_c.py
new file mode 100644
index 00000000000..cd8ffd687b6
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_c.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', [
+ ['cat', None],
+ ]],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['cat'].move_into(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_d.py b/tests/python/render_layer/test_move_into_scene_collection_sync_d.py
new file mode 100644
index 00000000000..848655cfe71
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_d.py
@@ -0,0 +1,42 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ # can't move into a collection if already the last item of the collection
+ self.assertFalse(tree['cat'].move_into(tree['3']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_e.py b/tests/python/render_layer/test_move_into_scene_collection_sync_e.py
new file mode 100644
index 00000000000..9efc9c2d1a5
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_e.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', [
+ ['B', None],
+ ]],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_into(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_f.py b/tests/python/render_layer/test_move_into_scene_collection_sync_f.py
new file mode 100644
index 00000000000..043b48131ac
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_f.py
@@ -0,0 +1,56 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ['B', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['B'].move_into(tree['3']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_g.py b/tests/python/render_layer/test_move_into_scene_collection_sync_g.py
new file mode 100644
index 00000000000..4749605e4ed
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_g.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', [
+ ['A', [
+ ['i', None],
+ ['ii', None],
+ ['iii', None],
+ ]],
+ ]],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['A'].move_into(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_h.py b/tests/python/render_layer/test_move_into_scene_collection_sync_h.py
new file mode 100644
index 00000000000..0b9b19594e0
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_h.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', [
+ ['ii', None],
+ ]],
+ ['3', [
+ ['dog', None],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['ii'].move_into(tree['2']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_i.py b/tests/python/render_layer/test_move_into_scene_collection_sync_i.py
new file mode 100644
index 00000000000..752b6507b12
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_i.py
@@ -0,0 +1,57 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ reference_tree_map = [
+ ['A', [
+ ['i', None],
+ ['iii', None],
+ ]],
+ ['B', None],
+ ['C', [
+ ['1', None],
+ ['2', None],
+ ['3', [
+ ['dog', [
+ ['ii', None],
+ ]],
+ ['cat', None],
+ ]],
+ ]],
+ ]
+ return reference_tree_map
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertTrue(tree['ii'].move_into(tree['dog']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_j.py b/tests/python/render_layer/test_move_into_scene_collection_sync_j.py
new file mode 100644
index 00000000000..5f3de6b095d
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_j.py
@@ -0,0 +1,48 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+
+ tree = self.setup_tree()
+
+ for collection in tree.values():
+ # can't move into master_collection anywhere
+ self.assertFalse(master_collection.move_into(collection))
+
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_k.py b/tests/python/render_layer/test_move_into_scene_collection_sync_k.py
new file mode 100644
index 00000000000..3ed3ccb28ae
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_k.py
@@ -0,0 +1,41 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_into(tree['2']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_move_into_scene_collection_sync_l.py b/tests/python/render_layer/test_move_into_scene_collection_sync_l.py
new file mode 100644
index 00000000000..a1e0605254f
--- /dev/null
+++ b/tests/python/render_layer/test_move_into_scene_collection_sync_l.py
@@ -0,0 +1,41 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(MoveSceneCollectionSyncTesting):
+ def get_reference_scene_tree_map(self):
+ # original tree, no changes
+ return self.get_initial_scene_tree_map()
+
+ def test_scene_collection_into(self):
+ """
+ Test outliner operations
+ """
+ tree = self.setup_tree()
+ self.assertFalse(tree['C'].move_into(tree['cat']))
+ self.compare_tree_maps()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_add_cylinder.py b/tests/python/render_layer/test_object_add_cylinder.py
new file mode 100644
index 00000000000..d8cd030dff1
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_cylinder.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_syncing_object_add_cylinder(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.mesh.primitive_cylinder_add()
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_object_add_cylinder.json')
+ self.do_object_add(filepath_json, 'CYLINDER')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_add_empty.py b/tests/python/render_layer/test_object_add_empty.py
new file mode 100644
index 00000000000..b7e1d2729b7
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_empty.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_syncing_object_add_empty(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.object.add()
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_object_add_empty.json')
+ self.do_object_add(filepath_json, 'EMPTY')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_add_no_collection_cylinder.py b/tests/python/render_layer/test_object_add_no_collection_cylinder.py
new file mode 100644
index 00000000000..31752b1eb05
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_no_collection_cylinder.py
@@ -0,0 +1,37 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_object_add_cylinder(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.mesh.primitive_cylinder_add()
+ """
+ import os
+ self.do_object_add_no_collection('CYLINDER')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_add_no_collection_empty.py b/tests/python/render_layer/test_object_add_no_collection_empty.py
new file mode 100644
index 00000000000..5eb87f6a3c5
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_no_collection_empty.py
@@ -0,0 +1,36 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_syncing_object_add_empty(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.object.add()
+ """
+ self.do_object_add_no_collection('EMPTY')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_add_no_collection_torus.py b/tests/python/render_layer/test_object_add_no_collection_torus.py
new file mode 100644
index 00000000000..1e0ca3ee9ce
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_no_collection_torus.py
@@ -0,0 +1,36 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_syncing_object_add_torus(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.mesh.primitive_torus_add()
+ """
+ self.do_object_add_no_collection('TORUS')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_add_torus.py b/tests/python/render_layer/test_object_add_torus.py
new file mode 100644
index 00000000000..9c4096ce2ec
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_torus.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_syncing_object_add_torus(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.mesh.primitive_torus_add()
+ """
+ import os
+ ROOT = self.get_root()
+ filepath_json = os.path.join(ROOT, 'layers_object_add_torus.json')
+ self.do_object_add(filepath_json, 'TORUS')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_copy.py b/tests/python/render_layer/test_object_copy.py
new file mode 100644
index 00000000000..468fbbd7207
--- /dev/null
+++ b/tests/python/render_layer/test_object_copy.py
@@ -0,0 +1,98 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def do_object_copy(self, mode):
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ ROOT = self.get_root()
+ with tempfile.TemporaryDirectory() as dirpath:
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ filepath_json = os.path.join(ROOT, 'layers_object_copy_duplicate.json')
+
+ # open file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # create sub-collections
+ three_b = bpy.data.objects.get('T.3b')
+ three_c = bpy.data.objects.get('T.3c')
+
+ scene = bpy.context.scene
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = subzero.collections.new('scorpion')
+ subzero.objects.link(three_b)
+ scorpion.objects.link(three_c)
+ layer = scene.render_layers.new('Fresh new Layer')
+ layer.collections.link(subzero)
+
+ scene.render_layers.active_index = len(scene.render_layers) - 1
+
+ if mode == 'DUPLICATE':
+ # assuming the latest layer is the active layer
+ bpy.ops.object.select_all(action='DESELECT')
+ three_c.select_set(action='SELECT')
+ bpy.ops.object.duplicate()
+
+ elif mode == 'NAMED':
+ bpy.ops.object.add_named(name=three_c.name)
+
+ # save file
+ filepath_objects = os.path.join(dirpath, 'objects.blend')
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_objects)
+
+ # get the generated json
+ datas = query_scene(filepath_objects, 'Main', (get_scene_collections, get_layers))
+ self.assertTrue(datas, "Data is not valid")
+
+ filepath_objects_json = os.path.join(dirpath, "objects.json")
+ with open(filepath_objects_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_objects_json,
+ filepath_json,
+ ),
+ "Scene dump files differ")
+
+ def test_copy_object(self):
+ """
+ OBJECT_OT_duplicate
+ """
+ self.do_object_copy('DUPLICATE')
+
+ def test_copy_object_named(self):
+ """
+ OBJECT_OT_add_named
+ """
+ self.do_object_copy('NAMED')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_delete_a.py b/tests/python/render_layer/test_object_delete_a.py
new file mode 100644
index 00000000000..500ace0da89
--- /dev/null
+++ b/tests/python/render_layer/test_object_delete_a.py
@@ -0,0 +1,36 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_object_delete_data(self):
+ """
+ See if objects are removed correctly from all related collections
+ bpy.data.objects.remove()
+ """
+ self.do_object_delete('DATA')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_delete_b.py b/tests/python/render_layer/test_object_delete_b.py
new file mode 100644
index 00000000000..890864568a9
--- /dev/null
+++ b/tests/python/render_layer/test_object_delete_b.py
@@ -0,0 +1,36 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_object_delete_operator(self):
+ """
+ See if new objects are added to the correct collection
+ bpy.ops.object.del()
+ """
+ self.do_object_delete('OPERATOR')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_link_a.py b/tests/python/render_layer/test_object_link_a.py
new file mode 100644
index 00000000000..21018019d36
--- /dev/null
+++ b/tests/python/render_layer/test_object_link_a.py
@@ -0,0 +1,37 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_object_link_scene(self):
+ """
+ See if we can link objects
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+ self.do_object_link(master_collection)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_link_b.py b/tests/python/render_layer/test_object_link_b.py
new file mode 100644
index 00000000000..0895a5ef3b5
--- /dev/null
+++ b/tests/python/render_layer/test_object_link_b.py
@@ -0,0 +1,38 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_object_link_context(self):
+ """
+ See if we can link objects via bpy.context.scene_collection
+ """
+ import bpy
+ bpy.context.scene.render_layers.active_index = len(bpy.context.scene.render_layers) - 1
+ master_collection = bpy.context.scene_collection
+ self.do_object_link(master_collection)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_object_link_c.py b/tests/python/render_layer/test_object_link_c.py
new file mode 100644
index 00000000000..6f4c33800d0
--- /dev/null
+++ b/tests/python/render_layer/test_object_link_c.py
@@ -0,0 +1,40 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_object_link_reload(self):
+ """
+ See if we can link objects and not crash
+ """
+ import bpy
+ master_collection = bpy.context.scene.master_collection
+ self.do_object_link(master_collection)
+
+ # force depsgraph to update
+ bpy.ops.wm.read_factory_settings()
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_operator_context.py b/tests/python/render_layer/test_operator_context.py
new file mode 100644
index 00000000000..865e8b7e32a
--- /dev/null
+++ b/tests/python/render_layer/test_operator_context.py
@@ -0,0 +1,133 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_operator_context(self):
+ """
+ See if render layer context is properly set/get with operators overrides
+ when we set render_layer in context, the collection should change as well
+ """
+ import bpy
+ import os
+
+ class SampleOperator(bpy.types.Operator):
+ bl_idname = "testing.sample"
+ bl_label = "Sample Operator"
+
+ render_layer = bpy.props.StringProperty(
+ default="Not Set",
+ options={'SKIP_SAVE'},
+ )
+
+ scene_collection = bpy.props.StringProperty(
+ default="",
+ options={'SKIP_SAVE'},
+ )
+
+ use_verbose = bpy.props.BoolProperty(
+ default=False,
+ options={'SKIP_SAVE'},
+ )
+
+ def execute(self, context):
+ render_layer = context.render_layer
+ ret = {'FINISHED'}
+
+ # this is simply playing safe
+ if render_layer.name != self.render_layer:
+ if self.use_verbose:
+ print('ERROR: Render Layer mismatch: "{0}" != "{1}"'.format(
+ render_layer.name, self.render_layer))
+ ret = {'CANCELLED'}
+
+ scene_collection_name = None
+ if self.scene_collection:
+ scene_collection_name = self.scene_collection
+ else:
+ scene_collection_name = render_layer.collections.active.name
+
+ # while this is the real test
+ if context.scene_collection.name != scene_collection_name:
+ if self.use_verbose:
+ print('ERROR: Scene Collection mismatch: "{0}" != "{1}"'.format(
+ context.scene_collection.name, scene_collection_name))
+ ret = {'CANCELLED'}
+ return ret
+
+ bpy.utils.register_class(SampleOperator)
+
+ # open sample file
+ ROOT = self.get_root()
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+
+ # change the file
+ three_b = bpy.data.objects.get('T.3b')
+ three_c = bpy.data.objects.get('T.3c')
+ scene = bpy.context.scene
+ subzero = scene.master_collection.collections['1'].collections.new('sub-zero')
+ scorpion = subzero.collections.new('scorpion')
+ subzero.objects.link(three_b)
+ scorpion.objects.link(three_c)
+ layer = scene.render_layers.new('Fresh new Layer')
+ layer.collections.unlink(layer.collections.active)
+ layer.collections.link(subzero)
+ layer.collections.active_index = 3
+ self.assertEqual(layer.collections.active.name, 'scorpion')
+
+ scene = bpy.context.scene
+ scene.render_layers.active_index = len(scene.render_layers) - 2
+ self.assertEqual(scene.render_layers.active.name, "Viewport")
+
+ # old layer
+ self.assertEqual(bpy.ops.testing.sample(render_layer='Viewport', use_verbose=True), {'FINISHED'})
+
+ # expected to fail
+ self.assertTrue(bpy.ops.testing.sample(render_layer=layer.name), {'CANCELLED'})
+
+ # set render layer and scene collection
+ override = bpy.context.copy()
+ override["render_layer"] = layer
+ override["scene_collection"] = subzero
+ self.assertEqual(bpy.ops.testing.sample(
+ override,
+ render_layer=layer.name,
+ scene_collection=subzero.name, # 'sub-zero'
+ use_verbose=True), {'FINISHED'})
+
+ # set only render layer
+ override = bpy.context.copy()
+ override["render_layer"] = layer
+
+ self.assertEqual(bpy.ops.testing.sample(
+ override,
+ render_layer=layer.name,
+ scene_collection=layer.collections.active.name, # 'scorpion'
+ use_verbose=True), {'FINISHED'})
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_scene_copy_a.py b/tests/python/render_layer/test_scene_copy_a.py
new file mode 100644
index 00000000000..146bc4d3aac
--- /dev/null
+++ b/tests/python/render_layer/test_scene_copy_a.py
@@ -0,0 +1,42 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_scene_collections_copy_full(self):
+ """
+ See if scene copying 'FULL_COPY' is working for scene collections
+ """
+ import os
+ ROOT = self.get_root()
+
+ filepath_layers_json_copy = os.path.join(ROOT, 'layers_copy_full_simple.json')
+ self.do_scene_copy(
+ filepath_layers_json_copy,
+ 'FULL_COPY',
+ (get_scene_collections,))
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_scene_copy_b.py b/tests/python/render_layer/test_scene_copy_b.py
new file mode 100644
index 00000000000..4a9cfa8c281
--- /dev/null
+++ b/tests/python/render_layer/test_scene_copy_b.py
@@ -0,0 +1,43 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_scene_collections_link(self):
+ """
+ See if scene copying 'LINK_OBJECTS' is working for scene collections
+ """
+ import os
+ ROOT = self.get_root()
+
+ # note: nothing should change, so using `layers_simple.json`
+ filepath_layers_json_copy = os.path.join(ROOT, 'layers_simple.json')
+ self.do_scene_copy(
+ filepath_layers_json_copy,
+ 'LINK_OBJECTS',
+ (get_scene_collections,))
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_scene_copy_c.py b/tests/python/render_layer/test_scene_copy_c.py
new file mode 100644
index 00000000000..fdddc8b6a89
--- /dev/null
+++ b/tests/python/render_layer/test_scene_copy_c.py
@@ -0,0 +1,42 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_scene_layers_copy(self):
+ """
+ See if scene copying 'FULL_COPY' is working for scene layers
+ """
+ import os
+ ROOT = self.get_root()
+
+ filepath_layers_json_copy = os.path.join(ROOT, 'layers_copy_full.json')
+ self.do_scene_copy(
+ filepath_layers_json_copy,
+ 'FULL_COPY',
+ (get_scene_collections, get_layers))
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_scene_copy_d.py b/tests/python/render_layer/test_scene_copy_d.py
new file mode 100644
index 00000000000..ea0c33ed678
--- /dev/null
+++ b/tests/python/render_layer/test_scene_copy_d.py
@@ -0,0 +1,42 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_scene_layers_link(self):
+ """
+ See if scene copying 'FULL_COPY' is working for scene layers
+ """
+ import os
+ ROOT = self.get_root()
+
+ filepath_layers_json_copy = os.path.join(ROOT, 'layers_copy_link.json')
+ self.do_scene_copy(
+ filepath_layers_json_copy,
+ 'LINK_OBJECTS',
+ (get_scene_collections, get_layers))
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_scene_write_read.py b/tests/python/render_layer/test_scene_write_read.py
new file mode 100644
index 00000000000..2f061227d65
--- /dev/null
+++ b/tests/python/render_layer/test_scene_write_read.py
@@ -0,0 +1,149 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def do_scene_write_read(self, filepath_layers, filepath_layers_json, data_callbacks, do_read):
+ """
+ See if write/read is working for scene collections and layers
+ """
+ import bpy
+ import os
+ import tempfile
+ import filecmp
+
+ with tempfile.TemporaryDirectory() as dirpath:
+ (self.path_exists(f) for f in (filepath_layers, filepath_layers_json))
+
+ filepath_doversion = os.path.join(dirpath, 'doversion.blend')
+ filepath_saved = os.path.join(dirpath, 'doversion_saved.blend')
+ filepath_read_json = os.path.join(dirpath, "read.json")
+
+ # doversion + write test
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_layers)
+ self.rename_collections()
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_doversion)
+
+ datas = query_scene(filepath_doversion, 'Main', data_callbacks)
+ self.assertTrue(datas, "Data is not valid")
+
+ filepath_doversion_json = os.path.join(dirpath, "doversion.json")
+ with open(filepath_doversion_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_doversion_json,
+ filepath_layers_json,
+ ),
+ "Run: test_scene_write_layers")
+
+ if do_read:
+ # read test, simply open and save the file
+ bpy.ops.wm.open_mainfile('EXEC_DEFAULT', filepath=filepath_doversion)
+ self.rename_collections()
+ bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=filepath_saved)
+
+ datas = query_scene(filepath_saved, 'Main', data_callbacks)
+ self.assertTrue(datas, "Data is not valid")
+
+ with open(filepath_read_json, "w") as f:
+ for data in datas:
+ f.write(dump(data))
+
+ self.assertTrue(compare_files(
+ filepath_read_json,
+ filepath_layers_json,
+ ),
+ "Scene dump files differ")
+
+ def test_scene_write_collections(self):
+ """
+ See if the doversion and writing are working for scene collections
+ """
+ import os
+
+ ROOT = self.get_root()
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ filepath_layers_json = os.path.join(ROOT, 'layers_simple.json')
+
+ self.do_scene_write_read(
+ filepath_layers,
+ filepath_layers_json,
+ (get_scene_collections,),
+ False)
+
+ def test_scene_write_layers(self):
+ """
+ See if the doversion and writing are working for collections and layers
+ """
+ import os
+
+ ROOT = self.get_root()
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ filepath_layers_json = os.path.join(ROOT, 'layers.json')
+
+ self.do_scene_write_read(
+ filepath_layers,
+ filepath_layers_json,
+ (get_scene_collections, get_layers),
+ False)
+
+ def test_scene_read_collections(self):
+ """
+ See if read is working for scene collections
+ (run `test_scene_write_colections` first)
+ """
+ import os
+
+ ROOT = self.get_root()
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ filepath_layers_json = os.path.join(ROOT, 'layers_simple.json')
+
+ self.do_scene_write_read(
+ filepath_layers,
+ filepath_layers_json,
+ (get_scene_collections,),
+ True)
+
+ def test_scene_read_layers(self):
+ """
+ See if read is working for scene layers
+ (run `test_scene_write_layers` first)
+ """
+ import os
+
+ ROOT = self.get_root()
+ filepath_layers = os.path.join(ROOT, 'layers.blend')
+ filepath_layers_json = os.path.join(ROOT, 'layers.json')
+
+ self.do_scene_write_read(
+ filepath_layers,
+ filepath_layers_json,
+ (get_scene_collections, get_layers),
+ True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()